diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..ea93d99d --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,38 @@ +{ + "tasks": [ + { + "label": "Build Release [Linux]", + "type": "shell", + "command": "bash", + "args": [ + "-c", + "./build-linux.sh . Release && ${env:HOME}/.local/share/neoLegacy/minecraft-lce-client" + ], + "options": { + "cwd": "${workspaceFolder}" + }, + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Builds + runs the project in Release mode w/ build-linux.sh" + }, + { + "label": "Build Debug [Linux]", + "type": "shell", + "command": "bash", + "args": [ + "-c", + "./build-linux.sh . Debug && ${env:HOME}/.local/share/neoLegacy/minecraft-lce-client" + ], + "options": { + "cwd": "${workspaceFolder}" + }, + "problemMatcher": [], + "group": "build", + "detail": "Builds + runs the project in Debug mode w/ build-linux.sh" + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index e1e928c9..c2562f70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required(VERSION 3.24) +cmake_policy(SET CMP0057 NEW) project(LCE-Revelations LANGUAGES C CXX RC ASM_MASM) set(CMAKE_CXX_STANDARD 17) @@ -234,6 +235,8 @@ if(TARGET Minecraft.Server) add_dependencies(Minecraft.Server GenerateStringIdLookup) endif() +# item.h takes priority as some tile.h blocks are not meant to be accessed +# for example: the wheat 'block' (stage 1 wheat crop) is NOT supposed to override the normal wheat item set(_item_map_inputs "${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.World/Item.h" "${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.World/Tile.h" diff --git a/Minecraft.Client/AbstractTexturePack.cpp b/Minecraft.Client/AbstractTexturePack.cpp index 3adb09b0..5a92e830 100644 --- a/Minecraft.Client/AbstractTexturePack.cpp +++ b/Minecraft.Client/AbstractTexturePack.cpp @@ -35,6 +35,107 @@ wstring AbstractTexturePack::trim(wstring line) return line; } +namespace { + class XmlColourTableCallback : public ATG::ISAXCallback + { + public: + HRESULT StartDocument() override { return S_OK; } + HRESULT EndDocument() override { return S_OK; } + + HRESULT ElementBegin(CONST WCHAR *strName, UINT NameLen, CONST ATG::XMLAttribute *pAttributes, UINT NumAttributes) override + { + const wstring elementName(strName, NameLen); + if (!equalsIgnoreCase(elementName, L"colour")) + { + return S_OK; + } + + wstring colourName; + wstring colourValueText; + for(UINT i = 0; i < NumAttributes; ++i) + { + const ATG::XMLAttribute &attribute = pAttributes[i]; + if (attribute.strValue == nullptr) + { + continue; + } + + const wstring attributeName(attribute.strName, attribute.NameLen); + if (equalsIgnoreCase(attributeName, L"name")) + { + colourName.assign(attribute.strValue, attribute.ValueLen); + } + else if (equalsIgnoreCase(attributeName, L"value")) + { + colourValueText.assign(attribute.strValue, attribute.ValueLen); + } + } + + if (!colourName.empty() && !colourValueText.empty()) + { + if (colourValueText[0] == L'#') + { + colourValueText = colourValueText.substr(1); + } + int colourValue = _fromHEXString(colourValueText); + m_colours.emplace_back(colourName, colourValue); + } + + return S_OK; + } + + HRESULT ElementContent(CONST WCHAR *, UINT, BOOL) override { return S_OK; } + HRESULT ElementEnd(CONST WCHAR *, UINT) override { return S_OK; } + HRESULT CDATABegin() override { return S_OK; } + HRESULT CDATAData(CONST WCHAR *, UINT, BOOL) override { return S_OK; } + HRESULT CDATAEnd() override { return S_OK; } + + VOID Error(HRESULT hError, CONST CHAR *strMessage) override + { + app.DebugPrintf("colours.xml parse error (%08X): %s\n", hError, strMessage ? strMessage : "(unknown)"); + } + + vector> m_colours; + }; + + static bool loadColourTableFromXmlFile(File xmlFile, ColourTable *&outTable) + { + FileInputStream fis(xmlFile); + DWORD dwLength = xmlFile.length(); + if(dwLength == 0) return false; + + byteArray textData(static_cast(dwLength)); + fis.read(textData, 0, dwLength); + fis.close(); + + ATG::XMLParser parser; + XmlColourTableCallback callback; + parser.RegisterSAXCallbackInterface(&callback); + + HRESULT hr = parser.ParseXMLBuffer(reinterpret_cast(textData.data), static_cast(dwLength)); + delete [] textData.data; + + if (FAILED(hr) || callback.m_colours.empty()) + return false; + + ByteArrayOutputStream baos; + DataOutputStream dos(&baos); + dos.writeInt(1); + dos.writeInt(static_cast(callback.m_colours.size())); + for (const auto &entry : callback.m_colours) + { + dos.writeUTF(entry.first); + dos.writeInt(entry.second); + } + + byteArray binaryData = baos.toByteArray(); + outTable = new ColourTable(binaryData.data, binaryData.length); + delete [] binaryData.data; + + return true; + } +} + void AbstractTexturePack::loadIcon() { #ifdef _XBOX @@ -223,7 +324,7 @@ wstring AbstractTexturePack::getAnimationString(const wstring &textureName, cons BufferedImage *AbstractTexturePack::getImageResource(const wstring& File, bool filenameHasExtension /*= false*/, bool bTitleUpdateTexture /*=false*/, const wstring &drive /*=L""*/) { const char *pchTexture=wstringtofilename(File); - app.DebugPrintf("AbstractTexturePack::getImageResource - %s, drive is %s\n",pchTexture, wstringtofilename(drive)); + // app.DebugPrintf("AbstractTexturePack::getImageResource - %s, drive is %s\n",pchTexture, wstringtofilename(drive)); return new BufferedImage(TexturePack::getResource(L"/" + File),filenameHasExtension,bTitleUpdateTexture,drive); } @@ -261,12 +362,12 @@ void AbstractTexturePack::loadDefaultColourTable() #ifdef __PS3__ // need to check if it's a BD build, so pass in the name File coloursFile(AbstractTexturePack::getPath(true,app.GetBootedFromDiscPatch()?"colours.col":nullptr).append(L"res/colours.col")); - + File coloursXmlFile(AbstractTexturePack::getPath(true,app.GetBootedFromDiscPatch()?"colours.xml":nullptr).append(L"res/colours.xml")); #else File coloursFile(AbstractTexturePack::getPath(true).append(L"res/colours.col")); + File coloursXmlFile(AbstractTexturePack::getPath(true).append(L"res/colours.xml")); #endif - if(coloursFile.exists()) { DWORD dwLength = coloursFile.length(); @@ -280,6 +381,16 @@ void AbstractTexturePack::loadDefaultColourTable() delete [] data.data; } + else if(coloursXmlFile.exists()) + { + app.DebugPrintf("Default colours table not found, loading colours.xml fallback\n"); + if(m_colourTable != nullptr) delete m_colourTable; + if(!loadColourTableFromXmlFile(coloursXmlFile, m_colourTable)) + { + app.DebugPrintf("Failed to load colours.xml as a fallback\n"); + app.FatalLoadError(); + } + } else { app.DebugPrintf("Failed to load the default colours table\n"); diff --git a/Minecraft.Client/ArchiveFile.cpp b/Minecraft.Client/ArchiveFile.cpp index defef24e..9914cecd 100644 --- a/Minecraft.Client/ArchiveFile.cpp +++ b/Minecraft.Client/ArchiveFile.cpp @@ -4,6 +4,7 @@ #include "../Minecraft.World/compression.h" #include "ArchiveFile.h" +#include "lce_filesystem/FolderFile.h" void ArchiveFile::_readHeader(DataInputStream *dis) { @@ -28,10 +29,19 @@ void ArchiveFile::_readHeader(DataInputStream *dis) } } -ArchiveFile::ArchiveFile(File file) +ArchiveFile::ArchiveFile(File file, bool allowFolder) { m_cachedData = nullptr; + m_folderFile = nullptr; + m_useFolder = false; m_sourcefile = file; + + if(allowFolder && file.exists() && file.isDirectory()) + { + m_folderFile = new FolderFile(file.getPath()); + m_useFolder = true; + return; + } app.DebugPrintf("Loading archive file...\n"); #ifndef _CONTENT_PACKAGE char buf[256]; @@ -72,10 +82,15 @@ ArchiveFile::ArchiveFile(File file) ArchiveFile::~ArchiveFile() { delete m_cachedData; + delete m_folderFile; } vector *ArchiveFile::getFileList() { + if(m_useFolder) + { + return m_folderFile->getFileList(); + } vector *out = new vector(); for ( const auto& it : m_index ) @@ -86,16 +101,28 @@ vector *ArchiveFile::getFileList() bool ArchiveFile::hasFile(const wstring &filename) { + if(m_useFolder) + { + return m_folderFile->hasFile(filename); + } return m_index.find(filename) != m_index.end(); } int ArchiveFile::getFileSize(const wstring &filename) { + if(m_useFolder) + { + return m_folderFile->getFileSize(filename); + } return hasFile(filename) ? m_index.at(filename)->filesize : -1; } byteArray ArchiveFile::getFile(const wstring &filename) { + if(m_useFolder) + { + return m_folderFile->getFile(filename); + } byteArray out; auto it = m_index.find(filename); diff --git a/Minecraft.Client/ArchiveFile.h b/Minecraft.Client/ArchiveFile.h index f529e806..9e21e337 100644 --- a/Minecraft.Client/ArchiveFile.h +++ b/Minecraft.Client/ArchiveFile.h @@ -8,11 +8,15 @@ using namespace std; +class FolderFile; + class ArchiveFile { protected: File m_sourcefile; BYTE *m_cachedData; + FolderFile *m_folderFile; + bool m_useFolder; typedef struct _MetaData { @@ -28,7 +32,7 @@ protected: public: void _readHeader(DataInputStream *dis); - ArchiveFile(File file); + ArchiveFile(File file, bool allowFolder = false); ~ArchiveFile(); vector *getFileList(); diff --git a/Minecraft.Client/BeaconRenderer.cpp b/Minecraft.Client/BeaconRenderer.cpp index 2922a336..986e3cda 100644 --- a/Minecraft.Client/BeaconRenderer.cpp +++ b/Minecraft.Client/BeaconRenderer.cpp @@ -88,7 +88,7 @@ void BeaconRenderer::render(shared_ptr _beacon, double x, double y, segments.push_back({curR, curG, curB, 1}); } - else if (tileID == 0 || tileID == Tile::glass_Id || tileID == Tile::thinGlass_Id) { + else if (tileID == 0 || tileID == Tile::glass_Id || tileID == Tile::glass_pane_Id) { if (segments.empty()) { segments.push_back({1.0f, 1.0f, 1.0f, 1}); } else { @@ -113,7 +113,7 @@ void BeaconRenderer::render(shared_ptr _beacon, double x, double y, glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthMask(true); - double currentYBase = 0; + double currentYBase = 1; for (const auto& seg : segments) { int r = (int)(seg.r * 255); int g = (int)(seg.g * 255); @@ -163,7 +163,7 @@ void BeaconRenderer::render(shared_ptr _beacon, double x, double y, glDepthMask(false); - currentYBase = 0; + currentYBase = 1; for (const auto& seg : segments) { int r = (int)(seg.r * 255); int g = (int)(seg.g * 255); diff --git a/Minecraft.Client/BufferedImage.cpp b/Minecraft.Client/BufferedImage.cpp index 2dcf2b5e..aa214e15 100644 --- a/Minecraft.Client/BufferedImage.cpp +++ b/Minecraft.Client/BufferedImage.cpp @@ -163,7 +163,7 @@ BufferedImage::BufferedImage(const wstring& File, bool filenameHasExtension /*=f const char *pchTextureName=wstringtofilename(name); #ifndef _CONTENT_PACKAGE - app.DebugPrintf("\n--- Loading TEXTURE - %s\n\n",pchTextureName); + // app.DebugPrintf("\n--- Loading TEXTURE - %s\n\n",pchTextureName); #endif D3DXIMAGE_INFO ImageInfo; @@ -209,16 +209,34 @@ BufferedImage::BufferedImage(DLCPack *dlcPack, const wstring& File, bool filenam { mipMapPath = L"MipMapLevel" + std::to_wstring(l+1); } + wstring basePath; if( filenameHasExtension ) { - name = L"res" + filePath.substr(0,filePath.length()); + basePath = filePath; } else { - name = L"res" + filePath.substr(0,filePath.length()-4) + mipMapPath + L".png"; + basePath = filePath.substr(0,filePath.length()-4) + mipMapPath + L".png"; } - if(!dlcPack->doesPackContainFile(DLCManager::e_DLCType_All, name)) + wstring candidates[2] = + { + L"res" + basePath, + L"x16Data/res" + basePath + }; + + bool found = false; + for (const auto &candidate : candidates) + { + if (dlcPack->doesPackContainFile(DLCManager::e_DLCType_All, candidate)) + { + name = candidate; + found = true; + break; + } + } + + if(!found) { // 4J - If we haven't loaded the non-mipmap version then exit the game if( l == 0 ) diff --git a/Minecraft.Client/CMakeLists.txt b/Minecraft.Client/CMakeLists.txt index 7e435a1d..fe87cc40 100644 --- a/Minecraft.Client/CMakeLists.txt +++ b/Minecraft.Client/CMakeLists.txt @@ -148,6 +148,18 @@ endif() # Copy redist files add_copyredist_target(Minecraft.Client) +# replace col file with xml file +add_custom_target(AssetTitleUpdateColourOverride_Minecraft.Client ALL + COMMAND ${CMAKE_COMMAND} -E remove "$/Common/res/TitleUpdate/res/colours.col" + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${CMAKE_CURRENT_SOURCE_DIR}/Common/res/TitleUpdate/res/colours.xml" + "$/Common/res/TitleUpdate/res/colours.xml" + VERBATIM +) +add_dependencies(AssetTitleUpdateColourOverride_Minecraft.Client AssetFolderCopy_Minecraft.Client) +add_dependencies(Minecraft.Client AssetTitleUpdateColourOverride_Minecraft.Client) +set_property(TARGET AssetTitleUpdateColourOverride_Minecraft.Client PROPERTY FOLDER "Build") + # Make sure GameHDD exists on Windows if(PLATFORM_NAME STREQUAL "Windows64") add_gamehdd_target(Minecraft.Client) diff --git a/Minecraft.Client/Camera.cpp b/Minecraft.Client/Camera.cpp index 0216149f..5d7c8717 100644 --- a/Minecraft.Client/Camera.cpp +++ b/Minecraft.Client/Camera.cpp @@ -111,7 +111,9 @@ int Camera::getBlockAt(Level *level, shared_ptr player, float alph Vec3 *p = Camera::getCameraPos(player, alpha); TilePos tp = TilePos(p); int t = level->getTile(tp.x, tp.y, tp.z); - if (t != 0 && Tile::tiles[t]->material->isLiquid()) + Tile *tile = Tile::tiles[t]; + if (tile == nullptr) return 0; // tu31 tutorial world fix + if (t != 0 && tile->material->isLiquid()) { float hh = LiquidTile::getHeight(level->getData(tp.x, tp.y, tp.z)) - 1 / 9.0f; float h = tp.y + 1 - hh; diff --git a/Minecraft.Client/Chunk.cpp b/Minecraft.Client/Chunk.cpp index d64e6243..afea63a0 100644 --- a/Minecraft.Client/Chunk.cpp +++ b/Minecraft.Client/Chunk.cpp @@ -181,6 +181,7 @@ void Chunk::makeCopyForRebuild(Chunk *source) void Chunk::rebuild() { + if (this == nullptr) return; PIXBeginNamedEvent(0,"Rebuilding chunk %d, %d, %d", x, y, z); #if defined __PS3__ && !defined DISABLE_SPU_CODE rebuild_SPU(); @@ -281,15 +282,15 @@ void Chunk::rebuild() // Establish whether this tile and its neighbours are all made of rock, dirt, unbreakable tiles, or have already // been determined to meet this criteria themselves and have a tile of 255 set. - if( !( ( tileId == Tile::stone_Id ) || ( tileId == Tile::dirt_Id ) || ( tileId == Tile::unbreakable_Id ) || ( tileId == 255) ) ) continue; + if( !( ( tileId == Tile::stone_Id ) || ( tileId == Tile::dirt_Id ) || ( tileId == Tile::bedrock_Id ) || ( tileId == 255) ) ) continue; tileId = tileIds[ offset + ( ( ( xx - 1 ) << 11 ) | ( ( zz + 0 ) << 7 ) | ( indexY + 0 )) ]; - if( !( ( tileId == Tile::stone_Id ) || ( tileId == Tile::dirt_Id ) || ( tileId == Tile::unbreakable_Id ) || ( tileId == 255) ) ) continue; + if( !( ( tileId == Tile::stone_Id ) || ( tileId == Tile::dirt_Id ) || ( tileId == Tile::bedrock_Id ) || ( tileId == 255) ) ) continue; tileId = tileIds[ offset + ( ( ( xx + 1 ) << 11 ) | ( ( zz + 0 ) << 7 ) | ( indexY + 0 )) ]; - if( !( ( tileId == Tile::stone_Id ) || ( tileId == Tile::dirt_Id ) || ( tileId == Tile::unbreakable_Id ) || ( tileId == 255) ) ) continue; + if( !( ( tileId == Tile::stone_Id ) || ( tileId == Tile::dirt_Id ) || ( tileId == Tile::bedrock_Id ) || ( tileId == 255) ) ) continue; tileId = tileIds[ offset + ( ( ( xx + 0 ) << 11 ) | ( ( zz - 1 ) << 7 ) | ( indexY + 0 )) ]; - if( !( ( tileId == Tile::stone_Id ) || ( tileId == Tile::dirt_Id ) || ( tileId == Tile::unbreakable_Id ) || ( tileId == 255) ) ) continue; + if( !( ( tileId == Tile::stone_Id ) || ( tileId == Tile::dirt_Id ) || ( tileId == Tile::bedrock_Id ) || ( tileId == 255) ) ) continue; tileId = tileIds[ offset + ( ( ( xx + 0 ) << 11 ) | ( ( zz + 1 ) << 7 ) | ( indexY + 0 )) ]; - if( !( ( tileId == Tile::stone_Id ) || ( tileId == Tile::dirt_Id ) || ( tileId == Tile::unbreakable_Id ) || ( tileId == 255) ) ) continue; + if( !( ( tileId == Tile::stone_Id ) || ( tileId == Tile::dirt_Id ) || ( tileId == Tile::bedrock_Id ) || ( tileId == 255) ) ) continue; // Treat the bottom of the world differently - we shouldn't ever be able to look up at this, so consider tiles as invisible // if they are surrounded on sides other than the bottom if( yy > 0 ) @@ -302,7 +303,7 @@ void Chunk::rebuild() yMinusOneOffset = Level::COMPRESSED_CHUNK_SECTION_TILES; } tileId = tileIds[ yMinusOneOffset + ( ( ( xx + 0 ) << 11 ) | ( ( zz + 0 ) << 7 ) | indexYMinusOne ) ]; - if( !( ( tileId == Tile::stone_Id ) || ( tileId == Tile::dirt_Id ) || ( tileId == Tile::unbreakable_Id ) || ( tileId == 255) ) ) continue; + if( !( ( tileId == Tile::stone_Id ) || ( tileId == Tile::dirt_Id ) || ( tileId == Tile::bedrock_Id ) || ( tileId == 255) ) ) continue; } int indexYPlusOne = yy + 1; int yPlusOneOffset = 0; @@ -312,7 +313,7 @@ void Chunk::rebuild() yPlusOneOffset = Level::COMPRESSED_CHUNK_SECTION_TILES; } tileId = tileIds[ yPlusOneOffset + ( ( ( xx + 0 ) << 11 ) | ( ( zz + 0 ) << 7 ) | indexYPlusOne ) ]; - if( !( ( tileId == Tile::stone_Id ) || ( tileId == Tile::dirt_Id ) || ( tileId == Tile::unbreakable_Id ) || ( tileId == 255) ) ) continue; + if( !( ( tileId == Tile::stone_Id ) || ( tileId == Tile::dirt_Id ) || ( tileId == Tile::bedrock_Id ) || ( tileId == 255) ) ) continue; // This tile is surrounded. Flag it as not requiring to be rendered by setting its id to 255. tileIds[ offset + ( ( ( xx + 0 ) << 11 ) | ( ( zz + 0 ) << 7 ) | ( indexY + 0 ) ) ] = 0xff; @@ -324,12 +325,14 @@ void Chunk::rebuild() if( empty ) { // 4J - added - clear any renderer data associated with this - for (int currentLayer = 0; currentLayer < 2; currentLayer++) + for (int currentLayer = 0; currentLayer < LevelRenderer::CHUNK_RENDER_LAYERS; currentLayer++) { - levelRenderer->setGlobalChunkFlag(this->x, this->y, this->z, level, LevelRenderer::CHUNK_FLAG_EMPTY0, currentLayer); + if (currentLayer < 2) + { + levelRenderer->setGlobalChunkFlag(this->x, this->y, this->z, level, LevelRenderer::CHUNK_FLAG_EMPTY0, currentLayer); + } RenderManager.CBuffClear(lists + currentLayer); } - RenderManager.CBuffClear(lists + 2); delete region; delete tileRenderer; @@ -404,6 +407,10 @@ void Chunk::rebuild() } Tile *tile = Tile::tiles[tileId]; + if (tile == nullptr) + { + continue; + } if (currentLayer == 0 && tile->isEntityTile()) { shared_ptr et = region->getTileEntity(x, y, z); @@ -416,6 +423,10 @@ void Chunk::rebuild() if (renderLayer > currentLayer) { + if (currentLayer == 1 && tile == Tile::slimeBlock) + { + rendered |= tileRenderer->tesselateSlimeInnerInWorld(tile, x, y, z); + } renderNextLayer = true; } else if (renderLayer == currentLayer) @@ -474,13 +485,26 @@ void Chunk::rebuild() if((currentLayer==0)&&(!renderNextLayer)) { levelRenderer->setGlobalChunkFlag(this->x, this->y, this->z, level, LevelRenderer::CHUNK_FLAG_EMPTY1); - RenderManager.CBuffClear(lists + 1); - RenderManager.CBuffClear(lists + 2); + for (int clearLayer = 1; clearLayer < LevelRenderer::CHUNK_RENDER_LAYERS; clearLayer++) + { + RenderManager.CBuffClear(lists + clearLayer); + } break; } if((currentLayer==1)&&(!renderNextLayer)) { - RenderManager.CBuffClear(lists + 2); + for (int clearLayer = 2; clearLayer < LevelRenderer::CHUNK_RENDER_LAYERS; clearLayer++) + { + RenderManager.CBuffClear(lists + clearLayer); + } + break; + } + if((currentLayer==2)&&(!renderNextLayer)) + { + for (int clearLayer = 3; clearLayer < LevelRenderer::CHUNK_RENDER_LAYERS; clearLayer++) + { + RenderManager.CBuffClear(lists + clearLayer); + } break; } } diff --git a/Minecraft.Client/ClientConnection.cpp b/Minecraft.Client/ClientConnection.cpp index 93e238ae..8fb1ceb7 100644 --- a/Minecraft.Client/ClientConnection.cpp +++ b/Minecraft.Client/ClientConnection.cpp @@ -574,7 +574,20 @@ void ClientConnection::handleAddEntity(shared_ptr packet) int iz = (int) z; app.DebugPrintf("ClientConnection ITEM_FRAME xyz %d,%d,%d\n",ix,iy,iz); } - e = std::make_shared(level, (int)x, (int)y, (int)z, packet->data); + { + int dir = packet->data & 0xFF; + bool placedByPlayer = (packet->data & 0x100) != 0; + e = std::make_shared(level, (int)x, (int)y, (int)z, dir); + shared_ptr frame = dynamic_pointer_cast(e); + if (frame != nullptr) + { + frame->placedByPlayer = placedByPlayer; + if (placedByPlayer) + { + frame->setDir(dir); + } + } + } packet->data = 0; setRot = false; break; @@ -706,7 +719,7 @@ void ClientConnection::handleAddEntity(shared_ptr packet) if (packet->type == AddEntityPacket::ENDER_CRYSTAL) e = shared_ptr( new EnderCrystal(level, x, y, z) ); if (packet->type == AddEntityPacket::FALLING_SAND) e = shared_ptr( new FallingTile(level, x, y, z, Tile::sand->id) ); if (packet->type == AddEntityPacket::FALLING_GRAVEL) e = shared_ptr( new FallingTile(level, x, y, z, Tile::gravel->id) ); - if (packet->type == AddEntityPacket::FALLING_EGG) e = shared_ptr( new FallingTile(level, x, y, z, Tile::dragonEgg_Id) ); + if (packet->type == AddEntityPacket::FALLING_EGG) e = shared_ptr( new FallingTile(level, x, y, z, Tile::dragon_egg_Id) ); */ @@ -828,6 +841,11 @@ void ClientConnection::handleAddGlobalEntity(shared_ptr p void ClientConnection::handleAddPainting(shared_ptr packet) { shared_ptr painting = std::make_shared(level, packet->x, packet->y, packet->z, packet->dir, packet->motive); + painting->placedByPlayer = packet->placedByPlayer; + if (packet->placedByPlayer) + { + painting->setDir(packet->dir); + } level->putEntity(packet->id, painting); m_trackedEntityIds.insert(packet->id); } @@ -1337,11 +1355,11 @@ void ClientConnection::handleChunkTilesUpdate(shared_ptr // Don't bother setting this to dirty if it isn't going to visually change - we get a lot of // water changing from static to dynamic for instance - if(!( ( ( prevTile == Tile::water_Id ) && ( tile == Tile::calmWater_Id ) ) || - ( ( prevTile == Tile::calmWater_Id ) && ( tile == Tile::water_Id ) ) || - ( ( prevTile == Tile::lava_Id ) && ( tile == Tile::calmLava_Id ) ) || - ( ( prevTile == Tile::calmLava_Id ) && ( tile == Tile::calmLava_Id ) ) || - ( ( prevTile == Tile::calmLava_Id ) && ( tile == Tile::lava_Id ) ) ) ) + if(!( ( ( prevTile == Tile::flowing_water_Id ) && ( tile == Tile::water_Id ) ) || + ( ( prevTile == Tile::water_Id ) && ( tile == Tile::flowing_water_Id ) ) || + ( ( prevTile == Tile::flowing_lava_Id ) && ( tile == Tile::lava_Id ) ) || + ( ( prevTile == Tile::lava_Id ) && ( tile == Tile::lava_Id ) ) || + ( ( prevTile == Tile::lava_Id ) && ( tile == Tile::flowing_lava_Id ) ) ) ) { dimensionLevel->setTilesDirty(x + xo, y, z + zo, x + xo, y, z + zo); } @@ -3160,10 +3178,10 @@ void ClientConnection::handleContainerOpen(shared_ptr packe break; case ContainerOpenPacket::BREWING_STAND: { - shared_ptr brewingStand = std::make_shared(); - if (packet->customName) brewingStand->setCustomName(packet->title); + shared_ptr brewing_stand = std::make_shared(); + if (packet->customName) brewing_stand->setCustomName(packet->title); - if( player->openBrewingStand(brewingStand)) + if( player->openBrewingStand(brewing_stand)) { player->containerMenu->containerId = packet->containerId; } diff --git a/Minecraft.Client/ClockTexture.cpp b/Minecraft.Client/ClockTexture.cpp index 340cc0d3..ab16da0b 100644 --- a/Minecraft.Client/ClockTexture.cpp +++ b/Minecraft.Client/ClockTexture.cpp @@ -23,8 +23,12 @@ ClockTexture::ClockTexture(int iPad, ClockTexture *dataTexture) : StitchedTextur void ClockTexture::cycleFrames() { - Minecraft *mc = Minecraft::GetInstance(); + int frameCount = getFrames(); + if (frameCount <= 0) + { + return; + } double rott = 0; if (m_iPad >= 0 && m_iPad < XUSER_MAX_COUNT && mc->level != nullptr && mc->localplayers[m_iPad] != nullptr) @@ -57,10 +61,10 @@ void ClockTexture::cycleFrames() // 4J Stu - We share data with another texture if(m_dataTexture != nullptr) { - int newFrame = static_cast((rot + 1.0) * m_dataTexture->frames->size()) % m_dataTexture->frames->size(); + int newFrame = static_cast((rot + 1.0) * frameCount) % frameCount; while (newFrame < 0) { - newFrame = (newFrame + m_dataTexture->frames->size()) % m_dataTexture->frames->size(); + newFrame = (newFrame + frameCount) % frameCount; } if (newFrame != frame) { @@ -70,10 +74,10 @@ void ClockTexture::cycleFrames() } else { - int newFrame = static_cast((rot + 1.0) * frames->size()) % frames->size(); + int newFrame = static_cast((rot + 1.0) * frameCount) % frameCount; while (newFrame < 0) { - newFrame = (newFrame + frames->size()) % frames->size(); + newFrame = (newFrame + frameCount) % frameCount; } if (newFrame != frame) { diff --git a/Minecraft.Client/Common/App_Defines.h b/Minecraft.Client/Common/App_Defines.h index eeb9942d..28b02191 100644 --- a/Minecraft.Client/Common/App_Defines.h +++ b/Minecraft.Client/Common/App_Defines.h @@ -108,7 +108,11 @@ enum EGameHostOptionWorldSize #define GAMESETTING_VSYNC 0x01000000 #define GAMESETTING_EXCLUSIVEFULLSCREEN 0x02000000 #define GAMESETTING_CLASSICCRAFTING 0x04000000 -#define GAMESETTING_HIDESAVESIZEBAR 0x08000000 +#define GAMESETTING_CAVESOUNDS 0x08000000 +#define GAMESETTING_MINECARTSOUNDS 0x10000000 +#define GAMESETTING_HIDESAVESIZEBAR 0x20000000 +#define GAMESETTING_SAFECAM 0x40000000 +#define GAMESETTING_SWAP 0x80000000 // defines for languages diff --git a/Minecraft.Client/Common/App_enums.h b/Minecraft.Client/Common/App_enums.h index 981e407e..f546a289 100644 --- a/Minecraft.Client/Common/App_enums.h +++ b/Minecraft.Client/Common/App_enums.h @@ -1,976 +1,985 @@ -#pragma once - -enum eFileExtensionType -{ - eFileExtensionType_PNG=0, - eFileExtensionType_INF, - eFileExtensionType_DAT, -}; - -enum eTMSFileType -{ - eTMSFileType_MinecraftStore=0, - eTMSFileType_TexturePack, - eTMSFileType_All -}; - -enum eTPDFileType -{ - eTPDFileType_Loc=0, - eTPDFileType_Icon, -// eTPDFileType_Banner, - eTPDFileType_Comparison, -}; - -enum eFont -{ - eFont_European=0, - eFont_Korean, - eFont_Japanese, - eFont_Chinese, - eFont_None, // to fallback to nothing -}; - -enum eXuiAction -{ - eAppAction_Idle=0, - eAppAction_SaveGame, - eAppAction_SaveGameCapturedThumbnail, - eAppAction_ExitWorld, - eAppAction_ExitWorldCapturedThumbnail, - eAppAction_ExitWorldTrial, - //eAppAction_ExitGameFatalLoadError, - eAppAction_Respawn, - eAppAction_WaitForRespawnComplete, - eAppAction_PrimaryPlayerSignedOut, - eAppAction_PrimaryPlayerSignedOutReturned, - eAppAction_PrimaryPlayerSignedOutReturned_Menus, - eAppAction_ExitPlayer, // secondary player - eAppAction_ExitPlayerPreLogin, - eAppAction_TrialOver, - eAppAction_ExitTrial, - eAppAction_WaitForDimensionChangeComplete, - eAppAction_SocialPost, - eAppAction_SocialPostScreenshot, - eAppAction_EthernetDisconnected, - eAppAction_EthernetDisconnectedReturned, - eAppAction_EthernetDisconnectedReturned_Menus, - eAppAction_ExitAndJoinFromInvite, - eAppAction_DashboardTrialJoinFromInvite, - eAppAction_ExitAndJoinFromInviteConfirmed, - eAppAction_JoinFromInvite, - eAppAction_ChangeSessionType, - eAppAction_SetDefaultOptions, - eAppAction_LocalPlayerJoined, - eAppAction_RemoteServerSave, - eAppAction_WaitRemoteServerSaveComplete, - eAppAction_FailedToJoinNoPrivileges, - eAppAction_AutosaveSaveGame, - eAppAction_AutosaveSaveGameCapturedThumbnail, - eAppAction_ProfileReadError, - eAppAction_DisplayLavaMessage, - eAppAction_BanLevel, - eAppAction_LevelInBanLevelList, - - eAppAction_ReloadTexturePack, - eAppAction_ReloadFont, - eAppAction_TexturePackRequired, // when the user has joined from invite, but doesn't have the texture pack - -#ifdef __ORBIS__ - eAppAction_OptionsSaveNoSpace, -#endif - eAppAction_DebugText, - -}; - - - -enum eTMSAction -{ - eTMSAction_Idle=0, - eTMSAction_TMS_RetrieveFiles_Complete, - eTMSAction_TMSPP_RetrieveFiles_CreateLoad_SignInReturned, - eTMSAction_TMSPP_RetrieveFiles_RunPlayGame, - eTMSAction_TMSPP_RetrieveFiles_HelpAndOptions, - eTMSAction_TMSPP_RetrieveFiles_DLCMain, - eTMSAction_TMSPP_GlobalFileList, - eTMSAction_TMSPP_GlobalFileList_Waiting, -// eTMSAction_TMSPP_ConfigFile, -// eTMSAction_TMSPP_ConfigFile_Waiting, - eTMSAction_TMSPP_UserFileList, - eTMSAction_TMSPP_UserFileList_Waiting, - eTMSAction_TMSPP_XUIDSFile, - eTMSAction_TMSPP_XUIDSFile_Waiting, - eTMSAction_TMSPP_DLCFile, - eTMSAction_TMSPP_DLCFile_Waiting, - eTMSAction_TMSPP_BannedListFile, - eTMSAction_TMSPP_BannedListFile_Waiting, - eTMSAction_TMSPP_RetrieveFiles_Complete, - eTMSAction_TMSPP_DLCFileOnly, - eTMSAction_TMSPP_RetrieveUserFilelist_DLCFileOnly, -}; - -// The server runs on its own thread, so we need to call its actions there rather than where all other Xui actions are performed -// In general these are debugging options -enum eXuiServerAction -{ - eXuiServerAction_Idle=0, - eXuiServerAction_DropItem, // Debug - eXuiServerAction_SaveGame, - eXuiServerAction_AutoSaveGame, - eXuiServerAction_SpawnMob, // Debug - eXuiServerAction_PauseServer, - eXuiServerAction_ToggleRain, // Debug - eXuiServerAction_ToggleThunder, // Debug - eXuiServerAction_ServerSettingChanged_Gamertags, - eXuiServerAction_ServerSettingChanged_Difficulty, - eXuiServerAction_ExportSchematic, //Debug - eXuiServerAction_ServerSettingChanged_BedrockFog, - eXuiServerAction_SetCameraLocation, //Debug -}; - -enum eGameSetting -{ - eGameSetting_MusicVolume=0, - eGameSetting_SoundFXVolume, - eGameSetting_RenderDistance, - eGameSetting_Gamma, - eGameSetting_FOV, - eGameSetting_Difficulty, - eGameSetting_Sensitivity_InGame, - eGameSetting_Sensitivity_InMenu, - eGameSetting_ViewBob, - eGameSetting_ControlScheme, - eGameSetting_ControlInvertLook, - eGameSetting_ControlSouthPaw, - eGameSetting_SplitScreenVertical, - eGameSetting_GamertagsVisible, - // Interim TU 1.6.6 - eGameSetting_Autosave, - eGameSetting_DisplaySplitscreenGamertags, - eGameSetting_Hints, - eGameSetting_InterfaceOpacity, - eGameSetting_Tooltips, - // TU5 - eGameSetting_Clouds, - eGameSetting_Online, - eGameSetting_InviteOnly, - eGameSetting_FriendsOfFriends, - eGameSetting_DisplayUpdateMessage, - - // TU6 - eGameSetting_BedrockFog, - eGameSetting_DisplayHUD, - eGameSetting_DisplayHand, - - // TU7 - eGameSetting_CustomSkinAnim, - - // TU9 - eGameSetting_DeathMessages, - eGameSetting_UISize, - eGameSetting_UISizeSplitscreen, - eGameSetting_AnimatedCharacter, - - // PS3 - eGameSetting_PS3_EULA_Read, - - // PSVita - eGameSetting_PSVita_NetworkModeAdhoc, - - // PC - eGameSetting_VSync, - eGameSetting_ExclusiveFullscreen, - - //TU25 - eGameSetting_ClassicCrafting, - // if enabled hides the save size bar in loadcreatejoinmenu (load tab) - eGameSetting_HideSaveSizeBar, -}; - - - -enum eGameMode -{ - eMode_Singleplayer, - eMode_Multiplayer -}; - - -enum eMinecraftColour -{ - eMinecraftColour_NOT_SET, - - eMinecraftColour_Foliage_Evergreen, - eMinecraftColour_Foliage_Birch, - eMinecraftColour_Foliage_Default, - eMinecraftColour_Foliage_Common, - eMinecraftColour_Foliage_Ocean, - eMinecraftColour_Foliage_Plains, - eMinecraftColour_Foliage_Desert, - eMinecraftColour_Foliage_ExtremeHills, - eMinecraftColour_Foliage_Forest, - eMinecraftColour_Foliage_Taiga, - eMinecraftColour_Foliage_Swampland, - eMinecraftColour_Foliage_River, - eMinecraftColour_Foliage_Hell, - eMinecraftColour_Foliage_Sky, - eMinecraftColour_Foliage_FrozenOcean, - eMinecraftColour_Foliage_FrozenRiver, - eMinecraftColour_Foliage_IcePlains, - eMinecraftColour_Foliage_IceMountains, - eMinecraftColour_Foliage_MushroomIsland, - eMinecraftColour_Foliage_MushroomIslandShore, - eMinecraftColour_Foliage_Beach, - eMinecraftColour_Foliage_DesertHills, - eMinecraftColour_Foliage_ForestHills, - eMinecraftColour_Foliage_TaigaHills, - eMinecraftColour_Foliage_ExtremeHillsEdge, - eMinecraftColour_Foliage_Jungle, - eMinecraftColour_Foliage_JungleHills, - eMinecraftColour_Foliage_Savanna, - eMinecraftColour_Foliage_RoofedForest, - eMinecraftColour_Foliage_Mesa, - - eMinecraftColour_Grass_Common, - eMinecraftColour_Grass_Ocean, - eMinecraftColour_Grass_Plains, - eMinecraftColour_Grass_Desert, - eMinecraftColour_Grass_ExtremeHills, - eMinecraftColour_Grass_Forest, - eMinecraftColour_Grass_Taiga, - eMinecraftColour_Grass_Swampland, - eMinecraftColour_Grass_River, - eMinecraftColour_Grass_Hell, - eMinecraftColour_Grass_Sky, - eMinecraftColour_Grass_FrozenOcean, - eMinecraftColour_Grass_FrozenRiver, - eMinecraftColour_Grass_IcePlains, - eMinecraftColour_Grass_IceMountains, - eMinecraftColour_Grass_MushroomIsland, - eMinecraftColour_Grass_MushroomIslandShore, - eMinecraftColour_Grass_Beach, - eMinecraftColour_Grass_DesertHills, - eMinecraftColour_Grass_ForestHills, - eMinecraftColour_Grass_TaigaHills, - eMinecraftColour_Grass_ExtremeHillsEdge, - eMinecraftColour_Grass_Jungle, - eMinecraftColour_Grass_JungleHills, - eMinecraftColour_Grass_Savanna, - eMinecraftColour_Grass_RoofedForest, - eMinecraftColour_Grass_Mesa, - - eMinecraftColour_Water_Ocean, - eMinecraftColour_Water_Plains, - eMinecraftColour_Water_Desert, - eMinecraftColour_Water_ExtremeHills, - eMinecraftColour_Water_Forest, - eMinecraftColour_Water_Taiga, - eMinecraftColour_Water_Swampland, - eMinecraftColour_Water_River, - eMinecraftColour_Water_Hell, - eMinecraftColour_Water_Sky, - eMinecraftColour_Water_FrozenOcean, - eMinecraftColour_Water_FrozenRiver, - eMinecraftColour_Water_IcePlains, - eMinecraftColour_Water_IceMountains, - eMinecraftColour_Water_MushroomIsland, - eMinecraftColour_Water_MushroomIslandShore, - eMinecraftColour_Water_Beach, - eMinecraftColour_Water_DesertHills, - eMinecraftColour_Water_ForestHills, - eMinecraftColour_Water_TaigaHills, - eMinecraftColour_Water_ExtremeHillsEdge, - eMinecraftColour_Water_Jungle, - eMinecraftColour_Water_JungleHills, - eMinecraftColour_Water_Mesa, - - eMinecraftColour_Sky_Ocean, - eMinecraftColour_Sky_Plains, - eMinecraftColour_Sky_Desert, - eMinecraftColour_Sky_ExtremeHills, - eMinecraftColour_Sky_Forest, - eMinecraftColour_Sky_Taiga, - eMinecraftColour_Sky_Swampland, - eMinecraftColour_Sky_River, - eMinecraftColour_Sky_Hell, - eMinecraftColour_Sky_Sky, - eMinecraftColour_Sky_FrozenOcean, - eMinecraftColour_Sky_FrozenRiver, - eMinecraftColour_Sky_IcePlains, - eMinecraftColour_Sky_IceMountains, - eMinecraftColour_Sky_MushroomIsland, - eMinecraftColour_Sky_MushroomIslandShore, - eMinecraftColour_Sky_Beach, - eMinecraftColour_Sky_DesertHills, - eMinecraftColour_Sky_ForestHills, - eMinecraftColour_Sky_TaigaHills, - eMinecraftColour_Sky_ExtremeHillsEdge, - eMinecraftColour_Sky_Jungle, - eMinecraftColour_Sky_JungleHills, - - eMinecraftColour_Tile_RedstoneDust, - eMinecraftColour_Tile_RedstoneDustUnlit, - eMinecraftColour_Tile_RedstoneDustLitMin, - eMinecraftColour_Tile_RedstoneDustLitMax, - eMinecraftColour_Tile_StemMin, - eMinecraftColour_Tile_StemMax, - eMinecraftColour_Tile_WaterLily, - - eMinecraftColour_Sky_Dawn_Dark, - eMinecraftColour_Sky_Dawn_Bright, - - eMinecraftColour_Material_None, - eMinecraftColour_Material_Grass, - eMinecraftColour_Material_Sand, - eMinecraftColour_Material_Cloth, - eMinecraftColour_Material_Fire, - eMinecraftColour_Material_Ice, - eMinecraftColour_Material_Metal, - eMinecraftColour_Material_Plant, - eMinecraftColour_Material_Snow, - eMinecraftColour_Material_Clay, - eMinecraftColour_Material_Dirt, - eMinecraftColour_Material_Stone, - eMinecraftColour_Material_Water, - eMinecraftColour_Material_Wood, - eMinecraftColour_Material_Emerald, - - eMinecraftColour_Particle_Note_00, - eMinecraftColour_Particle_Note_01, - eMinecraftColour_Particle_Note_02, - eMinecraftColour_Particle_Note_03, - eMinecraftColour_Particle_Note_04, - eMinecraftColour_Particle_Note_05, - eMinecraftColour_Particle_Note_06, - eMinecraftColour_Particle_Note_07, - eMinecraftColour_Particle_Note_08, - eMinecraftColour_Particle_Note_09, - eMinecraftColour_Particle_Note_10, - eMinecraftColour_Particle_Note_11, - eMinecraftColour_Particle_Note_12, - eMinecraftColour_Particle_Note_13, - eMinecraftColour_Particle_Note_14, - eMinecraftColour_Particle_Note_15, - eMinecraftColour_Particle_Note_16, - eMinecraftColour_Particle_Note_17, - eMinecraftColour_Particle_Note_18, - eMinecraftColour_Particle_Note_19, - eMinecraftColour_Particle_Note_20, - eMinecraftColour_Particle_Note_21, - eMinecraftColour_Particle_Note_22, - eMinecraftColour_Particle_Note_23, - eMinecraftColour_Particle_Note_24, - - eMinecraftColour_Particle_NetherPortal, - eMinecraftColour_Particle_EnderPortal, - eMinecraftColour_Particle_Smoke, - eMinecraftColour_Particle_Ender, - eMinecraftColour_Particle_Explode, - eMinecraftColour_Particle_HugeExplosion, - eMinecraftColour_Particle_DripWater, - eMinecraftColour_Particle_DripLavaStart, - eMinecraftColour_Particle_DripLavaEnd, - eMinecraftColour_Particle_EnchantmentTable, - eMinecraftColour_Particle_DragonBreathMin, - eMinecraftColour_Particle_DragonBreathMax, - eMinecraftColour_Particle_Suspend, - eMinecraftColour_Particle_CritStart, - eMinecraftColour_Particle_CritEnd, - - eMinecraftColour_Effect_MovementSpeed, - eMinecraftColour_Effect_MovementSlowDown, - eMinecraftColour_Effect_DigSpeed, - eMinecraftColour_Effect_DigSlowdown, - eMinecraftColour_Effect_DamageBoost, - eMinecraftColour_Effect_Heal, - eMinecraftColour_Effect_Harm, - eMinecraftColour_Effect_Jump, - eMinecraftColour_Effect_Confusion, - eMinecraftColour_Effect_Regeneration, - eMinecraftColour_Effect_DamageResistance, - eMinecraftColour_Effect_FireResistance, - eMinecraftColour_Effect_WaterBreathing, - eMinecraftColour_Effect_Invisiblity, - eMinecraftColour_Effect_Blindness, - eMinecraftColour_Effect_NightVision, - eMinecraftColour_Effect_Hunger, - eMinecraftColour_Effect_Weakness, - eMinecraftColour_Effect_Poison, - eMinecraftColour_Effect_Wither, - eMinecraftColour_Effect_HealthBoost, - eMinecraftColour_Effect_Absoprtion, - eMinecraftColour_Effect_Saturation, - - eMinecraftColour_Potion_BaseColour, - - eMinecraftColour_Mob_Creeper_Colour1, - eMinecraftColour_Mob_Creeper_Colour2, - eMinecraftColour_Mob_Skeleton_Colour1, - eMinecraftColour_Mob_Skeleton_Colour2, - eMinecraftColour_Mob_Spider_Colour1, - eMinecraftColour_Mob_Spider_Colour2, - eMinecraftColour_Mob_Zombie_Colour1, - eMinecraftColour_Mob_Zombie_Colour2, - eMinecraftColour_Mob_Slime_Colour1, - eMinecraftColour_Mob_Slime_Colour2, - eMinecraftColour_Mob_Ghast_Colour1, - eMinecraftColour_Mob_Ghast_Colour2, - eMinecraftColour_Mob_PigZombie_Colour1, - eMinecraftColour_Mob_PigZombie_Colour2, - eMinecraftColour_Mob_Enderman_Colour1, - eMinecraftColour_Mob_Enderman_Colour2, - eMinecraftColour_Mob_CaveSpider_Colour1, - eMinecraftColour_Mob_CaveSpider_Colour2, - eMinecraftColour_Mob_Silverfish_Colour1, - eMinecraftColour_Mob_Silverfish_Colour2, - eMinecraftColour_Mob_Blaze_Colour1, - eMinecraftColour_Mob_Blaze_Colour2, - eMinecraftColour_Mob_LavaSlime_Colour1, - eMinecraftColour_Mob_LavaSlime_Colour2, - eMinecraftColour_Mob_Pig_Colour1, - eMinecraftColour_Mob_Pig_Colour2, - eMinecraftColour_Mob_Sheep_Colour1, - eMinecraftColour_Mob_Sheep_Colour2, - eMinecraftColour_Mob_Cow_Colour1, - eMinecraftColour_Mob_Cow_Colour2, - eMinecraftColour_Mob_Chicken_Colour1, - eMinecraftColour_Mob_Chicken_Colour2, - eMinecraftColour_Mob_Squid_Colour1, - eMinecraftColour_Mob_Squid_Colour2, - eMinecraftColour_Mob_Wolf_Colour1, - eMinecraftColour_Mob_Wolf_Colour2, - eMinecraftColour_Mob_MushroomCow_Colour1, - eMinecraftColour_Mob_MushroomCow_Colour2, - eMinecraftColour_Mob_Ocelot_Colour1, - eMinecraftColour_Mob_Ocelot_Colour2, - eMinecraftColour_Mob_Villager_Colour1, - eMinecraftColour_Mob_Villager_Colour2, - eMinecraftColour_Mob_Bat_Colour1, - eMinecraftColour_Mob_Bat_Colour2, - eMinecraftColour_Mob_Witch_Colour1, - eMinecraftColour_Mob_Witch_Colour2, - eMinecraftColour_Mob_Horse_Colour1, - eMinecraftColour_Mob_Horse_Colour2, - eMinecraftColour_Mob_Rabbit_Colour1, - eMinecraftColour_Mob_Rabbit_Colour2, - eMinecraftColour_Mob_Endermite_Colour1, - eMinecraftColour_Mob_Endermite_Colour2, - eMinecraftColour_Mob_Guardian_Colour1, - eMinecraftColour_Mob_Guardian_Colour2, - eMinecraftColour_Mob_ElderGuardian_Colour1, - eMinecraftColour_Mob_ElderGuardian_Colour2, - - eMinecraftColour_Armour_Default_Leather_Colour, - - eMinecraftColour_Under_Water_Clear_Colour, - eMinecraftColour_Under_Lava_Clear_Colour, - eMinecraftColour_In_Cloud_Base_Colour, - - eMinecraftColour_Under_Water_Fog_Colour, - eMinecraftColour_Under_Lava_Fog_Colour, - eMinecraftColour_In_Cloud_Fog_Colour, - - eMinecraftColour_Default_Fog_Colour, - eMinecraftColour_Nether_Fog_Colour, - eMinecraftColour_End_Fog_Colour, - - eMinecraftColour_Sign_Text, - eMinecraftColour_Map_Text, - - eMinecraftColour_Leash_Light_Colour, - eMinecraftColour_Leash_Dark_Colour, - - eMinecraftColour_Fire_Overlay, - - eHTMLColor_0, - eHTMLColor_1, - eHTMLColor_2, - eHTMLColor_3, - eHTMLColor_4, - eHTMLColor_5, - eHTMLColor_6, - eHTMLColor_7, - eHTMLColor_8, - eHTMLColor_9, - eHTMLColor_a, - eHTMLColor_b, - eHTMLColor_c, - eHTMLColor_d, - eHTMLColor_e, - eHTMLColor_f, - eHTMLColor_0_dark, - eHTMLColor_1_dark, - eHTMLColor_2_dark, - eHTMLColor_3_dark, - eHTMLColor_4_dark, - eHTMLColor_5_dark, - eHTMLColor_6_dark, - eHTMLColor_7_dark, - eHTMLColor_8_dark, - eHTMLColor_9_dark, - eHTMLColor_a_dark, - eHTMLColor_b_dark, - eHTMLColor_c_dark, - eHTMLColor_d_dark, - eHTMLColor_e_dark, - eHTMLColor_f_dark, - eHTMLColor_T1, - eHTMLColor_T2, - eHTMLColor_T3, - eHTMLColor_Black, - eHTMLColor_White, - - eTextColor_Enchant, - eTextColor_EnchantFocus, - eTextColor_EnchantDisabled, - eTextColor_RenamedItemTitle, - - //eHTMLColor_0 = 0x000000, //r:0 , g: 0, b: 0, i: 0 - //eHTMLColor_1 = 0x0000aa, //r:0 , g: 0, b: aa, i: 1 // blue, quite dark - //eHTMLColor_2 = 0x109e10, // Changed by request of Dave //0x00aa00, //r:0 , g: aa, b: 0, i: 2 // green - //eHTMLColor_3 = 0x109e9e, // Changed by request of Dave //0x00aaaa, //r:0 , g: aa, b: aa, i: 3 // cyan - //eHTMLColor_4 = 0xaa0000, //r:aa , g: 0, b: 0, i: 4 // red - //eHTMLColor_5 = 0xaa00aa, //r:aa , g: 0, b: aa, i: 5 // purple - //eHTMLColor_6 = 0xffaa00, //r:ff , g: aa, b: 0, i: 6 // orange - //eHTMLColor_7 = 0xaaaaaa, //r:aa , g: aa, b: aa, i: 7 // light gray - //eHTMLColor_8 = 0x555555, //r:55 , g: 55, b: 55, i: 8 // gray - //eHTMLColor_9 = 0x5555ff, //r:55 , g: 55, b: ff, i: 9 // blue - //eHTMLColor_a = 0x55ff55, //r:55 , g: ff, b: 55, i: a // green - //eHTMLColor_b = 0x55ffff, //r:55 , g: ff, b: ff, i: b // cyan - //eHTMLColor_c = 0xff5555, //r:ff , g: 55, b: 55, i: c // red pink - //eHTMLColor_d = 0xff55ff, //r:ff , g: 55, b: ff, i: d // bright pink - //eHTMLColor_e = 0xffff55, //r:ff , g: ff, b: 55, i: e // yellow - //eHTMLColor_f = 0xffffff, //r:ff , g: ff, b: ff, i: f - //eHTMLColor_0_dark = 0x000000, //r:0 , g: 0, b: 0, i: 10 - //eHTMLColor_1_dark = 0x00002a, //r:0 , g: 0, b: 2a, i: 11 - //eHTMLColor_2_dark = 0x002a00, //r:0 , g: 2a, b: 0, i: 12 - //eHTMLColor_3_dark = 0x002a2a, //r:0 , g: 2a, b: 2a, i: 13 - //eHTMLColor_4_dark = 0x2a0000, //r:2a , g: 0, b: 0, i: 14 - //eHTMLColor_5_dark = 0x2a002a, //r:2a , g: 0, b: 2a, i: 15 - //eHTMLColor_6_dark = 0x2a2a00, //r:2a , g: 2a, b: 0, i: 16 - //eHTMLColor_7_dark = 0x2a2a2a, //r:2a , g: 2a, b: 2a, i: 17 // dark gray - //eHTMLColor_8_dark = 0x151515, //r:15 , g: 15, b: 15, i: 18 - //eHTMLColor_9_dark = 0x15153f, //r:15 , g: 15, b: 3f, i: 19 - //eHTMLColor_a_dark = 0x153f15, //r:15 , g: 3f, b: 15, i: 1a - //eHTMLColor_b_dark = 0x153f3f, //r:15 , g: 3f, b: 3f, i: 1b - //eHTMLColor_c_dark = 0x3f1515, //r:3f , g: 15, b: 15, i: 1c // brown - //eHTMLColor_d_dark = 0x3f153f, //r:3f , g: 15, b: 3f, i: 1d - //eHTMLColor_e_dark = 0x3f3f15, //r:3f , g: 3f, b: 15, i: 1e - //eHTMLColor_f_dark = 0x3f3f3f, //r:3f , g: 3f, b: 3f, i: 1f - - eMinecraftColour_COUNT, -}; - -enum eDLCContentType -{ - e_DLC_SkinPack=0, - e_DLC_TexturePacks, - e_DLC_MashupPacks, - e_DLC_Themes, - e_DLC_AvatarItems, - e_DLC_Gamerpics, - e_DLC_MAX_MinecraftStore, - e_DLC_TexturePackData, // for the icon, banner and text - e_DLC_MAX, - e_DLC_NotDefined, -}; - -enum eDLCMarketplaceType -{ - e_Marketplace_Content=0, // skins, texture packs and mashup packs - e_Marketplace_Themes, - e_Marketplace_AvatarItems, - e_Marketplace_Gamerpics, - e_Marketplace_MAX, - e_Marketplace_NotDefined, -}; - -enum eDLCContentState -{ - e_DLC_ContentState_Idle = 0, - e_DLC_ContentState_Retrieving, - e_DLC_ContentState_Retrieved -}; - -enum eTMSContentState -{ - e_TMS_ContentState_Idle = 0, - e_TMS_ContentState_Queued, - e_TMS_ContentState_Retrieving, - e_TMS_ContentState_Retrieved -}; - -enum eXUID -{ - eXUID_Undefined=0, - eXUID_NoName, // name not needed - eXUID_Notch, - eXUID_Carl, - eXUID_Daniel, - eXUID_Deadmau5, - eXUID_DannyBStyle, - eXUID_JulianClark, - eXUID_Millionth, - eXUID_4JPaddy, - eXUID_4JStuart, - eXUID_4JDavid, - eXUID_4JRichard, - eXUID_4JSteven, -}; - - -enum _eTerrainFeatureType -{ - eTerrainFeature_None=0, - eTerrainFeature_Stronghold, - eTerrainFeature_Mineshaft, - eTerrainFeature_Village, - eTerrainFeature_Ravine, - eTerrainFeature_NetherFortress, - eTerrainFeature_StrongholdEndPortal, - eTerrainFeature_OceanMonument, - eTerrainFeature_Count -}; - -// 4J Stu - Whend adding new options you should consider whether having them on should disable achievements, and if so add them to the CanRecordStatsAndAchievements function -// 4J Stu - These options are now saved in save data, so new options can ONLY be added to the end -enum eGameHostOption -{ - eGameHostOption_Difficulty=0, - eGameHostOption_OnlineGame, // Unused - eGameHostOption_InviteOnly, // Unused - eGameHostOption_FriendsOfFriends, - eGameHostOption_Gamertags, - eGameHostOption_Tutorial, // special case - eGameHostOption_GameType, - eGameHostOption_LevelType, // flat or default - eGameHostOption_Structures, - eGameHostOption_BonusChest, - eGameHostOption_HasBeenInCreative, - eGameHostOption_PvP, - eGameHostOption_TrustPlayers, - eGameHostOption_TNT, - eGameHostOption_FireSpreads, - eGameHostOption_CheatsEnabled, // special case - eGameHostOption_HostCanFly, - eGameHostOption_HostCanChangeHunger, - eGameHostOption_HostCanBeInvisible, - eGameHostOption_BedrockFog, - eGameHostOption_NoHUD, - eGameHostOption_WorldSize, - eGameHostOption_All, - - eGameHostOption_DisableSaving, - eGameHostOption_WasntSaveOwner, // Added for PS3 save transfer, so we can add a nice message in the future instead of the creative mode one - - eGameHostOption_MobGriefing, - eGameHostOption_KeepInventory, - eGameHostOption_DoMobSpawning, - eGameHostOption_DoMobLoot, - eGameHostOption_DoTileDrops, - eGameHostOption_NaturalRegeneration, - eGameHostOption_DoDaylightCycle, - eGameHostOption_Hardcore, // 4J Added - for hardcore mode -}; - -// 4J-PB - If any new DLC items are added to the TMSFiles, this array needs updated -#ifdef _XBOX -enum _TMSFILES -{ - TMS_SP1=0, - TMS_SP2, - TMS_SP3, - TMS_SP4, - TMS_SP5, - TMS_SP6, - TMS_SPF, - TMS_SPB, - TMS_SPC, - TMS_SPZ, - TMS_SPM, - TMS_SPI, - TMS_SPG, - TMS_SPD1, - TMS_SPSW1, - - TMS_THST, - TMS_THIR, - TMS_THGO, - TMS_THDI, - TMS_THAW, - - TMS_GPAN, - TMS_GPCO, - TMS_GPEN, - TMS_GPFO, - TMS_GPTO, - TMS_GPBA, - TMS_GPFA, - TMS_GPME, - TMS_GPMF, - TMS_GPMM, - TMS_GPSE, - TMS_GPOr, - TMS_GPMi, - TMS_GPMB, - TMS_GPBr, - TMS_GPM1, - TMS_GPM2, - TMS_GPM3, - - TMS_AH_0001, - TMS_AH_0002, - TMS_AH_0003, - TMS_AH_0004, - TMS_AH_0005, - TMS_AH_0006, - TMS_AH_0007, - TMS_AH_0008, - TMS_AH_0009, - TMS_AH_0010, - TMS_AH_0011, - TMS_AH_0012, - TMS_AH_0013, - - TMS_AT_0001, - TMS_AT_0002, - TMS_AT_0003, - TMS_AT_0004, - TMS_AT_0005, - TMS_AT_0006, - TMS_AT_0007, - TMS_AT_0008, - TMS_AT_0009, - TMS_AT_0010, - TMS_AT_0011, - TMS_AT_0012, - TMS_AT_0013, - TMS_AT_0014, - TMS_AT_0015, - TMS_AT_0016, - TMS_AT_0017, - TMS_AT_0018, - TMS_AT_0019, - TMS_AT_0020, - TMS_AT_0021, - TMS_AT_0022, - TMS_AT_0023, - TMS_AT_0024, - TMS_AT_0025, - TMS_AT_0026, - - TMS_AP_0001, - TMS_AP_0002, - TMS_AP_0003, - TMS_AP_0004, - TMS_AP_0005, - TMS_AP_0006, - TMS_AP_0007, - TMS_AP_0009, - TMS_AP_0010, - TMS_AP_0011, - TMS_AP_0012, - TMS_AP_0013, - TMS_AP_0014, - TMS_AP_0015, - TMS_AP_0016, - TMS_AP_0017, - TMS_AP_0018, - - TMS_AP_0019, - TMS_AP_0020, - TMS_AP_0021, - TMS_AP_0022, - TMS_AP_0023, - TMS_AP_0024, - TMS_AP_0025, - TMS_AP_0026, - TMS_AP_0027, - TMS_AP_0028, - TMS_AP_0029, - TMS_AP_0030, - TMS_AP_0031, - TMS_AP_0032, - TMS_AP_0033, - - TMS_AA_0001, - - TMS_MPMA, - TMS_MPMA_DAT, - TMS_MPSR, - TMS_MPSR_DAT, - TMS_MPHA, - TMS_MPHA_DAT, - TMS_MPFE, - TMS_MPFE_DAT, - - TMS_TP01, - TMS_TP01_DAT, - TMS_TP02, - TMS_TP02_DAT, - TMS_TP04, - TMS_TP04_DAT, - TMS_TP05, - TMS_TP05_DAT, - TMS_TP06, - TMS_TP06_DAT, - TMS_TP07, - TMS_TP07_DAT, - TMS_TP08, - TMS_TP08_DAT, - - TMS_COUNT -}; -#endif - -enum EHTMLFontSize -{ - eHTMLSize_Normal, - eHTMLSize_Splitscreen, - eHTMLSize_Tutorial, - eHTMLSize_EndPoem, - - eHTMLSize_COUNT, -}; - -enum EControllerActions -{ - ACTION_MENU_A, - ACTION_MENU_B, - ACTION_MENU_X, - ACTION_MENU_Y, - ACTION_MENU_UP, - ACTION_MENU_DOWN, - ACTION_MENU_RIGHT, - ACTION_MENU_LEFT, - ACTION_MENU_PAGEUP, - ACTION_MENU_PAGEDOWN, - ACTION_MENU_RIGHT_SCROLL, - ACTION_MENU_LEFT_SCROLL, - ACTION_MENU_STICK_PRESS, - ACTION_MENU_OTHER_STICK_PRESS, - ACTION_MENU_OTHER_STICK_UP, - ACTION_MENU_OTHER_STICK_DOWN, - ACTION_MENU_OTHER_STICK_LEFT, - ACTION_MENU_OTHER_STICK_RIGHT, - ACTION_MENU_PAUSEMENU, - ACTION_MENU_QUICK_MOVE, - -#ifdef _DURANGO - ACTION_MENU_GTC_PAUSE, - ACTION_MENU_GTC_RESUME, -#endif - -#ifdef __ORBIS__ - ACTION_MENU_TOUCHPAD_PRESS, -#endif - - ACTION_MENU_OK, - ACTION_MENU_CANCEL, - ACTION_MAX_MENU = ACTION_MENU_CANCEL, - - MINECRAFT_ACTION_JUMP, - MINECRAFT_ACTION_FORWARD, - MINECRAFT_ACTION_BACKWARD, - MINECRAFT_ACTION_LEFT, - MINECRAFT_ACTION_RIGHT, - MINECRAFT_ACTION_LOOK_LEFT, - MINECRAFT_ACTION_LOOK_RIGHT, - MINECRAFT_ACTION_LOOK_UP, - MINECRAFT_ACTION_LOOK_DOWN, - MINECRAFT_ACTION_USE, - MINECRAFT_ACTION_ACTION, - MINECRAFT_ACTION_LEFT_SCROLL, - MINECRAFT_ACTION_RIGHT_SCROLL, - MINECRAFT_ACTION_INVENTORY, - MINECRAFT_ACTION_PAUSEMENU, - MINECRAFT_ACTION_DROP, - MINECRAFT_ACTION_SNEAK_TOGGLE, - MINECRAFT_ACTION_CRAFTING, - MINECRAFT_ACTION_RENDER_THIRD_PERSON, - MINECRAFT_ACTION_GAME_INFO, - MINECRAFT_ACTION_DPAD_LEFT, - MINECRAFT_ACTION_DPAD_RIGHT, - MINECRAFT_ACTION_DPAD_UP, - MINECRAFT_ACTION_DPAD_DOWN, - - MINECRAFT_ACTION_MAX, - - // These 4 aren't mapped to the input manager directly but are created from the dpad controls if required in Minecraft::run_middle - // Don't use them with the input manager directly, just through LocalPlayer::ullButtonsPressed - MINECRAFT_ACTION_SPAWN_CREEPER, - MINECRAFT_ACTION_CHANGE_SKIN, - MINECRAFT_ACTION_FLY_TOGGLE, - MINECRAFT_ACTION_RENDER_DEBUG, - MINECRAFT_ACTION_SCREENSHOT -}; - -enum eMCLang -{ - eMCLang_null=0, - eMCLang_enUS, - eMCLang_enGB, - eMCLang_enIE, - eMCLang_enAU, - eMCLang_enNZ, - eMCLang_enCA, - eMCLang_jaJP, - eMCLang_deDE, - eMCLang_deAT, - eMCLang_frFR, - eMCLang_frCA, - eMCLang_esES, - eMCLang_esMX, - eMCLang_itIT, - eMCLang_koKR, - eMCLang_ptPT, - eMCLang_ptBR, - eMCLang_ruRU, - eMCLang_nlNL, - eMCLang_fiFI, - eMCLang_svSV, - eMCLang_daDA, - eMCLang_noNO, - eMCLang_plPL, - eMCLang_trTR, - eMCLang_elEL, - eMCLang_csCS, - eMCLang_zhCHT, - eMCLang_laLAS, - - eMCLang_zhSG, - eMCLang_zhCN, - eMCLang_zhHK, - eMCLang_zhTW, - eMCLang_nlBE, - eMCLang_daDK, - eMCLang_frBE, - eMCLang_frCH, - eMCLang_deCH, - eMCLang_nbNO, - eMCLang_enGR, - eMCLang_enHK, - eMCLang_enSA, - eMCLang_enHU, - eMCLang_enIN, - eMCLang_enIL, - eMCLang_enSG, - eMCLang_enSK, - eMCLang_enZA, - eMCLang_enCZ, - eMCLang_enAE, - eMCLang_esAR, - eMCLang_esCL, - eMCLang_esCO, - eMCLang_esUS, - eMCLang_svSE, - - eMCLang_csCZ, - eMCLang_elGR, - eMCLang_nnNO, - eMCLang_skSK, - - eMCLang_hans, - eMCLang_hant, -}; +#pragma once + +enum eFileExtensionType +{ + eFileExtensionType_PNG=0, + eFileExtensionType_INF, + eFileExtensionType_DAT, +}; + +enum eTMSFileType +{ + eTMSFileType_MinecraftStore=0, + eTMSFileType_TexturePack, + eTMSFileType_All +}; + +enum eTPDFileType +{ + eTPDFileType_Loc=0, + eTPDFileType_Icon, +// eTPDFileType_Banner, + eTPDFileType_Comparison, +}; + +enum eFont +{ + eFont_European=0, + eFont_Korean, + eFont_Japanese, + eFont_Chinese, + eFont_None, // to fallback to nothing +}; + +enum eXuiAction +{ + eAppAction_Idle=0, + eAppAction_SaveGame, + eAppAction_SaveGameCapturedThumbnail, + eAppAction_ExitWorld, + eAppAction_ExitWorldCapturedThumbnail, + eAppAction_ExitWorldTrial, + //eAppAction_ExitGameFatalLoadError, + eAppAction_Respawn, + eAppAction_WaitForRespawnComplete, + eAppAction_PrimaryPlayerSignedOut, + eAppAction_PrimaryPlayerSignedOutReturned, + eAppAction_PrimaryPlayerSignedOutReturned_Menus, + eAppAction_ExitPlayer, // secondary player + eAppAction_ExitPlayerPreLogin, + eAppAction_TrialOver, + eAppAction_ExitTrial, + eAppAction_WaitForDimensionChangeComplete, + eAppAction_SocialPost, + eAppAction_SocialPostScreenshot, + eAppAction_EthernetDisconnected, + eAppAction_EthernetDisconnectedReturned, + eAppAction_EthernetDisconnectedReturned_Menus, + eAppAction_ExitAndJoinFromInvite, + eAppAction_DashboardTrialJoinFromInvite, + eAppAction_ExitAndJoinFromInviteConfirmed, + eAppAction_JoinFromInvite, + eAppAction_ChangeSessionType, + eAppAction_SetDefaultOptions, + eAppAction_LocalPlayerJoined, + eAppAction_RemoteServerSave, + eAppAction_WaitRemoteServerSaveComplete, + eAppAction_FailedToJoinNoPrivileges, + eAppAction_AutosaveSaveGame, + eAppAction_AutosaveSaveGameCapturedThumbnail, + eAppAction_ProfileReadError, + eAppAction_DisplayLavaMessage, + eAppAction_BanLevel, + eAppAction_LevelInBanLevelList, + + eAppAction_ReloadTexturePack, + eAppAction_ReloadFont, + eAppAction_TexturePackRequired, // when the user has joined from invite, but doesn't have the texture pack + +#ifdef __ORBIS__ + eAppAction_OptionsSaveNoSpace, +#endif + eAppAction_DebugText, + +}; + + + +enum eTMSAction +{ + eTMSAction_Idle=0, + eTMSAction_TMS_RetrieveFiles_Complete, + eTMSAction_TMSPP_RetrieveFiles_CreateLoad_SignInReturned, + eTMSAction_TMSPP_RetrieveFiles_RunPlayGame, + eTMSAction_TMSPP_RetrieveFiles_HelpAndOptions, + eTMSAction_TMSPP_RetrieveFiles_DLCMain, + eTMSAction_TMSPP_GlobalFileList, + eTMSAction_TMSPP_GlobalFileList_Waiting, +// eTMSAction_TMSPP_ConfigFile, +// eTMSAction_TMSPP_ConfigFile_Waiting, + eTMSAction_TMSPP_UserFileList, + eTMSAction_TMSPP_UserFileList_Waiting, + eTMSAction_TMSPP_XUIDSFile, + eTMSAction_TMSPP_XUIDSFile_Waiting, + eTMSAction_TMSPP_DLCFile, + eTMSAction_TMSPP_DLCFile_Waiting, + eTMSAction_TMSPP_BannedListFile, + eTMSAction_TMSPP_BannedListFile_Waiting, + eTMSAction_TMSPP_RetrieveFiles_Complete, + eTMSAction_TMSPP_DLCFileOnly, + eTMSAction_TMSPP_RetrieveUserFilelist_DLCFileOnly, +}; + +// The server runs on its own thread, so we need to call its actions there rather than where all other Xui actions are performed +// In general these are debugging options +enum eXuiServerAction +{ + eXuiServerAction_Idle=0, + eXuiServerAction_DropItem, // Debug + eXuiServerAction_SaveGame, + eXuiServerAction_AutoSaveGame, + eXuiServerAction_SpawnMob, // Debug + eXuiServerAction_PauseServer, + eXuiServerAction_ToggleRain, // Debug + eXuiServerAction_ToggleThunder, // Debug + eXuiServerAction_ServerSettingChanged_Gamertags, + eXuiServerAction_ServerSettingChanged_Difficulty, + eXuiServerAction_ExportSchematic, //Debug + eXuiServerAction_ServerSettingChanged_BedrockFog, + eXuiServerAction_SetCameraLocation, //Debug +}; + +enum eGameSetting +{ + eGameSetting_MusicVolume=0, + eGameSetting_SoundFXVolume, + eGameSetting_RenderDistance, + eGameSetting_Gamma, + eGameSetting_FOV, + eGameSetting_Difficulty, + eGameSetting_Sensitivity_InGame, + eGameSetting_Sensitivity_InMenu, + eGameSetting_ViewBob, + eGameSetting_ControlScheme, + eGameSetting_ControlInvertLook, + eGameSetting_ControlSouthPaw, + eGameSetting_SplitScreenVertical, + eGameSetting_GamertagsVisible, + // Interim TU 1.6.6 + eGameSetting_Autosave, + eGameSetting_DisplaySplitscreenGamertags, + eGameSetting_Hints, + eGameSetting_InterfaceOpacity, + eGameSetting_Tooltips, + // TU5 + eGameSetting_Clouds, + eGameSetting_Online, + eGameSetting_InviteOnly, + eGameSetting_FriendsOfFriends, + eGameSetting_DisplayUpdateMessage, + + // TU6 + eGameSetting_BedrockFog, + eGameSetting_DisplayHUD, + eGameSetting_DisplayHand, + + // TU7 + eGameSetting_CustomSkinAnim, + + // TU9 + eGameSetting_DeathMessages, + eGameSetting_UISize, + eGameSetting_UISizeSplitscreen, + eGameSetting_AnimatedCharacter, + + // PS3 + eGameSetting_PS3_EULA_Read, + + // PSVita + eGameSetting_PSVita_NetworkModeAdhoc, + + // PC + eGameSetting_VSync, + eGameSetting_ExclusiveFullscreen, + + //TU25 + eGameSetting_ClassicCrafting, + eGameSetting_CaveSounds, + eGameSetting_MinecartSounds, + eGameSetting_ControlType, + // if enabled hides the save size bar in loadcreatejoinmenu (load tab) + eGameSetting_HideSaveSizeBar, + // TU31 + eGameSetting_SafeCam, //safe cam is safe sprint + eGameSetting_Swap, + eGameSetting_GameChat, +}; + + + +enum eGameMode +{ + eMode_Singleplayer, + eMode_Multiplayer +}; + + +enum eMinecraftColour +{ + eMinecraftColour_NOT_SET, + + eMinecraftColour_Foliage_Evergreen, + eMinecraftColour_Foliage_Birch, + eMinecraftColour_Foliage_Default, + eMinecraftColour_Foliage_Common, + eMinecraftColour_Foliage_Ocean, + eMinecraftColour_Foliage_Plains, + eMinecraftColour_Foliage_Desert, + eMinecraftColour_Foliage_ExtremeHills, + eMinecraftColour_Foliage_Forest, + eMinecraftColour_Foliage_Taiga, + eMinecraftColour_Foliage_Swampland, + eMinecraftColour_Foliage_River, + eMinecraftColour_Foliage_Hell, + eMinecraftColour_Foliage_Sky, + eMinecraftColour_Foliage_FrozenOcean, + eMinecraftColour_Foliage_FrozenRiver, + eMinecraftColour_Foliage_IcePlains, + eMinecraftColour_Foliage_IceMountains, + eMinecraftColour_Foliage_MushroomIsland, + eMinecraftColour_Foliage_MushroomIslandShore, + eMinecraftColour_Foliage_Beach, + eMinecraftColour_Foliage_DesertHills, + eMinecraftColour_Foliage_ForestHills, + eMinecraftColour_Foliage_TaigaHills, + eMinecraftColour_Foliage_ExtremeHillsEdge, + eMinecraftColour_Foliage_Jungle, + eMinecraftColour_Foliage_JungleHills, + eMinecraftColour_Foliage_Savanna, + eMinecraftColour_Foliage_RoofedForest, + eMinecraftColour_Foliage_Mesa, + + eMinecraftColour_Grass_Common, + eMinecraftColour_Grass_Ocean, + eMinecraftColour_Grass_Plains, + eMinecraftColour_Grass_Desert, + eMinecraftColour_Grass_ExtremeHills, + eMinecraftColour_Grass_Forest, + eMinecraftColour_Grass_Taiga, + eMinecraftColour_Grass_Swampland, + eMinecraftColour_Grass_River, + eMinecraftColour_Grass_Hell, + eMinecraftColour_Grass_Sky, + eMinecraftColour_Grass_FrozenOcean, + eMinecraftColour_Grass_FrozenRiver, + eMinecraftColour_Grass_IcePlains, + eMinecraftColour_Grass_IceMountains, + eMinecraftColour_Grass_MushroomIsland, + eMinecraftColour_Grass_MushroomIslandShore, + eMinecraftColour_Grass_Beach, + eMinecraftColour_Grass_DesertHills, + eMinecraftColour_Grass_ForestHills, + eMinecraftColour_Grass_TaigaHills, + eMinecraftColour_Grass_ExtremeHillsEdge, + eMinecraftColour_Grass_Jungle, + eMinecraftColour_Grass_JungleHills, + eMinecraftColour_Grass_Savanna, + eMinecraftColour_Grass_RoofedForest, + eMinecraftColour_Grass_Mesa, + + eMinecraftColour_Water_Ocean, + eMinecraftColour_Water_Plains, + eMinecraftColour_Water_Desert, + eMinecraftColour_Water_ExtremeHills, + eMinecraftColour_Water_Forest, + eMinecraftColour_Water_Taiga, + eMinecraftColour_Water_Swampland, + eMinecraftColour_Water_River, + eMinecraftColour_Water_Hell, + eMinecraftColour_Water_Sky, + eMinecraftColour_Water_FrozenOcean, + eMinecraftColour_Water_FrozenRiver, + eMinecraftColour_Water_IcePlains, + eMinecraftColour_Water_IceMountains, + eMinecraftColour_Water_MushroomIsland, + eMinecraftColour_Water_MushroomIslandShore, + eMinecraftColour_Water_Beach, + eMinecraftColour_Water_DesertHills, + eMinecraftColour_Water_ForestHills, + eMinecraftColour_Water_TaigaHills, + eMinecraftColour_Water_ExtremeHillsEdge, + eMinecraftColour_Water_Jungle, + eMinecraftColour_Water_JungleHills, + eMinecraftColour_Water_JungleEdge, + eMinecraftColour_Water_Mesa, + + eMinecraftColour_Sky_Ocean, + eMinecraftColour_Sky_Plains, + eMinecraftColour_Sky_Desert, + eMinecraftColour_Sky_ExtremeHills, + eMinecraftColour_Sky_Forest, + eMinecraftColour_Sky_Taiga, + eMinecraftColour_Sky_Swampland, + eMinecraftColour_Sky_River, + eMinecraftColour_Sky_Hell, + eMinecraftColour_Sky_Sky, + eMinecraftColour_Sky_FrozenOcean, + eMinecraftColour_Sky_FrozenRiver, + eMinecraftColour_Sky_IcePlains, + eMinecraftColour_Sky_IceMountains, + eMinecraftColour_Sky_MushroomIsland, + eMinecraftColour_Sky_MushroomIslandShore, + eMinecraftColour_Sky_Beach, + eMinecraftColour_Sky_DesertHills, + eMinecraftColour_Sky_ForestHills, + eMinecraftColour_Sky_TaigaHills, + eMinecraftColour_Sky_ExtremeHillsEdge, + eMinecraftColour_Sky_Jungle, + eMinecraftColour_Sky_JungleHills, + eMinecraftColour_Sky_JungleEdge, + + eMinecraftColour_Tile_RedstoneDust, + eMinecraftColour_Tile_RedstoneDustUnlit, + eMinecraftColour_Tile_RedstoneDustLitMin, + eMinecraftColour_Tile_RedstoneDustLitMax, + eMinecraftColour_Tile_StemMin, + eMinecraftColour_Tile_StemMax, + eMinecraftColour_Tile_WaterLily, + + eMinecraftColour_Sky_Dawn_Dark, + eMinecraftColour_Sky_Dawn_Bright, + + eMinecraftColour_Material_None, + eMinecraftColour_Material_Grass, + eMinecraftColour_Material_Sand, + eMinecraftColour_Material_Cloth, + eMinecraftColour_Material_Fire, + eMinecraftColour_Material_Ice, + eMinecraftColour_Material_Metal, + eMinecraftColour_Material_Plant, + eMinecraftColour_Material_Snow, + eMinecraftColour_Material_Clay, + eMinecraftColour_Material_Dirt, + eMinecraftColour_Material_Stone, + eMinecraftColour_Material_Water, + eMinecraftColour_Material_Wood, + eMinecraftColour_Material_Emerald, + + eMinecraftColour_Particle_Note_00, + eMinecraftColour_Particle_Note_01, + eMinecraftColour_Particle_Note_02, + eMinecraftColour_Particle_Note_03, + eMinecraftColour_Particle_Note_04, + eMinecraftColour_Particle_Note_05, + eMinecraftColour_Particle_Note_06, + eMinecraftColour_Particle_Note_07, + eMinecraftColour_Particle_Note_08, + eMinecraftColour_Particle_Note_09, + eMinecraftColour_Particle_Note_10, + eMinecraftColour_Particle_Note_11, + eMinecraftColour_Particle_Note_12, + eMinecraftColour_Particle_Note_13, + eMinecraftColour_Particle_Note_14, + eMinecraftColour_Particle_Note_15, + eMinecraftColour_Particle_Note_16, + eMinecraftColour_Particle_Note_17, + eMinecraftColour_Particle_Note_18, + eMinecraftColour_Particle_Note_19, + eMinecraftColour_Particle_Note_20, + eMinecraftColour_Particle_Note_21, + eMinecraftColour_Particle_Note_22, + eMinecraftColour_Particle_Note_23, + eMinecraftColour_Particle_Note_24, + + eMinecraftColour_Particle_NetherPortal, + eMinecraftColour_Particle_EnderPortal, + eMinecraftColour_Particle_Smoke, + eMinecraftColour_Particle_Ender, + eMinecraftColour_Particle_Explode, + eMinecraftColour_Particle_HugeExplosion, + eMinecraftColour_Particle_DripWater, + eMinecraftColour_Particle_DripLavaStart, + eMinecraftColour_Particle_DripLavaEnd, + eMinecraftColour_Particle_EnchantmentTable, + eMinecraftColour_Particle_DragonBreathMin, + eMinecraftColour_Particle_DragonBreathMax, + eMinecraftColour_Particle_Suspend, + eMinecraftColour_Particle_CritStart, + eMinecraftColour_Particle_CritEnd, + + eMinecraftColour_Effect_MovementSpeed, + eMinecraftColour_Effect_MovementSlowDown, + eMinecraftColour_Effect_DigSpeed, + eMinecraftColour_Effect_DigSlowdown, + eMinecraftColour_Effect_DamageBoost, + eMinecraftColour_Effect_Heal, + eMinecraftColour_Effect_Harm, + eMinecraftColour_Effect_Jump, + eMinecraftColour_Effect_Confusion, + eMinecraftColour_Effect_Regeneration, + eMinecraftColour_Effect_DamageResistance, + eMinecraftColour_Effect_FireResistance, + eMinecraftColour_Effect_WaterBreathing, + eMinecraftColour_Effect_Invisiblity, + eMinecraftColour_Effect_Blindness, + eMinecraftColour_Effect_NightVision, + eMinecraftColour_Effect_Hunger, + eMinecraftColour_Effect_Weakness, + eMinecraftColour_Effect_Poison, + eMinecraftColour_Effect_Wither, + eMinecraftColour_Effect_HealthBoost, + eMinecraftColour_Effect_Absoprtion, + eMinecraftColour_Effect_Saturation, + + eMinecraftColour_Potion_BaseColour, + + eMinecraftColour_Mob_Creeper_Colour1, + eMinecraftColour_Mob_Creeper_Colour2, + eMinecraftColour_Mob_Skeleton_Colour1, + eMinecraftColour_Mob_Skeleton_Colour2, + eMinecraftColour_Mob_Spider_Colour1, + eMinecraftColour_Mob_Spider_Colour2, + eMinecraftColour_Mob_Zombie_Colour1, + eMinecraftColour_Mob_Zombie_Colour2, + eMinecraftColour_Mob_Slime_Colour1, + eMinecraftColour_Mob_Slime_Colour2, + eMinecraftColour_Mob_Ghast_Colour1, + eMinecraftColour_Mob_Ghast_Colour2, + eMinecraftColour_Mob_PigZombie_Colour1, + eMinecraftColour_Mob_PigZombie_Colour2, + eMinecraftColour_Mob_Enderman_Colour1, + eMinecraftColour_Mob_Enderman_Colour2, + eMinecraftColour_Mob_CaveSpider_Colour1, + eMinecraftColour_Mob_CaveSpider_Colour2, + eMinecraftColour_Mob_Silverfish_Colour1, + eMinecraftColour_Mob_Silverfish_Colour2, + eMinecraftColour_Mob_Blaze_Colour1, + eMinecraftColour_Mob_Blaze_Colour2, + eMinecraftColour_Mob_LavaSlime_Colour1, + eMinecraftColour_Mob_LavaSlime_Colour2, + eMinecraftColour_Mob_Pig_Colour1, + eMinecraftColour_Mob_Pig_Colour2, + eMinecraftColour_Mob_Sheep_Colour1, + eMinecraftColour_Mob_Sheep_Colour2, + eMinecraftColour_Mob_Cow_Colour1, + eMinecraftColour_Mob_Cow_Colour2, + eMinecraftColour_Mob_Chicken_Colour1, + eMinecraftColour_Mob_Chicken_Colour2, + eMinecraftColour_Mob_Squid_Colour1, + eMinecraftColour_Mob_Squid_Colour2, + eMinecraftColour_Mob_Wolf_Colour1, + eMinecraftColour_Mob_Wolf_Colour2, + eMinecraftColour_Mob_MushroomCow_Colour1, + eMinecraftColour_Mob_MushroomCow_Colour2, + eMinecraftColour_Mob_Ocelot_Colour1, + eMinecraftColour_Mob_Ocelot_Colour2, + eMinecraftColour_Mob_Villager_Colour1, + eMinecraftColour_Mob_Villager_Colour2, + eMinecraftColour_Mob_Bat_Colour1, + eMinecraftColour_Mob_Bat_Colour2, + eMinecraftColour_Mob_Witch_Colour1, + eMinecraftColour_Mob_Witch_Colour2, + eMinecraftColour_Mob_Horse_Colour1, + eMinecraftColour_Mob_Horse_Colour2, + eMinecraftColour_Mob_Rabbit_Colour1, + eMinecraftColour_Mob_Rabbit_Colour2, + eMinecraftColour_Mob_Endermite_Colour1, + eMinecraftColour_Mob_Endermite_Colour2, + eMinecraftColour_Mob_Guardian_Colour1, + eMinecraftColour_Mob_Guardian_Colour2, + eMinecraftColour_Mob_ElderGuardian_Colour1, + eMinecraftColour_Mob_ElderGuardian_Colour2, + + eMinecraftColour_Armour_Default_Leather_Colour, + + eMinecraftColour_Under_Water_Clear_Colour, + eMinecraftColour_Under_Lava_Clear_Colour, + eMinecraftColour_In_Cloud_Base_Colour, + + eMinecraftColour_Under_Water_Fog_Colour, + eMinecraftColour_Under_Lava_Fog_Colour, + eMinecraftColour_In_Cloud_Fog_Colour, + + eMinecraftColour_Default_Fog_Colour, + eMinecraftColour_Nether_Fog_Colour, + eMinecraftColour_End_Fog_Colour, + + eMinecraftColour_Sign_Text, + eMinecraftColour_Map_Text, + + eMinecraftColour_Leash_Light_Colour, + eMinecraftColour_Leash_Dark_Colour, + + eMinecraftColour_Fire_Overlay, + + eHTMLColor_0, + eHTMLColor_1, + eHTMLColor_2, + eHTMLColor_3, + eHTMLColor_4, + eHTMLColor_5, + eHTMLColor_6, + eHTMLColor_7, + eHTMLColor_8, + eHTMLColor_9, + eHTMLColor_a, + eHTMLColor_b, + eHTMLColor_c, + eHTMLColor_d, + eHTMLColor_e, + eHTMLColor_f, + eHTMLColor_0_dark, + eHTMLColor_1_dark, + eHTMLColor_2_dark, + eHTMLColor_3_dark, + eHTMLColor_4_dark, + eHTMLColor_5_dark, + eHTMLColor_6_dark, + eHTMLColor_7_dark, + eHTMLColor_8_dark, + eHTMLColor_9_dark, + eHTMLColor_a_dark, + eHTMLColor_b_dark, + eHTMLColor_c_dark, + eHTMLColor_d_dark, + eHTMLColor_e_dark, + eHTMLColor_f_dark, + eHTMLColor_T1, + eHTMLColor_T2, + eHTMLColor_T3, + eHTMLColor_Black, + eHTMLColor_White, + + eTextColor_Enchant, + eTextColor_EnchantFocus, + eTextColor_EnchantDisabled, + eTextColor_RenamedItemTitle, + + //eHTMLColor_0 = 0x000000, //r:0 , g: 0, b: 0, i: 0 + //eHTMLColor_1 = 0x0000aa, //r:0 , g: 0, b: aa, i: 1 // blue, quite dark + //eHTMLColor_2 = 0x109e10, // Changed by request of Dave //0x00aa00, //r:0 , g: aa, b: 0, i: 2 // green + //eHTMLColor_3 = 0x109e9e, // Changed by request of Dave //0x00aaaa, //r:0 , g: aa, b: aa, i: 3 // cyan + //eHTMLColor_4 = 0xaa0000, //r:aa , g: 0, b: 0, i: 4 // red + //eHTMLColor_5 = 0xaa00aa, //r:aa , g: 0, b: aa, i: 5 // purple + //eHTMLColor_6 = 0xffaa00, //r:ff , g: aa, b: 0, i: 6 // orange + //eHTMLColor_7 = 0xaaaaaa, //r:aa , g: aa, b: aa, i: 7 // light gray + //eHTMLColor_8 = 0x555555, //r:55 , g: 55, b: 55, i: 8 // gray + //eHTMLColor_9 = 0x5555ff, //r:55 , g: 55, b: ff, i: 9 // blue + //eHTMLColor_a = 0x55ff55, //r:55 , g: ff, b: 55, i: a // green + //eHTMLColor_b = 0x55ffff, //r:55 , g: ff, b: ff, i: b // cyan + //eHTMLColor_c = 0xff5555, //r:ff , g: 55, b: 55, i: c // red pink + //eHTMLColor_d = 0xff55ff, //r:ff , g: 55, b: ff, i: d // bright pink + //eHTMLColor_e = 0xffff55, //r:ff , g: ff, b: 55, i: e // yellow + //eHTMLColor_f = 0xffffff, //r:ff , g: ff, b: ff, i: f + //eHTMLColor_0_dark = 0x000000, //r:0 , g: 0, b: 0, i: 10 + //eHTMLColor_1_dark = 0x00002a, //r:0 , g: 0, b: 2a, i: 11 + //eHTMLColor_2_dark = 0x002a00, //r:0 , g: 2a, b: 0, i: 12 + //eHTMLColor_3_dark = 0x002a2a, //r:0 , g: 2a, b: 2a, i: 13 + //eHTMLColor_4_dark = 0x2a0000, //r:2a , g: 0, b: 0, i: 14 + //eHTMLColor_5_dark = 0x2a002a, //r:2a , g: 0, b: 2a, i: 15 + //eHTMLColor_6_dark = 0x2a2a00, //r:2a , g: 2a, b: 0, i: 16 + //eHTMLColor_7_dark = 0x2a2a2a, //r:2a , g: 2a, b: 2a, i: 17 // dark gray + //eHTMLColor_8_dark = 0x151515, //r:15 , g: 15, b: 15, i: 18 + //eHTMLColor_9_dark = 0x15153f, //r:15 , g: 15, b: 3f, i: 19 + //eHTMLColor_a_dark = 0x153f15, //r:15 , g: 3f, b: 15, i: 1a + //eHTMLColor_b_dark = 0x153f3f, //r:15 , g: 3f, b: 3f, i: 1b + //eHTMLColor_c_dark = 0x3f1515, //r:3f , g: 15, b: 15, i: 1c // brown + //eHTMLColor_d_dark = 0x3f153f, //r:3f , g: 15, b: 3f, i: 1d + //eHTMLColor_e_dark = 0x3f3f15, //r:3f , g: 3f, b: 15, i: 1e + //eHTMLColor_f_dark = 0x3f3f3f, //r:3f , g: 3f, b: 3f, i: 1f + + eMinecraftColour_COUNT, +}; + +enum eDLCContentType +{ + e_DLC_SkinPack=0, + e_DLC_TexturePacks, + e_DLC_MashupPacks, + e_DLC_Themes, + e_DLC_AvatarItems, + e_DLC_Gamerpics, + e_DLC_MAX_MinecraftStore, + e_DLC_TexturePackData, // for the icon, banner and text + e_DLC_MAX, + e_DLC_NotDefined, +}; + +enum eDLCMarketplaceType +{ + e_Marketplace_Content=0, // skins, texture packs and mashup packs + e_Marketplace_Themes, + e_Marketplace_AvatarItems, + e_Marketplace_Gamerpics, + e_Marketplace_MAX, + e_Marketplace_NotDefined, +}; + +enum eDLCContentState +{ + e_DLC_ContentState_Idle = 0, + e_DLC_ContentState_Retrieving, + e_DLC_ContentState_Retrieved +}; + +enum eTMSContentState +{ + e_TMS_ContentState_Idle = 0, + e_TMS_ContentState_Queued, + e_TMS_ContentState_Retrieving, + e_TMS_ContentState_Retrieved +}; + +enum eXUID +{ + eXUID_Undefined=0, + eXUID_NoName, // name not needed + eXUID_Notch, + eXUID_Carl, + eXUID_Daniel, + eXUID_Deadmau5, + eXUID_DannyBStyle, + eXUID_JulianClark, + eXUID_Millionth, + eXUID_4JPaddy, + eXUID_4JStuart, + eXUID_4JDavid, + eXUID_4JRichard, + eXUID_4JSteven, +}; + + +enum _eTerrainFeatureType +{ + eTerrainFeature_None=0, + eTerrainFeature_Stronghold, + eTerrainFeature_Mineshaft, + eTerrainFeature_Village, + eTerrainFeature_Ravine, + eTerrainFeature_NetherFortress, + eTerrainFeature_StrongholdEndPortal, + eTerrainFeature_OceanMonument, + eTerrainFeature_Count +}; + +// 4J Stu - Whend adding new options you should consider whether having them on should disable achievements, and if so add them to the CanRecordStatsAndAchievements function +// 4J Stu - These options are now saved in save data, so new options can ONLY be added to the end +enum eGameHostOption +{ + eGameHostOption_Difficulty=0, + eGameHostOption_OnlineGame, // Unused + eGameHostOption_InviteOnly, // Unused + eGameHostOption_FriendsOfFriends, + eGameHostOption_Gamertags, + eGameHostOption_Tutorial, // special case + eGameHostOption_GameType, + eGameHostOption_LevelType, // flat or default + eGameHostOption_Structures, + eGameHostOption_BonusChest, + eGameHostOption_HasBeenInCreative, + eGameHostOption_PvP, + eGameHostOption_TrustPlayers, + eGameHostOption_TNT, + eGameHostOption_FireSpreads, + eGameHostOption_CheatsEnabled, // special case + eGameHostOption_HostCanFly, + eGameHostOption_HostCanChangeHunger, + eGameHostOption_HostCanBeInvisible, + eGameHostOption_BedrockFog, + eGameHostOption_NoHUD, + eGameHostOption_WorldSize, + eGameHostOption_All, + + eGameHostOption_DisableSaving, + eGameHostOption_WasntSaveOwner, // Added for PS3 save transfer, so we can add a nice message in the future instead of the creative mode one + + eGameHostOption_MobGriefing, + eGameHostOption_KeepInventory, + eGameHostOption_DoMobSpawning, + eGameHostOption_DoMobLoot, + eGameHostOption_DoTileDrops, + eGameHostOption_NaturalRegeneration, + eGameHostOption_DoDaylightCycle, + eGameHostOption_Hardcore, // 4J Added - for hardcore mode +}; + +// 4J-PB - If any new DLC items are added to the TMSFiles, this array needs updated +#ifdef _XBOX +enum _TMSFILES +{ + TMS_SP1=0, + TMS_SP2, + TMS_SP3, + TMS_SP4, + TMS_SP5, + TMS_SP6, + TMS_SPF, + TMS_SPB, + TMS_SPC, + TMS_SPZ, + TMS_SPM, + TMS_SPI, + TMS_SPG, + TMS_SPD1, + TMS_SPSW1, + + TMS_THST, + TMS_THIR, + TMS_THGO, + TMS_THDI, + TMS_THAW, + + TMS_GPAN, + TMS_GPCO, + TMS_GPEN, + TMS_GPFO, + TMS_GPTO, + TMS_GPBA, + TMS_GPFA, + TMS_GPME, + TMS_GPMF, + TMS_GPMM, + TMS_GPSE, + TMS_GPOr, + TMS_GPMi, + TMS_GPMB, + TMS_GPBr, + TMS_GPM1, + TMS_GPM2, + TMS_GPM3, + + TMS_AH_0001, + TMS_AH_0002, + TMS_AH_0003, + TMS_AH_0004, + TMS_AH_0005, + TMS_AH_0006, + TMS_AH_0007, + TMS_AH_0008, + TMS_AH_0009, + TMS_AH_0010, + TMS_AH_0011, + TMS_AH_0012, + TMS_AH_0013, + + TMS_AT_0001, + TMS_AT_0002, + TMS_AT_0003, + TMS_AT_0004, + TMS_AT_0005, + TMS_AT_0006, + TMS_AT_0007, + TMS_AT_0008, + TMS_AT_0009, + TMS_AT_0010, + TMS_AT_0011, + TMS_AT_0012, + TMS_AT_0013, + TMS_AT_0014, + TMS_AT_0015, + TMS_AT_0016, + TMS_AT_0017, + TMS_AT_0018, + TMS_AT_0019, + TMS_AT_0020, + TMS_AT_0021, + TMS_AT_0022, + TMS_AT_0023, + TMS_AT_0024, + TMS_AT_0025, + TMS_AT_0026, + + TMS_AP_0001, + TMS_AP_0002, + TMS_AP_0003, + TMS_AP_0004, + TMS_AP_0005, + TMS_AP_0006, + TMS_AP_0007, + TMS_AP_0009, + TMS_AP_0010, + TMS_AP_0011, + TMS_AP_0012, + TMS_AP_0013, + TMS_AP_0014, + TMS_AP_0015, + TMS_AP_0016, + TMS_AP_0017, + TMS_AP_0018, + + TMS_AP_0019, + TMS_AP_0020, + TMS_AP_0021, + TMS_AP_0022, + TMS_AP_0023, + TMS_AP_0024, + TMS_AP_0025, + TMS_AP_0026, + TMS_AP_0027, + TMS_AP_0028, + TMS_AP_0029, + TMS_AP_0030, + TMS_AP_0031, + TMS_AP_0032, + TMS_AP_0033, + + TMS_AA_0001, + + TMS_MPMA, + TMS_MPMA_DAT, + TMS_MPSR, + TMS_MPSR_DAT, + TMS_MPHA, + TMS_MPHA_DAT, + TMS_MPFE, + TMS_MPFE_DAT, + + TMS_TP01, + TMS_TP01_DAT, + TMS_TP02, + TMS_TP02_DAT, + TMS_TP04, + TMS_TP04_DAT, + TMS_TP05, + TMS_TP05_DAT, + TMS_TP06, + TMS_TP06_DAT, + TMS_TP07, + TMS_TP07_DAT, + TMS_TP08, + TMS_TP08_DAT, + + TMS_COUNT +}; +#endif + +enum EHTMLFontSize +{ + eHTMLSize_Normal, + eHTMLSize_Splitscreen, + eHTMLSize_Tutorial, + eHTMLSize_EndPoem, + + eHTMLSize_COUNT, +}; + +enum EControllerActions +{ + ACTION_MENU_A, + ACTION_MENU_B, + ACTION_MENU_X, + ACTION_MENU_Y, + ACTION_MENU_UP, + ACTION_MENU_DOWN, + ACTION_MENU_RIGHT, + ACTION_MENU_LEFT, + ACTION_MENU_PAGEUP, + ACTION_MENU_PAGEDOWN, + ACTION_MENU_RIGHT_SCROLL, + ACTION_MENU_LEFT_SCROLL, + ACTION_MENU_STICK_PRESS, + ACTION_MENU_OTHER_STICK_PRESS, + ACTION_MENU_OTHER_STICK_UP, + ACTION_MENU_OTHER_STICK_DOWN, + ACTION_MENU_OTHER_STICK_LEFT, + ACTION_MENU_OTHER_STICK_RIGHT, + ACTION_MENU_PAUSEMENU, + ACTION_MENU_QUICK_MOVE, + +#ifdef _DURANGO + ACTION_MENU_GTC_PAUSE, + ACTION_MENU_GTC_RESUME, +#endif + +#ifdef __ORBIS__ + ACTION_MENU_TOUCHPAD_PRESS, +#endif + + ACTION_MENU_OK, + ACTION_MENU_CANCEL, + ACTION_MAX_MENU = ACTION_MENU_CANCEL, + + MINECRAFT_ACTION_JUMP, + MINECRAFT_ACTION_FORWARD, + MINECRAFT_ACTION_BACKWARD, + MINECRAFT_ACTION_LEFT, + MINECRAFT_ACTION_RIGHT, + MINECRAFT_ACTION_LOOK_LEFT, + MINECRAFT_ACTION_LOOK_RIGHT, + MINECRAFT_ACTION_LOOK_UP, + MINECRAFT_ACTION_LOOK_DOWN, + MINECRAFT_ACTION_USE, + MINECRAFT_ACTION_ACTION, + MINECRAFT_ACTION_LEFT_SCROLL, + MINECRAFT_ACTION_RIGHT_SCROLL, + MINECRAFT_ACTION_INVENTORY, + MINECRAFT_ACTION_PAUSEMENU, + MINECRAFT_ACTION_DROP, + MINECRAFT_ACTION_SNEAK_TOGGLE, + MINECRAFT_ACTION_CRAFTING, + MINECRAFT_ACTION_RENDER_THIRD_PERSON, + MINECRAFT_ACTION_GAME_INFO, + MINECRAFT_ACTION_DPAD_LEFT, + MINECRAFT_ACTION_DPAD_RIGHT, + MINECRAFT_ACTION_DPAD_UP, + MINECRAFT_ACTION_DPAD_DOWN, + + MINECRAFT_ACTION_MAX, + + // These 4 aren't mapped to the input manager directly but are created from the dpad controls if required in Minecraft::run_middle + // Don't use them with the input manager directly, just through LocalPlayer::ullButtonsPressed + MINECRAFT_ACTION_SPAWN_CREEPER, + MINECRAFT_ACTION_CHANGE_SKIN, + MINECRAFT_ACTION_FLY_TOGGLE, + MINECRAFT_ACTION_RENDER_DEBUG, + MINECRAFT_ACTION_SCREENSHOT +}; + +enum eMCLang +{ + eMCLang_null=0, + eMCLang_enUS, + eMCLang_enGB, + eMCLang_enIE, + eMCLang_enAU, + eMCLang_enNZ, + eMCLang_enCA, + eMCLang_jaJP, + eMCLang_deDE, + eMCLang_deAT, + eMCLang_frFR, + eMCLang_frCA, + eMCLang_esES, + eMCLang_esMX, + eMCLang_itIT, + eMCLang_koKR, + eMCLang_ptPT, + eMCLang_ptBR, + eMCLang_ruRU, + eMCLang_nlNL, + eMCLang_fiFI, + eMCLang_svSV, + eMCLang_daDA, + eMCLang_noNO, + eMCLang_plPL, + eMCLang_trTR, + eMCLang_elEL, + eMCLang_csCS, + eMCLang_zhCHT, + eMCLang_laLAS, + + eMCLang_zhSG, + eMCLang_zhCN, + eMCLang_zhHK, + eMCLang_zhTW, + eMCLang_nlBE, + eMCLang_daDK, + eMCLang_frBE, + eMCLang_frCH, + eMCLang_deCH, + eMCLang_nbNO, + eMCLang_enGR, + eMCLang_enHK, + eMCLang_enSA, + eMCLang_enHU, + eMCLang_enIN, + eMCLang_enIL, + eMCLang_enSG, + eMCLang_enSK, + eMCLang_enZA, + eMCLang_enCZ, + eMCLang_enAE, + eMCLang_esAR, + eMCLang_esCL, + eMCLang_esCO, + eMCLang_esUS, + eMCLang_svSE, + + eMCLang_csCZ, + eMCLang_elGR, + eMCLang_nnNO, + eMCLang_skSK, + + eMCLang_hans, + eMCLang_hant, +}; diff --git a/Minecraft.Client/Common/App_structs.h b/Minecraft.Client/Common/App_structs.h index 6a6e0354..2d54135e 100644 --- a/Minecraft.Client/Common/App_structs.h +++ b/Minecraft.Client/Common/App_structs.h @@ -85,6 +85,7 @@ typedef struct // 0x00000200 - eGameSetting_CustomSkinAnim - on // TU9 // 0x00000400 - eGameSetting_DeathMessages - on + // 0x00070000 - eGameSetting_ControlType - 0..6 // Adding another bitmask to store "special" completion tasks for the tutorial unsigned int uiSpecialTutorialBitmask; diff --git a/Minecraft.Client/Common/Audio/SoundEngine.cpp b/Minecraft.Client/Common/Audio/SoundEngine.cpp index 2828713d..d9a94929 100644 --- a/Minecraft.Client/Common/Audio/SoundEngine.cpp +++ b/Minecraft.Client/Common/Audio/SoundEngine.cpp @@ -29,6 +29,8 @@ #include #include +constexpr float MUSIC_FADE_DURATION_SECONDS = 4.0f; + #ifdef __ORBIS__ #include //#define __DISABLE_MILES__ // MGH disabled for now as it crashes if we call sceNpMatching2Initialize @@ -448,6 +450,9 @@ SoundEngine::SoundEngine() m_StreamingAudioInfo.z=0; m_StreamingAudioInfo.volume=1; m_StreamingAudioInfo.pitch=1; + m_musicFadeSecondsRemaining = 0.0f; + m_musicFadeLastUpdateTime = std::chrono::steady_clock::now(); + m_bCurrentStreamIsCustom = false; memset(CurrentSoundsPlaying,0,sizeof(int)*(eSoundType_MAX+eSFX_MAX)); memset(m_ListenerA,0,sizeof(AUDIO_LISTENER)*XUSER_MAX_COUNT); @@ -605,34 +610,8 @@ void SoundEngine::play(int iSound, float x, float y, float z, float volume, floa m_activeSounds.push_back(s); } -///////////////////////////////////////////// -// -// -// startElytraSound / stopElytraSound -// Manages a single persistent looping sound for elytra gliding. -// Call startElytraSound every tick while gliding (it no-ops if already running, -// just updates volume). Call stopElytraSound when gliding ends. -// -// IMPORTANT: m_elytraLoopingSound is NOT added to m_activeSounds. -// The tick() cleanup loop deletes sounds where is_playing()==false. -// A looping sound briefly reports is_playing()==false at the loop point, -// which would cause tick() to free it and leave m_elytraLoopingSound dangling. -// -///////////////////////////////////////////// -void SoundEngine::startElytraSound(float x, float y, float z, float volume, float pitch) +MiniAudioSound* SoundEngine::startLoopingSound(const wstring& name, float x, float y, float z, float volume, float pitch, bool bIs3D) { - // If already initialized just update volume and pitch - never reinitialize mid-flight. - if (m_elytraLoopingSound != nullptr) - { - float finalVolume = volume * m_MasterEffectsVolume * SFX_VOLUME_MULTIPLIER; - if (finalVolume > SFX_MAX_GAIN) finalVolume = SFX_MAX_GAIN; - ma_sound_set_volume(&m_elytraLoopingSound->sound, finalVolume); - ma_sound_set_pitch(&m_elytraLoopingSound->sound, pitch); - return; - } - - // Resolve file path using the same logic as play(). - wstring name = wchSoundNames[eSoundType_ITEM_ELYTRA_FLYING]; char* soundName = ConvertSoundPathToName(name); char basePath[256]; sprintf_s(basePath, "Windows64Media/Sound/Minecraft/%s", soundName); @@ -652,42 +631,100 @@ void SoundEngine::startElytraSound(float x, float y, float z, float volume, floa break; } } - if (!found) return; + if (!found) + { + return nullptr; + } MiniAudioSound* s = new MiniAudioSound(); memset(&s->info, 0, sizeof(AUDIO_INFO)); - s->info.volume = volume; s->info.pitch = pitch; - s->info.bIs3D = false; - s->info.iSound = eSoundType_ITEM_ELYTRA_FLYING + eSFX_MAX; + s->info.x = x; + s->info.y = y; + s->info.z = z; + s->info.volume = volume; + s->info.pitch = pitch; + s->info.bIs3D = bIs3D; + s->info.bUseSoundsPitchVal = false; - // Synchronous load so the sound is immediately ready - no ASYNC gap. - if (ma_sound_init_from_file(&m_engine, finalPath, 0, - nullptr, nullptr, &s->sound) != MA_SUCCESS) + if (ma_sound_init_from_file(&m_engine, finalPath, 0, nullptr, nullptr, &s->sound) != MA_SUCCESS) { delete s; - return; + return nullptr; } - ma_sound_set_spatialization_enabled(&s->sound, MA_FALSE); + ma_sound_set_spatialization_enabled(&s->sound, bIs3D ? MA_TRUE : MA_FALSE); ma_sound_set_looping(&s->sound, MA_TRUE); float finalVolume = volume * m_MasterEffectsVolume * SFX_VOLUME_MULTIPLIER; - if (finalVolume > SFX_MAX_GAIN) finalVolume = SFX_MAX_GAIN; + if (finalVolume > SFX_MAX_GAIN) + finalVolume = SFX_MAX_GAIN; ma_sound_set_volume(&s->sound, finalVolume); ma_sound_set_pitch(&s->sound, pitch); + if (bIs3D) + { + ma_sound_set_position(&s->sound, x, y, z); + } ma_sound_start(&s->sound); + return s; +} +void SoundEngine::updateLoopingSound(MiniAudioSound* sound, float x, float y, float z, float volume, float pitch) +{ + if (sound == nullptr) + { + return; + } + + float finalVolume = volume * m_MasterEffectsVolume * SFX_VOLUME_MULTIPLIER; + if (finalVolume > SFX_MAX_GAIN) + finalVolume = SFX_MAX_GAIN; + ma_sound_set_volume(&sound->sound, finalVolume); + ma_sound_set_pitch(&sound->sound, pitch); + ma_sound_set_position(&sound->sound, x, y, z); +} + +void SoundEngine::stopLoopingSound(MiniAudioSound* sound) +{ + if (sound == nullptr) + { + return; + } + + ma_sound_stop(&sound->sound); + ma_sound_uninit(&sound->sound); + delete sound; +} + +///////////////////////////////////////////// +// +// +// startElytraSound / stopElytraSound +// Manages a single persistent looping sound for elytra gliding. +// Call startElytraSound every tick while gliding (it no-ops if already running, +// just updates volume). Call stopElytraSound when gliding ends. +// +// IMPORTANT: m_elytraLoopingSound is NOT added to m_activeSounds. +// The tick() cleanup loop deletes sounds where is_playing()==false. +// A looping sound briefly reports is_playing()==false at the loop point, +// which would cause tick() to free it and leave m_elytraLoopingSound dangling. +// +///////////////////////////////////////////// +void SoundEngine::startElytraSound(float x, float y, float z, float volume, float pitch) +{ + // If already initialized just update volume and pitch - never reinitialize mid-flight. + if (m_elytraLoopingSound != nullptr) + { + updateLoopingSound(m_elytraLoopingSound, x, y, z, volume, pitch); + return; + } // NOT added to m_activeSounds - tick() cleanup would delete it at loop boundaries. - m_elytraLoopingSound = s; + m_elytraLoopingSound = startLoopingSound(wchSoundNames[eSoundType_ITEM_ELYTRA_FLYING], x, y, z, volume, pitch, false); } void SoundEngine::stopElytraSound() { if (m_elytraLoopingSound == nullptr) return; - - ma_sound_stop(&m_elytraLoopingSound->sound); - ma_sound_uninit(&m_elytraLoopingSound->sound); - delete m_elytraLoopingSound; + stopLoopingSound(m_elytraLoopingSound); m_elytraLoopingSound = nullptr; } ///////////////////////////////////////////// @@ -793,10 +830,22 @@ void SoundEngine::playStreaming(const wstring& name, float x, float y, float z, m_StreamingAudioInfo.volume = volume; m_StreamingAudioInfo.pitch = pitch; + bool bNextCustom = isCustomMusicRequest(name); + bool bCurrentCustom = m_musicStreamActive && m_bCurrentStreamIsCustom; + if(m_StreamState == eMusicStreamState_Playing) - m_StreamState = eMusicStreamState_Stop; + { + if (bCurrentCustom != bNextCustom) + { + m_StreamState = eMusicStreamState_Fading; + m_musicFadeSecondsRemaining = MUSIC_FADE_DURATION_SECONDS; + m_musicFadeLastUpdateTime = std::chrono::steady_clock::now(); + } + } else if(m_StreamState == eMusicStreamState_Opening) + { m_StreamState = eMusicStreamState_OpeningCancel; + } if(name.empty()) { @@ -832,62 +881,79 @@ void SoundEngine::playStreaming(const wstring& name, float x, float y, float z, else if(playerInNether) m_musicID = getMusicID(eMusicType_Nether); else - getGameModeMusicID(pMinecraft, i); + { + bool foundCreative = false; + for(unsigned int j = 0; j < MAX_LOCAL_PLAYERS; j++) + { + if(pMinecraft->localplayers[j] != nullptr && + pMinecraft->localplayers[j]->abilities.instabuild && + pMinecraft->localplayers[j]->abilities.mayfly) + { + m_musicID = getMusicID(eMusicType_Creative); + foundCreative = true; + break; + } + } + if(!foundCreative) + { + m_musicID = getMusicID(eMusicType_Overworld); + } + } } else { // jukebox - m_StreamingAudioInfo.bIs3D=true; - m_musicID=getMusicID(name); - m_iMusicDelay=0; + m_StreamingAudioInfo.bIs3D=true; + m_musicID=getMusicID(name); + m_iMusicDelay=0; } } +bool SoundEngine::isCustomMusicRequest(const wstring& name) const +{ + if (!name.empty()) + { + return false; + } + Minecraft *pMinecraft = Minecraft::GetInstance(); + if (!pMinecraft) + { + return false; + } + + return pMinecraft->skins->getSelected()->hasAudio(); +} int SoundEngine::GetRandomishTrack(int iStart,int iEnd) { - // 4J-PB - make it more likely that we'll get a track we've not heard for a while, although repeating tracks sometimes is fine - - // if all tracks have been heard, clear the flags bool bAllTracksHeard=true; int iVal=iStart; for(size_t i=iStart;i<=iEnd;i++) { - if(m_bHeardTrackA[i]==false) + if(m_bHeardTrackA[i]==false) { bAllTracksHeard=false; - //app.DebugPrintf("Not heard all tracks yet\n"); break; } } if(bAllTracksHeard) { - //app.DebugPrintf("Heard all tracks - resetting the tracking array\n"); - for(size_t i=iStart;i<=iEnd;i++) { m_bHeardTrackA[i]=false; } } - // trying to get a track we haven't heard, but not too hard for(size_t i=0;i<=((iEnd-iStart)/2);i++) { - // random->nextInt(1) will always return 0 iVal=random->nextInt((iEnd-iStart)+1)+iStart; if(m_bHeardTrackA[iVal]==false) { - // not heard this - //app.DebugPrintf("(%d) Not heard track %d yet, so playing it now\n",i,iVal); m_bHeardTrackA[iVal]=true; break; } - else - { - //app.DebugPrintf("(%d) Skipping track %d already heard it recently\n",i,iVal); - } } //app.DebugPrintf("Select track %d\n",iVal); @@ -1331,7 +1397,38 @@ void SoundEngine::playMusicUpdate() if (m_StreamingAudioInfo.bIs3D) { ma_sound_set_spatialization_enabled(&m_musicStream, MA_TRUE); - ma_sound_set_position(&m_musicStream, m_StreamingAudioInfo.x, m_StreamingAudioInfo.y, m_StreamingAudioInfo.z); + if (m_validListenerCount > 1) + { + int iClosestListener = 0; + float fClosestDist = 1e6f; + + for (size_t i = 0; i < MAX_LOCAL_PLAYERS; i++) + { + if (m_ListenerA[i].bValid) + { + float dx = m_StreamingAudioInfo.x - m_ListenerA[i].vPosition.x; + float dy = m_StreamingAudioInfo.y - m_ListenerA[i].vPosition.y; + float dz = m_StreamingAudioInfo.z - m_ListenerA[i].vPosition.z; + float dist = sqrtf(dx*dx + dy*dy + dz*dz); + + if (dist < fClosestDist) + { + fClosestDist = dist; + iClosestListener = i; + } + } + } + + float relX = m_StreamingAudioInfo.x - m_ListenerA[iClosestListener].vPosition.x; + float relY = m_StreamingAudioInfo.y - m_ListenerA[iClosestListener].vPosition.y; + float relZ = m_StreamingAudioInfo.z - m_ListenerA[iClosestListener].vPosition.z; + + ma_sound_set_position(&m_musicStream, relX, relY, relZ); + } + else + { + ma_sound_set_position(&m_musicStream, m_StreamingAudioInfo.x, m_StreamingAudioInfo.y, m_StreamingAudioInfo.z); + } } else { @@ -1344,6 +1441,7 @@ void SoundEngine::playMusicUpdate() ma_sound_set_volume(&m_musicStream, finalVolume); ma_result startResult = ma_sound_start(&m_musicStream); + m_bCurrentStreamIsCustom = Minecraft::GetInstance() && Minecraft::GetInstance()->skins->getSelected()->hasAudio(); app.DebugPrintf("ma_sound_start result: %d\n", startResult); m_StreamState=eMusicStreamState_Playing; @@ -1370,6 +1468,36 @@ void SoundEngine::playMusicUpdate() m_StreamState = eMusicStreamState_Idle; break; + case eMusicStreamState_Fading: + if (m_musicStreamActive) + { + const auto now = std::chrono::steady_clock::now(); + const float elapsedSeconds = std::chrono::duration(now - m_musicFadeLastUpdateTime).count(); + if (elapsedSeconds > 0.0f) + { + m_musicFadeSecondsRemaining = (elapsedSeconds >= m_musicFadeSecondsRemaining) + ? 0.0f + : m_musicFadeSecondsRemaining - elapsedSeconds; + m_musicFadeLastUpdateTime = now; + } + + if (m_musicFadeSecondsRemaining > 0.0f) + { + const float fadeFactor = m_musicFadeSecondsRemaining / MUSIC_FADE_DURATION_SECONDS; + const float finalVolume = m_StreamingAudioInfo.volume * getMasterMusicVolume() * fadeFactor; + ma_sound_set_volume(&m_musicStream, finalVolume); + break; + } + + ma_sound_stop(&m_musicStream); + ma_sound_uninit(&m_musicStream); + m_musicStreamActive = false; + } + + SetIsPlayingStreamingCDMusic(false); + SetIsPlayingStreamingGameMusic(false); + m_StreamState = eMusicStreamState_Idle; + break; case eMusicStreamState_Stopping: break; case eMusicStreamState_Play: @@ -1557,7 +1685,7 @@ void SoundEngine::playMusicUpdate() } else { - m_musicID = getMusicID(eMusicType_Overworld); + getGameModeMusicID(pMinecraft, i); SetIsPlayingNetherMusic(false); SetIsPlayingEndMusic(false); } diff --git a/Minecraft.Client/Common/Audio/SoundEngine.h b/Minecraft.Client/Common/Audio/SoundEngine.h index 5a593df9..3cef9432 100644 --- a/Minecraft.Client/Common/Audio/SoundEngine.h +++ b/Minecraft.Client/Common/Audio/SoundEngine.h @@ -5,6 +5,7 @@ using namespace std; #include "../../Minecraft.World/SoundTypes.h" #include "miniaudio.h" +#include constexpr float SFX_3D_MIN_DISTANCE = 1.0f; constexpr float SFX_3D_MAX_DISTANCE = 16.0f; @@ -82,6 +83,7 @@ enum eMusicStreamState { eMusicStreamState_Idle=0, eMusicStreamState_Stop, + eMusicStreamState_Fading, eMusicStreamState_Stopping, eMusicStreamState_Opening, eMusicStreamState_OpeningCancel, @@ -127,6 +129,9 @@ public: void GetSoundName(char *szSoundName,int iSound); #endif void play(int iSound, float x, float y, float z, float volume, float pitch) override; + MiniAudioSound* startLoopingSound(const wstring& name, float x, float y, float z, float volume, float pitch, bool bIs3D = true); + void updateLoopingSound(MiniAudioSound* sound, float x, float y, float z, float volume, float pitch); + void stopLoopingSound(MiniAudioSound* sound); void startElytraSound(float x, float y, float z, float volume, float pitch); void stopElytraSound(); void playStreaming(const wstring& name, float x, float y , float z, float volume, float pitch, bool bMusicDelay=true) override; @@ -160,9 +165,13 @@ private: #endif int GetRandomishTrack(int iStart,int iEnd); + bool isCustomMusicRequest(const wstring& name) const; MiniAudioSound* m_elytraLoopingSound = nullptr; + float m_musicFadeSecondsRemaining; + std::chrono::steady_clock::time_point m_musicFadeLastUpdateTime; + bool m_bCurrentStreamIsCustom; ma_engine m_engine; ma_engine_config m_engineConfig; diff --git a/Minecraft.Client/Common/Colours/ColourTable.cpp b/Minecraft.Client/Common/Colours/ColourTable.cpp index 5e7afa74..6e6b4755 100644 --- a/Minecraft.Client/Common/Colours/ColourTable.cpp +++ b/Minecraft.Client/Common/Colours/ColourTable.cpp @@ -90,6 +90,7 @@ const wchar_t *ColourTable::ColourTableElements[eMinecraftColour_COUNT] = L"Water_ExtremeHillsEdge", L"Water_Jungle", L"Water_JungleHills", + L"Water_JungleEdge", L"Water_Mesa", L"Sky_Ocean", @@ -115,6 +116,7 @@ const wchar_t *ColourTable::ColourTableElements[eMinecraftColour_COUNT] = L"Sky_ExtremeHillsEdge", L"Sky_Jungle", L"Sky_JungleHills", + L"Sky_JungleEdge", L"Tile_RedstoneDust", L"Tile_RedstoneDustUnlit", diff --git a/Minecraft.Client/Common/Consoles_App.cpp b/Minecraft.Client/Common/Consoles_App.cpp index 6c103e53..7593da75 100644 --- a/Minecraft.Client/Common/Consoles_App.cpp +++ b/Minecraft.Client/Common/Consoles_App.cpp @@ -1,10741 +1,10866 @@ -#include "stdafx.h" -#include "../../Minecraft.World/net.minecraft.world.entity.item.h" -#include "../../Minecraft.World/net.minecraft.world.entity.player.h" -#include "../../Minecraft.World/net.minecraft.world.level.tile.entity.h" -#include "../../Minecraft.World/net.minecraft.world.phys.h" -#include "../../Minecraft.World/InputOutputStream.h" -#include "../../Minecraft.World/compression.h" -#include "../Options.h" -#include "../MinecraftServer.h" -#include "../MultiPlayerLevel.h" -#include "../GameRenderer.h" -#include "../ProgressRenderer.h" -#include "../LevelRenderer.h" -#include "../MobSkinMemTextureProcessor.h" -#include "../Minecraft.h" -#include "../ClientConnection.h" -#include "../MultiPlayerLocalPlayer.h" -#include "../LocalPlayer.h" -#include "../../Minecraft.World/Player.h" -#include "../../Minecraft.World/Inventory.h" -#include "../../Minecraft.World/Level.h" -#include "../../Minecraft.World/FurnaceTileEntity.h" -#include "../../Minecraft.World/Container.h" -#include "../../Minecraft.World/DispenserTileEntity.h" -#include "../../Minecraft.World/SignTileEntity.h" -#include "../StatsCounter.h" -#include "../GameMode.h" -#include "../Xbox/Social/SocialManager.h" -#include "Tutorial/TutorialMode.h" -#ifdef _WINDOWS64 -#include "../Windows64/Network/WinsockNetLayer.h" // HUCKLE - added for quit on disconnect -#endif -#if defined _XBOX || defined _WINDOWS64 -#include "../Xbox/XML/ATGXmlParser.h" -#include "../Xbox/XML/xmlFilesCallback.h" -#endif -#include "Minecraft_Macros.h" -#include "../PlayerList.h" -#include "../ServerPlayer.h" -#include "GameRules/ConsoleGameRules.h" -#include "GameRules/ConsoleSchematicFile.h" -#include "../User.h" -#include "../../Minecraft.World/LevelData.h" -#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) -#include "../../Minecraft.Server/ServerLogManager.h" -#endif -#include "../../Minecraft.World/net.minecraft.world.entity.player.h" -#include "../EntityRenderDispatcher.h" -#include "../../Minecraft.World/compression.h" -#include "../TexturePackRepository.h" -#include "../DLCTexturePack.h" -#include "DLC/DLCPack.h" -#include "../StringTable.h" -#ifndef _XBOX -#include "../ArchiveFile.h" -#endif -#include "../Minecraft.h" -#ifdef _XBOX -#include "../Xbox/GameConfig/Minecraft.spa.h" -#include "../Xbox/Network/NetworkPlayerXbox.h" -#include "XUI/XUI_TextEntry.h" -#include "XUI/XUI_XZP_Icons.h" -#include "XUI/XUI_PauseMenu.h" -#else -#include "UI/UI.h" -#include "UI/UIScene_PauseMenu.h" -#endif -#ifdef __PS3__ -#include -#endif -#ifdef __ORBIS__ -#include -#endif - -#include "../Common/Leaderboards/LeaderboardManager.h" -#include - -//CMinecraftApp app; -unsigned int CMinecraftApp::m_uiLastSignInData = 0; - -const float CMinecraftApp::fSafeZoneX = 64.0f; // 5% of 1280 -const float CMinecraftApp::fSafeZoneY = 36.0f; // 5% of 720 - -int CMinecraftApp::s_iHTMLFontSizesA[eHTMLSize_COUNT] = -{ -#ifdef _XBOX - 14,12,14,24 -#else - //20,15,20,24 - 20,13,20,26 -#endif -}; - - -CMinecraftApp::CMinecraftApp() -{ - if(GAME_SETTINGS_PROFILE_DATA_BYTES != sizeof(GAME_SETTINGS)) - { - // 4J Stu - See comment for GAME_SETTINGS_PROFILE_DATA_BYTES in Xbox_App.h - DebugPrintf("WARNING: The size of the profile GAME_SETTINGS struct has changed, so all stat data is likely incorrect. Is: %d, Should be: %d\n",sizeof(GAME_SETTINGS),GAME_SETTINGS_PROFILE_DATA_BYTES); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - } - - for(int i=0;i; - } - - LocaleAndLanguageInit(); - -#ifdef _XBOX_ONE - m_hasReachedMainMenu = false; -#endif -} - - -void CMinecraftApp::GetSkinAdjustments(_SkinAdjustments* out, unsigned int skinId) -{ - _SkinAdjustments adj; - - EnterCriticalSection(&csAdditionalSkinBoxes); - - if (!m_SkinAdjustmentsMap.empty()) - { - auto it = m_SkinAdjustmentsMap.find(skinId); - if (it != m_SkinAdjustmentsMap.end()) - adj = it->second; - } - - LeaveCriticalSection(&csAdditionalSkinBoxes); - - *out = adj; -} - -void CMinecraftApp::SetSkinAdjustments(unsigned int skinId, const _SkinAdjustments& adj) -{ - EnterCriticalSection(&csAdditionalSkinBoxes); - - m_SkinAdjustmentsMap[skinId] = adj; - - LeaveCriticalSection(&csAdditionalSkinBoxes); -} - -void CMinecraftApp::DebugPrintf(const char *szFormat, ...) -{ - -#ifndef _FINAL_BUILD - va_list ap; - va_start(ap, szFormat); -#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) - // Dedicated server routes client debug spew through ServerLogger so CLI output stays prompt-safe. - if (ServerRuntime::ServerLogManager::ShouldForwardClientDebugLogs()) - { - ServerRuntime::ServerLogManager::ForwardClientAppDebugLogV(szFormat, ap); - va_end(ap); - return; - } -#endif - char buf[1024]; - vsnprintf(buf, sizeof(buf), szFormat, ap); - va_end(ap); - OutputDebugStringA(buf); -#endif - -} - -void CMinecraftApp::DebugPrintf(int user, const char *szFormat, ...) -{ -#ifndef _FINAL_BUILD - if(user == USER_NONE) - return; - va_list ap; - va_start(ap, szFormat); -#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) - // Dedicated server routes client debug spew through ServerLogger so CLI output stays prompt-safe. - if (ServerRuntime::ServerLogManager::ShouldForwardClientDebugLogs()) - { - ServerRuntime::ServerLogManager::ForwardClientUserDebugLogV(user, szFormat, ap); - va_end(ap); - return; - } -#endif - char buf[1024]; - vsnprintf(buf, sizeof(buf), szFormat, ap); - va_end(ap); -#ifdef __PS3__ - unsigned int writelen; - sys_tty_write(SYS_TTYP_USER1 + ( user - 1 ), buf, strlen(buf), &writelen ); -#elif defined __PSVITA__ - switch(user) - { - case 0: - { - SceUID tty2 = sceIoOpen("tty2:", SCE_O_WRONLY, 0); - if(tty2>=0) - { - std::string string1(buf); - sceIoWrite(tty2, string1.c_str(), string1.length()); - sceIoClose(tty2); - } - } - break; - case 1: - { - SceUID tty3 = sceIoOpen("tty3:", SCE_O_WRONLY, 0); - if(tty3>=0) - { - std::string string1(buf); - sceIoWrite(tty3, string1.c_str(), string1.length()); - sceIoClose(tty3); - } - } - break; - default: - OutputDebugStringA(buf); - break; - } -#else - OutputDebugStringA(buf); -#endif -#ifndef _XBOX - if(user == USER_UI) - { - ui.logDebugString(buf); - } -#endif -#endif -} - -namespace -{ -const wchar_t *ResolveStringKeyFromId(int iID) -{ -#ifdef _WINDOWS64 - switch(iID) - { - #include "StringIdLookup.generated.inc" - default: - return nullptr; - } -#else - (void)iID; - return nullptr; -#endif -} -} - -LPCWSTR CMinecraftApp::GetString(int iID) -{ - if(app.m_stringTable == nullptr) - { - const wchar_t *key = ResolveStringKeyFromId(iID); - return key != nullptr ? key : L""; - } - - LPCWSTR byIndex = app.m_stringTable->getString(iID); - if(byIndex != nullptr && byIndex[0] != L'\0') - { - return byIndex; - } - - const wchar_t *key = ResolveStringKeyFromId(iID); - if(key != nullptr) - { - LPCWSTR byKey = app.m_stringTable->getString(key); - if(byKey != nullptr && byKey[0] != L'\0') - { - return byKey; - } - - // Prefer visible fallback text instead of returning an empty string. - return key; - } - - return L""; -} - -LPCWSTR CMinecraftApp::GetString(const wchar_t *id) -{ - if(id == nullptr) - { - return L""; - } - - if(app.m_stringTable == nullptr) - { - return id; - } - - LPCWSTR byKey = app.m_stringTable->getString(id); - if(byKey != nullptr && byKey[0] != L'\0') - { - return byKey; - } - - return id; -} - -void CMinecraftApp::SetAction(int iPad, eXuiAction action, LPVOID param) -{ - if( ( m_eXuiAction[iPad] == eAppAction_ReloadTexturePack ) && ( action == eAppAction_EthernetDisconnected ) ) - { - app.DebugPrintf("Invalid change of App action for pad %d from %d to %d, ignoring\n", iPad, m_eXuiAction[iPad], action); - } - else if( ( m_eXuiAction[iPad] == eAppAction_ReloadTexturePack ) && ( action == eAppAction_ExitWorld ) ) - { - app.DebugPrintf("Invalid change of App action for pad %d from %d to %d, ignoring\n", iPad, m_eXuiAction[iPad], action); - } - else if(m_eXuiAction[iPad] == eAppAction_ExitWorldCapturedThumbnail && action != eAppAction_Idle) - { - app.DebugPrintf("Invalid change of App action for pad %d from %d to %d, ignoring\n", iPad, m_eXuiAction[iPad], action); - } - else - { - app.DebugPrintf("Changing App action for pad %d from %d to %d\n", iPad, m_eXuiAction[iPad], action); - m_eXuiAction[iPad]=action; - m_eXuiActionParam[iPad] = param; - } -} - -bool CMinecraftApp::IsAppPaused() -{ -#if defined(_XBOX_ONE) || defined(__ORBIS__) || defined(_WINDOWS64) - bool paused = m_bIsAppPaused; - EnterCriticalSection(&m_saveNotificationCriticalSection); - if( g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 ) - { - paused |= m_saveNotificationDepth > 0; - } - LeaveCriticalSection(&m_saveNotificationCriticalSection); - return paused; -#else - return m_bIsAppPaused; -#endif -} - -void CMinecraftApp::SetAppPaused(bool val) -{ - m_bIsAppPaused = val; -} - -void CMinecraftApp::HandleButtonPresses() -{ - for(int i=0;i<4;i++) - { - HandleButtonPresses(i); - } -} - -void CMinecraftApp::HandleButtonPresses(int iPad) -{ - - // // test an update of the profile data - // void *pData=ProfileManager.GetGameDefinedProfileData(iPad); - // - // unsigned char *pchData= (unsigned char *)pData; - // int iCount=0; - // for(int i=0;i player,bool bNavigateBack) -{ - bool success = true; - - InventoryScreenInput* initData = new InventoryScreenInput(); - initData->player = player; - initData->bNavigateBack=bNavigateBack; - initData->iPad = iPad; - - if(app.GetLocalPlayerCount()>1) - { - initData->bSplitscreen=true; - success = ui.NavigateToScene(iPad,eUIScene_InventoryMenu,initData); - } - else - { - initData->bSplitscreen=false; - success = ui.NavigateToScene(iPad,eUIScene_InventoryMenu,initData); - } - - return success; -} - -bool CMinecraftApp::LoadCreativeMenu(int iPad,shared_ptr player,bool bNavigateBack) -{ - bool success = true; - - InventoryScreenInput* initData = new InventoryScreenInput(); - initData->player = player; - initData->bNavigateBack=bNavigateBack; - initData->iPad = iPad; - - if(app.GetLocalPlayerCount()>1) - { - initData->bSplitscreen=true; - success = ui.NavigateToScene(iPad,eUIScene_CreativeMenu,initData); - } - else - { - initData->bSplitscreen=false; - success = ui.NavigateToScene(iPad,eUIScene_CreativeMenu,initData); - } - - return success; -} - -bool CMinecraftApp::LoadCrafting2x2Menu(int iPad,shared_ptr player) -{ - bool success = true; - - CraftingPanelScreenInput* initData = new CraftingPanelScreenInput(); - initData->player = player; - initData->iContainerType=RECIPE_TYPE_2x2; - initData->iPad = iPad; - initData->x = 0; - initData->y = 0; - initData->z = 0; - - if(app.GetLocalPlayerCount()>1) - { - initData->bSplitscreen=true; - success = ui.NavigateToScene(iPad,eUIScene_Crafting2x2Menu, initData); - } - else - { - initData->bSplitscreen=false; - success = ui.NavigateToScene(iPad,eUIScene_Crafting2x2Menu, initData); - } - - return success; -} - -bool CMinecraftApp::LoadCrafting3x3Menu(int iPad,shared_ptr player, int x, int y, int z) -{ - bool success = true; - - CraftingPanelScreenInput* initData = new CraftingPanelScreenInput(); - initData->player = player; - initData->iContainerType=RECIPE_TYPE_3x3; - initData->iPad = iPad; - initData->x = x; - initData->y = y; - initData->z = z; - - if (app.GetLocalPlayerCount() > 1) - initData->bSplitscreen = true; - else - initData->bSplitscreen = false; - - if (app.GetGameSettings(iPad, eGameSetting_ClassicCrafting)) - success = ui.NavigateToScene(iPad, eUIScene_ClassicCraftingMenu, initData); - else - success = ui.NavigateToScene(iPad, eUIScene_Crafting3x3Menu, initData); - - return success; -} - -bool CMinecraftApp::LoadFireworksMenu(int iPad,shared_ptr player, int x, int y, int z) -{ - bool success = true; - - FireworksScreenInput* initData = new FireworksScreenInput(); - initData->player = player; - initData->iPad = iPad; - initData->x = x; - initData->y = y; - initData->z = z; - - if(app.GetLocalPlayerCount()>1) - { - initData->bSplitscreen=true; - success = ui.NavigateToScene(iPad,eUIScene_FireworksMenu, initData); - } - else - { - initData->bSplitscreen=false; - success = ui.NavigateToScene(iPad,eUIScene_FireworksMenu, initData); - } - - return success; -} - -bool CMinecraftApp::LoadEnchantingMenu(int iPad,shared_ptr inventory, int x, int y, int z, Level *level, const wstring &name) -{ - bool success = true; - - EnchantingScreenInput* initData = new EnchantingScreenInput(); - initData->inventory = inventory; - initData->level = level; - initData->x = x; - initData->y = y; - initData->z = z; - initData->iPad = iPad; - initData->name = name; - - if(app.GetLocalPlayerCount()>1) - { - initData->bSplitscreen=true; - success = ui.NavigateToScene(iPad,eUIScene_EnchantingMenu, initData); - } - else - { - initData->bSplitscreen=false; - success = ui.NavigateToScene(iPad,eUIScene_EnchantingMenu, initData); - } - - return success; -} - -bool CMinecraftApp::LoadFurnaceMenu(int iPad,shared_ptr inventory, shared_ptr furnace) -{ - bool success = true; - - FurnaceScreenInput* initData = new FurnaceScreenInput(); - - initData->furnace = furnace; - initData->inventory = inventory; - initData->iPad = iPad; - - // Load the scene. - if(app.GetLocalPlayerCount()>1) - { - initData->bSplitscreen=true; - success = ui.NavigateToScene(iPad,eUIScene_FurnaceMenu, initData); - } - else - { - initData->bSplitscreen=false; - success = ui.NavigateToScene(iPad,eUIScene_FurnaceMenu, initData); - } - - return success; -} - -bool CMinecraftApp::LoadBrewingStandMenu(int iPad,shared_ptr inventory, shared_ptr brewingStand) -{ - bool success = true; - - BrewingScreenInput* initData = new BrewingScreenInput(); - - initData->brewingStand = brewingStand; - initData->inventory = inventory; - initData->iPad = iPad; - - // Load the scene. - if(app.GetLocalPlayerCount()>1) - { - initData->bSplitscreen=true; - success = ui.NavigateToScene(iPad,eUIScene_BrewingStandMenu, initData); - } - else - { - initData->bSplitscreen=false; - success = ui.NavigateToScene(iPad,eUIScene_BrewingStandMenu, initData); - } - - return success; -} - - -bool CMinecraftApp::LoadContainerMenu(int iPad,shared_ptr inventory, shared_ptr container) -{ - bool success = true; - - ContainerScreenInput* initData = new ContainerScreenInput(); - - initData->inventory = inventory; - initData->container = container; - initData->iPad = iPad; - - // Load the scene. - if(app.GetLocalPlayerCount()>1) - { - initData->bSplitscreen=true; - - bool bLargeChest = (initData->container->getContainerSize() > 3*9)?true:false; - if(bLargeChest) - { - success = ui.NavigateToScene(iPad,eUIScene_LargeContainerMenu,initData); - } - else - { - success = ui.NavigateToScene(iPad,eUIScene_ContainerMenu,initData); - } - } - else - { - initData->bSplitscreen=false; - success = ui.NavigateToScene(iPad,eUIScene_ContainerMenu,initData); - } - - return success; -} - -bool CMinecraftApp::LoadTrapMenu(int iPad,shared_ptr inventory, shared_ptr trap) -{ - bool success = true; - - TrapScreenInput* initData = new TrapScreenInput(); - - initData->inventory = inventory; - initData->trap = trap; - initData->iPad = iPad; - - // Load the scene. - if(app.GetLocalPlayerCount()>1) - { - initData->bSplitscreen=true; - success = ui.NavigateToScene(iPad,eUIScene_DispenserMenu, initData); - } - else - { - initData->bSplitscreen=false; - success = ui.NavigateToScene(iPad,eUIScene_DispenserMenu, initData); - } - - return success; -} - -bool CMinecraftApp::LoadSignEntryMenu(int iPad,shared_ptr sign) -{ - bool success = true; - - SignEntryScreenInput* initData = new SignEntryScreenInput(); - - initData->sign = sign; - initData->iPad = iPad; - - success = ui.NavigateToScene(iPad,eUIScene_SignEntryMenu, initData); - - delete initData; - - return success; -} - -bool CMinecraftApp::LoadRepairingMenu(int iPad,shared_ptr inventory, Level *level, int x, int y, int z) -{ - bool success = true; - - AnvilScreenInput *initData = new AnvilScreenInput(); - initData->inventory = inventory; - initData->level = level; - initData->x = x; - initData->y = y; - initData->z = z; - initData->iPad = iPad; - if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; - else initData->bSplitscreen=false; - - success = ui.NavigateToScene(iPad,eUIScene_AnvilMenu, initData); - - return success; -} - -bool CMinecraftApp::LoadTradingMenu(int iPad, shared_ptr inventory, shared_ptr trader, Level *level, const wstring &name) -{ - bool success = true; - - TradingScreenInput *initData = new TradingScreenInput(); - initData->inventory = inventory; - initData->trader = trader; - initData->level = level; - initData->iPad = iPad; - if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; - else initData->bSplitscreen=false; - - success = ui.NavigateToScene(iPad,eUIScene_TradingMenu, initData); - - return success; -} - -bool CMinecraftApp::LoadHopperMenu(int iPad ,shared_ptr inventory, shared_ptr hopper) -{ - bool success = true; - - HopperScreenInput *initData = new HopperScreenInput(); - initData->inventory = inventory; - initData->hopper = hopper; - initData->iPad = iPad; - if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; - else initData->bSplitscreen=false; - - success = ui.NavigateToScene(iPad,eUIScene_HopperMenu, initData); - - return success; -} - -bool CMinecraftApp::LoadHopperMenu(int iPad ,shared_ptr inventory, shared_ptr hopper) -{ - bool success = true; - - HopperScreenInput *initData = new HopperScreenInput(); - initData->inventory = inventory; - initData->hopper = dynamic_pointer_cast(hopper); - initData->iPad = iPad; - if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; - else initData->bSplitscreen=false; - - success = ui.NavigateToScene(iPad,eUIScene_HopperMenu, initData); - - return success; -} - - -bool CMinecraftApp::LoadHorseMenu(int iPad ,shared_ptr inventory, shared_ptr container, shared_ptr horse) -{ - bool success = true; - - HorseScreenInput *initData = new HorseScreenInput(); - initData->inventory = inventory; - initData->container = container; - initData->horse = horse; - initData->iPad = iPad; - if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; - else initData->bSplitscreen=false; - - success = ui.NavigateToScene(iPad,eUIScene_HorseMenu, initData); - - return success; -} - -bool CMinecraftApp::LoadBeaconMenu(int iPad ,shared_ptr inventory, shared_ptr beacon) -{ - bool success = true; - - BeaconScreenInput *initData = new BeaconScreenInput(); - initData->inventory = inventory; - initData->beacon = beacon; - initData->iPad = iPad; - if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; - else initData->bSplitscreen=false; - - success = ui.NavigateToScene(iPad,eUIScene_BeaconMenu, initData); - - return success; -} - -bool CMinecraftApp::LoadWritingBookMenu(int iPad, shared_ptr instance, shared_ptr player, bool editable) -{ - bool success = true; - - WritingBookMenuParams* initData = new WritingBookMenuParams(); - initData->itemInstance = instance; - initData->player = player; - initData->iPad = iPad; - initData->isEditable = editable; - - success = ui.NavigateToScene(iPad, eUIScene_BookMenu, initData); - - return success; -} - -////////////////////////////////////////////// -// GAME SETTINGS -////////////////////////////////////////////// - -#ifdef _WINDOWS64 -static void Win64_GetSettingsPath(char *outPath, DWORD size) -{ - GetModuleFileNameA(nullptr, outPath, size); - char *lastSlash = strrchr(outPath, '\\'); - if (lastSlash) *(lastSlash + 1) = '\0'; - strncat_s(outPath, size, "settings.dat", _TRUNCATE); -} -static void Win64_SaveSettings(GAME_SETTINGS *gs) -{ - if (!gs) return; - char filePath[MAX_PATH] = {}; - Win64_GetSettingsPath(filePath, MAX_PATH); - FILE *f = nullptr; - if (fopen_s(&f, filePath, "wb") == 0 && f) - { - fwrite(gs, sizeof(GAME_SETTINGS), 1, f); - fclose(f); - } -} -static void Win64_LoadSettings(GAME_SETTINGS *gs) -{ - if (!gs) return; - char filePath[MAX_PATH] = {}; - Win64_GetSettingsPath(filePath, MAX_PATH); - FILE *f = nullptr; - if (fopen_s(&f, filePath, "rb") == 0 && f) - { - GAME_SETTINGS temp = {}; - if (fread(&temp, sizeof(GAME_SETTINGS), 1, f) == 1) - memcpy(gs, &temp, sizeof(GAME_SETTINGS)); - fclose(f); - } -} -#endif - -void CMinecraftApp::InitGameSettings() -{ - for(int i=0;i(ProfileManager.GetGameDefinedProfileData(i)); -#endif - // clear the flag to say the settings have changed - GameSettingsA[i]->bSettingsChanged=false; - - //SetDefaultGameSettings(i); - done on a callback from the profile manager - - // 4J-PB - adding in for Windows & PS3 to set the defaults for the joypad -#if defined _WINDOWS64// || defined __PSVITA__ - C_4JProfile::PROFILESETTINGS *pProfileSettings=ProfileManager.GetDashboardProfileSettings(i); - // clear this for now - it will come from reading the system values - memset(pProfileSettings,0,sizeof(C_4JProfile::PROFILESETTINGS)); - SetDefaultOptions(pProfileSettings,i); - Win64_LoadSettings(GameSettingsA[i]); -#ifndef MINECRAFT_SERVER_BUILD - ApplyGameSettingsChanged(i); -#endif -#elif defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__ - C4JStorage::PROFILESETTINGS *pProfileSettings=StorageManager.GetDashboardProfileSettings(i); - // 4J-PB - don't cause an options write to happen here - SetDefaultOptions(pProfileSettings,i,false); - -#endif - - Minecraft* minecraft = Minecraft::GetInstance(); - if (minecraft != nullptr && minecraft->stats[i] != nullptr) - { - minecraft->stats[i]->clear(); - minecraft->stats[i]->parse(GameSettingsA[i]); - } - } -} - -#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) -int CMinecraftApp::SetDefaultOptions(C4JStorage::PROFILESETTINGS *pSettings,const int iPad,bool bWriteProfile) -#else -int CMinecraftApp::SetDefaultOptions(C_4JProfile::PROFILESETTINGS *pSettings,const int iPad) -#endif -{ - SetGameSettings(iPad,eGameSetting_MusicVolume,DEFAULT_VOLUME_LEVEL); - SetGameSettings(iPad,eGameSetting_SoundFXVolume,DEFAULT_VOLUME_LEVEL); - SetGameSettings(iPad,eGameSetting_RenderDistance,16); - SetGameSettings(iPad,eGameSetting_Gamma,50); - SetGameSettings(iPad,eGameSetting_FOV,0); - - // 4J-PB - Don't reset the difficult level if we're in-game - if(Minecraft::GetInstance()->level==nullptr) - { - app.DebugPrintf("SetDefaultOptions - Difficulty = 1\n"); - SetGameSettings(iPad,eGameSetting_Difficulty,1); - } - SetGameSettings(iPad,eGameSetting_Sensitivity_InGame,100); - SetGameSettings(iPad,eGameSetting_ViewBob,1); - SetGameSettings(iPad,eGameSetting_ControlScheme,0); - SetGameSettings(iPad,eGameSetting_ControlInvertLook,(pSettings->iYAxisInversion!=0)?1:0); - SetGameSettings(iPad,eGameSetting_ControlSouthPaw,pSettings->bSwapSticks?1:0); - SetGameSettings(iPad,eGameSetting_SplitScreenVertical,0); - SetGameSettings(iPad,eGameSetting_GamertagsVisible,1); - - // Interim TU 1.6.6 - SetGameSettings(iPad,eGameSetting_Sensitivity_InMenu,100); - SetGameSettings(iPad,eGameSetting_DisplaySplitscreenGamertags,1); - SetGameSettings(iPad,eGameSetting_Hints,1); - SetGameSettings(iPad,eGameSetting_Autosave,2); - SetGameSettings(iPad,eGameSetting_Tooltips,1); - SetGameSettings(iPad,eGameSetting_InterfaceOpacity,80); - - // TU 5 - SetGameSettings(iPad,eGameSetting_Clouds,1); - SetGameSettings(iPad,eGameSetting_Online,1); - SetGameSettings(iPad,eGameSetting_InviteOnly,0); - SetGameSettings(iPad,eGameSetting_FriendsOfFriends,1); - - // default the update changes message to zero - // 4J-PB - We'll only display the message if the profile is pre-TU5 - //SetGameSettings(iPad,eGameSetting_DisplayUpdateMessage,0); - - // TU 6 - SetGameSettings(iPad,eGameSetting_BedrockFog,0); - SetGameSettings(iPad,eGameSetting_DisplayHUD,1); - SetGameSettings(iPad,eGameSetting_DisplayHand,1); - - // TU 7 - SetGameSettings(iPad,eGameSetting_CustomSkinAnim,1); - - // TU 9 - SetGameSettings(iPad,eGameSetting_DeathMessages,1); - SetGameSettings(iPad,eGameSetting_UISize,1); - SetGameSettings(iPad,eGameSetting_UISizeSplitscreen,2); - SetGameSettings(iPad,eGameSetting_AnimatedCharacter,1); - - // TU 12 - GameSettingsA[iPad]->ucCurrentFavoriteSkinPos=0; - for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; - } - - // TU 13 - GameSettingsA[iPad]->uiMashUpPackWorldsDisplay=0xFFFFFFFF; - - // 1.6.4 - app.SetGameHostOption(eGameHostOption_MobGriefing, 1); - app.SetGameHostOption(eGameHostOption_KeepInventory, 0); - app.SetGameHostOption(eGameHostOption_DoMobSpawning, 1 ); - app.SetGameHostOption(eGameHostOption_DoMobLoot, 1 ); - app.SetGameHostOption(eGameHostOption_DoTileDrops, 1 ); - app.SetGameHostOption(eGameHostOption_NaturalRegeneration, 1 ); - app.SetGameHostOption(eGameHostOption_DoDaylightCycle, 1 ); - - //TU25 - SetGameSettings(iPad, eGameSetting_ClassicCrafting, 0); - - // 4J-PB - leave these in, or remove from everywhere they are referenced! - // Although probably best to leave in unless we split the profile settings into platform specific classes - having different meaning per platform for the same bitmask could get confusing - //#ifdef __PS3__ - // PS3DEC13 - SetGameSettings(iPad,eGameSetting_PS3_EULA_Read,0); // EULA not read - - // PS3 1.05 - added Greek - - // 4J-JEV: We cannot change these in-game, as they could affect localised strings and font. - // XB1: Fix for #172947 - Content: Gameplay: While playing in language different form system default one and resetting options to their defaults in active gameplay causes in-game language to change and HUD to disappear - if (!app.GetGameStarted()) - { - GameSettingsA[iPad]->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language - GameSettingsA[iPad]->ucLocale = MINECRAFT_LANGUAGE_DEFAULT; // use the system locale - } - - //#endif - -#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) - GameSettingsA[iPad]->bSettingsChanged=bWriteProfile; -#endif - - return 0; -} - -#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) -int CMinecraftApp::DefaultOptionsCallback(LPVOID pParam,C4JStorage::PROFILESETTINGS *pSettings, const int iPad) -#else -int CMinecraftApp::DefaultOptionsCallback(LPVOID pParam,C_4JProfile::PROFILESETTINGS *pSettings, const int iPad) -#endif -{ - CMinecraftApp *pApp=static_cast(pParam); - - // flag the default options to be set - - pApp->DebugPrintf("Setting default options for player %d", iPad); - pApp->SetAction(iPad,eAppAction_SetDefaultOptions, (LPVOID)pSettings); - //pApp->SetDefaultOptions(pSettings,iPad); - - // if the profile data has been changed, then force a profile write - // It seems we're allowed to break the 5 minute rule if it's the result of a user action - //pApp->CheckGameSettingsChanged(); - - return 0; -} - -#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) - -wstring CMinecraftApp::toStringOptionsStatus(const C4JStorage::eOptionsCallback &eStatus) -{ -#ifndef _CONTENT_PACKAGE - switch(eStatus) - { - case C4JStorage::eOptions_Callback_Idle: return L"Idle"; - case C4JStorage::eOptions_Callback_Write: return L"Write"; - case C4JStorage::eOptions_Callback_Write_Fail_NoSpace: return L"Write_Fail_NoSpace"; - case C4JStorage::eOptions_Callback_Write_Fail: return L"Write_Fail"; - case C4JStorage::eOptions_Callback_Read: return L"Read"; - case C4JStorage::eOptions_Callback_Read_Fail: return L"Read_Fail"; - case C4JStorage::eOptions_Callback_Read_FileNotFound: return L"Read_FileNotFound"; - case C4JStorage::eOptions_Callback_Read_Corrupt: return L"Read_Corrupt"; - case C4JStorage::eOptions_Callback_Read_CorruptDeletePending: return L"Read_CorruptDeletePending"; - case C4JStorage::eOptions_Callback_Read_CorruptDeleted: return L"Read_CorruptDeleted"; - default: return L"[UNRECOGNISED_OPTIONS_STATUS]"; - } -#else - return L""; -#endif -} - -#ifdef __ORBIS__ -int CMinecraftApp::OptionsDataCallback(LPVOID pParam,int iPad,unsigned short usVersion,C4JStorage::eOptionsCallback eStatus,int iBlocksRequired) -{ - CMinecraftApp *pApp=(CMinecraftApp *)pParam; - pApp->m_eOptionsStatusA[iPad]=eStatus; - pApp->m_eOptionsBlocksRequiredA[iPad]=iBlocksRequired; - return 0; -} - -int CMinecraftApp::GetOptionsBlocksRequired(int iPad) -{ - return m_eOptionsBlocksRequiredA[iPad]; -} - -#else -int CMinecraftApp::OptionsDataCallback(LPVOID pParam,int iPad,unsigned short usVersion,C4JStorage::eOptionsCallback eStatus) -{ - CMinecraftApp *pApp=(CMinecraftApp *)pParam; - -#ifndef _CONTENT_PACKAGE - pApp->DebugPrintf("[OptionsDataCallback] Pad_%i: new status == %ls(%i).\n", iPad, pApp->toStringOptionsStatus(eStatus).c_str(), (int) eStatus); -#endif - - pApp->m_eOptionsStatusA[iPad] = eStatus; - - return 0; -} -#endif - -C4JStorage::eOptionsCallback CMinecraftApp::GetOptionsCallbackStatus(int iPad) -{ - return m_eOptionsStatusA[iPad]; -} - -void CMinecraftApp::SetOptionsCallbackStatus(int iPad, C4JStorage::eOptionsCallback eStatus) -{ - m_eOptionsStatusA[iPad]=eStatus; -} -#endif - -int CMinecraftApp::OldProfileVersionCallback(LPVOID pParam,unsigned char *pucData, const unsigned short usVersion, const int iPad) -{ - // check what needs to be done with this version to update to the current one - - switch(usVersion) - { -#ifdef _XBOX - case PROFILE_VERSION_1: - case PROFILE_VERSION_2: - // need to fill in values for the new profile data. No need to save the profile - that'll happen if they get changed, or if the auto save for the profile kicks in - { - GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; - pGameSettings->ucMenuSensitivity=100; //eGameSetting_Sensitivity_InMenu - pGameSettings->ucInterfaceOpacity=80; //eGameSetting_Sensitivity_InMenu - pGameSettings->usBitmaskValues|=0x0200; //eGameSetting_DisplaySplitscreenGamertags - on - pGameSettings->usBitmaskValues|=0x0400; //eGameSetting_Hints - on - pGameSettings->usBitmaskValues|=0x1000; //eGameSetting_Autosave - 2 - pGameSettings->usBitmaskValues|=0x8000; //eGameSetting_Tooltips - on - - // 4J-PB - Let's also award all the achievements they have again because of the profile bug that seemed to stop the awards of some - // Changing this to check the system achievements at sign-in and award any that the game says we have and the system says we haven't - //ProfileManager.ReAwardAchievements(iPad); - - pGameSettings->uiBitmaskValues=0L; // reset - pGameSettings->uiBitmaskValues|=GAMESETTING_CLOUDS; //eGameSetting_Clouds - on - pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on - //eGameSetting_GameSetting_Invite - off - pGameSettings->uiBitmaskValues|=GAMESETTING_FRIENDSOFFRIENDS; //eGameSetting_GameSetting_FriendsOfFriends - on - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) - // TU6 - pGameSettings->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on - // TU7 - pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on - // TU9 - pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on - pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 - pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 - pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on - // TU12 - // favorite skins added, but only set in TU12 - set to FFs - for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; - } - pGameSettings->ucCurrentFavoriteSkinPos=0; - // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list - pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; - - // PS3 1.05 - added Greek - pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language - } - break; - case PROFILE_VERSION_3: - - { - GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; - pGameSettings->uiBitmaskValues=0L; // reset - pGameSettings->uiBitmaskValues|=GAMESETTING_CLOUDS; //eGameSetting_Clouds - on - pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on - //eGameSetting_GameSetting_Invite - off - pGameSettings->uiBitmaskValues|=GAMESETTING_FRIENDSOFFRIENDS; //eGameSetting_GameSetting_FriendsOfFriends - on - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) - // TU6 - pGameSettings->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on - // TU7 - pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on - // TU9 - pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on - pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 - pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 - pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on - // TU12 - // favorite skins added, but only set in TU12 - set to FFs - for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; - } - pGameSettings->ucCurrentFavoriteSkinPos=0; - // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list - pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; - - // PS3 1.05 - added Greek - pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language - - } - break; - case PROFILE_VERSION_4: - { - GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; - - pGameSettings->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on - // TU7 - pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on - // TU9 - pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on - pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 - pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 - pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on - - // Set the online flag to on, so it's not saved if a game starts offline when the user didn't change it to be offline (xbox disconnected from LIVE) - pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on - // TU12 - // favorite skins added, but only set in TU12 - set to FFs - for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; - } - pGameSettings->ucCurrentFavoriteSkinPos=0; - // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list - pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; - - // PS3 1.05 - added Greek - pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language - - } - - break; - case PROFILE_VERSION_5: - { - GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; - - // reset the display new message counter - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) - // TU7 - pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on - // TU9 - pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on - pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 - pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 - pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on - // Set the online flag to on, so it's not saved if a game starts offline when the user didn't change it to be offline (xbox disconnected from LIVE) - pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on - // TU12 - // favorite skins added, but only set in TU12 - set to FFs - for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; - } - pGameSettings->ucCurrentFavoriteSkinPos=0; - // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list - pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; - - // PS3 1.05 - added Greek - pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language - - - } - - break; - case PROFILE_VERSION_6: - { - GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; - - // Added gui size for splitscreen and fullscreen - // Added death messages toggle - - // reset the display new message counter - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) - // TU9 - pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on - pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 - pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 - pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on - // Set the online flag to on, so it's not saved if a game starts offline when the user didn't change it to be offline (xbox disconnected from LIVE) - pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on - // TU12 - // favorite skins added, but only set in TU12 - set to FFs - for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; - } - pGameSettings->ucCurrentFavoriteSkinPos=0; - // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list - pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; - - // PS3 1.05 - added Greek - pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language - - - } - - break; - - case PROFILE_VERSION_7: - { - GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; - // reset the display new message counter - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) - - // TU12 - // favorite skins added, but only set in TU12 - set to FFs - for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; - } - pGameSettings->ucCurrentFavoriteSkinPos=0; - // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list - pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; - - // PS3 1.05 - added Greek - pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language - - - } - break; -#endif - case PROFILE_VERSION_8: - { - GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; - // reset the display new message counter - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) - - // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list - pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; - - // PS3DEC13 - pGameSettings->uiBitmaskValues&=~GAMESETTING_PS3EULAREAD; //eGameSetting_PS3_EULA_Read - off - - // PS3 1.05 - added Greek - pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language - - } - break; - case PROFILE_VERSION_9: - // PS3DEC13 - { - GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) - pGameSettings->uiBitmaskValues&=~GAMESETTING_PS3EULAREAD; //eGameSetting_PS3_EULA_Read - off - - // PS3 1.05 - added Greek - pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language - - } - break; - case PROFILE_VERSION_10: - { - GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) - pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language - } - break; - case PROFILE_VERSION_11: - { - GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) - } - break; - case PROFILE_VERSION_12: - { - GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) - } - break; - default: - { - // This might be from a version during testing of new profile updates - app.DebugPrintf("Don't know what to do with this profile version!\n"); - - GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; - pGameSettings->ucMenuSensitivity=100; //eGameSetting_Sensitivity_InMenu - pGameSettings->ucInterfaceOpacity=80; //eGameSetting_Sensitivity_InMenu - pGameSettings->usBitmaskValues|=0x0200; //eGameSetting_DisplaySplitscreenGamertags - on - pGameSettings->usBitmaskValues|=0x0400; //eGameSetting_Hints - on - pGameSettings->usBitmaskValues|=0x1000; //eGameSetting_Autosave - 2 - pGameSettings->usBitmaskValues|=0x8000; //eGameSetting_Tooltips - on - - pGameSettings->uiBitmaskValues=0L; // reset - pGameSettings->uiBitmaskValues|=GAMESETTING_CLOUDS; //eGameSetting_Clouds - on - pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on - //eGameSetting_GameSetting_Invite - off - pGameSettings->uiBitmaskValues|=GAMESETTING_FRIENDSOFFRIENDS; //eGameSetting_GameSetting_FriendsOfFriends - on - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) - pGameSettings->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on - pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on - pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on - pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on - pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 - pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 - pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on - pGameSettings->uiBitmaskValues |= GAMESETTING_CLASSICCRAFTING; //eGameSetting_ClassicCrafting - off - // TU12 - // favorite skins added, but only set in TU12 - set to FFs - for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; - } - pGameSettings->ucCurrentFavoriteSkinPos=0; - // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list - pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; - - // PS3DEC13 - pGameSettings->uiBitmaskValues&=~GAMESETTING_PS3EULAREAD; //eGameSetting_PS3_EULA_Read - off - - // PS3 1.05 - added Greek - pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language - - } - break; - } - - return 0; -} - -void CMinecraftApp::ApplyGameSettingsChanged(int iPad) -{ - ActionGameSettings(iPad,eGameSetting_MusicVolume ); - ActionGameSettings(iPad,eGameSetting_SoundFXVolume ); - ActionGameSettings(iPad,eGameSetting_RenderDistance ); - ActionGameSettings(iPad,eGameSetting_Gamma ); - ActionGameSettings(iPad,eGameSetting_FOV ); - ActionGameSettings(iPad,eGameSetting_Difficulty ); - ActionGameSettings(iPad,eGameSetting_Sensitivity_InGame ); - ActionGameSettings(iPad,eGameSetting_ViewBob ); - ActionGameSettings(iPad,eGameSetting_ControlScheme ); - ActionGameSettings(iPad,eGameSetting_ControlInvertLook); - ActionGameSettings(iPad,eGameSetting_ControlSouthPaw); - ActionGameSettings(iPad,eGameSetting_SplitScreenVertical); - ActionGameSettings(iPad,eGameSetting_GamertagsVisible); - - // Interim TU 1.6.6 - ActionGameSettings(iPad,eGameSetting_Sensitivity_InMenu ); - ActionGameSettings(iPad,eGameSetting_DisplaySplitscreenGamertags); - ActionGameSettings(iPad,eGameSetting_Hints); - ActionGameSettings(iPad,eGameSetting_InterfaceOpacity); - ActionGameSettings(iPad,eGameSetting_Tooltips); - - ActionGameSettings(iPad,eGameSetting_Clouds); - ActionGameSettings(iPad,eGameSetting_BedrockFog); - ActionGameSettings(iPad,eGameSetting_DisplayHUD); - ActionGameSettings(iPad,eGameSetting_DisplayHand); - ActionGameSettings(iPad,eGameSetting_CustomSkinAnim); - ActionGameSettings(iPad,eGameSetting_DeathMessages); - ActionGameSettings(iPad,eGameSetting_UISize); - ActionGameSettings(iPad,eGameSetting_UISizeSplitscreen); - ActionGameSettings(iPad,eGameSetting_AnimatedCharacter); - - ActionGameSettings(iPad,eGameSetting_PS3_EULA_Read); - ActionGameSettings(iPad,eGameSetting_VSync); - - //TU25 - ActionGameSettings(iPad, eGameSetting_ClassicCrafting); - ActionGameSettings(iPad, eGameSetting_HideSaveSizeBar); -} - -void CMinecraftApp::ActionGameSettings(int iPad,eGameSetting eVal) -{ - Minecraft *pMinecraft=Minecraft::GetInstance(); - switch(eVal) - { - case eGameSetting_MusicVolume: - if(iPad==ProfileManager.GetPrimaryPad()) - { - pMinecraft->options->set(Options::Option::MUSIC,static_cast(GameSettingsA[iPad]->ucMusicVolume)/100.0f); - } - break; - case eGameSetting_SoundFXVolume: - if (iPad == ProfileManager.GetPrimaryPad()) - { - pMinecraft->options->set(Options::Option::SOUND, static_cast(GameSettingsA[iPad]->ucSoundFXVolume) / 100.0f); - } - break; - case eGameSetting_RenderDistance: - if (iPad == ProfileManager.GetPrimaryPad()) - { - int dist = (GameSettingsA[iPad]->uiBitmaskValues >> 16) & 0xFF; - - int level = UIScene_SettingsGraphicsMenu::DistanceToLevel(dist); - pMinecraft->options->set(Options::Option::RENDER_DISTANCE, 3 - level); - }; - break; - case eGameSetting_Gamma: - if(iPad==ProfileManager.GetPrimaryPad()) - { -#if defined(_WIN64) || defined(_WINDOWS64) - pMinecraft->options->set(Options::Option::GAMMA, static_cast(GameSettingsA[iPad]->ucGamma) / 100.0f); -#else - // ucGamma range is 0-100, UpdateGamma is 0 - 32768 - float fVal=((float)GameSettingsA[iPad]->ucGamma)*327.68f; - RenderManager.UpdateGamma((unsigned short)fVal); -#endif - } - - break; - case eGameSetting_FOV: - if(iPad==ProfileManager.GetPrimaryPad()) - { - float fovDeg = 70.0f + (float)GameSettingsA[iPad]->ucFov * 40.0f / 100.0f; - pMinecraft->gameRenderer->SetFovVal(fovDeg); - pMinecraft->options->set(Options::Option::FOV, (float)GameSettingsA[iPad]->ucFov / 100.0f); - } - break; - case eGameSetting_Difficulty: - if(iPad==ProfileManager.GetPrimaryPad()) - { - pMinecraft->options->toggle(Options::Option::DIFFICULTY,GameSettingsA[iPad]->usBitmaskValues&0x03); - app.DebugPrintf("Difficulty toggle to %d\n",GameSettingsA[iPad]->usBitmaskValues&0x03); - - // Update the Game Host setting - app.SetGameHostOption(eGameHostOption_Difficulty,pMinecraft->options->difficulty); - - // send this to the other players if we are in-game - bool bInGame=pMinecraft->level!=nullptr; - - // Game Host only (and for now we can't change the diff while in game, so this shouldn't happen) - if(bInGame && g_NetworkManager.IsHost() && (iPad==ProfileManager.GetPrimaryPad())) - { - app.SetXuiServerAction(iPad,eXuiServerAction_ServerSettingChanged_Difficulty); - } - } - else - { - app.DebugPrintf("NOT ACTIONING DIFFICULTY - Primary pad is %d, This pad is %d\n",ProfileManager.GetPrimaryPad(),iPad); - } - - break; - case eGameSetting_Sensitivity_InGame: - // 4J-PB - we don't use the options value - // tell the input that we've changed the sensitivity - range of the slider is 0 to 200, default is 100 - pMinecraft->options->set(Options::Option::SENSITIVITY,static_cast(GameSettingsA[iPad]->ucSensitivity)/100.0f); - //InputManager.SetJoypadSensitivity(iPad,((float)GameSettingsA[iPad]->ucSensitivity)/100.0f); - - break; - case eGameSetting_ViewBob: - // 4J-PB - not handled here any more - it's read from the gamesettings per player - //pMinecraft->options->toggle(Options::Option::VIEW_BOBBING,GameSettingsA[iPad]->usBitmaskValues&0x04); - break; - case eGameSetting_ControlScheme: - InputManager.SetJoypadMapVal(iPad,(GameSettingsA[iPad]->usBitmaskValues&0x30)>>4); - break; - - case eGameSetting_ControlInvertLook: - // Nothing specific to do for this setting. - break; - - case eGameSetting_ControlSouthPaw: - // What is the setting? - if ( GameSettingsA[iPad]->usBitmaskValues & 0x80 ) - { - // Southpaw. - InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_LX, AXIS_MAP_RX ); - InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_LY, AXIS_MAP_RY ); - InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_RX, AXIS_MAP_LX ); - InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_RY, AXIS_MAP_LY ); - InputManager.SetJoypadStickTriggerMap( iPad, TRIGGER_MAP_0, TRIGGER_MAP_1 ); - InputManager.SetJoypadStickTriggerMap( iPad, TRIGGER_MAP_1, TRIGGER_MAP_0 ); - } - else - { - // Right handed. - InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_LX, AXIS_MAP_LX ); - InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_LY, AXIS_MAP_LY ); - InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_RX, AXIS_MAP_RX ); - InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_RY, AXIS_MAP_RY ); - InputManager.SetJoypadStickTriggerMap( iPad, TRIGGER_MAP_0, TRIGGER_MAP_0 ); - InputManager.SetJoypadStickTriggerMap( iPad, TRIGGER_MAP_1, TRIGGER_MAP_1 ); - } - break; - case eGameSetting_SplitScreenVertical: - if(iPad==ProfileManager.GetPrimaryPad()) - { - pMinecraft->updatePlayerViewportAssignments(); - } - break; - case eGameSetting_GamertagsVisible: - { - bool bInGame=pMinecraft->level!=nullptr; - - // Game Host only - if(bInGame && g_NetworkManager.IsHost() && (iPad==ProfileManager.GetPrimaryPad())) - { - // Update the Game Host setting if you are the host and you are in-game - app.SetGameHostOption(eGameHostOption_Gamertags,((GameSettingsA[iPad]->usBitmaskValues&0x0008)!=0)?1:0); - app.SetXuiServerAction(iPad,eXuiServerAction_ServerSettingChanged_Gamertags); - - PlayerList *players = MinecraftServer::getInstance()->getPlayerList(); - for( auto& decorationPlayer : players->players ) - { - decorationPlayer->setShowOnMaps((app.GetGameHostOption(eGameHostOption_Gamertags)!=0)?true:false); - } - } - } - break; - // Interim TU 1.6.6 - case eGameSetting_Sensitivity_InMenu: - // 4J-PB - we don't use the options value - // tell the input that we've changed the sensitivity - range of the slider is 0 to 200, default is 100 - //pMinecraft->options->set(Options::Option::SENSITIVITY,((float)GameSettingsA[iPad]->ucSensitivity)/100.0f); - //InputManager.SetJoypadSensitivity(iPad,((float)GameSettingsA[iPad]->ucSensitivity)/100.0f); - - break; - - case eGameSetting_DisplaySplitscreenGamertags: - for( BYTE idx = 0; idx < XUSER_MAX_COUNT; ++idx) - { - if(pMinecraft->localplayers[idx] != nullptr) - { - if(pMinecraft->localplayers[idx]->m_iScreenSection==C4JRender::VIEWPORT_TYPE_FULLSCREEN) - { - ui.DisplayGamertag(idx,false); - } - else - { - ui.DisplayGamertag(idx,true); - } - } - } - - break; - case eGameSetting_InterfaceOpacity: - // update the tooltips display - ui.RefreshTooltips( iPad); - - break; - case eGameSetting_Hints: - //nothing to do here - break; - case eGameSetting_Tooltips: - if((GameSettingsA[iPad]->usBitmaskValues&0x8000)!=0) - { - ui.SetEnableTooltips(iPad,TRUE); - } - else - { - ui.SetEnableTooltips(iPad,FALSE); - } - break; - case eGameSetting_Clouds: - //nothing to do here - break; - case eGameSetting_Online: - //nothing to do here - break; - case eGameSetting_InviteOnly: - //nothing to do here - break; - case eGameSetting_FriendsOfFriends: - //nothing to do here - break; - case eGameSetting_BedrockFog: - { - bool bInGame = pMinecraft->level != nullptr; - - if (bInGame && g_NetworkManager.IsHost() && (iPad == ProfileManager.GetPrimaryPad())) - { - app.SetGameHostOption(eGameHostOption_BedrockFog, GetGameSettings(iPad, eGameSetting_BedrockFog) ? 1 : 0); - app.SetXuiServerAction(iPad, eXuiServerAction_ServerSettingChanged_BedrockFog); - } - } - break; - case eGameSetting_DisplayHUD: - //nothing to do here - break; - case eGameSetting_DisplayHand: - //nothing to do here - break; - case eGameSetting_CustomSkinAnim: - //nothing to do here - break; - case eGameSetting_DeathMessages: - //nothing to do here - break; - case eGameSetting_UISize: - //nothing to do here - break; - case eGameSetting_UISizeSplitscreen: - //nothing to do here - break; - case eGameSetting_AnimatedCharacter: - //nothing to do here - break; - case eGameSetting_PS3_EULA_Read: - //nothing to do here - break; - case eGameSetting_PSVita_NetworkModeAdhoc: - //nothing to do here - break; - case eGameSetting_VSync: -#ifdef _WINDOWS64 - { - extern bool g_bVSync; - g_bVSync = (GetGameSettings(iPad, eGameSetting_VSync) != 0); - } -#endif - break; - case eGameSetting_ExclusiveFullscreen: -#ifdef _WINDOWS64 - { - extern void SetExclusiveFullscreen(bool enabled); - SetExclusiveFullscreen(GetGameSettings(iPad, eGameSetting_ExclusiveFullscreen) != 0); - } -#endif - break; - case eGameSetting_ClassicCrafting: - //nothing to do here - break; - case eGameSetting_HideSaveSizeBar: - //nothing to do here - break; - } -} - -void CMinecraftApp::SetPlayerSkin(int iPad,const wstring &name) -{ - DWORD skinId = app.getSkinIdFromPath(name); - - SetPlayerSkin(iPad,skinId); -} - -void CMinecraftApp::SetPlayerSkin(int iPad,DWORD dwSkinId) -{ - DebugPrintf("Setting skin for %d to %08X\n", iPad, dwSkinId); - - GameSettingsA[iPad]->dwSelectedSkin = dwSkinId; - GameSettingsA[iPad]->bSettingsChanged = true; - - TelemetryManager->RecordSkinChanged(iPad, GameSettingsA[iPad]->dwSelectedSkin); - - if(Minecraft::GetInstance()->localplayers[iPad]!=nullptr) Minecraft::GetInstance()->localplayers[iPad]->setAndBroadcastCustomSkin(dwSkinId); -} - - -wstring CMinecraftApp::GetPlayerSkinName(int iPad) -{ - return app.getSkinPathFromId(GameSettingsA[iPad]->dwSelectedSkin); -} - -DWORD CMinecraftApp::GetPlayerSkinId(int iPad) -{ - // 4J-PB -check the user has rights to use this skin - they may have had at some point but the entitlement has been removed. - DLCPack *Pack=nullptr; - DLCSkinFile *skinFile=nullptr; - DWORD dwSkin=GameSettingsA[iPad]->dwSelectedSkin; - wchar_t chars[256]; - - if( GET_IS_DLC_SKIN_FROM_BITMASK(dwSkin) ) - { - // 4J Stu - DLC skins are numbered using decimal rather than hex to make it easier to number manually - swprintf(chars, 256, L"dlcskin%08d.png", GET_DLC_SKIN_ID_FROM_BITMASK(dwSkin)); - - Pack=app.m_dlcManager.getPackContainingSkin(chars); - - if(Pack) - { - skinFile = Pack->getSkinFile(chars); - - bool bSkinIsFree = skinFile->getParameterAsBool( DLCManager::e_DLCParamType_Free ); - bool bLicensed = Pack->hasPurchasedFile( DLCManager::e_DLCType_Skin, skinFile->getPath() ); - - if(bSkinIsFree || bLicensed) - { - return dwSkin; - } - else - { - return 0; - } - } - } - - - return dwSkin; -} - -DWORD CMinecraftApp::GetAdditionalModelParts(int iPad) -{ - return m_dwAdditionalModelParts[iPad]; -} - - -void CMinecraftApp::SetPlayerCape(int iPad,const wstring &name) -{ - DWORD capeId = Player::getCapeIdFromPath(name); - - SetPlayerCape(iPad,capeId); -} - -void CMinecraftApp::SetPlayerCape(int iPad,DWORD dwCapeId) -{ - DebugPrintf("Setting cape for %d to %08X\n", iPad, dwCapeId); - - GameSettingsA[iPad]->dwSelectedCape = dwCapeId; - GameSettingsA[iPad]->bSettingsChanged = true; - - //SentientManager.RecordSkinChanged(iPad, GameSettingsA[iPad]->dwSelectedSkin); - - if(Minecraft::GetInstance()->localplayers[iPad]!=nullptr) Minecraft::GetInstance()->localplayers[iPad]->setAndBroadcastCustomCape(dwCapeId); -} - -wstring CMinecraftApp::GetPlayerCapeName(int iPad) -{ - return Player::getCapePathFromId(GameSettingsA[iPad]->dwSelectedCape); -} - -DWORD CMinecraftApp::GetPlayerCapeId(int iPad) -{ - return GameSettingsA[iPad]->dwSelectedCape; -} - -void CMinecraftApp::SetPlayerFavoriteSkin(int iPad, int iIndex,unsigned int uiSkinID) -{ - DebugPrintf("Setting favorite skin for %d to %08X\n", iPad, uiSkinID); - - GameSettingsA[iPad]->uiFavoriteSkinA[iIndex] = uiSkinID; - GameSettingsA[iPad]->bSettingsChanged = true; -} - -unsigned int CMinecraftApp::GetPlayerFavoriteSkin(int iPad,int iIndex) -{ - return GameSettingsA[iPad]->uiFavoriteSkinA[iIndex]; -} - -unsigned char CMinecraftApp::GetPlayerFavoriteSkinsPos(int iPad) -{ - return GameSettingsA[iPad]->ucCurrentFavoriteSkinPos; -} - -void CMinecraftApp::SetPlayerFavoriteSkinsPos(int iPad, int iPos) -{ - GameSettingsA[iPad]->ucCurrentFavoriteSkinPos=static_cast(iPos); - GameSettingsA[iPad]->bSettingsChanged = true; -} - -unsigned int CMinecraftApp::GetPlayerFavoriteSkinsCount(int iPad) -{ - unsigned int uiCount=0; - for(int i=0;iuiFavoriteSkinA[i]!=0xFFFFFFFF) - { - uiCount++; - } - else - { - break; - } - } - return uiCount; -} - -void CMinecraftApp::ValidateFavoriteSkins(int iPad) -{ - unsigned int uiCount=GetPlayerFavoriteSkinsCount(iPad); - - // remove invalid skins - unsigned int uiValidSkin=0; - wchar_t chars[256]; - - for(unsigned int i=0;igetFile(DLCManager::e_DLCType_Skin,chars); - DLCSkinFile *pSkinFile = pDLCPack->getSkinFile(chars); - - if( pDLCPack->hasPurchasedFile(DLCManager::e_DLCType_Skin, L"") || (pSkinFile && pSkinFile->isFree())) - { - GameSettingsA[iPad]->uiFavoriteSkinA[uiValidSkin++]=GameSettingsA[iPad]->uiFavoriteSkinA[i]; - } - } - } - - for(unsigned int i=uiValidSkin;iuiFavoriteSkinA[i]=0xFFFFFFFF; - } -} - -// Mash-up pack worlds -void CMinecraftApp::HideMashupPackWorld(int iPad, unsigned int iMashupPackID) -{ - unsigned int uiPackID=iMashupPackID - 1024; // mash-up ids start at 1024 - GameSettingsA[iPad]->uiMashUpPackWorldsDisplay&=~(1<bSettingsChanged = true; -} - -void CMinecraftApp::EnableMashupPackWorlds(int iPad) -{ - GameSettingsA[iPad]->uiMashUpPackWorldsDisplay=0xFFFFFFFF; - GameSettingsA[iPad]->bSettingsChanged = true; -} - -unsigned int CMinecraftApp::GetMashupPackWorlds(int iPad) -{ - return GameSettingsA[iPad]->uiMashUpPackWorldsDisplay; -} - -void CMinecraftApp::SetMinecraftLanguage(int iPad, unsigned char ucLanguage) -{ - GameSettingsA[iPad]->ucLanguage = ucLanguage; - GameSettingsA[iPad]->bSettingsChanged = true; -} - -unsigned char CMinecraftApp::GetMinecraftLanguage(int iPad) -{ - // if there are no game settings read yet, return the default language - if(GameSettingsA[iPad]==nullptr) - { - return 0; - } - else - { - return GameSettingsA[iPad]->ucLanguage; - } -} - -void CMinecraftApp::SetMinecraftLocale(int iPad, unsigned char ucLocale) -{ - GameSettingsA[iPad]->ucLocale = ucLocale; - GameSettingsA[iPad]->bSettingsChanged = true; -} - -unsigned char CMinecraftApp::GetMinecraftLocale(int iPad) -{ - // if there are no game settings read yet, return the default language - if(GameSettingsA[iPad]==nullptr) - { - return 0; - } - else - { - return GameSettingsA[iPad]->ucLocale; - } -} - -void CMinecraftApp::SetGameSettings(int iPad,eGameSetting eVal,unsigned char ucVal) -{ - //Minecraft *pMinecraft=Minecraft::GetInstance(); - - switch(eVal) - { - case eGameSetting_MusicVolume: - if(GameSettingsA[iPad]->ucMusicVolume!=ucVal) - { - GameSettingsA[iPad]->ucMusicVolume=ucVal; - if(iPad==ProfileManager.GetPrimaryPad()) - { - ActionGameSettings(iPad,eVal); - } - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_SoundFXVolume: - if(GameSettingsA[iPad]->ucSoundFXVolume!=ucVal) - { - GameSettingsA[iPad]->ucSoundFXVolume=ucVal; - if(iPad==ProfileManager.GetPrimaryPad()) - { - ActionGameSettings(iPad,eVal); - } - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_RenderDistance: - { - unsigned int val = ucVal & 0xFF; - - GameSettingsA[iPad]->uiBitmaskValues &= ~(0xFF << 16); - GameSettingsA[iPad]->uiBitmaskValues |= val << 16; - if(iPad == ProfileManager.GetPrimaryPad()) - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged = true; - } - break; - case eGameSetting_Gamma: - if(GameSettingsA[iPad]->ucGamma!=ucVal) - { - GameSettingsA[iPad]->ucGamma=ucVal; - if(iPad==ProfileManager.GetPrimaryPad()) - { - ActionGameSettings(iPad,eVal); - } - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_FOV: - if(GameSettingsA[iPad]->ucFov!=ucVal) - { - GameSettingsA[iPad]->ucFov=ucVal; - if(iPad==ProfileManager.GetPrimaryPad()) - { - ActionGameSettings(iPad,eVal); - } - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_Difficulty: - if((GameSettingsA[iPad]->usBitmaskValues&0x03)!=(ucVal&0x03)) - { - GameSettingsA[iPad]->usBitmaskValues&=~0x03; - GameSettingsA[iPad]->usBitmaskValues|=ucVal&0x03; - if(iPad==ProfileManager.GetPrimaryPad()) - { - ActionGameSettings(iPad,eVal); - } - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_Sensitivity_InGame: - if(GameSettingsA[iPad]->ucSensitivity!=ucVal) - { - GameSettingsA[iPad]->ucSensitivity=ucVal; - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_ViewBob: - if((GameSettingsA[iPad]->usBitmaskValues&0x0004)!=((ucVal&0x01)<<2)) - { - if(ucVal!=0) - { - GameSettingsA[iPad]->usBitmaskValues|=0x0004; - } - else - { - GameSettingsA[iPad]->usBitmaskValues&=~0x0004; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_ControlScheme: // bits 5 and 6 - if((GameSettingsA[iPad]->usBitmaskValues&0x30)!=((ucVal&0x03)<<4)) - { - GameSettingsA[iPad]->usBitmaskValues&=~0x0030; - if(ucVal!=0) - { - GameSettingsA[iPad]->usBitmaskValues|=(ucVal&0x03)<<4; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - - case eGameSetting_ControlInvertLook: - if((GameSettingsA[iPad]->usBitmaskValues&0x0040)!=((ucVal&0x01)<<6)) - { - if(ucVal!=0) - { - GameSettingsA[iPad]->usBitmaskValues|=0x0040; - } - else - { - GameSettingsA[iPad]->usBitmaskValues&=~0x0040; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - - case eGameSetting_ControlSouthPaw: - if((GameSettingsA[iPad]->usBitmaskValues&0x0080)!=((ucVal&0x01)<<7)) - { - if(ucVal!=0) - { - GameSettingsA[iPad]->usBitmaskValues|=0x0080; - } - else - { - GameSettingsA[iPad]->usBitmaskValues&=~0x0080; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_SplitScreenVertical: - if((GameSettingsA[iPad]->usBitmaskValues&0x0100)!=((ucVal&0x01)<<8)) - { - if(ucVal!=0) - { - GameSettingsA[iPad]->usBitmaskValues|=0x0100; - } - else - { - GameSettingsA[iPad]->usBitmaskValues&=~0x0100; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_GamertagsVisible: - if((GameSettingsA[iPad]->usBitmaskValues&0x0008)!=((ucVal&0x01)<<3)) - { - if(ucVal!=0) - { - GameSettingsA[iPad]->usBitmaskValues|=0x0008; - } - else - { - GameSettingsA[iPad]->usBitmaskValues&=~0x0008; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - - // 4J-PB - Added for Interim TU for 1.6.6 - case eGameSetting_Sensitivity_InMenu: - if(GameSettingsA[iPad]->ucMenuSensitivity!=ucVal) - { - GameSettingsA[iPad]->ucMenuSensitivity=ucVal; - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_DisplaySplitscreenGamertags: - if((GameSettingsA[iPad]->usBitmaskValues&0x0200)!=((ucVal&0x01)<<9)) - { - if(ucVal!=0) - { - GameSettingsA[iPad]->usBitmaskValues|=0x0200; - } - else - { - GameSettingsA[iPad]->usBitmaskValues&=~0x0200; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_Hints: - if((GameSettingsA[iPad]->usBitmaskValues&0x0400)!=((ucVal&0x01)<<10)) - { - if(ucVal!=0) - { - GameSettingsA[iPad]->usBitmaskValues|=0x0400; - } - else - { - GameSettingsA[iPad]->usBitmaskValues&=~0x0400; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_Autosave: - if((GameSettingsA[iPad]->usBitmaskValues&0x7800)!=((ucVal&0x0F)<<11)) - { - GameSettingsA[iPad]->usBitmaskValues&=~0x7800; - if(ucVal!=0) - { - GameSettingsA[iPad]->usBitmaskValues|=(ucVal&0x0F)<<11; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - - case eGameSetting_Tooltips: - if((GameSettingsA[iPad]->usBitmaskValues&0x8000)!=((ucVal&0x01)<<15)) - { - if(ucVal!=0) - { - GameSettingsA[iPad]->usBitmaskValues|=0x8000; - } - else - { - GameSettingsA[iPad]->usBitmaskValues&=~0x8000; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_InterfaceOpacity: - if(GameSettingsA[iPad]->ucInterfaceOpacity!=ucVal) - { - GameSettingsA[iPad]->ucInterfaceOpacity=ucVal; - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - - break; - case eGameSetting_Clouds: - if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_CLOUDS)!=(ucVal&0x01)) - { - if(ucVal==1) - { - GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_CLOUDS; - } - else - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_CLOUDS; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - - break; - - case eGameSetting_Online: - if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_ONLINE)!=(ucVal&0x01)<<1) - { - if(ucVal==1) - { - GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_ONLINE; - } - else - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_ONLINE; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - - break; - case eGameSetting_InviteOnly: - if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_INVITEONLY)!=(ucVal&0x01)<<2) - { - if(ucVal==1) - { - GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_INVITEONLY; - } - else - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_INVITEONLY; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - - break; - case eGameSetting_FriendsOfFriends: - if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_FRIENDSOFFRIENDS)!=(ucVal&0x01)<<3) - { - if(ucVal==1) - { - GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_FRIENDSOFFRIENDS; - } - else - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_FRIENDSOFFRIENDS; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - - break; - case eGameSetting_DisplayUpdateMessage: - if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYUPDATEMSG)!=(ucVal&0x03)<<4) - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_DISPLAYUPDATEMSG; - if(ucVal>0) - { - GameSettingsA[iPad]->uiBitmaskValues|=(ucVal&0x03)<<4; - } - - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - - break; - - case eGameSetting_BedrockFog: - if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_BEDROCKFOG)!=(ucVal&0x01)<<6) - { - if(ucVal==1) - { - GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_BEDROCKFOG; - } - else - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - - break; - case eGameSetting_DisplayHUD: - if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYHUD)!=(ucVal&0x01)<<7) - { - if(ucVal==1) - { - GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; - } - else - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_DISPLAYHUD; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - - break; - case eGameSetting_DisplayHand: - if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYHAND)!=(ucVal&0x01)<<8) - { - if(ucVal==1) - { - GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; - } - else - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_DISPLAYHAND; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - - break; - - case eGameSetting_CustomSkinAnim: - if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_CUSTOMSKINANIM)!=(ucVal&0x01)<<9) - { - if(ucVal==1) - { - GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; - } - else - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_CUSTOMSKINANIM; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - - break; - // TU9 - case eGameSetting_DeathMessages: - if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DEATHMESSAGES)!=(ucVal&0x01)<<10) - { - if(ucVal==1) - { - GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; - } - else - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_DEATHMESSAGES; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_UISize: - if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_UISIZE)!=((ucVal&0x03)<<11)) - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_UISIZE; - if(ucVal!=0) - { - GameSettingsA[iPad]->uiBitmaskValues|=(ucVal&0x03)<<11; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_UISizeSplitscreen: - if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_UISIZE_SPLITSCREEN)!=((ucVal&0x03)<<13)) - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_UISIZE_SPLITSCREEN; - if(ucVal!=0) - { - GameSettingsA[iPad]->uiBitmaskValues|=(ucVal&0x03)<<13; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_AnimatedCharacter: - if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_ANIMATEDCHARACTER)!=(ucVal&0x01)<<15) - { - if(ucVal==1) - { - GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; - } - else - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_ANIMATEDCHARACTER; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_PS3_EULA_Read: - if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PS3EULAREAD)!=(ucVal&0x01)<<16) - { - if(ucVal==1) - { - GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_PS3EULAREAD; - } - else - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_PS3EULAREAD; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_PSVita_NetworkModeAdhoc: - if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PSVITANETWORKMODEADHOC)!=(ucVal&0x01)<<17) - { - if(ucVal==1) - { - GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_PSVITANETWORKMODEADHOC; - } - else - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_PSVITANETWORKMODEADHOC; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - - case eGameSetting_VSync: - if(((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_VSYNC)>>24)!=(ucVal&0x01)) - { - if(ucVal==1) - { - GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_VSYNC; - } - else - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_VSYNC; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - - case eGameSetting_ExclusiveFullscreen: - if(((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_EXCLUSIVEFULLSCREEN)>>25)!=(ucVal&0x01)) - { - if(ucVal==1) - { - GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_EXCLUSIVEFULLSCREEN; - } - else - { - GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_EXCLUSIVEFULLSCREEN; - } - ActionGameSettings(iPad,eVal); - GameSettingsA[iPad]->bSettingsChanged=true; - } - break; - case eGameSetting_ClassicCrafting: - if ((GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_CLASSICCRAFTING) != (ucVal & 0x01) << 19) - { - if (ucVal == 1) - { - GameSettingsA[iPad]->uiBitmaskValues |= GAMESETTING_CLASSICCRAFTING; - } - else - { - GameSettingsA[iPad]->uiBitmaskValues &= ~GAMESETTING_CLASSICCRAFTING; - } - ActionGameSettings(iPad, eVal); - GameSettingsA[iPad]->bSettingsChanged = true; - } - break; - case eGameSetting_HideSaveSizeBar: - if ((GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_HIDESAVESIZEBAR) != (ucVal & 0x01) << 27) - { - if (ucVal == 1) - { - GameSettingsA[iPad]->uiBitmaskValues |= GAMESETTING_HIDESAVESIZEBAR; - } - else - { - GameSettingsA[iPad]->uiBitmaskValues &= ~GAMESETTING_HIDESAVESIZEBAR; - } - ActionGameSettings(iPad, eVal); - GameSettingsA[iPad]->bSettingsChanged = true; - } - break; - } -} - -unsigned char CMinecraftApp::GetGameSettings(eGameSetting eVal) -{ - int iPad=ProfileManager.GetPrimaryPad(); - - return GetGameSettings(iPad,eVal); -} - -unsigned char CMinecraftApp::GetGameSettings(int iPad,eGameSetting eVal) -{ - switch(eVal) - { - case eGameSetting_MusicVolume: - return GameSettingsA[iPad]->ucMusicVolume; - break; - case eGameSetting_SoundFXVolume: - return GameSettingsA[iPad]->ucSoundFXVolume; - break; - case eGameSetting_RenderDistance: - { - int val = (GameSettingsA[iPad]->uiBitmaskValues >> 16) & 0xFF; - if(val == 0) return val = 16; //brain - return val; - break; - } - case eGameSetting_Gamma: - return GameSettingsA[iPad]->ucGamma; - break; - case eGameSetting_FOV: - return GameSettingsA[iPad]->ucFov; - break; - case eGameSetting_Difficulty: - return GameSettingsA[iPad]->usBitmaskValues&0x0003; - break; - case eGameSetting_Sensitivity_InGame: - return GameSettingsA[iPad]->ucSensitivity; - break; - case eGameSetting_ViewBob: - return ((GameSettingsA[iPad]->usBitmaskValues&0x0004)>>2); - break; - case eGameSetting_GamertagsVisible: - return ((GameSettingsA[iPad]->usBitmaskValues&0x0008)>>3); - break; - case eGameSetting_ControlScheme: - return ((GameSettingsA[iPad]->usBitmaskValues&0x0030)>>4); // 2 bits - break; - case eGameSetting_ControlInvertLook: - return ((GameSettingsA[iPad]->usBitmaskValues&0x0040)>>6); - break; - case eGameSetting_ControlSouthPaw: - return ((GameSettingsA[iPad]->usBitmaskValues&0x0080)>>7); - break; - case eGameSetting_SplitScreenVertical: - return ((GameSettingsA[iPad]->usBitmaskValues&0x0100)>>8); - break; - // 4J-PB - Added for Interim TU for 1.6.6 - case eGameSetting_Sensitivity_InMenu: - return GameSettingsA[iPad]->ucMenuSensitivity; - break; - - case eGameSetting_DisplaySplitscreenGamertags: - return ((GameSettingsA[iPad]->usBitmaskValues&0x0200)>>9); - break; - - case eGameSetting_Hints: - return ((GameSettingsA[iPad]->usBitmaskValues&0x0400)>>10); - break; - case eGameSetting_Autosave: - { - unsigned char ucVal=(GameSettingsA[iPad]->usBitmaskValues&0x7800)>>11; - return ucVal; - } - break; - case eGameSetting_Tooltips: - return ((GameSettingsA[iPad]->usBitmaskValues&0x8000)>>15); - break; - - case eGameSetting_InterfaceOpacity: - return GameSettingsA[iPad]->ucInterfaceOpacity; - break; - - case eGameSetting_Clouds: - return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_CLOUDS); - break; - case eGameSetting_Online: - return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_ONLINE)>>1; - break; - case eGameSetting_InviteOnly: - return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_INVITEONLY)>>2; - break; - case eGameSetting_FriendsOfFriends: - return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_FRIENDSOFFRIENDS)>>3; - break; - case eGameSetting_DisplayUpdateMessage: - return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYUPDATEMSG)>>4; - break; - case eGameSetting_BedrockFog: - return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_BEDROCKFOG)>>6; - break; - case eGameSetting_DisplayHUD: - return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYHUD)>>7; - break; - case eGameSetting_DisplayHand: - return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYHAND)>>8; - break; - case eGameSetting_CustomSkinAnim: - return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_CUSTOMSKINANIM)>>9; - break; - // TU9 - case eGameSetting_DeathMessages: - return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DEATHMESSAGES)>>10; - break; - case eGameSetting_UISize: - { - unsigned char ucVal=(GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_UISIZE)>>11; - return ucVal; - } - break; - case eGameSetting_UISizeSplitscreen: - { - unsigned char ucVal=(GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_UISIZE_SPLITSCREEN)>>13; - return ucVal; - } - break; - case eGameSetting_AnimatedCharacter: - return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_ANIMATEDCHARACTER)>>15; - - case eGameSetting_PS3_EULA_Read: - return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PS3EULAREAD)>>16; - - case eGameSetting_PSVita_NetworkModeAdhoc: - return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PSVITANETWORKMODEADHOC)>>17; - - case eGameSetting_ClassicCrafting: - return (GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_CLASSICCRAFTING) >> 26; - - case eGameSetting_HideSaveSizeBar: - return (GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_HIDESAVESIZEBAR) >> 27; - - case eGameSetting_VSync: - return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_VSYNC)>>24; - - case eGameSetting_ExclusiveFullscreen: - return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_EXCLUSIVEFULLSCREEN)>>25; - - } - return 0; -} - -void CMinecraftApp::CheckGameSettingsChanged(bool bOverride5MinuteTimer, int iPad) -{ - // If the settings have changed, write them to the profile - - if(iPad==XUSER_INDEX_ANY) - { - for(int i=0;ibSettingsChanged) - { -#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__ ) - StorageManager.WriteToProfile(i,true, bOverride5MinuteTimer); -#else - ProfileManager.WriteToProfile(i,true, bOverride5MinuteTimer); -#ifdef _WINDOWS64 - Win64_SaveSettings(GameSettingsA[i]); -#endif -#endif - GameSettingsA[i]->bSettingsChanged=false; - } - } - } - else - { - if(GameSettingsA[iPad]->bSettingsChanged) - { -#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) - StorageManager.WriteToProfile(iPad,true, bOverride5MinuteTimer); -#else - ProfileManager.WriteToProfile(iPad,true, bOverride5MinuteTimer); -#ifdef _WINDOWS64 - Win64_SaveSettings(GameSettingsA[iPad]); -#endif -#endif - GameSettingsA[iPad]->bSettingsChanged=false; - } - } -} - -void CMinecraftApp::ClearGameSettingsChangedFlag(int iPad) -{ - GameSettingsA[iPad]->bSettingsChanged=false; -} - -/////////////////////////// -// -// Remove the debug settings in the release build -// -//////////////////////////// -#ifndef _DEBUG -unsigned int CMinecraftApp::GetGameSettingsDebugMask(int iPad,bool bOverridePlayer) //bOverridePlayer is to force the send for the server to get the read options -{ - return 0; -} - -void CMinecraftApp::SetGameSettingsDebugMask(int iPad, unsigned int uiVal) -{ -} - -void CMinecraftApp::ActionDebugMask(int iPad,bool bSetAllClear) -{ -} - -#else - -unsigned int CMinecraftApp::GetGameSettingsDebugMask(int iPad,bool bOverridePlayer) //bOverridePlayer is to force the send for the server to get the read options -{ - if(iPad==-1) - { - iPad=ProfileManager.GetPrimaryPad(); - } - if(iPad < 0) iPad = 0; - - shared_ptr player = Minecraft::GetInstance()->localplayers[iPad]; - - if(bOverridePlayer || player==nullptr) - { - return GameSettingsA[iPad]->uiDebugBitmask; - } - else - { - return player->GetDebugOptions(); - } -} - - -void CMinecraftApp::SetGameSettingsDebugMask(int iPad, unsigned int uiVal) -{ -#ifndef _CONTENT_PACKAGE - GameSettingsA[iPad]->bSettingsChanged=true; - GameSettingsA[iPad]->uiDebugBitmask=uiVal; - - // update the value so the network server can use it - shared_ptr player = Minecraft::GetInstance()->localplayers[iPad]; - - if(player) - { - Minecraft::GetInstance()->localgameModes[iPad]->handleDebugOptions(uiVal,player); - } -#endif -} - -void CMinecraftApp::ActionDebugMask(int iPad,bool bSetAllClear) -{ - unsigned int ulBitmask=app.GetGameSettingsDebugMask(iPad); - - if(bSetAllClear) ulBitmask=0L; - - - - // these settings should only be actioned for the primary player - if(ProfileManager.GetPrimaryPad()!=iPad) return; - - for(int i=0;i(param); - app.SetAction(actionInfo->iPad, actionInfo->action); -} - - -void CMinecraftApp::HandleXuiActions(void) -{ - eXuiAction eAction; - eTMSAction eTMS; - LPVOID param; - Minecraft *pMinecraft=Minecraft::GetInstance(); - shared_ptr player; - - // are there any global actions to deal with? - eAction = app.GetGlobalXuiAction(); - if(eAction!=eAppAction_Idle) - { - switch(eAction) - { - case eAppAction_DisplayLavaMessage: - // Display a warning about placing lava in the spawn area - { - UINT uiIDA[1]; - uiIDA[0]=IDS_CONFIRM_OK; - C4JStorage::EMessageResult result = ui.RequestErrorMessage( IDS_CANT_PLACE_NEAR_SPAWN_TITLE, IDS_CANT_PLACE_NEAR_SPAWN_TEXT, uiIDA,1,XUSER_INDEX_ANY); - if(result != C4JStorage::EMessage_Busy) SetGlobalXuiAction(eAppAction_Idle); - - } - break; - default: - break; - } - } - - // are there any app actions to deal with? - for(int i=0;iIsTitleAllowedToPostImages() && CSocialManager::Instance()->AreAllUsersAllowedToPostImages() ) - { - // disable character name tags for the shot - //m_bwasHidingGui = pMinecraft->options->hideGui; // 4J Stu - Removed 1.8.2 bug fix (TU6) as don't need this - pMinecraft->options->hideGui = true; - - SetAction(i,eAppAction_SocialPostScreenshot); - } - else - { - SetAction(i,eAppAction_Idle); - } - } - else - { - SetAction(i,eAppAction_Idle); - } - break; - case eAppAction_SocialPostScreenshot: - { - SetAction(i,eAppAction_Idle); - bool bKeepHiding = false; - for(int j=0; j < XUSER_MAX_COUNT;++j) - { - if(app.GetXuiAction(j) == eAppAction_SocialPostScreenshot) - { - bKeepHiding = true; - break; - } - } - pMinecraft->options->hideGui=bKeepHiding; - - // Facebook Share - - if(app.GetLocalPlayerCount()>1) - { - ui.NavigateToScene(i,eUIScene_SocialPost); - } - else - { - ui.NavigateToScene(i,eUIScene_SocialPost); - } - } - break; - case eAppAction_SaveGame: - SetAction(i,eAppAction_Idle); - if(!GetChangingSessionType()) - { - // If this is the trial game, do an upsell - if(ProfileManager.IsFullVersion()) - { - - // flag the render to capture the screenshot for the save - SetAction(i,eAppAction_SaveGameCapturedThumbnail); - } - else - { - // ask the player if they would like to upgrade, or they'll lose the level - - UINT uiIDA[2]; - uiIDA[0]=IDS_CONFIRM_OK; - uiIDA[1]=IDS_CONFIRM_CANCEL; - ui.RequestErrorMessage(IDS_UNLOCK_TITLE, IDS_UNLOCK_TOSAVE_TEXT, uiIDA, 2,i,&CMinecraftApp::UnlockFullSaveReturned,this); - } - } - - break; - case eAppAction_AutosaveSaveGame: - { - // Need to run a check to see if the save exists in order to stop the dialog asking if we want to overwrite it coming up on an autosave - bool bSaveExists; - StorageManager.DoesSaveExist(&bSaveExists); - - SetAction(i,eAppAction_Idle); - if(!GetChangingSessionType()) - { - - // flag the render to capture the screenshot for the save - SetAction(i,eAppAction_AutosaveSaveGameCapturedThumbnail); - } - } - - break; - - case eAppAction_SaveGameCapturedThumbnail: - // reset the autosave timer - app.SetAutosaveTimerTime(); - SetAction(i,eAppAction_Idle); - // Check that there is a name for the save - if we're saving from the tutorial and this is the first save from the tutorial, we'll not have a name - /*if(StorageManager.GetSaveName()==nullptr) - { - app.NavigateToScene(i,eUIScene_SaveWorld); - } - else*/ - { - // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen - ui.HideAllGameUIElements(); - - // Hide the other players scenes - ui.ShowOtherPlayersBaseScene(ProfileManager.GetPrimaryPad(), false); - - //INT saveOrCheckpointId = 0; - //bool validSave = StorageManager.GetSaveUniqueNumber(&saveOrCheckpointId); - //SentientManager.RecordLevelSaveOrCheckpoint(ProfileManager.GetPrimaryPad(), saveOrCheckpointId); - - LoadingInputParams *loadingParams = new LoadingInputParams(); - loadingParams->func = &UIScene_PauseMenu::SaveWorldThreadProc; - loadingParams->lpParam = static_cast(false); - - // 4J-JEV - PS4: Fix for #5708 - [ONLINE] - If the user pulls their network cable out while saving the title will hang. - loadingParams->waitForThreadToDelete = true; - - UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); - completionData->bShowBackground=TRUE; - completionData->bShowLogo=TRUE; - completionData->type = e_ProgressCompletion_NavigateBackToScene; - completionData->iPad = ProfileManager.GetPrimaryPad(); - - if( ui.IsSceneInStack( ProfileManager.GetPrimaryPad(), eUIScene_EndPoem ) ) - { - completionData->scene = eUIScene_EndPoem; - } - else - { - completionData->scene = eUIScene_PauseMenu; - } - - loadingParams->completionData = completionData; - - // 4J Stu - Xbox only -#ifdef _XBOX - // Temporarily make this scene fullscreen - CXuiSceneBase::SetPlayerBaseScenePosition( ProfileManager.GetPrimaryPad(), CXuiSceneBase::e_BaseScene_Fullscreen ); -#endif - - ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams , eUILayer_Fullscreen, eUIGroup_Fullscreen); - - } - break; - case eAppAction_AutosaveSaveGameCapturedThumbnail: - - { - app.SetAutosaveTimerTime(); - SetAction(i,eAppAction_Idle); - -#if defined(_XBOX_ONE) || defined(__ORBIS__) - app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_AutoSaveGame); - - if(app.GetGameHostOption(eGameHostOption_DisableSaving)) StorageManager.SetSaveDisabled(true); -#else - // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen - ui.HideAllGameUIElements(); - - //app.CloseAllPlayersXuiScenes(); - // Hide the other players scenes - ui.ShowOtherPlayersBaseScene(ProfileManager.GetPrimaryPad(), false); - - // This just allows it to be shown - if(pMinecraft->localgameModes[ProfileManager.GetPrimaryPad()] != nullptr) pMinecraft->localgameModes[ProfileManager.GetPrimaryPad()]->getTutorial()->showTutorialPopup(false); - - //INT saveOrCheckpointId = 0; - //bool validSave = StorageManager.GetSaveUniqueNumber(&saveOrCheckpointId); - //SentientManager.RecordLevelSaveOrCheckpoint(ProfileManager.GetPrimaryPad(), saveOrCheckpointId); - - - LoadingInputParams *loadingParams = new LoadingInputParams(); - loadingParams->func = &UIScene_PauseMenu::SaveWorldThreadProc; - - loadingParams->lpParam = (LPVOID)(true); - - UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); - completionData->bShowBackground=TRUE; - completionData->bShowLogo=TRUE; - completionData->type = e_ProgressCompletion_AutosaveNavigateBack; - completionData->iPad = ProfileManager.GetPrimaryPad(); - //completionData->bAutosaveWasMenuDisplayed=ui.GetMenuDisplayed(ProfileManager.GetPrimaryPad()); - loadingParams->completionData = completionData; - - // 4J Stu - Xbox only -#ifdef _XBOX - // Temporarily make this scene fullscreen - CXuiSceneBase::SetPlayerBaseScenePosition( ProfileManager.GetPrimaryPad(), CXuiSceneBase::e_BaseScene_Fullscreen ); -#endif - - ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams , eUILayer_Fullscreen, eUIGroup_Fullscreen); -#endif - } - break; - case eAppAction_ExitPlayer: - // a secondary player has chosen to quit - { - int iPlayerC=g_NetworkManager.GetPlayerCount(); - - // Since the player is exiting, let's flush any profile writes for them, and hope we're not breaking TCR 136... -#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) - StorageManager.ForceQueuedProfileWrites(i); - LeaderboardManager::Instance()->OpenSession(); - for (int j = 0; j < XUSER_MAX_COUNT; j++) - { - if( ProfileManager.IsSignedIn(j) ) - { - app.DebugPrintf("Stats save for an offline game for the player at index %d\n", 0); - Minecraft::GetInstance()->forceStatsSave(j); - } - } - LeaderboardManager::Instance()->CloseSession(); -#else - ProfileManager.ForceQueuedProfileWrites(i); -#endif - - // not required - it's done within the removeLocalPlayerIdx - // if(pMinecraft->level->isClientSide) - // { - // // we need to remove the qnetplayer, or this player won't be able to get back into the game until qnet times out and removes them - // g_NetworkManager.NotifyPlayerLeaving(g_NetworkManager.GetLocalPlayerByUserIndex(i)); - // } - - // if there are any tips showing, we need to close them - - pMinecraft->gui->clearMessages(i); - - // Make sure we've not got this player selected as current - this shouldn't be the case anyway - pMinecraft->setLocalPlayerIdx(ProfileManager.GetPrimaryPad()); - pMinecraft->removeLocalPlayerIdx(i); - -#ifdef _XBOX - // tell the xui scenes a splitscreen player left - has to come after removeLocalPlayerIdx which calls updatePlayerViewportAssignments - XUIMessage xuiMsg; - CustomMessage_Splitscreenplayer_Struct myMsgData; - CustomMessage_Splitscreenplayer( &xuiMsg, &myMsgData, false); - - // send the message - for(int idx=0;idxlocalplayers[idx]!=nullptr)) - { - XuiBroadcastMessage( CXuiSceneBase::GetPlayerBaseScene(idx), &xuiMsg ); - } - } -#endif - -#ifndef _XBOX - // Wipe out the tooltips - ui.SetTooltips(i, -1); -#endif - - // Change the presence info - // Are we offline or online, and how many players are there - if(iPlayerC>2) // one player is about to leave here - they'll be set to idle in the qnet manager player leave - { - for(int iPlayer=0;iPlayerlocalplayers[iPlayer]) - { - if(g_NetworkManager.IsLocalGame()) - { - ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); - } - else - { - ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER,false); - } - } - } - } - else - { - for(int iPlayer=0;iPlayerlocalplayers[iPlayer]) - { - if(g_NetworkManager.IsLocalGame()) - { - ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); - } - else - { - ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); - } - } - } - } - -#ifdef _DURANGO - ProfileManager.RemoveGamepadFromGame(i); -#endif - - SetAction(i,eAppAction_Idle); - } - break; - case eAppAction_ExitPlayerPreLogin: - { - int iPlayerC=g_NetworkManager.GetPlayerCount(); - // Since the player is exiting, let's flush any profile writes for them, and hope we're not breaking TCR 136... -#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) - StorageManager.ForceQueuedProfileWrites(i); -#else - ProfileManager.ForceQueuedProfileWrites(i); -#endif - // if there are any tips showing, we need to close them - - pMinecraft->gui->clearMessages(i); - - // Make sure we've not got this player selected as current - this shouldn't be the case anyway - pMinecraft->setLocalPlayerIdx(ProfileManager.GetPrimaryPad()); - pMinecraft->removeLocalPlayerIdx(i); - -#ifdef _XBOX - // tell the xui scenes a splitscreen player left - has to come after removeLocalPlayerIdx which calls updatePlayerViewportAssignments - XUIMessage xuiMsg; - CustomMessage_Splitscreenplayer_Struct myMsgData; - CustomMessage_Splitscreenplayer( &xuiMsg, &myMsgData, false); - - // send the message - for(int idx=0;idxlocalplayers[idx]!=nullptr)) - { - XuiBroadcastMessage( CXuiSceneBase::GetPlayerBaseScene(idx), &xuiMsg ); - } - } -#endif - -#ifndef _XBOX - // Wipe out the tooltips - ui.SetTooltips(i, -1); -#endif - - // Change the presence info - // Are we offline or online, and how many players are there - if(iPlayerC>2) // one player is about to leave here - they'll be set to idle in the qnet manager player leave - { - for(int iPlayer=0;iPlayerlocalplayers[iPlayer]) - { - if(g_NetworkManager.IsLocalGame()) - { - ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); - } - else - { - ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER,false); - } - } - } - } - else - { - for(int iPlayer=0;iPlayerlocalplayers[iPlayer]) - { - if(g_NetworkManager.IsLocalGame()) - { - ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); - } - else - { - ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); - } - } - } - } - SetAction(i,eAppAction_Idle); - } - break; - -#ifdef __ORBIS__ - case eAppAction_OptionsSaveNoSpace: - { - SetAction(i,eAppAction_Idle); - - SceSaveDataDialogParam param; - SceSaveDataDialogSystemMessageParam sysParam; - SceSaveDataDialogItems items; - SceSaveDataDirName dirName; - - sceSaveDataDialogParamInitialize(¶m); - param.mode = SCE_SAVE_DATA_DIALOG_MODE_SYSTEM_MSG; - param.dispType = SCE_SAVE_DATA_DIALOG_TYPE_SAVE; - memset(&sysParam,0,sizeof(sysParam)); - param.sysMsgParam = &sysParam; - param.sysMsgParam->sysMsgType = SCE_SAVE_DATA_DIALOG_SYSMSG_TYPE_NOSPACE_CONTINUABLE; - param.sysMsgParam->value = app.GetOptionsBlocksRequired(i); - memset(&items, 0, sizeof(items)); - param.items = &items; - param.items->userId = ProfileManager.getUserID(i); - - int ret = sceSaveDataDialogInitialize(); - ret = sceSaveDataDialogOpen(¶m); - - app.SetOptionsSaveDataDialogRunning(true);//m_bOptionsSaveDataDialogRunning = true; - //pClass->m_eSaveIncompleteType = saveIncompleteType; - - //StorageManager.SetSaveDisabled(true); - //pClass->EnterSaveNotificationSection(); - - } - break; -#endif - - case eAppAction_ExitWorld: - - SetAction(i,eAppAction_Idle); - - // HUCKLE - added for quit game on disconnect -#ifdef _WINDOWS64 - if(g_Win64MultiplayerQuitOnDisconnect == true) - { - app.ExitGame(); - return; - } -#endif - - // If we're already leaving don't exit - if (g_NetworkManager.IsLeavingGame()) - { - break; - } - - pMinecraft->gui->clearMessages(); - - // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen - ui.HideAllGameUIElements(); - - // reset the flag stopping new dlc message being shown if you've seen the message before - DisplayNewDLCTipAgain(); - - // clear the autosave timer that might be on screen - ui.ShowAutosaveCountdownTimer(false); - - // Hide the selected item text - ui.HideAllGameUIElements(); - - // Since the player forced the exit, let's flush any profile writes, and hope we're not breaking TCR 136... -#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) - StorageManager.ForceQueuedProfileWrites(); - LeaderboardManager::Instance()->OpenSession(); - for (int j = 0; j < XUSER_MAX_COUNT; j++) - { - if( ProfileManager.IsSignedIn(j) ) - { - app.DebugPrintf("Stats save for an offline game for the player at index %d\n", 0); - Minecraft::GetInstance()->forceStatsSave(j); - } - } - LeaderboardManager::Instance()->CloseSession(); -#elif (defined _XBOX) - ProfileManager.ForceQueuedProfileWrites(); -#endif - - // 4J-PB - cancel any possible string verifications queued with LIVE - //InputManager.CancelAllVerifyInProgress(); - - if(ProfileManager.IsFullVersion()) - { - - // In a split screen, only the primary player actually quits the game, others just remove their players - if( i != ProfileManager.GetPrimaryPad() ) - { - // Make sure we've not got this player selected as current - this shouldn't be the case anyway - pMinecraft->setLocalPlayerIdx(ProfileManager.GetPrimaryPad()); - pMinecraft->removeLocalPlayerIdx(i); - -#ifdef _DURANGO - ProfileManager.RemoveGamepadFromGame(i); -#endif - SetAction(i,eAppAction_Idle); - return; - } - // flag to capture the save thumbnail - SetAction(i,eAppAction_ExitWorldCapturedThumbnail, param); - } - else - { - // ask the player if they would like to upgrade, or they'll lose the level - UINT uiIDA[2]; - uiIDA[0]=IDS_CONFIRM_OK; - uiIDA[1]=IDS_CONFIRM_CANCEL; - ui.RequestErrorMessage(IDS_UNLOCK_TITLE, IDS_UNLOCK_TOSAVE_TEXT, uiIDA, 2, i,&CMinecraftApp::UnlockFullExitReturned,this); - } - - // Change the presence info - // Are we offline or online, and how many players are there - - if(g_NetworkManager.GetPlayerCount()>1) - { - for(int j=0;jlocalplayers[j]) - { - if(g_NetworkManager.IsLocalGame()) - { - app.SetRichPresenceContext(j,CONTEXT_GAME_STATE_BLANK); - ProfileManager.SetCurrentGameActivity(j,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); - } - else - { - app.SetRichPresenceContext(j,CONTEXT_GAME_STATE_BLANK); - ProfileManager.SetCurrentGameActivity(j,CONTEXT_PRESENCE_MULTIPLAYER,false); - } - TelemetryManager->RecordLevelExit(j, eSen_LevelExitStatus_Exited); - } - } - } - else - { - app.SetRichPresenceContext(i,CONTEXT_GAME_STATE_BLANK); - if(g_NetworkManager.IsLocalGame()) - { - ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); - } - else - { - ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); - } - TelemetryManager->RecordLevelExit(i, eSen_LevelExitStatus_Exited); - } - break; - case eAppAction_ExitWorldCapturedThumbnail: - { - SetAction(i,eAppAction_Idle); - // Stop app running - SetGameStarted(false); - SetChangingSessionType(true); // Added to stop handling ethernet disconnects - - ui.CloseAllPlayersScenes(); - - // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen - ui.HideAllGameUIElements(); - - // 4J Stu - Fix for #12368 - Crash: Game crashes when saving then exiting and selecting to save - for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) - { -#ifdef _XBOX - app.TutorialSceneNavigateBack(idx,true); -#endif - - // 4J Stu - Fix for #13257 - CRASH: Gameplay: Title crashed after exiting the tutorial - // It doesn't matter if they were in the tutorial already - pMinecraft->playerLeftTutorial( idx ); - } - - LoadingInputParams *loadingParams = new LoadingInputParams(); - loadingParams->func = &UIScene_PauseMenu::ExitWorldThreadProc; - loadingParams->lpParam = param; - - UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); - // If param is non-null then this is a forced exit by the server, so make sure the player knows why - // 4J Stu - Changed - Don't use the FullScreenProgressScreen for action, use a dialog instead - completionData->bRequiresUserAction = FALSE;//(param != nullptr) ? TRUE : FALSE; - completionData->bShowTips = (param != nullptr) ? FALSE : TRUE; - completionData->bShowBackground=TRUE; - completionData->bShowLogo=TRUE; - completionData->type = e_ProgressCompletion_NavigateToHomeMenu; - completionData->iPad = DEFAULT_XUI_MENU_USER; - loadingParams->completionData = completionData; - - ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); - } - break; - case eAppAction_ExitWorldTrial: - { - SetAction(i,eAppAction_Idle); - - pMinecraft->gui->clearMessages(); - - // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen - ui.HideAllGameUIElements(); - - // Stop app running - SetGameStarted(false); - - ui.CloseAllPlayersScenes(); - - // 4J Stu - Fix for #12368 - Crash: Game crashes when saving then exiting and selecting to save - for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) - { -#ifdef _XBOX - app.TutorialSceneNavigateBack(idx,true); -#endif - - // 4J Stu - Fix for #13257 - CRASH: Gameplay: Title crashed after exiting the tutorial - // It doesn't matter if they were in the tutorial already - pMinecraft->playerLeftTutorial( idx ); - } - - LoadingInputParams *loadingParams = new LoadingInputParams(); - loadingParams->func = &UIScene_PauseMenu::ExitWorldThreadProc; - loadingParams->lpParam = param; - - UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); - completionData->bShowBackground=TRUE; - completionData->bShowLogo=TRUE; - completionData->type = e_ProgressCompletion_NavigateToHomeMenu; - completionData->iPad = DEFAULT_XUI_MENU_USER; - loadingParams->completionData = completionData; - - ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); - } - - break; - case eAppAction_ExitTrial: - //XLaunchNewImage(XLAUNCH_KEYWORD_DASH_ARCADE, 0); - ExitGame(); - break; - - case eAppAction_Respawn: - { - ConnectionProgressParams *param = new ConnectionProgressParams(); - param->iPad = i; - param->stringId = IDS_PROGRESS_RESPAWNING; - param->showTooltips = false; - param->setFailTimer = false; - ui.NavigateToScene(i,eUIScene_ConnectingProgress, param); - - // Need to reset this incase the player has already died and respawned - pMinecraft->localplayers[i]->SetPlayerRespawned(false); - - SetAction(i,eAppAction_WaitForRespawnComplete); - if( app.GetLocalPlayerCount()>1 ) - { - // In split screen mode, we don't want to do any async loading or flushing of the cache, just a simple respawn - pMinecraft->localplayers[i]->respawn(); - - // If the respawn requires a dimension change then the action will have changed - //if(app.GetXuiAction(i) == eAppAction_Respawn) - //{ - // SetAction(i,eAppAction_Idle); - // CloseXuiScenes(i); - //} - } - else - { - //SetAction(i,eAppAction_WaitForRespawnComplete); - - //LoadingInputParams *loadingParams = new LoadingInputParams(); - //loadingParams->func = &CScene_Death::RespawnThreadProc; - //loadingParams->lpParam = (LPVOID)i; - - // Disable game & update thread whilst we do any of this - //app.SetGameStarted(false); - pMinecraft->gameRenderer->DisableUpdateThread(); - - // 4J Stu - We don't need this on a thread in multiplayer as respawning is asynchronous. - pMinecraft->localplayers[i]->respawn(); - - //app.SetGameStarted(true); - pMinecraft->gameRenderer->EnableUpdateThread(); - - //UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); - //completionData->bShowBackground=TRUE; - //completionData->bShowLogo=TRUE; - //completionData->type = e_ProgressCompletion_CloseUIScenes; - //completionData->iPad = i; - //loadingParams->completionData = completionData; - - //app.NavigateToScene(i,eUIScene_FullscreenProgress, loadingParams, true); - } - } - break; - case eAppAction_WaitForRespawnComplete: - player = pMinecraft->localplayers[i]; - if(player != nullptr && player->GetPlayerRespawned()) - { - SetAction(i,eAppAction_Idle); - - if(ui.IsSceneInStack(i, eUIScene_EndPoem)) - { - ui.NavigateBack(i,false,eUIScene_EndPoem); - } - else - { - ui.CloseUIScenes(i); - } - - // clear the progress messages - - // pMinecraft->progressRenderer->progressStart(-1); - // pMinecraft->progressRenderer->progressStage(-1); - } - else if(!g_NetworkManager.IsInGameplay()) - { - SetAction(i,eAppAction_Idle); - } - break; - case eAppAction_WaitForDimensionChangeComplete: - player = pMinecraft->localplayers[i]; - if(player != nullptr && player->connection && player->connection->isStarted()) - { - SetAction(i,eAppAction_Idle); - ui.CloseUIScenes(i); - } - else if(!g_NetworkManager.IsInGameplay()) - { - SetAction(i,eAppAction_Idle); - } - break; - case eAppAction_PrimaryPlayerSignedOut: - { - //SetAction(i,eAppAction_Idle); - - // clear the autosavetimer that might be displayed - ui.ShowAutosaveCountdownTimer(false); - - // If the player signs out before the game started the server can be killed a bit earlier to stop - // the loading or saving of a new game continuing running while the UI/Guide is up - if(!app.GetGameStarted()) MinecraftServer::HaltServer(true); - - // inform the player they are being returned to the menus because they signed out - StorageManager.SetSaveDeviceSelected(i,false); - // need to clear the player stats - can't assume it'll be done in setlevel - we may not be in the game - StatsCounter* pStats = Minecraft::GetInstance()->stats[ i ]; - pStats->clear(); - - // 4J-PB - the libs will display the Returned to Title screen - // UINT uiIDA[1]; - // uiIDA[0]=IDS_CONFIRM_OK; - // - // ui.RequestMessageBox(IDS_RETURNEDTOMENU_TITLE, IDS_RETURNEDTOTITLESCREEN_TEXT, uiIDA, 1, i,&CMinecraftApp::PrimaryPlayerSignedOutReturned,this,app.GetStringTable()); - if( g_NetworkManager.IsInSession() ) - { - app.SetAction(i,eAppAction_PrimaryPlayerSignedOutReturned); - } - else - { - app.SetAction(i,eAppAction_PrimaryPlayerSignedOutReturned_Menus); - MinecraftServer::resetFlags(); - } - } - break; - case eAppAction_EthernetDisconnected: - { - app.DebugPrintf("Handling eAppAction_EthernetDisconnected\n"); - SetAction(i,eAppAction_Idle); - - // 4J Stu - Fix for #12530 -TCR 001 BAS Game Stability: Title will crash if the player disconnects while starting a new world and then opts to play the tutorial once they have been returned to the Main Menu. - if(!g_NetworkManager.IsLeavingGame()) - { - app.DebugPrintf("Handling eAppAction_EthernetDisconnected - Not leaving game\n"); - // 4J-PB - not the same as a signout. We should only leave the game if this machine is not the host. We shouldn't get rid of the save device either. - if( g_NetworkManager.IsHost() ) - { - app.DebugPrintf("Handling eAppAction_EthernetDisconnected - Is Host\n"); - // If it's already a local game, then an ethernet disconnect should have no effect - if( !g_NetworkManager.IsLocalGame() && g_NetworkManager.IsInGameplay() ) - { - // Change the session to an offline session - SetAction(i,eAppAction_ChangeSessionType); - } - else if(!g_NetworkManager.IsLocalGame() && !g_NetworkManager.IsInGameplay() ) - { - // There are two cases here, either: - // 1. We're early enough in the create/load game that we can do a really minimal shutdown or - // 2. We're far enough in (game has started but the actual game started flag hasn't been set) that we should just wait until we're in the game and switch to offline mode - - // If there's a non-null level then, for our purposes, the game has started - bool gameStarted = false; - for(int j = 0; j < pMinecraft->levels.length; j++) - { - if (pMinecraft->levels.data[i] != nullptr) - { - gameStarted = true; - break; - } - } - - if (!gameStarted) - { - // 1. Exit - MinecraftServer::HaltServer(); - - // Fix for #12530 - TCR 001 BAS Game Stability: Title will crash if the player disconnects while starting a new world and then opts to play the tutorial once they have been returned to the Main Menu. - // 4J Stu - Leave the session - g_NetworkManager.LeaveGame(FALSE); - - // need to clear the player stats - can't assume it'll be done in setlevel - we may not be in the game - StatsCounter* pStats = Minecraft::GetInstance()->stats[ i ]; - pStats->clear(); - UINT uiIDA[1]; - uiIDA[0]=IDS_CONFIRM_OK; - - ui.RequestErrorMessage(g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST), g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST_LIVE), uiIDA, 1, i,&CMinecraftApp::EthernetDisconnectReturned,this); - } - else - { - // 2. Switch to offline - SetAction(i,eAppAction_ChangeSessionType); - } - } - } - else - { -#if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ - if(UIScene_LoadOrJoinMenu::isSaveTransferRunning()) - { - // the save transfer is still in progress, delay jumping back to the main menu until we've cleaned up - SetAction(i,eAppAction_EthernetDisconnected); - } - else -#endif - { - app.DebugPrintf("Handling eAppAction_EthernetDisconnected - Not host\n"); - // need to clear the player stats - can't assume it'll be done in setlevel - we may not be in the game - StatsCounter* pStats = Minecraft::GetInstance()->stats[ i ]; - pStats->clear(); - UINT uiIDA[1]; - uiIDA[0]=IDS_CONFIRM_OK; - - ui.RequestErrorMessage(g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST), g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST_LIVE), uiIDA, 1, i,&CMinecraftApp::EthernetDisconnectReturned,this); - - } - } - } - } - break; - // We currently handle both these returns the same way. - case eAppAction_EthernetDisconnectedReturned: - case eAppAction_PrimaryPlayerSignedOutReturned: - { - SetAction(i,eAppAction_Idle); - - pMinecraft->gui->clearMessages(); - - // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen - ui.HideAllGameUIElements(); - - // set the state back to pre-game - ProfileManager.ResetProfileProcessState(); - - - if( g_NetworkManager.IsLeavingGame() ) - { - // 4J Stu - If we are already leaving the game, then we just need to signal that the player signed out to stop saves - pMinecraft->progressRenderer->progressStartNoAbort( IDS_EXITING_GAME ); - pMinecraft->progressRenderer->progressStage(-1); - // This has no effect on client machines - MinecraftServer::HaltServer(true); - } - else - { - // Stop app running - SetGameStarted(false); - - // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen - ui.HideAllGameUIElements(); - - ui.CloseAllPlayersScenes(); - - // 4J Stu - Fix for #12368 - Crash: Game crashes when saving then exiting and selecting to save - for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) - { -#ifdef _XBOX - app.TutorialSceneNavigateBack(idx,true); -#endif - - // 4J Stu - Fix for #13257 - CRASH: Gameplay: Title crashed after exiting the tutorial - // It doesn't matter if they were in the tutorial already - pMinecraft->playerLeftTutorial( idx ); - } - - LoadingInputParams *loadingParams = new LoadingInputParams(); - loadingParams->func = &CMinecraftApp::SignoutExitWorldThreadProc; - - UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); - completionData->bShowBackground=TRUE; - completionData->bShowLogo=TRUE; - completionData->iPad=DEFAULT_XUI_MENU_USER; - completionData->type = e_ProgressCompletion_NavigateToHomeMenu; - loadingParams->completionData = completionData; - - ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); - } - } - break; - case eAppAction_PrimaryPlayerSignedOutReturned_Menus: - SetAction(i,eAppAction_Idle); - // set the state back to pre-game - ProfileManager.ResetProfileProcessState(); - // clear the save device - StorageManager.SetSaveDeviceSelected(i,false); - - ui.UpdatePlayerBasePositions(); - // there are multiple layers in the help menu, so a navigate back isn't enough - ui.NavigateToHomeMenu(); - - break; - case eAppAction_EthernetDisconnectedReturned_Menus: - SetAction(i,eAppAction_Idle); - // set the state back to pre-game - ProfileManager.ResetProfileProcessState(); - - ui.UpdatePlayerBasePositions(); - - // there are multiple layers in the help menu, so a navigate back isn't enough - ui.NavigateToHomeMenu(); - - break; - - case eAppAction_TrialOver: - { - SetAction(i,eAppAction_Idle); - UINT uiIDA[2]; - uiIDA[0]=IDS_UNLOCK_TITLE; - uiIDA[1]=IDS_EXIT_GAME; - - ui.RequestErrorMessage(IDS_TRIALOVER_TITLE, IDS_TRIALOVER_TEXT, uiIDA, 2, i,&CMinecraftApp::TrialOverReturned,this); - } - break; - - // INVITES - case eAppAction_DashboardTrialJoinFromInvite: - { - TelemetryManager->RecordUpsellPresented(i, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID); - - SetAction(i,eAppAction_Idle); - UINT uiIDA[2]; - uiIDA[0]=IDS_CONFIRM_OK; - uiIDA[1]=IDS_CONFIRM_CANCEL; - - ui.RequestErrorMessage(IDS_UNLOCK_TITLE, IDS_UNLOCK_ACCEPT_INVITE, uiIDA, 2, i,&CMinecraftApp::UnlockFullInviteReturned,this); - } - break; - case eAppAction_ExitAndJoinFromInvite: - { - UINT uiIDA[3]; - - SetAction(i,eAppAction_Idle); - // Check the player really wants to do this - -#if defined(_XBOX_ONE) || defined(__ORBIS__) - // Show save option is saves ARE disabled - if(ProfileManager.IsFullVersion() && StorageManager.GetSaveDisabled() && i==ProfileManager.GetPrimaryPad() && g_NetworkManager.IsHost() && GetGameStarted() ) - { - uiIDA[0]=IDS_CONFIRM_CANCEL; - uiIDA[1]=IDS_EXIT_GAME_SAVE; - uiIDA[2]=IDS_EXIT_GAME_NO_SAVE; - - ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_LEAVE_VIA_INVITE, uiIDA, 3, i,&CMinecraftApp::ExitAndJoinFromInviteSaveDialogReturned,this); - } - else -#else - if(ProfileManager.IsFullVersion() && !StorageManager.GetSaveDisabled() && i==ProfileManager.GetPrimaryPad() && g_NetworkManager.IsHost() && GetGameStarted() ) - { - uiIDA[0]=IDS_CONFIRM_CANCEL; - uiIDA[1]=IDS_EXIT_GAME_SAVE; - uiIDA[2]=IDS_EXIT_GAME_NO_SAVE; - - ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_LEAVE_VIA_INVITE, uiIDA, 3, i,&CMinecraftApp::ExitAndJoinFromInviteSaveDialogReturned,this); - } - else -#endif - { - if(!ProfileManager.IsFullVersion()) - { - TelemetryManager->RecordUpsellPresented(i, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID); - - // upsell - uiIDA[0]=IDS_CONFIRM_OK; - uiIDA[1]=IDS_CONFIRM_CANCEL; - ui.RequestErrorMessage(IDS_UNLOCK_TITLE, IDS_UNLOCK_ACCEPT_INVITE, uiIDA, 2, i,&CMinecraftApp::UnlockFullInviteReturned,this); - } - else - { - uiIDA[0]=IDS_CONFIRM_CANCEL; - uiIDA[1]=IDS_CONFIRM_OK; - ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_LEAVE_VIA_INVITE, uiIDA, 2,i,&CMinecraftApp::ExitAndJoinFromInvite,this); - } - } - } - break; - case eAppAction_ExitAndJoinFromInviteConfirmed: - { - SetAction(i,eAppAction_Idle); - - pMinecraft->gui->clearMessages(); - - // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen - ui.HideAllGameUIElements(); - - // Stop app running - SetGameStarted(false); - - ui.CloseAllPlayersScenes(); - - // 4J Stu - Fix for #12368 - Crash: Game crashes when saving then exiting and selecting to save - for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) - { -#ifdef _XBOX - app.TutorialSceneNavigateBack(idx,true); -#endif - - // 4J Stu - Fix for #13257 - CRASH: Gameplay: Title crashed after exiting the tutorial - // It doesn't matter if they were in the tutorial already - pMinecraft->playerLeftTutorial( idx ); - } - - // 4J-PB - may have been using a texture pack with audio , so clean up anything texture pack related here - - // unload any texture pack audio - // if there is audio in use, clear out the audio, and unmount the pack - TexturePack *pTexPack=Minecraft::GetInstance()->skins->getSelected(); - DLCTexturePack *pDLCTexPack=nullptr; - - if(pTexPack->hasAudio()) - { - // get the dlc texture pack, and store it - pDLCTexPack=static_cast(pTexPack); - } - - // change to the default texture pack - pMinecraft->skins->selectTexturePackById(TexturePackRepository::DEFAULT_TEXTURE_PACK_ID); - - if(pTexPack->hasAudio()) - { - // need to stop the streaming audio - by playing streaming audio from the default texture pack now - // reset the streaming sounds back to the normal ones -#ifndef _XBOX - pMinecraft->soundEngine->SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3, - eStream_Nether1,eStream_Nether4, - eStream_end_dragon,eStream_end_end, - eStream_Overworld_Creative1,eStream_Overworld_Creative6, - eStream_Overworld_Menu1,eStream_Overworld_Menu4, - eStream_BattleMode1,eStream_BattleMode4, - eStream_CD_1); -#endif - pMinecraft->soundEngine->playStreaming(L"", 0, 0, 0, 1, 1); - -#ifdef _XBOX - if(pDLCTexPack->m_pStreamedWaveBank!=nullptr) - { - pDLCTexPack->m_pStreamedWaveBank->Destroy(); - } - if(pDLCTexPack->m_pSoundBank!=nullptr) - { - pDLCTexPack->m_pSoundBank->Destroy(); - } -#endif -#ifdef _DURANGO - DWORD result = StorageManager.UnmountInstalledDLC(L"TPACK"); -#else - DWORD result = StorageManager.UnmountInstalledDLC("TPACK"); -#endif - app.DebugPrintf("Unmount result is %d\n",result); - } - -#ifdef _XBOX_ONE - // 4J Stu - It's possible that we can sign in/remove players between the mask initially being set and this point - m_InviteData.dwLocalUsersMask = 0; - for(unsigned int index = 0; index < XUSER_MAX_COUNT; ++index) - { - if(ProfileManager.IsSignedIn(index) ) - { - if (index == i || pMinecraft->localplayers[index] != nullptr) - { - m_InviteData.dwLocalUsersMask |= g_NetworkManager.GetLocalPlayerMask(index); - } - } - } -#endif - - LoadingInputParams *loadingParams = new LoadingInputParams(); - loadingParams->func = &CGameNetworkManager::ExitAndJoinFromInviteThreadProc; - loadingParams->lpParam = static_cast(&m_InviteData); - - UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); - completionData->bShowBackground=TRUE; - completionData->bShowLogo=TRUE; - completionData->iPad=DEFAULT_XUI_MENU_USER; - completionData->type = e_ProgressCompletion_NoAction; - loadingParams->completionData = completionData; - - ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); - } - - break; - case eAppAction_JoinFromInvite: - { - SetAction(i,eAppAction_Idle); - - // 4J Stu - Move this state block from CPlatformNetworkManager::ExitAndJoinFromInviteThreadProc, as g_NetworkManager.JoinGameFromInviteInfo ultimately can call NavigateToScene, - /// and we should only be calling that from the main thread - app.SetTutorialMode( false ); - - g_NetworkManager.SetLocalGame(false); - - JoinFromInviteData *inviteData = static_cast(param); - // 4J-PB - clear any previous connection errors - Minecraft::GetInstance()->clearConnectionFailed(); - - app.DebugPrintf( "Changing Primary Pad on an invite accept - pad was %d, and is now %d\n", ProfileManager.GetPrimaryPad(), inviteData->dwUserIndex ); - ProfileManager.SetLockedProfile(inviteData->dwUserIndex); - ProfileManager.SetPrimaryPad(inviteData->dwUserIndex); - -#ifdef _XBOX_ONE - // 4J Stu - If a player is signed in (i.e. locked) but not in the mask, unlock them - for(unsigned int index = 0; index < XUSER_MAX_COUNT; ++index) - { - if( index != inviteData->dwUserIndex && ProfileManager.IsSignedIn(index) ) - { - if( (m_InviteData.dwLocalUsersMask & g_NetworkManager.GetLocalPlayerMask( index ) ) == 0 ) - { - ProfileManager.RemoveGamepadFromGame(index); - } - } - } -#endif - - // change the minecraft player name - Minecraft::GetInstance()->user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); - - bool success = g_NetworkManager.JoinGameFromInviteInfo( - inviteData->dwUserIndex, // dwUserIndex - inviteData->dwLocalUsersMask, // dwUserMask - inviteData->pInviteInfo ); // pInviteInfo - - if( !success ) - { - app.DebugPrintf( "Failed joining game from invite\n" ); - //return hr; - - // 4J Stu - Copied this from XUI_FullScreenProgress to properly handle the fail case, as the thread will no longer be failing - UINT uiIDA[1]; - uiIDA[0]=IDS_CONFIRM_OK; - ui.RequestErrorMessage( IDS_CONNECTION_FAILED, IDS_CONNECTION_LOST_SERVER, uiIDA,1,ProfileManager.GetPrimaryPad()); - - ui.NavigateToHomeMenu(); - ui.UpdatePlayerBasePositions(); - } - } - break; - case eAppAction_ChangeSessionType: - { - // If we are not in gameplay yet, then wait until the server is setup before changing the session type - if( g_NetworkManager.IsInGameplay() ) - { - // This kicks off a thread that waits for the server to end, then closes the current session, starts a new one and joins the local players into it - - SetAction(i,eAppAction_Idle); - - if( !GetChangingSessionType() && !g_NetworkManager.IsLocalGame() ) - { - SetGameStarted(false); - SetChangingSessionType(true); - SetReallyChangingSessionType(true); - - // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen - ui.HideAllGameUIElements(); - - if( !ui.IsSceneInStack( ProfileManager.GetPrimaryPad(), eUIScene_EndPoem ) ) - { - ui.CloseAllPlayersScenes(); - } - ui.ShowOtherPlayersBaseScene(ProfileManager.GetPrimaryPad(), true); - - // Remove this line to fix: - // #49084 - TU5: Code: Gameplay: The title crashes every time client navigates to 'Play game' menu and loads/creates new game after a "Connection to Xbox LIVE was lost" message has appeared. - //app.NavigateToScene(0,eUIScene_Main); - - LoadingInputParams *loadingParams = new LoadingInputParams(); - loadingParams->func = &CGameNetworkManager::ChangeSessionTypeThreadProc; - loadingParams->lpParam = nullptr; - - UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); -#ifdef __PS3__ - completionData->bRequiresUserAction=FALSE; -#else - completionData->bRequiresUserAction=TRUE; -#endif - completionData->bShowBackground=TRUE; - completionData->bShowLogo=TRUE; - completionData->iPad=DEFAULT_XUI_MENU_USER; - if( ui.IsSceneInStack( ProfileManager.GetPrimaryPad(), eUIScene_EndPoem ) ) - { - completionData->type = e_ProgressCompletion_NavigateBackToScene; - completionData->scene = eUIScene_EndPoem; - } - else - { - completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes; - } - loadingParams->completionData = completionData; - - ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); - } - } - else if( g_NetworkManager.IsLeavingGame() ) - { - // If we are leaving the game, then ignore the state change - SetAction(i,eAppAction_Idle); - } -#if 0 - // 4J-HG - Took this out since ChangeSessionType is only set in two places (both in EthernetDisconnected) and this case is handled there, plus this breaks - // this if statements original purpose (to allow us to wait for IsInGameplay before actioning switching to offline - - // QNet must do this kind of thing automatically by itself, but on PS3 at least, we need the disconnection to definitely end up with us out of the game one way or another, - // and the other two cases above don't catch the case where we are just starting the game and get a disconnection during the loading/creation - else - { - if( g_NetworkManager.IsInSession() ) - { - g_NetworkManager._LeaveGame(); - } - } -#endif - } - break; - case eAppAction_SetDefaultOptions: - SetAction(i,eAppAction_Idle); -#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) - SetDefaultOptions((C4JStorage::PROFILESETTINGS *)param,i); -#else - SetDefaultOptions(static_cast(param), i); -#endif - - // if the profile data has been changed, then force a profile write - // It seems we're allowed to break the 5 minute rule if it's the result of a user action - CheckGameSettingsChanged(true,i); - - break; - - case eAppAction_RemoteServerSave: - { - // If the remote server save has already finished, don't complete the action - if (GetGameStarted()) - { - SetAction(ProfileManager.GetPrimaryPad(), eAppAction_Idle); - break; - } - - SetAction(i,eAppAction_WaitRemoteServerSaveComplete); - - for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) - { - ui.CloseUIScenes(i, true); - } - - // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen - ui.HideAllGameUIElements(); - - LoadingInputParams *loadingParams = new LoadingInputParams(); - loadingParams->func = &CMinecraftApp::RemoteSaveThreadProc; - loadingParams->lpParam = nullptr; - - UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); - completionData->bRequiresUserAction=FALSE; - completionData->bShowBackground=TRUE; - completionData->bShowLogo=TRUE; - completionData->iPad=DEFAULT_XUI_MENU_USER; - if( ui.IsSceneInStack( ProfileManager.GetPrimaryPad(), eUIScene_EndPoem ) ) - { - completionData->type = e_ProgressCompletion_NavigateBackToScene; - completionData->scene = eUIScene_EndPoem; - } - else - { - completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes; - } - loadingParams->completionData = completionData; - - loadingParams->cancelFunc = &CMinecraftApp::ExitGameFromRemoteSave; - loadingParams->cancelText = IDS_TOOLTIPS_EXIT; - - ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); - } - break; - case eAppAction_WaitRemoteServerSaveComplete: - // Do nothing - break; - case eAppAction_FailedToJoinNoPrivileges: - { - UINT uiIDA[1]; - uiIDA[0]=IDS_CONFIRM_OK; - C4JStorage::EMessageResult result = ui.RequestErrorMessage( IDS_NO_MULTIPLAYER_PRIVILEGE_TITLE, IDS_NO_MULTIPLAYER_PRIVILEGE_JOIN_TEXT, uiIDA,1,ProfileManager.GetPrimaryPad()); - if(result != C4JStorage::EMessage_Busy) SetAction(i,eAppAction_Idle); - } - break; - case eAppAction_ProfileReadError: - // Return player to the main menu - code largely copied from that for handling - // eAppAction_PrimaryPlayerSignedOut, although I don't think we should have got as - // far as needing to halt the server, or running the game, before returning to the menu - if(!app.GetGameStarted()) MinecraftServer::HaltServer(true); - - if( g_NetworkManager.IsInSession() ) - { - app.SetAction(i,eAppAction_PrimaryPlayerSignedOutReturned); - } - else - { - app.SetAction(i,eAppAction_PrimaryPlayerSignedOutReturned_Menus); - MinecraftServer::resetFlags(); - } - break; - - case eAppAction_BanLevel: - { - // It's possible that this state can get set after the game has been exited (e.g. by network disconnection) so we can't ban the level at that point - if(g_NetworkManager.IsInGameplay() && !g_NetworkManager.IsLeavingGame()) - { - TelemetryManager->RecordBanLevel(i); - -#if defined _XBOX - INetworkPlayer *pHost=g_NetworkManager.GetHostPlayer(); - // write the level to the banned level list, and exit the world - AddLevelToBannedLevelList(i,((NetworkPlayerXbox *)pHost)->GetUID(),GetUniqueMapName(),true); -#elif defined _XBOX_ONE - INetworkPlayer *pHost=g_NetworkManager.GetHostPlayer(); - AddLevelToBannedLevelList(i,pHost->GetUID(),GetUniqueMapName(),true); -#endif - // primary player would exit the world, secondary would exit the player - if(ProfileManager.GetPrimaryPad()==i) - { - SetAction(i,eAppAction_ExitWorld); - } - else - { - SetAction(i,eAppAction_ExitPlayer); - } - } - } - break; - case eAppAction_LevelInBanLevelList: - { - UINT uiIDA[2]; - uiIDA[0]=IDS_BUTTON_REMOVE_FROM_BAN_LIST; - uiIDA[1]=IDS_EXIT_GAME; - - // pass in the gamertag format string - WCHAR wchFormat[40]; - INetworkPlayer *player = g_NetworkManager.GetLocalPlayerByUserIndex(i); - - // If not the primary player, but the primary player has banned this level and decided not to unban - // then we may have left the game by now - if(player) - { - swprintf(wchFormat, 40, L"%ls\n\n%%ls",player->GetOnlineName()); - - C4JStorage::EMessageResult result = ui.RequestErrorMessage( IDS_BANNED_LEVEL_TITLE, IDS_PLAYER_BANNED_LEVEL, uiIDA,2,i,&CMinecraftApp::BannedLevelDialogReturned,this, wchFormat); - if(result != C4JStorage::EMessage_Busy) SetAction(i,eAppAction_Idle); - } - else - { - SetAction(i,eAppAction_Idle); - } - } - break; - case eAppAction_DebugText: - // launch the xui for text entry - { -#ifdef _XBOX - CScene_TextEntry::XuiTextInputParams *pDebugTextParams= new CScene_TextEntry::XuiTextInputParams; - pDebugTextParams->iPad=i; - pDebugTextParams->wch=(WCHAR)param; - - app.NavigateToScene(i,eUIScene_TextEntry,pDebugTextParams); -#endif - SetAction(i,eAppAction_Idle); - } - break; - - case eAppAction_ReloadTexturePack: - { - SetAction(i,eAppAction_Idle); - Minecraft *pMinecraft = Minecraft::GetInstance(); - pMinecraft->textures->reloadAll(); - pMinecraft->skins->updateUI(); - - if(!pMinecraft->skins->isUsingDefaultSkin()) - { - TexturePack *pTexturePack = pMinecraft->skins->getSelected(); - - DLCPack *pDLCPack=pTexturePack->getDLCPack(); - - bool purchased = false; - // do we have a license? - if(pDLCPack && pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) - { - purchased = true; - } -#ifdef _XBOX - TelemetryManager->RecordTexturePackLoaded(i, pTexturePack->getId(), purchased?1:0); -#endif - } - - // 4J-PB - If the texture pack has audio, we need to switch to this - if(pMinecraft->skins->getSelected()->hasAudio()) - { - Minecraft::GetInstance()->soundEngine->playStreaming(L"", 0, 0, 0, 1, 1); - } - } - break; - - case eAppAction_ReloadFont: - { -#ifndef _XBOX - app.DebugPrintf( - "[Consoles_App] eAppAction_ReloadFont, ingame='%s'.\n", - app.GetGameStarted() ? "Yes" : "No" ); - - SetAction(i,eAppAction_Idle); - - ui.SetTooltips(i, -1); - - ui.ReloadSkin(); - ui.StartReloadSkinThread(); - - ui.setCleanupOnReload(); -#endif - } - break; - - case eAppAction_TexturePackRequired: - { -#if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ - UINT uiIDA[2]; - uiIDA[0]=IDS_TEXTUREPACK_FULLVERSION; - uiIDA[1]=IDS_CONFIRM_CANCEL; // let them continue without the texture pack here (as this is only really for r - // Give the player a warning about the texture pack missing - ui.RequestErrorMessage(IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE, IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::TexturePackDialogReturned,this); - SetAction(i,eAppAction_Idle); -#else -#ifdef _XBOX - ULONGLONG ullOfferID_Full; - app.GetDLCFullOfferIDForPackID(app.GetRequiredTexturePackID(),&ullOfferID_Full); - - TelemetryManager->RecordUpsellPresented(ProfileManager.GetPrimaryPad(), eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF); -#endif - UINT uiIDA[2]; - - uiIDA[0]=IDS_TEXTUREPACK_FULLVERSION; - uiIDA[1]=IDS_TEXTURE_PACK_TRIALVERSION; - - // Give the player a warning about the texture pack missing - ui.RequestErrorMessage(IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE, IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::TexturePackDialogReturned,this); - SetAction(i,eAppAction_Idle); -#endif - } - - break; - } - } - - // Any TMS actions? - - eTMS = app.GetTMSAction(i); - - if(eTMS!=eTMSAction_Idle) - { - switch(eTMS) - { - // TMS++ actions - case eTMSAction_TMSPP_RetrieveFiles_CreateLoad_SignInReturned: - case eTMSAction_TMSPP_RetrieveFiles_RunPlayGame: -#ifdef _XBOX - app.TMSPP_SetTitleGroupID(GROUP_ID); - SetTMSAction(i,eTMSAction_TMSPP_GlobalFileList); -#elif defined _XBOX_ONE - SetTMSAction(i,eTMSAction_TMSPP_GlobalFileList_Waiting); - app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_Title,eTMSAction_TMSPP_UserFileList); -#else - SetTMSAction(i,eTMSAction_TMSPP_UserFileList); -#endif - break; - -#ifdef _XBOX - case eTMSAction_TMSPP_GlobalFileList: - SetTMSAction(i,eTMSAction_TMSPP_GlobalFileList_Waiting); - app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_Title,"\\",eTMSAction_TMSPP_UserFileList); - break; -#endif - case eTMSAction_TMSPP_UserFileList: - // retrieve the file list first -#if defined _XBOX - SetTMSAction(i,eTMSAction_TMSPP_UserFileList_Waiting); - app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_TitleUser,"\\",eTMSAction_TMSPP_XUIDSFile); -#elif defined _XBOX_ONE - SetTMSAction(i,eTMSAction_TMSPP_UserFileList_Waiting); - app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_TitleUser,eTMSAction_TMSPP_DLCFile); -#else - SetTMSAction(i,eTMSAction_TMSPP_XUIDSFile); -#endif - break; - case eTMSAction_TMSPP_XUIDSFile: -#ifdef _XBOX - SetTMSAction(i,eTMSAction_TMSPP_XUIDSFile_Waiting); - // pass in the next app action on the call or callback completing - app.TMSPP_ReadXuidsFile(i,eTMSAction_TMSPP_DLCFile); -#else - SetTMSAction(i,eTMSAction_TMSPP_DLCFile); -#endif - - break; - case eTMSAction_TMSPP_DLCFile: -#if defined _XBOX || defined _XBOX_ONE - SetTMSAction(i,eTMSAction_TMSPP_DLCFile_Waiting); - // pass in the next app action on the call or callback completing - app.TMSPP_ReadDLCFile(i,eTMSAction_TMSPP_BannedListFile); -#else - SetTMSAction(i,eTMSAction_TMSPP_BannedListFile); -#endif - break; - case eTMSAction_TMSPP_BannedListFile: - // If we have one in TMSPP, then we can assume we can ignore TMS -#if defined _XBOX - SetTMSAction(i,eTMSAction_TMSPP_BannedListFile_Waiting); - // pass in the next app action on the call or callback completing - if(app.TMSPP_ReadBannedList(i,eTMSAction_TMS_RetrieveFiles_Complete)==false) - { - // we don't have a banned list in TMSPP, so we should check TMS - app.ReadBannedList(i, eTMSAction_TMS_RetrieveFiles_Complete,true); - } -#elif defined _XBOX_ONE - SetTMSAction(i,eTMSAction_TMSPP_BannedListFile_Waiting); - // pass in the next app action on the call or callback completing - app.TMSPP_ReadBannedList(i,eTMSAction_TMS_RetrieveFiles_Complete); - -#else - SetTMSAction(i,eTMSAction_TMS_RetrieveFiles_Complete); -#endif - break; - - // SPECIAL CASE - where the user goes directly in to Help & Options from the main menu - case eTMSAction_TMSPP_RetrieveFiles_HelpAndOptions: - case eTMSAction_TMSPP_RetrieveFiles_DLCMain: - // retrieve the file list first -#if defined _XBOX - // pass in the next app action on the call or callback completing - SetTMSAction(i,eTMSAction_TMSPP_XUIDSFile_Waiting); - app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_Title,"\\",eTMSAction_TMSPP_DLCFileOnly); -#elif defined _XBOX_ONE - SetTMSAction(i,eTMSAction_TMSPP_GlobalFileList_Waiting); - app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_Title,eTMSAction_TMSPP_RetrieveUserFilelist_DLCFileOnly); -#else - SetTMSAction(i,eTMSAction_TMSPP_DLCFileOnly); -#endif - break; - case eTMSAction_TMSPP_RetrieveUserFilelist_DLCFileOnly: -#if defined _XBOX - SetTMSAction(i,eTMSAction_TMSPP_UserFileList_Waiting); - app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_TitleUser,"\\",eTMSAction_TMSPP_XUIDSFile); -#elif defined _XBOX_ONE - //StorageManager.TMSPP_DeleteFile(i,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,L"TP06.png",nullptr,nullptr, 0); - SetTMSAction(i,eTMSAction_TMSPP_UserFileList_Waiting); - app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_TitleUser,eTMSAction_TMSPP_DLCFileOnly); -#else - SetTMSAction(i,eTMSAction_TMSPP_DLCFileOnly); -#endif - - break; - - case eTMSAction_TMSPP_DLCFileOnly: -#if defined _XBOX || defined _XBOX_ONE - SetTMSAction(i,eTMSAction_TMSPP_DLCFile_Waiting); - // pass in the next app action on the call or callback completing - app.TMSPP_ReadDLCFile(i,eTMSAction_TMSPP_RetrieveFiles_Complete); -#else - SetTMSAction(i,eTMSAction_TMSPP_RetrieveFiles_Complete); -#endif - break; - - - case eTMSAction_TMSPP_RetrieveFiles_Complete: - SetTMSAction(i,eTMSAction_Idle); - break; - - - // TMS files - /* case eTMSAction_TMS_RetrieveFiles_CreateLoad_SignInReturned: - case eTMSAction_TMS_RetrieveFiles_RunPlayGame: - #ifdef _XBOX - SetTMSAction(i,eTMSAction_TMS_XUIDSFile_Waiting); - // pass in the next app action on the call or callback completing - app.ReadXuidsFileFromTMS(i,eTMSAction_TMS_DLCFile,true); - #else - SetTMSAction(i,eTMSAction_TMS_DLCFile); - #endif - break; - - case eTMSAction_TMS_DLCFile: - #ifdef _XBOX - SetTMSAction(i,eTMSAction_TMS_DLCFile_Waiting); - // pass in the next app action on the call or callback completing - app.ReadDLCFileFromTMS(i,eTMSAction_TMS_BannedListFile,true); - #else - SetTMSAction(i,eTMSAction_TMS_BannedListFile); - #endif - - break; - - case eTMSAction_TMS_RetrieveFiles_HelpAndOptions: - case eTMSAction_TMS_RetrieveFiles_DLCMain: - #ifdef _XBOX - SetTMSAction(i,eTMSAction_TMS_DLCFile_Waiting); - // pass in the next app action on the call or callback completing - app.ReadDLCFileFromTMS(i,eTMSAction_Idle,true); - #else - SetTMSAction(i,eTMSAction_Idle); - #endif - - break; - case eTMSAction_TMS_BannedListFile: - #ifdef _XBOX - SetTMSAction(i,eTMSAction_TMS_BannedListFile_Waiting); - // pass in the next app action on the call or callback completing - app.ReadBannedList(i, eTMSAction_TMS_RetrieveFiles_Complete,true); - #else - SetTMSAction(i,eTMSAction_TMS_RetrieveFiles_Complete); - #endif - - break; - - */ - case eTMSAction_TMS_RetrieveFiles_Complete: - SetTMSAction(i,eTMSAction_Idle); - // if(StorageManager.SetSaveDevice(&CScene_Main::DeviceSelectReturned,pClass)) - // { - // // save device already selected - // // ensure we've applied this player's settings - // app.ApplyGameSettingsChanged(ProfileManager.GetPrimaryPad()); - // app.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_MultiGameJoinLoad); - // } - break; - } - } - - } -} - -int CMinecraftApp::BannedLevelDialogReturned(void *pParam,int iPad,const C4JStorage::EMessageResult result) -{ - CMinecraftApp* pApp = static_cast(pParam); - //Minecraft *pMinecraft=Minecraft::GetInstance(); - - if(result==C4JStorage::EMessage_ResultAccept) - { -#if defined _XBOX || defined _XBOX_ONE - INetworkPlayer *pHost = g_NetworkManager.GetHostPlayer(); - // unban the level - if (pHost != nullptr) - { -#if defined _XBOX - pApp->RemoveLevelFromBannedLevelList(iPad,((NetworkPlayerXbox *)pHost)->GetUID(),pApp->GetUniqueMapName()); -#else - pApp->RemoveLevelFromBannedLevelList(iPad,pHost->GetUID(),pApp->GetUniqueMapName()); -#endif - } -#endif - } - else - { - if( iPad == ProfileManager.GetPrimaryPad() ) - { - pApp->SetAction(iPad,eAppAction_ExitWorld); - } - else - { - pApp->SetAction(iPad,eAppAction_ExitPlayer); - } - } - - return 0; -} - -void CMinecraftApp::loadMediaArchive() -{ - wstring mediapath = L""; - -#ifdef __PS3__ - mediapath = L"Common\\Media\\MediaPS3"; -#elif _WINDOWS64 - mediapath = L"Common\\Media\\MediaWindows64"; -#elif __ORBIS__ - mediapath = L"Common\\Media\\MediaOrbis"; -#elif _DURANGO - mediapath = L"Common\\Media\\MediaDurango"; -#elif __PSVITA__ - mediapath = L"Common\\Media\\MediaPSVita"; -#endif - - if (!mediapath.empty()) - { - m_mediaArchive = new FolderFile(mediapath); - } -#if 0 - string path = "Common\\media.arc"; - HANDLE hFile = CreateFile( path.c_str(), - GENERIC_READ, - FILE_SHARE_READ, - nullptr, - OPEN_EXISTING, - FILE_FLAG_SEQUENTIAL_SCAN, - nullptr ); - - if( hFile != INVALID_HANDLE_VALUE ) - { - File fileHelper(convStringToWstring(path)); - DWORD dwFileSize = fileHelper.length(); - - // Initialize memory. - PBYTE m_fBody = new BYTE[ dwFileSize ]; - ZeroMemory(m_fBody, dwFileSize); - - DWORD m_fSize = 0; - BOOL hr = ReadFile( hFile, - m_fBody, - dwFileSize, - &m_fSize, - nullptr ); - - assert( m_fSize == dwFileSize ); - - CloseHandle( hFile ); - - m_mediaArchive = new ArchiveFile(m_fBody, m_fSize); - } - else - { - assert( false ); - // AHHHHHHHHHHHH - m_mediaArchive = nullptr; - } -#endif -} - -void CMinecraftApp::loadStringTable() -{ -#ifndef _XBOX - - if(m_stringTable!=nullptr) - { - // we need to unload the current string table, this is a reload - delete m_stringTable; - } -#ifdef _WINDOWS64 - m_stringTable = nullptr; - const wstring localisationCandidates[] = - { - L"Common\\Localization", // Fireblade - check multiple directories before resulting to .loc usage - L"Windows64Media\\loc", - L"..\\Minecraft.Client\\Windows64Media\\loc" - }; - - for (const auto &localisationFolder : localisationCandidates) - { - File localisationDirectory(localisationFolder); - if (localisationDirectory.exists() && localisationDirectory.isDirectory()) - { - StringTable *candidateTable = new StringTable(localisationFolder); // Fireblade - xml before loc - - const bool hasKeyString = candidateTable->hasStringKey(L"IDS_OK"); - bool hasIndexString = false; - #ifdef IDS_OK - LPCWSTR indexedString = candidateTable->getString(IDS_OK); - hasIndexString = (indexedString != nullptr && indexedString[0] != L'\0'); - #endif - - if (hasKeyString || hasIndexString) - { - m_stringTable = candidateTable; - app.DebugPrintf("Loaded language data from '%ls'\n", localisationFolder.c_str()); - break; - } - - app.DebugPrintf("Ignoring localisation path '%ls' (missing expected IDs)\n", localisationFolder.c_str()); - delete candidateTable; - } - } - - if (m_stringTable == nullptr && m_mediaArchive != nullptr) // Fireblade - fallback to previous behavior - { - const wstring localisationFile = L"languages.loc"; - if (m_mediaArchive->hasFile(localisationFile)) - { - byteArray locFile = m_mediaArchive->getFile(localisationFile); - m_stringTable = new StringTable(locFile.data, locFile.length); - delete locFile.data; - } - } - - if (m_stringTable == nullptr) - { - app.DebugPrintf("Failed to initialize language data\n"); - assert(false); - } -#else // Fireblade - other platforms keep same logic - wstring localisationFile = L"languages.loc"; - if (m_mediaArchive->hasFile(localisationFile)) - { - byteArray locFile = m_mediaArchive->getFile(localisationFile); - m_stringTable = new StringTable(locFile.data, locFile.length); - delete locFile.data; - } - else - { - m_stringTable = nullptr; - assert(false); - // AHHHHHHHHH. - } -#endif -#endif -} - -int CMinecraftApp::PrimaryPlayerSignedOutReturned(void *pParam,int iPad,const C4JStorage::EMessageResult) -{ - //CMinecraftApp* pApp = (CMinecraftApp*)pParam; - //Minecraft *pMinecraft=Minecraft::GetInstance(); - - // if the player is null, we're in the menus - //if(Minecraft::GetInstance()->player!=nullptr) - - // We always create a session before kicking of any of the game code, so even though we may still be joining/creating a game - // at this point we want to handle it differently from just being in a menu - if( g_NetworkManager.IsInSession() ) - { - app.SetAction(iPad,eAppAction_PrimaryPlayerSignedOutReturned); - } - else - { - app.SetAction(iPad,eAppAction_PrimaryPlayerSignedOutReturned_Menus); - } - return 0; -} - -int CMinecraftApp::EthernetDisconnectReturned(void *pParam,int iPad,const C4JStorage::EMessageResult) -{ - //CMinecraftApp* pApp = (CMinecraftApp*)pParam; - Minecraft *pMinecraft=Minecraft::GetInstance(); - - // if the player is null, we're in the menus - if (Minecraft::GetInstance()->player != nullptr) - { - app.SetAction(pMinecraft->player->GetXboxPad(), eAppAction_EthernetDisconnectedReturned); - } - else - { - // 4J-PB - turn off the PSN store icon just in case this happened when we were in one of the DLC menus -#if defined __ORBIS__ || defined __PSVITA__ - app.GetCommerce()->HidePsStoreIcon(); -#endif - app.SetAction(iPad,eAppAction_EthernetDisconnectedReturned_Menus); - } - return 0; -} - -int CMinecraftApp::SignoutExitWorldThreadProc( void* lpParameter ) -{ - - // Share AABB & Vec3 pools with default (main thread) - should be ok as long as we don't tick the main thread whilst this thread is running - AABB::UseDefaultThreadStorage(); - Vec3::UseDefaultThreadStorage(); - Compression::UseDefaultThreadStorage(); - - //app.SetGameStarted(false); - - Minecraft *pMinecraft=Minecraft::GetInstance(); - - int exitReasonStringId = -1; - - bool saveStats = false; - if (pMinecraft->isClientSide() || g_NetworkManager.IsInSession() ) - { - if(lpParameter != nullptr ) - { - switch( app.GetDisconnectReason() ) - { - case DisconnectPacket::eDisconnect_Kicked: - exitReasonStringId = IDS_DISCONNECTED_KICKED; - break; - case DisconnectPacket::eDisconnect_NoUGC_AllLocal: - exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_ALL_LOCAL; - break; - case DisconnectPacket::eDisconnect_NoUGC_Single_Local: - exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL; - break; -#ifdef _XBOX - case DisconnectPacket::eDisconnect_NoUGC_Remote: - exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_REMOTE; - break; -#endif - case DisconnectPacket::eDisconnect_NoFlying: - exitReasonStringId = IDS_DISCONNECTED_FLYING; - break; - case DisconnectPacket::eDisconnect_OutdatedServer: - exitReasonStringId = IDS_DISCONNECTED_SERVER_OLD; - break; - case DisconnectPacket::eDisconnect_OutdatedClient: - exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD; - break; - default: - exitReasonStringId = IDS_DISCONNECTED; - } - pMinecraft->progressRenderer->progressStartNoAbort( exitReasonStringId ); - // 4J - Force a disconnection, this handles the situation that the server has already disconnected - if( pMinecraft->levels[0] != nullptr ) pMinecraft->levels[0]->disconnect(false); - if( pMinecraft->levels[1] != nullptr ) pMinecraft->levels[1]->disconnect(false); - } - else - { - exitReasonStringId = IDS_EXITING_GAME; - pMinecraft->progressRenderer->progressStartNoAbort( IDS_EXITING_GAME ); - - if( pMinecraft->levels[0] != nullptr ) pMinecraft->levels[0]->disconnect(); - if( pMinecraft->levels[1] != nullptr ) pMinecraft->levels[1]->disconnect(); - } - - // 4J Stu - This only does something if we actually have a server, so don't need to do any other checks - MinecraftServer::HaltServer(true); - - // We need to call the stats & leaderboards save before we exit the session - //pMinecraft->forceStatsSave(); - saveStats = false; - - // 4J Stu - Leave the session once the disconnect packet has been sent - g_NetworkManager.LeaveGame(FALSE); - } - else - { - if(lpParameter != nullptr ) - { - switch( app.GetDisconnectReason() ) - { - case DisconnectPacket::eDisconnect_Kicked: - exitReasonStringId = IDS_DISCONNECTED_KICKED; - break; - case DisconnectPacket::eDisconnect_NoUGC_AllLocal: - exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_ALL_LOCAL; - break; - case DisconnectPacket::eDisconnect_NoUGC_Single_Local: - exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL; - break; -#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) - case DisconnectPacket::eDisconnect_ContentRestricted_AllLocal: - exitReasonStringId = IDS_CONTENT_RESTRICTION_MULTIPLAYER; - break; - case DisconnectPacket::eDisconnect_ContentRestricted_Single_Local: - exitReasonStringId = IDS_CONTENT_RESTRICTION; - break; -#endif -#ifdef _XBOX - case DisconnectPacket::eDisconnect_NoUGC_Remote: - exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_REMOTE; - break; -#endif - case DisconnectPacket::eDisconnect_OutdatedServer: - exitReasonStringId = IDS_DISCONNECTED_SERVER_OLD; - break; - case DisconnectPacket::eDisconnect_OutdatedClient: - exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD; - default: - exitReasonStringId = IDS_DISCONNECTED; - } - pMinecraft->progressRenderer->progressStartNoAbort( exitReasonStringId ); - } - } - pMinecraft->setLevel(nullptr,exitReasonStringId,nullptr,saveStats,true); - - // 4J-JEV: Fix for #106402 - TCR #014 BAS Debug Output: - // TU12: Mass Effect Mash-UP: Save file "Default_DisplayName" is created on all storage devices after signing out from a re-launched pre-generated world - app.m_gameRules.unloadCurrentGameRules(); // - - MinecraftServer::resetFlags(); - - // We can't start/join a new game until the session is destroyed, so wait for it to be idle again - while( g_NetworkManager.IsInSession() ) - { - Sleep(1); - } - - return S_OK; -} - -int CMinecraftApp::UnlockFullInviteReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) -{ - //CMinecraftApp* pApp = (CMinecraftApp*)pParam; - Minecraft *pMinecraft=Minecraft::GetInstance(); - bool bNoPlayer; - - // bug 11285 - TCR 001: BAS Game Stability: CRASH - When trying to join a full version game with a trial version, the trial crashes - // 4J-PB - we may be in the main menus here, and we don't have a pMinecraft->player - - if(pMinecraft->player==nullptr) - { - bNoPlayer=true; - } - - if(result==C4JStorage::EMessage_ResultAccept) - { - if(ProfileManager.IsSignedInLive(iPad)) - { - // 4J-PB - need to check this user can access the store -#if defined(__PS3__) || defined(__PSVITA__) - bool bContentRestricted; - ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,nullptr,&bContentRestricted,nullptr); - if(bContentRestricted) - { - UINT uiIDA[1]; - uiIDA[0]=IDS_CONFIRM_OK; - ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); - } - else -#endif - { - ProfileManager.DisplayFullVersionPurchase(false,iPad,eSen_UpsellID_Full_Version_Of_Game); - } - } -#if defined(__PS3__) - else - { - // you're not signed in to PSN! - UINT uiIDA[2]; - uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; - uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; - ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); - - } -#endif - } - else - { - TelemetryManager->RecordUpsellResponded(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, eSen_UpsellOutcome_Declined); - } - - return 0; -} - -int CMinecraftApp::UnlockFullSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) -{ - //CMinecraftApp* pApp = (CMinecraftApp*)pParam; - Minecraft *pMinecraft=Minecraft::GetInstance(); - - if(result==C4JStorage::EMessage_ResultAccept) - { - if(ProfileManager.IsSignedInLive(pMinecraft->player->GetXboxPad())) - { - // 4J-PB - need to check this user can access the store -#if defined(__PS3__) || defined(__PSVITA__) - bool bContentRestricted; - ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,nullptr,&bContentRestricted,nullptr); - if(bContentRestricted) - { - UINT uiIDA[1]; - uiIDA[0]=IDS_CONFIRM_OK; - ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); - } - else -#endif - { - ProfileManager.DisplayFullVersionPurchase(false,pMinecraft->player->GetXboxPad(),eSen_UpsellID_Full_Version_Of_Game); - } - } -#if defined(__PS3__) - else - { - // you're not signed in to PSN! - UINT uiIDA[2]; - uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; - uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; - ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); - } -#elif defined(__ORBIS__) - else - { - // Determine why they're not "signed in live" - if (ProfileManager.isSignedInPSN(iPad)) - { - // Signed in to PSN but not connected (no internet access) - assert(!ProfileManager.isConnectedToPSN(iPad)); - - UINT uiIDA[1]; - uiIDA[0] = IDS_OK; - ui.RequestErrorMessage( IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, iPad); - } - else - { - // Not signed in to PSN - UINT uiIDA[1]; - uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; - ui.RequestAlertMessage( IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, iPad, &CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); - } - } -#endif - } - else - { - TelemetryManager->RecordUpsellResponded(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, eSen_UpsellOutcome_Declined); - } - - return 0; -} - -int CMinecraftApp::UnlockFullExitReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) -{ - CMinecraftApp* pApp = static_cast(pParam); - Minecraft *pMinecraft=Minecraft::GetInstance(); - - if(result==C4JStorage::EMessage_ResultAccept) - { - if(ProfileManager.IsSignedInLive(pMinecraft->player->GetXboxPad())) - { - // 4J-PB - need to check this user can access the store -#if defined(__PS3__) || defined(__PSVITA__) - bool bContentRestricted; - ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,nullptr,&bContentRestricted,nullptr); - if(bContentRestricted) - { - UINT uiIDA[1]; - uiIDA[0]=IDS_CONFIRM_OK; - ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); - } - else -#endif - { - ProfileManager.DisplayFullVersionPurchase(false,pMinecraft->player->GetXboxPad(),eSen_UpsellID_Full_Version_Of_Game); -#if defined __ORBIS__ || defined __PS3__ || defined __PSVITA__ - // still need to exit the trial or we'll be in the Pause menu with input ignored - pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); -#endif - } - } -#if defined(__PS3__) || defined __PSVITA__ - else - { - // you're not signed in to PSN! - UINT uiIDA[2]; - uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; - uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; - ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturnedExitTrial,&app); - } -#elif defined(__ORBIS__) - else - { - // Determine why they're not "signed in live" - if (ProfileManager.isSignedInPSN(iPad)) - { - // Signed in to PSN but not connected (no internet access) - assert(!ProfileManager.isConnectedToPSN(iPad)); - - UINT uiIDA[1]; - uiIDA[0] = IDS_OK; - ui.RequestErrorMessage( IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, iPad); - // still need to exit the trial or we'll be in the Pause menu with input ignored - pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); - } - else - { - // Not signed in to PSN - UINT uiIDA[1]; - uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; - ui.RequestAlertMessage( IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, iPad, &CMinecraftApp::MustSignInFullVersionPurchaseReturnedExitTrial,&app); - } - } -#endif - } - else - { - TelemetryManager->RecordUpsellResponded(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, eSen_UpsellOutcome_Declined); - pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); - } - - return 0; -} - -int CMinecraftApp::TrialOverReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) -{ - CMinecraftApp* pApp = static_cast(pParam); - Minecraft *pMinecraft=Minecraft::GetInstance(); - - if(result==C4JStorage::EMessage_ResultAccept) - { - // we need a signed in user for the unlock - if(ProfileManager.IsSignedInLive(pMinecraft->player->GetXboxPad())) - { - // 4J-PB - need to check this user can access the store -#if defined(__PS3__) || defined(__PSVITA__) - bool bContentRestricted; - ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,nullptr,&bContentRestricted,nullptr); - if(bContentRestricted) - { - UINT uiIDA[1]; - uiIDA[0]=IDS_CONFIRM_OK; - ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); - } - else -#endif - { - ProfileManager.DisplayFullVersionPurchase(false,pMinecraft->player->GetXboxPad(),eSen_UpsellID_Full_Version_Of_Game); - } - } - else - { -#if defined(__PS3__) - - // you're not signed in to PSN! - UINT uiIDA[2]; - uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; - uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; - ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); - - // 4J Stu - We can't actually exit the game, so just exit back to the main menu - //pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); -#else - pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitTrial); -#endif - } - } - else - { - TelemetryManager->RecordUpsellResponded(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, eSen_UpsellOutcome_Declined); - -#if defined(__PS3__) || defined(__ORBIS__) - // 4J Stu - We can't actually exit the game, so just exit back to the main menu - pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); -#else - pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitTrial); -#endif - } - - return 0; -} - -void CMinecraftApp::ProfileReadErrorCallback(void *pParam) -{ - CMinecraftApp *pApp=static_cast(pParam); - int iPrimaryPlayer=ProfileManager.GetPrimaryPad(); - pApp->SetAction(iPrimaryPlayer, eAppAction_ProfileReadError); -} - -void CMinecraftApp::ClearSignInChangeUsersMask() -{ - // 4J-PB - When in the main menu, the user is on pad 0, and any change they make to their profile will be to pad 0 data - // If they then go in as a secondary player to a splitscreen game, their profile will not be read again on pad 1 if they were previously in a splitscreen game - // This is because m_uiLastSignInData remembers they were in previously, and doesn't read the profile data for them again - // Fix this by resetting the m_uiLastSignInData on pressing play game for secondary users. The Primary user does a read profile on play game anyway - int iPrimaryPlayer=ProfileManager.GetPrimaryPad(); - - if(m_uiLastSignInData!=0) - { - if(iPrimaryPlayer>=0) - { - m_uiLastSignInData=1<user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); -#endif - - CMinecraftApp *pApp=static_cast(pParam); - // check if the primary player signed out - int iPrimaryPlayer=ProfileManager.GetPrimaryPad(); - - if((ProfileManager.GetLockedProfile()!=-1) && iPrimaryPlayer!=-1) - { - if ( ((uiSignInData & (1<SetAction(iPrimaryPlayer,eAppAction_PrimaryPlayerSignedOut); - - // 4J-PB - invalidate their banned level list - pApp->InvalidateBannedList(iPrimaryPlayer); - - // need to ditch any DLCOffers info - StorageManager.ClearDLCOffers(); - pApp->ClearAndResetDLCDownloadQueue(); - pApp->ClearDLCInstalled(); - } - else - { - unsigned int uiChangedPlayers = uiSignInData ^ m_uiLastSignInData; - - if( g_NetworkManager.IsInSession() ) - { - bool hasGuestIdChanged = false; - for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) - { - DWORD guestNumber = 0; - if(ProfileManager.IsSignedIn(i)) - { - XUSER_SIGNIN_INFO info; - XUserGetSigninInfo(i,XUSER_GET_SIGNIN_INFO_OFFLINE_XUID_ONLY ,&info); - pApp->DebugPrintf("Player at index %d has guest number %d\n", i,info.dwGuestNumber ); - guestNumber = info.dwGuestNumber; - } - if( pApp->m_currentSigninInfo[i].dwGuestNumber != 0 && guestNumber != 0 && pApp->m_currentSigninInfo[i].dwGuestNumber != guestNumber ) - { - hasGuestIdChanged = true; - } - } - - if( hasGuestIdChanged ) - { - UINT uiIDA[1]; - uiIDA[0]=IDS_CONFIRM_OK; - ui.RequestErrorMessage(IDS_GUEST_ORDER_CHANGED_TITLE, IDS_GUEST_ORDER_CHANGED_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad()); - } - - // 4J Stu - On PS4 we can also cause to exit players if they are signed out here, but we shouldn't do that if - // we are going to switch to an offline game as it will likely crash due to incompatible parallel processes - bool switchToOffline = false; - // If it's an online game, and the primary profile is no longer signed into LIVE then we act as if disconnected - if( !ProfileManager.IsSignedInLive( ProfileManager.GetLockedProfile() ) && !g_NetworkManager.IsLocalGame() ) - { - switchToOffline = true; - } - - //printf("Old: %x, New: %x, Changed: %x\n", m_ulLastSignInData, ulSignInData, changedPlayers); - for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) - { - // Primary player shouldn't be subjected to these checks, and shouldn't call ExitPlayer - if(i == iPrimaryPlayer) continue; - - // A guest a signed in or out, out of order which invalidates all the guest players we have in the game - if(hasGuestIdChanged && pApp->m_currentSigninInfo[i].dwGuestNumber != 0 && g_NetworkManager.GetLocalPlayerByUserIndex(i)!=nullptr) - { - pApp->DebugPrintf("Recommending removal of player at index %d because their guest id changed\n",i); - pApp->SetAction(i, eAppAction_ExitPlayer); - } - else - { - XUSER_SIGNIN_INFO info; - XUserGetSigninInfo(i,XUSER_GET_SIGNIN_INFO_OFFLINE_XUID_ONLY ,&info); - // 4J Stu - Also need to detect the case where the sign in mask is the same, but the player has swapped users (eg still signed in but xuid different) - // Fix for #48451 - TU5: Code: UI: Splitscreen: Title crashes when switching to a profile previously signed out via splitscreen profile selection - - // 4J-PB - compiler complained about if below ('&&' within '||') - making it easier to read - bool bPlayerChanged=(uiChangedPlayers&(1<m_currentSigninInfo[i].xuid, info.xuid) ) )) - { - // 4J-PB - invalidate their banned level list - pApp->DebugPrintf("Player at index %d Left - invalidating their banned list\n",i); - pApp->InvalidateBannedList(i); - - // 4J-HG: If either the player is in the network manager or in the game, need to exit player - // TODO: Do we need to check the network manager? - if (g_NetworkManager.GetLocalPlayerByUserIndex(i) != nullptr || Minecraft::GetInstance()->localplayers[i] != nullptr) - { - pApp->DebugPrintf("Player %d signed out\n", i); - pApp->SetAction(i, eAppAction_ExitPlayer); - } - } - } -#ifdef __ORBIS__ - // check if any of the addition players have signed out of PSN (primary player is handled below) - if(!switchToOffline && i != ProfileManager.GetLockedProfile() && !g_NetworkManager.IsLocalGame()) - { - if(g_NetworkManager.GetLocalPlayerByUserIndex(i)!=nullptr) - { - if(ProfileManager.IsSignedInLive(i) == false) - { - pApp->DebugPrintf("Recommending removal of player at index %d because they're no longer signed into PSNd\n",i); - pApp->SetAction(i,eAppAction_ExitPlayer); - } - } - } -#endif - } - - // If it's an online game, and the primary profile is no longer signed into LIVE then we act as if disconnected - if( switchToOffline ) - { - pApp->SetAction(iPrimaryPlayer,eAppAction_EthernetDisconnected); - } - - - g_NetworkManager.HandleSignInChange(); - } - // Some menus require the player to be signed in to live, so if this callback happens and the primary player is - // no longer signed in then nav back - else if ( pApp->GetLiveLinkRequired() && !ProfileManager.IsSignedInLive( ProfileManager.GetLockedProfile() ) ) - { -#ifdef __PSVITA__ - if(!CGameNetworkManager::usingAdhocMode()) // if we're in adhoc mode, we can ignore this -#endif - { - pApp->SetAction(iPrimaryPlayer,eAppAction_EthernetDisconnected); - } - } - -#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__ ) - // 4J-JEV: Need to kick of loading of profile data for sub-sign in players. - for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) - { - if( i != iPrimaryPlayer - && ( uiChangedPlayers & (1<InvalidateBannedList(iPrimaryPlayer); - - // need to ditch any DLCOffers info - StorageManager.ClearDLCOffers(); - pApp->ClearAndResetDLCDownloadQueue(); - pApp->ClearDLCInstalled(); - - } - - // Update the guest numbers to the current state - for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) - { - if(FAILED(XUserGetSigninInfo(i,XUSER_GET_SIGNIN_INFO_OFFLINE_XUID_ONLY,&pApp->m_currentSigninInfo[i]))) - { - pApp->m_currentSigninInfo[i].xuid = INVALID_XUID; - pApp->m_currentSigninInfo[i].dwGuestNumber = 0; - } - app.DebugPrintf("Player at index %d has guest number %d\n", i,pApp->m_currentSigninInfo[i].dwGuestNumber ); - } -} - -void CMinecraftApp::NotificationsCallback(LPVOID pParam,DWORD dwNotification, unsigned int uiParam) -{ - CMinecraftApp* pClass = static_cast(pParam); - - // push these on to the notifications to be handled in qnet's dowork - - PNOTIFICATION pNotification = new NOTIFICATION; - - pNotification->dwNotification=dwNotification; - pNotification->uiParam=uiParam; - - switch( dwNotification ) - { - case XN_SYS_SIGNINCHANGED: - { - pClass->DebugPrintf("Signing changed - %d\n", uiParam ); - } - break; - case XN_SYS_INPUTDEVICESCHANGED: - if(app.GetGameStarted() && g_NetworkManager.IsInSession()) - { - for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) - { - if(!InputManager.IsPadConnected(i) && - Minecraft::GetInstance()->localplayers[i] != nullptr && - !ui.IsPauseMenuDisplayed(i) && !ui.IsSceneInStack(i, eUIScene_EndPoem) ) - { - ui.CloseUIScenes(i); - ui.NavigateToScene(i,eUIScene_PauseMenu); - } - } - } - break; - case XN_LIVE_CONTENT_INSTALLED: - // Need to inform xuis that we've possibly had DLC installed - { - //app.m_dlcManager.SetNeedsUpdated(true); - // Clear the DLC installed flag to cause a GetDLC to run if it's called - app.ClearDLCInstalled(); - - ui.HandleDLCInstalled(ProfileManager.GetPrimaryPad()); - } - break; - case XN_SYS_STORAGEDEVICESCHANGED: - { -#ifdef _XBOX - // If the devices have changed, and we've got a dlc pack with audio selected, and that pack's content device is no longer valid... then pull the plug on - // audio streaming, as if we leave this until later xact gets locked up attempting to destroy the streamed wave bank. - TexturePack *pTexPack=Minecraft::GetInstance()->skins->getSelected(); - if(pTexPack->hasAudio()) - { - DLCTexturePack *pDLCTexPack=(DLCTexturePack *)pTexPack; - XCONTENTDEVICEID deviceID = pDLCTexPack->GetDLCDeviceID(); - if( XContentGetDeviceState( deviceID, nullptr ) != ERROR_SUCCESS ) - { - // Set texture pack flag so that it is now considered as not having audio - this is critical so that the next playStreaming does what it is meant to do, - // and also so that we don't try and unmount this again, or play any sounds from it in the future - pTexPack->setHasAudio(false); - // need to stop the streaming audio - by playing streaming audio from the default texture pack now - Minecraft::GetInstance()->soundEngine->playStreaming(L"", 0, 0, 0, 0, 0); - - if(pDLCTexPack->m_pStreamedWaveBank!=nullptr) - { - pDLCTexPack->m_pStreamedWaveBank->Destroy(); - } - if(pDLCTexPack->m_pSoundBank!=nullptr) - { - pDLCTexPack->m_pSoundBank->Destroy(); - } - DWORD result = StorageManager.UnmountInstalledDLC("TPACK"); - app.DebugPrintf("Unmount result is %d\n",result); - } - } -#endif - } - break; - } - - pClass->m_vNotifications.push_back(pNotification); -} - -#if defined __PS3__ || defined __PSVITA__ || defined __ORBIS__ -int CMinecraftApp::MustSignInFullVersionPurchaseReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) -{ - if(result==C4JStorage::EMessage_ResultAccept) - { -#ifdef __PS3__ - SQRNetworkManager_PS3::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); -#elif defined __PSVITA__ - SQRNetworkManager_Vita::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); -#else // __PS4__ - SQRNetworkManager_Orbis::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); -#endif - } - - return 0; -} - -#if defined __PS3__ || defined __PSVITA__ || defined __ORBIS__ -int CMinecraftApp::MustSignInFullVersionPurchaseReturnedExitTrial(void *pParam,int iPad,C4JStorage::EMessageResult result) -{ - if(result==C4JStorage::EMessage_ResultAccept) - { -#ifdef __PS3__ - SQRNetworkManager_PS3::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); -#elif defined __PSVITA__ - SQRNetworkManager_Vita::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); -#else // __PS4__ - SQRNetworkManager_Orbis::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); -#endif - } - - //4J-PB - we need to exit the trial, or we'll be in the pause menu with ignore input true - app.SetAction(iPad,eAppAction_ExitWorldTrial); - - return 0; -} -#endif - -int CMinecraftApp::NowDisplayFullVersionPurchase(void *pParam, bool bContinue, int iPad) -{ - app.m_bDisplayFullVersionPurchase=true; - return 0; -} -#endif -void CMinecraftApp::UpsellReturnedCallback(LPVOID pParam, eUpsellType type, eUpsellResponse result, int iUserData) -{ - ESen_UpsellID senType; - ESen_UpsellOutcome senResponse; -#ifdef __PS3__ - UINT uiIDA[2]; -#endif - - // Map the eUpsellResponse to the enum we use for sentient - switch(result) - { - case eUpsellResponse_Accepted_NoPurchase: - senResponse = eSen_UpsellOutcome_Went_To_Guide; - break; - case eUpsellResponse_Accepted_Purchase: - senResponse = eSen_UpsellOutcome_Accepted; - break; -#ifdef __PS3__ - // special case for people who are not signed in to the PSN while playing the trial game - case eUpsellResponse_UserNotSignedInPSN: - - uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; - uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; - ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); - - return; - - case eUpsellResponse_NotAllowedOnline: // On earning a trophy in the trial version, where the user is underage and can't go online to buy the game, but they selected to buy the game on the trophy upsell - uiIDA[0]=IDS_CONFIRM_OK; - ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); - break; -#endif - case eUpsellResponse_Declined: - default: - senResponse = eSen_UpsellOutcome_Declined; - break; - }; - - // Map the eUpsellType to the enum we use for sentient - switch(type) - { - case eUpsellType_Custom: - senType = eSen_UpsellID_Full_Version_Of_Game; - break; - default: - senType = eSen_UpsellID_Undefined; - break; - }; - - // Always the primary pad that gets an upsell - TelemetryManager->RecordUpsellResponded(ProfileManager.GetPrimaryPad(), eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, senResponse); -} - -#ifdef _DEBUG_MENUS_ENABLED -bool CMinecraftApp::DebugArtToolsOn() -{ - return DebugSettingsOn() && (GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<(pParam); - //printf("sequence matched\n"); - pClass->m_bDebugOptions=!pClass->m_bDebugOptions; - - for(int i=0;ilocalplayers[i] != nullptr) - { - iPlayerC++; - } - } - - return iPlayerC; -} - -int CMinecraftApp::MarketplaceCountsCallback(LPVOID pParam,C4JStorage::DLC_TMS_DETAILS *pTMSDetails, int iPad) -{ - app.DebugPrintf("Marketplace Counts= New - %d Total - %d\n",pTMSDetails->dwNewOffers,pTMSDetails->dwTotalOffers); - - if(pTMSDetails->dwNewOffers>0) - { - app.m_bNewDLCAvailable=true; - app.m_bSeenNewDLCTip=false; - } - else - { - app.m_bNewDLCAvailable=false; - app.m_bSeenNewDLCTip=true; - } - - return 0; -} - -bool CMinecraftApp::StartInstallDLCProcess(int iPad) -{ - app.DebugPrintf("--- CMinecraftApp::StartInstallDLCProcess: pad=%i.\n", iPad); - - // If there is already a call to this in progress, then do nothing - // If the app says dlc is installed, then there has been no new system message to tell us there's new DLC since the last call to StartInstallDLCProcess - if((app.DLCInstallProcessCompleted()==false) && (m_bDLCInstallPending==false)) - { - app.m_dlcManager.resetUnnamedCorruptCount(); - m_bDLCInstallPending = true; - m_iTotalDLC = 0; - m_iTotalDLCInstalled = 0; - app.DebugPrintf("--- CMinecraftApp::StartInstallDLCProcess - StorageManager.GetInstalledDLC\n"); - - StorageManager.GetInstalledDLC(iPad,&CMinecraftApp::DLCInstalledCallback,this); - return true; - } - else - { - app.DebugPrintf("--- CMinecraftApp::StartInstallDLCProcess - nothing to do\n"); - - return false; - } - -} - -// Installed DLC callback -int CMinecraftApp::DLCInstalledCallback(LPVOID pParam,int iInstalledC,int iPad) -{ - app.DebugPrintf("--- CMinecraftApp::DLCInstalledCallback: totalDLC=%i, pad=%i.\n", iInstalledC, iPad); - app.m_iTotalDLC = iInstalledC; - app.MountNextDLC(iPad); - return 0; -} - -void CMinecraftApp::MountNextDLC(int iPad) -{ - app.DebugPrintf("--- CMinecraftApp::MountNextDLC: pad=%i.\n", iPad); - if(m_iTotalDLCInstalled < m_iTotalDLC) - { - // Mount it - // We also need to match the ones the user wants to mount with the installed DLC - // We're supposed to use a generic save game as a cache of these to do this, with XUSER_ANY - - if(StorageManager.MountInstalledDLC(iPad,m_iTotalDLCInstalled,&CMinecraftApp::DLCMountedCallback,this)!=ERROR_IO_PENDING ) - { - // corrupt DLC - app.DebugPrintf("Failed to mount DLC %d for pad %d\n",m_iTotalDLCInstalled,iPad); - ++m_iTotalDLCInstalled; - app.MountNextDLC(iPad); - } - else - { - app.DebugPrintf("StorageManager.MountInstalledDLC ok\n"); - } - } - else - { - /* Removed - now loading these on demand instead of as each pack is mounted - if(m_iTotalDLCInstalled > 0) - { - Minecraft *pMinecraft=Minecraft::GetInstance(); - pMinecraft->levelRenderer->AddDLCSkinsToMemTextures(); - } - */ - - m_bDLCInstallPending = false; - m_bDLCInstallProcessCompleted=true; - - ui.HandleDLCMountingComplete(); - -#if defined(_XBOX_ONE) || defined(__ORBIS__) - // Check if the current texture pack is now installed - if(!Minecraft::GetInstance()->skins->isUsingDefaultSkin()) - { - TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); - DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; - - DLCPack *pParentPack=pDLCTexPack->getDLCInfoParentPack();//tPack->getDLCPack(); - - if(pParentPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) - { - StorageManager.SetSaveDisabled(false); - } - } -#endif -#if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ - { - TexturePack* currentTPack = Minecraft::GetInstance()->skins->getSelected(); - TexturePack* requiredTPack = Minecraft::GetInstance()->skins->getTexturePackById(app.GetRequiredTexturePackID()); - if(currentTPack != requiredTPack) - { - Minecraft::GetInstance()->skins->selectTexturePackById(app.GetRequiredTexturePackID()); - } - } -#endif - } -} - -// 4J-JEV: For the sake of clarity in DLCMountedCallback. -#if defined(_XBOX) || defined(__PS3__) || defined(_WINDOWS64) -#define CONTENT_DATA_DISPLAY_NAME(a) (a.szDisplayName) -#else -#define CONTENT_DATA_DISPLAY_NAME(a) (a.wszDisplayName) -#endif - -int CMinecraftApp::DLCMountedCallback(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicenceMask) -{ -#if defined(_XBOX) || defined(_DURANGO) || defined(__PS3__) || defined(__ORBIS__) || defined(_WINDOWS64) || defined (__PSVITA__) //Chris TODO - app.DebugPrintf("--- CMinecraftApp::DLCMountedCallback\n"); - - if(dwErr!=ERROR_SUCCESS) - { - // corrupt DLC - app.DebugPrintf("Failed to mount DLC for pad %d: %d\n",iPad,dwErr); - app.m_dlcManager.incrementUnnamedCorruptCount(); - } - else - { - XCONTENT_DATA ContentData = StorageManager.GetDLC(app.m_iTotalDLCInstalled); - - DLCPack *pack = app.m_dlcManager.getPack( CONTENT_DATA_DISPLAY_NAME(ContentData) ); - - if( pack != nullptr && pack->IsCorrupt() ) - { - app.DebugPrintf("Pack '%ls' is corrupt, removing it from the DLC Manager.\n", CONTENT_DATA_DISPLAY_NAME(ContentData)); - - app.m_dlcManager.removePack(pack); - pack = nullptr; - } - - if(pack == nullptr) - { - app.DebugPrintf("Pack \"%ls\" is not installed, so adding it\n", CONTENT_DATA_DISPLAY_NAME(ContentData)); - -#if defined(_XBOX) || defined(__PS3__) || defined(_WINDOWS64) - pack = new DLCPack(ContentData.szDisplayName,dwLicenceMask); -#elif defined _XBOX_ONE - pack = new DLCPack(ContentData.wszDisplayName,ContentData.wszProductID,dwLicenceMask); -#else - pack = new DLCPack(ContentData.wszDisplayName,dwLicenceMask); -#endif - pack->SetDLCMountIndex(app.m_iTotalDLCInstalled); - pack->SetDLCDeviceID(ContentData.DeviceID); - app.m_dlcManager.addPack(pack); - - app.HandleDLC(pack); - - if(pack->getDLCItemsCount(DLCManager::e_DLCType_Texture) > 0) - { - Minecraft::GetInstance()->skins->addTexturePackFromDLC(pack, pack->GetPackId() ); - } - } - else - { - app.DebugPrintf("Pack \"%ls\" is already installed. Updating license to %d\n", CONTENT_DATA_DISPLAY_NAME(ContentData), dwLicenceMask); - - pack->SetDLCMountIndex(app.m_iTotalDLCInstalled); - pack->SetDLCDeviceID(ContentData.DeviceID); - pack->updateLicenseMask(dwLicenceMask); - } - - StorageManager.UnmountInstalledDLC(); - } - ++app.m_iTotalDLCInstalled; - app.MountNextDLC(iPad); - -#endif // __PSVITA__ - return 0; -} -#undef CONTENT_DATA_DISPLAY_NAME - -// void CMinecraftApp::InstallDefaultCape() -// { -// if(!m_bDefaultCapeInstallAttempted) -// { -// // we only attempt to install the cape once per launch of the game -// m_bDefaultCapeInstallAttempted=true; -// -// wstring wTemp=L"Default_Cape.png"; -// bool bRes=app.IsFileInMemoryTextures(wTemp); -// // if the file is not already in the memory textures, then read it from TMS -// if(!bRes) -// { -// BYTE* pBuffer = nullptr; -// DWORD dwSize=0; -// // 4J-PB - out for now for DaveK so he doesn't get the birthday cape -// #ifdef _CONTENT_PACKAGE -// C4JStorage::ETMSStatus eTMSStatus; -// eTMSStatus=StorageManager.ReadTMSFile(ProfileManager.GetPrimaryPad(),C4JStorage::eGlobalStorage_Title,C4JStorage::eTMS_FileType_Graphic, L"Default_Cape.png",&pBuffer, &dwSize); -// if(eTMSStatus==C4JStorage::ETMSStatus_Idle) -// { -// app.AddMemoryTextureFile(wTemp,pBuffer,dwSize); -// } -// #endif -// } -// } -// } - -void CMinecraftApp::HandleDLC(DLCPack *pack) -{ - DWORD dwFilesProcessed = 0; -#ifndef _XBOX -#if defined(__PS3__) || defined(__ORBIS__) || defined(_WINDOWS64) || defined (__PSVITA__) - std::vector dlcFilenames; -#elif defined _DURANGO - std::vector dlcFilenames; -#endif - StorageManager.GetMountedDLCFileList("DLCDrive", dlcFilenames); -#ifdef __ORBIS__ - // 4J Stu - I don't know why we handle more than one file here any more, however this doesn't seem to work with the PS4 patches - if(dlcFilenames.size() > 0) m_dlcManager.readDLCDataFile(dwFilesProcessed, dlcFilenames[0], pack); -#else - for(size_t i=0; i(qwTicksPerSec.QuadPart); - - // Save the start time - QueryPerformanceCounter( &m_Time.qwTime ); - - // Zero out the elapsed and total time - m_Time.qwAppTime.QuadPart = 0; - m_Time.fAppTime = 0.0f; - m_Time.fElapsedTime = 0.0f; -} - -//------------------------------------------------------------------------------------- -// Name: UpdateTime() -// Desc: Updates the elapsed time since our last frame. -//------------------------------------------------------------------------------------- -void CMinecraftApp::UpdateTime() -{ - LARGE_INTEGER qwNewTime; - LARGE_INTEGER qwDeltaTime; - - QueryPerformanceCounter( &qwNewTime ); - qwDeltaTime.QuadPart = qwNewTime.QuadPart - m_Time.qwTime.QuadPart; - - m_Time.qwAppTime.QuadPart += qwDeltaTime.QuadPart; - m_Time.qwTime.QuadPart = qwNewTime.QuadPart; - - m_Time.fElapsedTime = m_Time.fSecsPerTick * static_cast(qwDeltaTime.QuadPart); - m_Time.fAppTime = m_Time.fSecsPerTick * static_cast(m_Time.qwAppTime.QuadPart); -} - -bool CMinecraftApp::isXuidNotch(PlayerUID xuid) -{ - if(m_xuidNotch != INVALID_XUID && xuid != INVALID_XUID) - { - return ProfileManager.AreXUIDSEqual(xuid, m_xuidNotch) == TRUE; - } - return false; -} - -bool CMinecraftApp::isXuidDeadmau5(PlayerUID xuid) -{ - auto it = MojangData.find(xuid); // 4J Stu - The .at and [] accessors insert elements if they don't exist - if (it != MojangData.end() ) - { - MOJANG_DATA *pMojangData=MojangData[xuid]; - if(pMojangData && pMojangData->eXuid==eXUID_Deadmau5) - { - return true; - } - } - - return false; -} - -void CMinecraftApp::AddMemoryTextureFile(const wstring &wName,PBYTE pbData,DWORD dwBytes) -{ - EnterCriticalSection(&csMemFilesLock); - // check it's not already in - PMEMDATA pData=nullptr; - auto it = m_MEM_Files.find(wName); - if(it != m_MEM_Files.end()) - { -#ifndef _CONTENT_PACKAGE - wprintf(L"Incrementing the memory texture file count for %ls\n", wName.c_str()); -#endif - pData = (*it).second; - - if(pData->dwBytes == 0 && dwBytes != 0) - { - // This should never be nullptr if dwBytes is 0 - if(pData->pbData!=nullptr) delete [] pData->pbData; - - pData->pbData=pbData; - pData->dwBytes=dwBytes; - } - - ++pData->ucRefCount; - LeaveCriticalSection(&csMemFilesLock); - return; - } - -#ifndef _CONTENT_PACKAGE - //wprintf(L"Adding the memory texture file data for %ls\n", wName.c_str()); -#endif - // this is a texture (png) file - - // add this texture to the list of memory texture files - it will then be picked up by the level renderer's AddEntity - - pData = (PMEMDATA)new BYTE[sizeof(MEMDATA)]; - ZeroMemory( pData, sizeof(MEMDATA) ); - pData->pbData=pbData; - pData->dwBytes=dwBytes; - pData->ucRefCount = 1; - - // use the xuid to access the skin data - m_MEM_Files[wName]=pData; - - LeaveCriticalSection(&csMemFilesLock); -} - -void CMinecraftApp::RemoveMemoryTextureFile(const wstring &wName) -{ - EnterCriticalSection(&csMemFilesLock); - - auto it = m_MEM_Files.find(wName); - if(it != m_MEM_Files.end()) - { -#ifndef _CONTENT_PACKAGE - wprintf(L"Decrementing the memory texture file count for %ls\n", wName.c_str()); -#endif - PMEMDATA pData = (*it).second; - --pData->ucRefCount; - if(pData->ucRefCount <= 0) - { -#ifndef _CONTENT_PACKAGE - wprintf(L"Erasing the memory texture file data for %ls\n", wName.c_str()); -#endif - delete [] pData; - m_MEM_Files.erase(wName); - } - } - LeaveCriticalSection(&csMemFilesLock); -} - -bool CMinecraftApp::DefaultCapeExists() -{ - wstring wTex=L"Special_Cape.png"; - bool val = false; - - EnterCriticalSection(&csMemFilesLock); - auto it = m_MEM_Files.find(wTex); - if(it != m_MEM_Files.end()) val = true; - LeaveCriticalSection(&csMemFilesLock); - - return val; -} - -bool CMinecraftApp::IsFileInMemoryTextures(const wstring &wName) -{ - bool val = false; - - EnterCriticalSection(&csMemFilesLock); - auto it = m_MEM_Files.find(wName); - if(it != m_MEM_Files.end()) val = true; - LeaveCriticalSection(&csMemFilesLock); - - return val; -} - -void CMinecraftApp::GetMemFileDetails(const wstring &wName,PBYTE *ppbData,DWORD *pdwBytes) -{ - EnterCriticalSection(&csMemFilesLock); - auto it = m_MEM_Files.find(wName); - if(it != m_MEM_Files.end()) - { - PMEMDATA pData = (*it).second; - *ppbData=pData->pbData; - *pdwBytes=pData->dwBytes; - } - LeaveCriticalSection(&csMemFilesLock); -} - -void CMinecraftApp::AddMemoryTPDFile(int iConfig,PBYTE pbData,DWORD dwBytes) -{ - EnterCriticalSection(&csMemTPDLock); - // check it's not already in - PMEMDATA pData=nullptr; - auto it = m_MEM_TPD.find(iConfig); - if(it == m_MEM_TPD.end()) - { - pData = (PMEMDATA)new BYTE[sizeof(MEMDATA)]; - ZeroMemory( pData, sizeof(MEMDATA) ); - pData->pbData=pbData; - pData->dwBytes=dwBytes; - pData->ucRefCount = 1; - - m_MEM_TPD[iConfig]=pData; - } - - LeaveCriticalSection(&csMemTPDLock); -} - -void CMinecraftApp::RemoveMemoryTPDFile(int iConfig) -{ - EnterCriticalSection(&csMemTPDLock); - // check it's not already in - PMEMDATA pData=nullptr; - auto it = m_MEM_TPD.find(iConfig); - if(it != m_MEM_TPD.end()) - { - pData=m_MEM_TPD[iConfig]; - delete [] pData; - m_MEM_TPD.erase(iConfig); - } - - LeaveCriticalSection(&csMemTPDLock); -} - -#ifdef _XBOX -int CMinecraftApp::GetTPConfigVal(WCHAR *pwchDataFile) -{ - DLC_INFO *pDLCInfo=nullptr; - // run through the DLC info to find the right texture pack/mash-up pack - for(unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i) - { - ULONGLONG ull=app.GetDLCInfoTexturesFullOffer(i); - pDLCInfo=app.GetDLCInfoForFullOfferID(ull); - - if(wcscmp(pwchDataFile,pDLCInfo->wchDataFile)==0) - { - return pDLCInfo->iConfig; - } - } - - return -1; -} -#elif defined _XBOX_ONE -int CMinecraftApp::GetTPConfigVal(WCHAR *pwchDataFile) -{ - DLC_INFO *pDLCInfo=nullptr; - // run through the DLC info to find the right texture pack/mash-up pack - for(unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i) - { - pDLCInfo=app.GetDLCInfoForFullOfferID((WCHAR *)app.GetDLCInfoTexturesFullOffer(i).c_str()); - - if(wcscmp(pwchDataFile,pDLCInfo->wchDataFile)==0) - { - return pDLCInfo->iConfig; - } - } - - return -1; -} -#elif defined _WINDOWS64 -int CMinecraftApp::GetTPConfigVal(WCHAR *pwchDataFile) -{ - return -1; -} -#endif -bool CMinecraftApp::IsFileInTPD(int iConfig) -{ - bool val = false; - - EnterCriticalSection(&csMemTPDLock); - auto it = m_MEM_TPD.find(iConfig); - if(it != m_MEM_TPD.end()) val = true; - LeaveCriticalSection(&csMemTPDLock); - - return val; -} - -void CMinecraftApp::GetTPD(int iConfig,PBYTE *ppbData,DWORD *pdwBytes) -{ - EnterCriticalSection(&csMemTPDLock); - auto it = m_MEM_TPD.find(iConfig); - if(it != m_MEM_TPD.end()) - { - PMEMDATA pData = (*it).second; - *ppbData=pData->pbData; - *pdwBytes=pData->dwBytes; - } - LeaveCriticalSection(&csMemTPDLock); -} - - -// bool CMinecraftApp::UploadFileToGlobalStorage(int iQuadrant, C4JStorage::eGlobalStorage eStorageFacility, wstring *wsFile ) -// { -// bool bRes=false; -// #ifndef _CONTENT_PACKAGE -// // read the local file -// File gtsFile( wsFile->c_str() ); -// -// int64_t fileSize = gtsFile.length(); -// -// if(fileSize!=0) -// { -// FileInputStream fis(gtsFile); -// byteArray ba((int)fileSize); -// fis.read(ba); -// fis.close(); -// -// bRes=StorageManager.WriteTMSFile(iQuadrant,eStorageFacility,(WCHAR *)wsFile->c_str(),ba.data, ba.length); -// -// } -// #endif -// return bRes; -// } - - - - - - -void CMinecraftApp::StoreLaunchData() -{ - -} - -void CMinecraftApp::ExitGame() -{ -} - -// Invites - -void CMinecraftApp::ProcessInvite(DWORD dwUserIndex, DWORD dwLocalUsersMask, const INVITE_INFO * pInviteInfo) -{ - m_InviteData.dwUserIndex=dwUserIndex; - m_InviteData.dwLocalUsersMask=dwLocalUsersMask; - m_InviteData.pInviteInfo=pInviteInfo; - //memcpy(&m_InviteData,pJoinData,sizeof(JoinFromInviteData)); - SetAction(dwUserIndex,eAppAction_ExitAndJoinFromInvite); -} - -int CMinecraftApp::ExitAndJoinFromInvite(void *pParam,int iPad,C4JStorage::EMessageResult result) -{ - CMinecraftApp* pApp = static_cast(pParam); - //Minecraft *pMinecraft=Minecraft::GetInstance(); - - // buttons are swapped on this menu - if(result==C4JStorage::EMessage_ResultDecline) - { - pApp->SetAction(iPad,eAppAction_ExitAndJoinFromInviteConfirmed); - } - - return 0; -} - -int CMinecraftApp::ExitAndJoinFromInviteSaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) -{ - CMinecraftApp *pClass = static_cast(pParam); - // Exit with or without saving - // Decline means save in this dialog - if(result==C4JStorage::EMessage_ResultDecline || result==C4JStorage::EMessage_ResultThirdOption) - { - if( result==C4JStorage::EMessage_ResultDecline ) // Save - { - // Check they have the full texture pack if they are using one - // 4J-PB - Is the player trying to save but they are using a trial texturepack ? - if(!Minecraft::GetInstance()->skins->isUsingDefaultSkin()) - { - TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); - - DLCPack * pDLCPack=tPack->getDLCPack(); - if(!pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) - { - // upsell - // get the dlc texture pack - -#ifdef _XBOX - DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; - ULONGLONG ullOfferID_Full; - app.GetDLCFullOfferIDForPackID(pDLCTexPack->getDLCParentPackId(),&ullOfferID_Full); - - // tell sentient about the upsell of the full version of the skin pack - TelemetryManager->RecordUpsellPresented(iPad, eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF); -#endif - - UINT uiIDA[2]; - uiIDA[0]=IDS_CONFIRM_OK; - uiIDA[1]=IDS_CONFIRM_CANCEL; - - // Give the player a warning about the trial version of the texture pack - ui.RequestErrorMessage(IDS_WARNING_DLC_TRIALTEXTUREPACK_TITLE, IDS_WARNING_DLC_TRIALTEXTUREPACK_TEXT, uiIDA, 2, iPad,&CMinecraftApp::WarningTrialTexturePackReturned,pClass); - - return S_OK; - } - } -#ifndef _XBOX_ONE - // does the save exist? - bool bSaveExists; - StorageManager.DoesSaveExist(&bSaveExists); - // 4J-PB - we check if the save exists inside the libs - // we need to ask if they are sure they want to overwrite the existing game - if(bSaveExists) - { - UINT uiIDA[2]; - uiIDA[0]=IDS_CONFIRM_CANCEL; - uiIDA[1]=IDS_CONFIRM_OK; - ui.RequestErrorMessage(IDS_TITLE_SAVE_GAME, IDS_CONFIRM_SAVE_GAME, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::ExitAndJoinFromInviteAndSaveReturned,pClass); - return 0; - } - else -#endif - { -#if defined(_XBOX_ONE) || defined(__ORBIS__) - StorageManager.SetSaveDisabled(false); -#endif - MinecraftServer::getInstance()->setSaveOnExit( true ); - } - } - else - { - // been a few requests for a confirm on exit without saving - UINT uiIDA[2]; - uiIDA[0]=IDS_CONFIRM_CANCEL; - uiIDA[1]=IDS_CONFIRM_OK; - ui.RequestErrorMessage(IDS_TITLE_DECLINE_SAVE_GAME, IDS_CONFIRM_DECLINE_SAVE_GAME, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::ExitAndJoinFromInviteDeclineSaveReturned,pClass); - return 0; - } - - app.SetAction(ProfileManager.GetPrimaryPad(),eAppAction_ExitAndJoinFromInviteConfirmed); - } - return 0; -} - -int CMinecraftApp::WarningTrialTexturePackReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) -{ - // 4J Stu - I added this in when fixing an X1 bug. We should probably add this as well but I don't have time to test all platforms atm -#if 0 //defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) - if(result==C4JStorage::EMessage_ResultAccept) - { - if(!ProfileManager.IsSignedInLive(iPad)) - { - // you're not signed in to PSN! - - } - else - { - // 4J-PB - need to check this user can access the store - bool bContentRestricted; - ProfileManager.GetChatAndContentRestrictions(iPad,true,nullptr,&bContentRestricted,nullptr); - if(bContentRestricted) - { - UINT uiIDA[1]; - uiIDA[0]=IDS_CONFIRM_OK; - ui.RequestAlertMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, iPad); - } - else - { - // need to get info on the pack to see if the user has already downloaded it - TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); - DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; - - // retrieve the store name for the skin pack - DLCPack *pDLCPack=pDLCTexPack->getDLCInfoParentPack();//tPack->getDLCPack(); - const char *pchPackName=wstringtofilename(pDLCPack->getName()); - app.DebugPrintf("Texture Pack - %s\n",pchPackName); - SONYDLC *pSONYDLCInfo=app.GetSONYDLCInfo((char *)pchPackName); - - if(pSONYDLCInfo!=nullptr) - { - char chName[42]; - char chSkuID[SCE_NP_COMMERCE2_SKU_ID_LEN]; - - memset(chSkuID,0,SCE_NP_COMMERCE2_SKU_ID_LEN); - // find the info on the skin pack - // we have to retrieve the skuid from the store info, it can't be hardcoded since Sony may change it. - // So we assume the first sku for the product is the one we want -#ifdef __ORBIS__ - sprintf(chName,"%s",pSONYDLCInfo->chDLCKeyname); -#else - sprintf(chName,"%s-%s",app.GetCommerceCategory(),pSONYDLCInfo->chDLCKeyname); -#endif - app.GetDLCSkuIDFromProductList(chName,chSkuID); - // 4J-PB - need to check for an empty store -#if defined __ORBIS__ || defined __PSVITA__ || defined __PS3__ - if(app.CheckForEmptyStore(iPad)==false) -#endif - { - if(app.DLCAlreadyPurchased(chSkuID)) - { - app.DownloadAlreadyPurchased(chSkuID); - } - else - { - app.Checkout(chSkuID); - } - } - } - } - } - } -#endif // - -#ifdef _XBOX_ONE - if(result==C4JStorage::EMessage_ResultAccept) - { - if(ProfileManager.IsSignedIn(iPad)) - { - if (ProfileManager.IsSignedInLive(iPad)) - { - TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); - // get the dlc texture pack - DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; - - DLCPack *pDLCPack=pDLCTexPack->getDLCInfoParentPack(); - - DLC_INFO *pDLCInfo=app.GetDLCInfoForProductName((WCHAR *)pDLCPack->getName().c_str()); - - StorageManager.InstallOffer(1,(WCHAR *)pDLCInfo->wsProductId.c_str(),nullptr,nullptr); - - // the license change coming in when the offer has been installed will cause this scene to refresh - } - else - { - // 4J-JEV: Fix for XB1: #165863 - XR-074: Compliance: With no active network connection user is unable to convert from Trial to Full texture pack and is not messaged why. - UINT uiIDA[1] = { IDS_CONFIRM_OK }; - ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_XBOXLIVE_NOTIFICATION, uiIDA, 1, iPad); - } - } - } - -#endif -#ifdef _XBOX - - CMinecraftApp* pClass = (CMinecraftApp*)pParam; - - TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); - // get the dlc texture pack - DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; - ULONGLONG ullIndexA[1]; - - // Need to get the parent packs id, since this may be one of many child packs with their own ids - app.GetDLCFullOfferIDForPackID(pDLCTexPack->getDLCParentPackId(),&ullIndexA[0]); - - if(result==C4JStorage::EMessage_ResultAccept) - { - if(ProfileManager.IsSignedIn(iPad)) - { - // need to allow downloads here, or the player would need to quit the game to let the download of a texture pack happen. This might affect the network traffic, since the download could take all the bandwidth... - XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); - - StorageManager.InstallOffer(1,ullIndexA,nullptr,nullptr); - } - } - else - { - TelemetryManager->RecordUpsellResponded(iPad, eSet_UpsellID_Texture_DLC, ( ullIndexA[0] & 0xFFFFFFFF ), eSen_UpsellOutcome_Declined); - } -#endif - return 0; -} - -int CMinecraftApp::ExitAndJoinFromInviteAndSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) -{ - //CMinecraftApp* pClass = (CMinecraftApp*)pParam; - - // results switched for this dialog - if(result==C4JStorage::EMessage_ResultDecline) - { - INT saveOrCheckpointId = 0; - - // Check they have the full texture pack if they are using one - // 4J-PB - Is the player trying to save but they are using a trial texturepack ? - if(!Minecraft::GetInstance()->skins->isUsingDefaultSkin()) - { - TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); - - DLCPack * pDLCPack=tPack->getDLCPack(); - if(!pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) - { - // upsell - // get the dlc texture pack - -#ifdef _XBOX - DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; - ULONGLONG ullOfferID_Full; - app.GetDLCFullOfferIDForPackID(pDLCTexPack->getDLCParentPackId(),&ullOfferID_Full); - - // tell sentient about the upsell of the full version of the skin pack - TelemetryManager->RecordUpsellPresented(iPad, eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF); -#endif - - UINT uiIDA[2]; - uiIDA[0]=IDS_CONFIRM_OK; - uiIDA[1]=IDS_CONFIRM_CANCEL; - - // Give the player a warning about the trial version of the texture pack - ui.RequestErrorMessage(IDS_WARNING_DLC_TRIALTEXTUREPACK_TITLE, IDS_WARNING_DLC_TRIALTEXTUREPACK_TEXT, uiIDA, 2, iPad,&CMinecraftApp::WarningTrialTexturePackReturned,nullptr); - - return S_OK; - } - } - //bool validSave = StorageManager.GetSaveUniqueNumber(&saveOrCheckpointId); - //SentientManager.RecordLevelSaveOrCheckpoint(ProfileManager.GetPrimaryPad(), saveOrCheckpointId); - MinecraftServer::getInstance()->setSaveOnExit( true ); - // flag a app action of exit and join game from invite - app.SetAction(iPad,eAppAction_ExitAndJoinFromInviteConfirmed); - } - return 0; -} - -int CMinecraftApp::ExitAndJoinFromInviteDeclineSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) -{ - // results switched for this dialog - if(result==C4JStorage::EMessage_ResultDecline) - { -#if defined(_XBOX_ONE) || defined(__ORBIS__) - StorageManager.SetSaveDisabled(false); -#endif - MinecraftServer::getInstance()->setSaveOnExit( false ); - // flag a app action of exit and join game from invite - app.SetAction(iPad,eAppAction_ExitAndJoinFromInviteConfirmed); - } - return 0; -} - -////////////////////////////////////////////////////////////////////////// -// -// FatalLoadError -// -// This is called when we can't load one of the required files at startup -// It tends to mean the files have been corrupted. -// We have to assume that we've not been able to load the text for the game. -// -////////////////////////////////////////////////////////////////////////// -void CMinecraftApp::FatalLoadError() -{ - -} - -TIPSTRUCT CMinecraftApp::m_GameTipA[MAX_TIPS_GAMETIP]= -{ - { 0, IDS_TIPS_GAMETIP_1}, - { 0, IDS_TIPS_GAMETIP_2}, - { 0, IDS_TIPS_GAMETIP_3}, - { 0, IDS_TIPS_GAMETIP_4}, - { 0, IDS_TIPS_GAMETIP_5}, - { 0, IDS_TIPS_GAMETIP_6}, - { 0, IDS_TIPS_GAMETIP_7}, - { 0, IDS_TIPS_GAMETIP_8}, - { 0, IDS_TIPS_GAMETIP_9}, - { 0, IDS_TIPS_GAMETIP_10}, - { 0, IDS_TIPS_GAMETIP_11}, - { 0, IDS_TIPS_GAMETIP_12}, - { 0, IDS_TIPS_GAMETIP_13}, - { 0, IDS_TIPS_GAMETIP_14}, - { 0, IDS_TIPS_GAMETIP_15}, - { 0, IDS_TIPS_GAMETIP_16}, - { 0, IDS_TIPS_GAMETIP_17}, - { 0, IDS_TIPS_GAMETIP_18}, - { 0, IDS_TIPS_GAMETIP_19}, - { 0, IDS_TIPS_GAMETIP_20}, - { 0, IDS_TIPS_GAMETIP_21}, - { 0, IDS_TIPS_GAMETIP_22}, - { 0, IDS_TIPS_GAMETIP_23}, - { 0, IDS_TIPS_GAMETIP_24}, - { 0, IDS_TIPS_GAMETIP_25}, - { 0, IDS_TIPS_GAMETIP_26}, - { 0, IDS_TIPS_GAMETIP_27}, - { 0, IDS_TIPS_GAMETIP_28}, - { 0, IDS_TIPS_GAMETIP_29}, - { 0, IDS_TIPS_GAMETIP_30}, - { 0, IDS_TIPS_GAMETIP_31}, - { 0, IDS_TIPS_GAMETIP_32}, - { 0, IDS_TIPS_GAMETIP_33}, - { 0, IDS_TIPS_GAMETIP_34}, - { 0, IDS_TIPS_GAMETIP_35}, - { 0, IDS_TIPS_GAMETIP_36}, - { 0, IDS_TIPS_GAMETIP_37}, - { 0, IDS_TIPS_GAMETIP_38}, - { 0, IDS_TIPS_GAMETIP_39}, - { 0, IDS_TIPS_GAMETIP_40}, - { 0, IDS_TIPS_GAMETIP_41}, - { 0, IDS_TIPS_GAMETIP_42}, - { 0, IDS_TIPS_GAMETIP_43}, - { 0, IDS_TIPS_GAMETIP_44}, - { 0, IDS_TIPS_GAMETIP_45}, - { 0, IDS_TIPS_GAMETIP_46}, - { 0, IDS_TIPS_GAMETIP_47}, - { 0, IDS_TIPS_GAMETIP_48}, - { 0, IDS_TIPS_GAMETIP_49}, - { 0, IDS_TIPS_GAMETIP_50}, -}; - -TIPSTRUCT CMinecraftApp::m_TriviaTipA[MAX_TIPS_TRIVIATIP]= -{ - { 0, IDS_TIPS_TRIVIA_1}, - { 0, IDS_TIPS_TRIVIA_2}, - { 0, IDS_TIPS_TRIVIA_3}, - { 0, IDS_TIPS_TRIVIA_4}, - { 0, IDS_TIPS_TRIVIA_5}, - { 0, IDS_TIPS_TRIVIA_6}, - { 0, IDS_TIPS_TRIVIA_7}, - { 0, IDS_TIPS_TRIVIA_8}, - { 0, IDS_TIPS_TRIVIA_9}, - { 0, IDS_TIPS_TRIVIA_10}, - { 0, IDS_TIPS_TRIVIA_11}, - { 0, IDS_TIPS_TRIVIA_12}, - { 0, IDS_TIPS_TRIVIA_13}, - { 0, IDS_TIPS_TRIVIA_14}, - { 0, IDS_TIPS_TRIVIA_15}, - { 0, IDS_TIPS_TRIVIA_16}, - { 0, IDS_TIPS_TRIVIA_17}, - { 0, IDS_TIPS_TRIVIA_18}, - { 0, IDS_TIPS_TRIVIA_19}, - { 0, IDS_TIPS_TRIVIA_20}, -}; - -Random *CMinecraftApp::TipRandom = new Random(); - -int CMinecraftApp::TipsSortFunction(const void* a, const void* b) -{ - return ((TIPSTRUCT*)a)->iSortValue - ((TIPSTRUCT*)b)->iSortValue; -} - -void CMinecraftApp::InitialiseTips() -{ - // We'll randomise the tips at start up based on their priority - - ZeroMemory(m_TipIDA,sizeof(UINT)*MAX_TIPS_GAMETIP+MAX_TIPS_TRIVIATIP); - - // Make the first tip tell you that you can play splitscreen in HD modes if you are in SD - if(!RenderManager.IsHiDef()) - { - m_GameTipA[0].uiStringID=IDS_TIPS_GAMETIP_0; - } - // randomise then quicksort - // going to leave the multiplayer tip so it is always first - - // Only randomise the content package build -#ifdef _CONTENT_PACKAGE - - for(int i=1;inextInt(); - } - qsort( &m_GameTipA[1], MAX_TIPS_GAMETIP-1, sizeof(TIPSTRUCT), TipsSortFunction ); -#endif - - for(int i=0;inextInt(); - } - qsort( m_TriviaTipA, MAX_TIPS_TRIVIATIP, sizeof(TIPSTRUCT), TipsSortFunction ); - - - int iCurrentGameTip=0; - int iCurrentTriviaTip=0; - - for(int i=0;iskins->getSelected()->getColourTable()->getColour(colour); -} - -int CMinecraftApp::GetHTMLFontSize(EHTMLFontSize size) -{ - return s_iHTMLFontSizesA[size]; -} - -wstring CMinecraftApp::FormatHTMLString(int iPad, const wstring &desc, int shadowColour /*= 0xFFFFFFFF*/, bool override) -{ - wstring text(desc); - - wchar_t replacements[64]; - // We will also insert line breaks here as couldn't figure out how to get them to come through from strings.resx ! - text = replaceAll(text, L"{*B*}", L"
" ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_T1)); - text = replaceAll(text, L"{*T1*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_T2)); - text = replaceAll(text, L"{*T2*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_T3)); - text = replaceAll(text, L"{*T3*}", replacements ); // for How To Play - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_Black)); - text = replaceAll(text, L"{*ETB*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_White)); - text = replaceAll(text, L"{*ETW*}", replacements ); - text = replaceAll(text, L"{*EF*}", L"" ); - - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_0), shadowColour); - text = replaceAll(text, L"{*C0*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_1), shadowColour); - text = replaceAll(text, L"{*C1*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_2), shadowColour); - text = replaceAll(text, L"{*C2*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_3), shadowColour); - text = replaceAll(text, L"{*C3*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_4), shadowColour); - text = replaceAll(text, L"{*C4*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_5), shadowColour); - text = replaceAll(text, L"{*C5*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_6), shadowColour); - text = replaceAll(text, L"{*C6*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_7), shadowColour); - text = replaceAll(text, L"{*C7*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_8), shadowColour); - text = replaceAll(text, L"{*C8*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_9), shadowColour); - text = replaceAll(text, L"{*C9*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_a), shadowColour); - text = replaceAll(text, L"{*CA*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_b), shadowColour); - text = replaceAll(text, L"{*CB*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_c), shadowColour); - text = replaceAll(text, L"{*CC*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_d), shadowColour); - text = replaceAll(text, L"{*CD*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_e), shadowColour); - text = replaceAll(text, L"{*CE*}", replacements ); - swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_f), shadowColour); - text = replaceAll(text, L"{*CF*}", replacements ); - - // Swap for southpaw. - if ( app.GetGameSettings(iPad,eGameSetting_ControlSouthPaw) ) - { - text = replaceAll(text, L"{*CONTROLLER_ACTION_MOVE*}", GetActionReplacement(iPad,MINECRAFT_ACTION_LOOK_RIGHT ) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_LOOK*}", GetActionReplacement(iPad,MINECRAFT_ACTION_RIGHT ) ); - - text = replaceAll(text, L"{*CONTROLLER_MENU_NAVIGATE*}", GetVKReplacement(VK_PAD_RTHUMB_LEFT) ); - } - else // Normal right handed. - { - text = replaceAll(text, L"{*CONTROLLER_ACTION_MOVE*}", GetActionReplacement(iPad,MINECRAFT_ACTION_RIGHT ) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_LOOK*}", GetActionReplacement(iPad,MINECRAFT_ACTION_LOOK_RIGHT ) ); - - text = replaceAll(text, L"{*CONTROLLER_MENU_NAVIGATE*}", GetVKReplacement(VK_PAD_LTHUMB_LEFT) ); - } - - text = replaceAll(text, L"{*CONTROLLER_ACTION_JUMP*}", GetActionReplacement(iPad,MINECRAFT_ACTION_JUMP ) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_SNEAK*}", GetActionReplacement(iPad,MINECRAFT_ACTION_SNEAK_TOGGLE ) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_USE*}", GetActionReplacement(iPad,MINECRAFT_ACTION_USE ) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_ACTION*}", GetActionReplacement(iPad,MINECRAFT_ACTION_ACTION ) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_LEFT_SCROLL*}", GetActionReplacement(iPad,MINECRAFT_ACTION_LEFT_SCROLL ) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_RIGHT_SCROLL*}", GetActionReplacement(iPad,MINECRAFT_ACTION_RIGHT_SCROLL ) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_INVENTORY*}", GetActionReplacement(iPad,MINECRAFT_ACTION_INVENTORY ) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_CRAFTING*}", GetActionReplacement(iPad,MINECRAFT_ACTION_CRAFTING ) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_DROP*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DROP ) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_CAMERA*}", GetActionReplacement(iPad,MINECRAFT_ACTION_RENDER_THIRD_PERSON ) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_MENU_PAGEDOWN*}", GetActionReplacement(iPad,ACTION_MENU_PAGEDOWN ) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_DISMOUNT*}", GetActionReplacement(iPad,MINECRAFT_ACTION_SNEAK_TOGGLE ) ); - text = replaceAll(text, L"{*CONTROLLER_VK_A*}", GetVKReplacement(VK_PAD_A) ); - text = replaceAll(text, L"{*CONTROLLER_VK_B*}", GetVKReplacement(VK_PAD_B) ); - text = replaceAll(text, L"{*CONTROLLER_VK_X*}", GetVKReplacement(VK_PAD_X) ); - text = replaceAll(text, L"{*CONTROLLER_VK_Y*}", GetVKReplacement(VK_PAD_Y, override) ); - text = replaceAll(text, L"{*CONTROLLER_VK_LB*}", GetVKReplacement(VK_PAD_LSHOULDER) ); - text = replaceAll(text, L"{*CONTROLLER_VK_RB*}", GetVKReplacement(VK_PAD_RSHOULDER) ); - text = replaceAll(text, L"{*CONTROLLER_VK_LS*}", GetVKReplacement(VK_PAD_LTHUMB_UP) ); - text = replaceAll(text, L"{*CONTROLLER_VK_RS*}", GetVKReplacement(VK_PAD_RTHUMB_UP) ); - text = replaceAll(text, L"{*CONTROLLER_VK_LT*}", GetVKReplacement(VK_PAD_LTRIGGER) ); - text = replaceAll(text, L"{*CONTROLLER_VK_RT*}", GetVKReplacement(VK_PAD_RTRIGGER) ); - text = replaceAll(text, L"{*ICON_SHANK_01*}", GetIconReplacement(XZP_ICON_SHANK_01) ); - text = replaceAll(text, L"{*ICON_SHANK_03*}", GetIconReplacement(XZP_ICON_SHANK_03) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_DPAD_UP*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DPAD_UP ) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_DPAD_DOWN*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DPAD_DOWN ) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_DPAD_RIGHT*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DPAD_RIGHT ) ); - text = replaceAll(text, L"{*CONTROLLER_ACTION_DPAD_LEFT*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DPAD_LEFT ) ); -#if defined _XBOX_ONE || defined __PSVITA__ - text = replaceAll(text, L"{*CONTROLLER_VK_START*}", GetVKReplacement(VK_PAD_START ) ); - text = replaceAll(text, L"{*CONTROLLER_VK_BACK*}", GetVKReplacement(VK_PAD_BACK ) ); -#endif - -#ifdef _XBOX - wstring imageRoot = L""; - - Minecraft *pMinecraft = Minecraft::GetInstance(); - imageRoot = pMinecraft->skins->getSelected()->getXuiRootPath(); - - text = replaceAll(text, L"{*IMAGEROOT*}", imageRoot); -#endif // _XBOX - - // Fix for #8903 - UI: Localization: KOR/JPN/CHT: Button Icons are rendered with padding space, which looks no good - DWORD dwLanguage = XGetLanguage( ); - switch(dwLanguage) - { - case XC_LANGUAGE_KOREAN: - case XC_LANGUAGE_JAPANESE: - case XC_LANGUAGE_TCHINESE: - text = replaceAll(text, L" ", L"" ); - break; - } - - return text; -} - -//found list of html escapes at https://stackoverflow.com/questions/7381974/which-characters-need-to-be-escaped-in-html -wstring CMinecraftApp::EscapeHTMLString(const wstring& desc) -{ - static std::unordered_map replacementMap = { - {L'&', L"&"}, - {L'<', L"<"}, - {L'>', L">"}, - {L'\'', L"\u2019"}, - }; - - wstring finalString = L""; - for (int i = 0; i < desc.size(); i++) { - wchar_t _char = desc[i]; - auto it = replacementMap.find(_char); - - if (it != replacementMap.end()) finalString += it->second; - else finalString += _char; - } - - return finalString; -} - -eMinecraftColour GetColorFromCode(wchar_t _char) { - switch (_char) { - case L'0': return eHTMLColor_0; - case L'1': return eHTMLColor_1; - case L'2': return eHTMLColor_2; - case L'3': return eHTMLColor_3; - case L'4': return eHTMLColor_4; - case L'5': return eHTMLColor_5; - case L'6': return eHTMLColor_6; - case L'7': return eHTMLColor_7; - case L'8': return eHTMLColor_8; - case L'9': return eHTMLColor_9; - case L'a': return eHTMLColor_a; - case L'b': return eHTMLColor_b; - case L'c': return eHTMLColor_c; - case L'd': return eHTMLColor_d; - case L'e': return eHTMLColor_e; - case L'f': return eHTMLColor_f; - default: return eMinecraftColour_NOT_SET; - } -} - -wstring CMinecraftApp::FormatColoredString(const wstring& string) { - static constexpr std::wstring_view colorFormatString = L""; - - wstring result; - - bool fontOpen = false; - bool italicOpen = false; - - auto CloseItalic = [&]() { - if (italicOpen) { - result += L""; - italicOpen = false; - } - }; - - auto CloseFont = [&]() { - if (fontOpen) { - result += L""; - fontOpen = false; - } - }; - - wchar_t buffer[64]; - - for (size_t i = 0; i < string.length(); ++i) { - if (string[i] == L'\u00A7' && i + 1 < string.length()) { - wchar_t code = towlower(string[i + 1]); - - if (GetColorFromCode(code) != eMinecraftColour_NOT_SET) { - bool restoreItalic = italicOpen; - - CloseItalic(); - CloseFont(); - - swprintf(buffer, _countof(buffer), colorFormatString.data(), GetHTMLColour(GetColorFromCode(code))); - - result += buffer; - fontOpen = true; - - if (restoreItalic) { - result += L""; - italicOpen = true; - } - - ++i; - continue; - } - - if (code == L'o') { - if (!italicOpen) { - result += L""; - italicOpen = true; - } - - ++i; - continue; - } - - if (code == L'r') { - CloseItalic(); - CloseFont(); - - ++i; - continue; - } - } - - result += string[i]; - } - - CloseItalic(); - CloseFont(); - - return result; -} - -wstring CMinecraftApp::GetActionReplacement(int iPad, unsigned char ucAction) -{ - unsigned int input = InputManager.GetGameJoypadMaps(InputManager.GetJoypadMapVal(iPad) ,ucAction); - -#ifdef _XBOX - switch(input) - { - case _360_JOY_BUTTON_A: - return app.GetString( IDS_CONTROLLER_A ); - case _360_JOY_BUTTON_B: - return app.GetString( IDS_CONTROLLER_B ); - case _360_JOY_BUTTON_X: - return app.GetString( IDS_CONTROLLER_X ); - case _360_JOY_BUTTON_Y: - return app.GetString( IDS_CONTROLLER_Y ); - case _360_JOY_BUTTON_LSTICK_UP: - case _360_JOY_BUTTON_LSTICK_DOWN: - case _360_JOY_BUTTON_LSTICK_LEFT: - case _360_JOY_BUTTON_LSTICK_RIGHT: - return app.GetString( IDS_CONTROLLER_LEFT_STICK ); - case _360_JOY_BUTTON_RSTICK_LEFT: - case _360_JOY_BUTTON_RSTICK_RIGHT: - case _360_JOY_BUTTON_RSTICK_UP: - case _360_JOY_BUTTON_RSTICK_DOWN: - return app.GetString( IDS_CONTROLLER_RIGHT_STICK ); - case _360_JOY_BUTTON_LT: - return app.GetString( IDS_CONTROLLER_LEFT_TRIGGER ); - case _360_JOY_BUTTON_RT: - return app.GetString( IDS_CONTROLLER_RIGHT_TRIGGER ); - case _360_JOY_BUTTON_RB: - return app.GetString( IDS_CONTROLLER_RIGHT_BUMPER ); - case _360_JOY_BUTTON_LB: - return app.GetString( IDS_CONTROLLER_LEFT_BUMPER ); - case _360_JOY_BUTTON_BACK: - return app.GetString( IDS_CONTROLLER_BACK ); - case _360_JOY_BUTTON_START: - return app.GetString( IDS_CONTROLLER_START ); - case _360_JOY_BUTTON_RTHUMB: - return app.GetString( IDS_CONTROLLER_RIGHT_THUMBSTICK ); - case _360_JOY_BUTTON_LTHUMB: - return app.GetString( IDS_CONTROLLER_LEFT_THUMBSTICK ); - case _360_JOY_BUTTON_DPAD_LEFT: - return app.GetString( IDS_CONTROLLER_DPAD_L ); - case _360_JOY_BUTTON_DPAD_RIGHT: - return app.GetString( IDS_CONTROLLER_DPAD_R ); - case _360_JOY_BUTTON_DPAD_UP: - return app.GetString( IDS_CONTROLLER_DPAD_U ); - case _360_JOY_BUTTON_DPAD_DOWN: - return app.GetString( IDS_CONTROLLER_DPAD_D ); - }; - return L""; -#else - wstring replacement = L""; - - // 4J Stu - Some of our actions can be mapped to multiple physical buttons, so replaces the switch that was here - if (input & _360_JOY_BUTTON_A) replacement = L"ButtonA"; - else if(input &_360_JOY_BUTTON_B) replacement = L"ButtonB"; - else if(input &_360_JOY_BUTTON_X) replacement = L"ButtonX"; - else if(input &_360_JOY_BUTTON_Y) replacement = L"ButtonY"; - else if( - (input &_360_JOY_BUTTON_LSTICK_UP) || - (input &_360_JOY_BUTTON_LSTICK_DOWN) || - (input &_360_JOY_BUTTON_LSTICK_LEFT) || - (input &_360_JOY_BUTTON_LSTICK_RIGHT) - ) - { - replacement = L"ButtonLeftStick"; - } - else if( - (input &_360_JOY_BUTTON_RSTICK_LEFT) || - (input &_360_JOY_BUTTON_RSTICK_RIGHT) || - (input &_360_JOY_BUTTON_RSTICK_UP) || - (input &_360_JOY_BUTTON_RSTICK_DOWN) - ) - { - replacement = L"ButtonRightStick"; - } - else if(input &_360_JOY_BUTTON_DPAD_LEFT) replacement = L"ButtonDpadL"; - else if(input &_360_JOY_BUTTON_DPAD_RIGHT) replacement = L"ButtonDpadR"; - else if(input &_360_JOY_BUTTON_DPAD_UP) replacement = L"ButtonDpadU"; - else if(input &_360_JOY_BUTTON_DPAD_DOWN) replacement = L"ButtonDpadD"; - else if(input &_360_JOY_BUTTON_LT) replacement = L"ButtonLeftTrigger"; - else if(input &_360_JOY_BUTTON_RT) replacement = L"ButtonRightTrigger"; - else if(input &_360_JOY_BUTTON_RB) replacement = L"ButtonRightBumper"; - else if(input &_360_JOY_BUTTON_LB) replacement = L"ButtonLeftBumper"; - else if(input &_360_JOY_BUTTON_BACK) replacement = L"ButtonBack"; - else if(input &_360_JOY_BUTTON_START) replacement = L"ButtonStart"; - else if(input &_360_JOY_BUTTON_RTHUMB) replacement = L"ButtonRS"; - else if(input &_360_JOY_BUTTON_LTHUMB) replacement = L"ButtonLS"; - - wchar_t string[128]; - -#ifdef __PS3__ - int size = 30; -#elif defined _WIN64 - int size = 45; - if(ui.getScreenHeight() < 1080) size = 30; -#else - int size = 45; -#endif - - swprintf(string,128,L"", replacement.c_str(), size, size); - - return string; -#endif -} - -wstring CMinecraftApp::GetVKReplacement(unsigned int uiVKey, bool override) -{ -#ifdef _XBOX - switch(uiVKey) - { - case VK_PAD_A: - return app.GetString( IDS_CONTROLLER_A ); - case VK_PAD_B: - return app.GetString( IDS_CONTROLLER_B ); - case VK_PAD_X: - return app.GetString( IDS_CONTROLLER_X ); - case VK_PAD_Y: - return app.GetString( IDS_CONTROLLER_Y ); - case VK_PAD_LSHOULDER: - return app.GetString( IDS_CONTROLLER_LEFT_BUMPER ); - case VK_PAD_RSHOULDER: - return app.GetString( IDS_CONTROLLER_RIGHT_BUMPER ); - case VK_PAD_LTRIGGER: - return app.GetString( IDS_CONTROLLER_LEFT_TRIGGER ); - case VK_PAD_RTRIGGER: - return app.GetString( IDS_CONTROLLER_RIGHT_TRIGGER ); - case VK_PAD_LTHUMB_UP : - case VK_PAD_LTHUMB_DOWN : - case VK_PAD_LTHUMB_RIGHT : - case VK_PAD_LTHUMB_LEFT : - case VK_PAD_LTHUMB_UPLEFT : - case VK_PAD_LTHUMB_UPRIGHT : - case VK_PAD_LTHUMB_DOWNRIGHT: - case VK_PAD_LTHUMB_DOWNLEFT : - return app.GetString( IDS_CONTROLLER_LEFT_STICK ); - case VK_PAD_RTHUMB_UP : - case VK_PAD_RTHUMB_DOWN : - case VK_PAD_RTHUMB_RIGHT : - case VK_PAD_RTHUMB_LEFT : - case VK_PAD_RTHUMB_UPLEFT : - case VK_PAD_RTHUMB_UPRIGHT : - case VK_PAD_RTHUMB_DOWNRIGHT: - case VK_PAD_RTHUMB_DOWNLEFT : - return app.GetString( IDS_CONTROLLER_RIGHT_STICK ); - default: - break; - } - return nullptr; -#else - wstring replacement = L""; - switch(uiVKey) - { - case VK_PAD_A: -#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) - if( InputManager.IsCircleCrossSwapped() ) replacement = L"ButtonB"; - else replacement = L"ButtonA"; -#else - replacement = L"ButtonA"; -#endif - break; - case VK_PAD_B: -#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) - if( InputManager.IsCircleCrossSwapped() ) replacement = L"ButtonA"; - else replacement = L"ButtonB"; -#else - replacement = L"ButtonB"; -#endif - break; - case VK_PAD_X: - replacement = L"ButtonX"; - break; - case VK_PAD_Y: - replacement = L"ButtonY"; - break; - case VK_PAD_LSHOULDER: - replacement = L"ButtonLeftBumper"; - break; - case VK_PAD_RSHOULDER: - replacement = L"ButtonRightBumper"; - break; - case VK_PAD_LTRIGGER: - replacement = L"ButtonLeftTrigger"; - break; - case VK_PAD_RTRIGGER: - replacement = L"ButtonRightTrigger"; - break; - case VK_PAD_LTHUMB_UP : - case VK_PAD_LTHUMB_DOWN : - case VK_PAD_LTHUMB_RIGHT : - case VK_PAD_LTHUMB_LEFT : - case VK_PAD_LTHUMB_UPLEFT : - case VK_PAD_LTHUMB_UPRIGHT : - case VK_PAD_LTHUMB_DOWNRIGHT: - case VK_PAD_LTHUMB_DOWNLEFT : - replacement = L"ButtonLeftStick"; - break; - case VK_PAD_RTHUMB_UP : - case VK_PAD_RTHUMB_DOWN : - case VK_PAD_RTHUMB_RIGHT : - case VK_PAD_RTHUMB_LEFT : - case VK_PAD_RTHUMB_UPLEFT : - case VK_PAD_RTHUMB_UPRIGHT : - case VK_PAD_RTHUMB_DOWNRIGHT: - case VK_PAD_RTHUMB_DOWNLEFT : - replacement = L"ButtonRightStick"; - break; -#if defined _XBOX_ONE || defined __PSVITA__ - case VK_PAD_START: - replacement = L"ButtonStart"; - break; - case VK_PAD_BACK: - replacement = L"ButtonBack"; - break; -#endif - default: - break; - } - wchar_t string[128]; - -#ifdef __PS3__ - int size = 30; -#elif defined _WIN64 - int size = 45; - if(ui.getScreenHeight() < 1080 || override == true) size = 30; -#else - int size = 45; -#endif - - swprintf(string,128,L"", replacement.c_str(), size, size); - - return string; -#endif -} - -wstring CMinecraftApp::GetIconReplacement(unsigned int uiIcon) -{ -#ifdef _XBOX - switch(uiIcon) - { - case XZP_ICON_SHANK_01: - return app.GetString( IDS_ICON_SHANK_01 ); - case XZP_ICON_SHANK_03: - return app.GetString( IDS_ICON_SHANK_03 ); - default: - break; - } - return nullptr; -#else - wchar_t string[128]; - -#ifdef __PS3__ - int size = 22; -#elif defined _WIN64 - int size = 33; - if(ui.getScreenHeight() < 1080) size = 22; -#else - int size = 33; -#endif - - swprintf(string,128,L"", size, size); - wstring result = L""; - switch(uiIcon) - { - case XZP_ICON_SHANK_01: - result = string; - break; - case XZP_ICON_SHANK_03: - result.append(string).append(string).append(string); - break; - default: - break; - } - return result; -#endif -} - -#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) -unordered_map CMinecraftApp::MojangData; -unordered_map CMinecraftApp::DLCTextures_PackID; -unordered_map CMinecraftApp::DLCInfo; -unordered_map CMinecraftApp::DLCInfo_SkinName; -#elif defined(_DURANGO) -unordered_map CMinecraftApp::MojangData; -unordered_map CMinecraftApp::DLCTextures_PackID; // for mash-up packs & texture packs -//unordered_map CMinecraftApp::DLCInfo_Trial; // full offerid, dlc_info -unordered_map CMinecraftApp::DLCInfo_Full; // full offerid, dlc_info -unordered_map CMinecraftApp::DLCInfo_SkinName; // skin name, full offer id -#else -unordered_map CMinecraftApp::MojangData; -unordered_map CMinecraftApp::DLCTextures_PackID; -unordered_map CMinecraftApp::DLCInfo_Trial; -unordered_map CMinecraftApp::DLCInfo_Full; -unordered_map CMinecraftApp::DLCInfo_SkinName; -#endif - - - -HRESULT CMinecraftApp::RegisterMojangData(WCHAR *pXuidName, PlayerUID xuid, WCHAR *pSkin, WCHAR *pCape) -{ - HRESULT hr=S_OK; - eXUID eTempXuid=eXUID_Undefined; - MOJANG_DATA *pMojangData=nullptr; - - // ignore the names if we don't recognize them - if (pXuidName != nullptr) - { - if( wcscmp( pXuidName, L"XUID_NOTCH" ) == 0 ) - { - eTempXuid = eXUID_Notch; // might be needed for the apple at some point - } - else if( wcscmp( pXuidName, L"XUID_DEADMAU5" ) == 0 ) - { - eTempXuid = eXUID_Deadmau5; // Needed for the deadmau5 ears - } - else - { - eTempXuid=eXUID_NoName; - } - } - - if(eTempXuid!=eXUID_Undefined) - { - pMojangData = new MOJANG_DATA; - ZeroMemory(pMojangData,sizeof(MOJANG_DATA)); - pMojangData->eXuid=eTempXuid; - - wcsncpy( pMojangData->wchSkin, pSkin, MAX_CAPENAME_SIZE); - wcsncpy( pMojangData->wchCape, pCape, MAX_CAPENAME_SIZE); - MojangData[xuid]=pMojangData; - } - - return hr; -} - -MOJANG_DATA *CMinecraftApp::GetMojangDataForXuid(PlayerUID xuid) -{ - return MojangData[xuid]; -} - -HRESULT CMinecraftApp::RegisterConfigValues(WCHAR *pType, int iValue) -{ - HRESULT hr=S_OK; - - // #ifdef _XBOX - // if(pType!=nullptr) - // { - // if(wcscmp(pType,L"XboxOneTransfer")==0) - // { - // if(iValue>0) - // { - // app.m_bTransferSavesToXboxOne=true; - // } - // else - // { - // app.m_bTransferSavesToXboxOne=false; - // } - // } - // else if(wcscmp(pType,L"TransferSlotCount")==0) - // { - // app.m_uiTransferSlotC=iValue; - // } - // - // } - // #endif - - - return hr; -} - -#if (defined _XBOX || defined _WINDOWS64) -HRESULT CMinecraftApp::RegisterDLCData(WCHAR *pType, WCHAR *pBannerName, int iGender, uint64_t ullOfferID_Full, uint64_t ullOfferID_Trial, WCHAR *pFirstSkin, unsigned int uiSortIndex, int iConfig, WCHAR *pDataFile) -{ - HRESULT hr=S_OK; - DLC_INFO *pDLCData=new DLC_INFO; - ZeroMemory(pDLCData,sizeof(DLC_INFO)); - pDLCData->ullOfferID_Full=ullOfferID_Full; - pDLCData->ullOfferID_Trial=ullOfferID_Trial; - pDLCData->eDLCType=e_DLC_NotDefined; - pDLCData->iGender=iGender; - pDLCData->uiSortIndex=uiSortIndex; - pDLCData->iConfig=iConfig; - -#ifndef __ORBIS__ - // ignore the names if we don't recognize them - if(pBannerName!=L"") - { - wcsncpy_s( pDLCData->wchBanner, pBannerName, MAX_BANNERNAME_SIZE); - } - - if(pDataFile[0]!=0) - { - wcsncpy_s( pDLCData->wchDataFile, pDataFile, MAX_BANNERNAME_SIZE); - } -#endif - - if(pType!=nullptr) - { - if(wcscmp(pType,L"Skin")==0) - { - pDLCData->eDLCType=e_DLC_SkinPack; - } - else if(wcscmp(pType,L"Gamerpic")==0) - { - pDLCData->eDLCType=e_DLC_Gamerpics; - } - else if(wcscmp(pType,L"Theme")==0) - { - pDLCData->eDLCType=e_DLC_Themes; - } - else if(wcscmp(pType,L"Avatar")==0) - { - pDLCData->eDLCType=e_DLC_AvatarItems; - } - else if(wcscmp(pType,L"MashUpPack")==0) - { - pDLCData->eDLCType=e_DLC_MashupPacks; - DLCTextures_PackID[pDLCData->iConfig]=ullOfferID_Full; - } - else if(wcscmp(pType,L"TexturePack")==0) - { - pDLCData->eDLCType=e_DLC_TexturePacks; - DLCTextures_PackID[pDLCData->iConfig]=ullOfferID_Full; - } - - - } - - if(ullOfferID_Trial!=0ll) DLCInfo_Trial[ullOfferID_Trial]=pDLCData; - if(ullOfferID_Full!=0ll) DLCInfo_Full[ullOfferID_Full]=pDLCData; - if(pFirstSkin[0]!=0) DLCInfo_SkinName[pFirstSkin]=ullOfferID_Full; - - return hr; -} -#elif defined _XBOX_ONE - -unordered_map *CMinecraftApp::GetDLCInfo() -{ - return &DLCInfo_Full; -} - -HRESULT CMinecraftApp::RegisterDLCData(eDLCContentType eType, WCHAR *pwchBannerName,WCHAR *pwchProductId, WCHAR *pwchProductName, WCHAR *pwchFirstSkin, int iConfig, unsigned int uiSortIndex) -{ - HRESULT hr=S_OK; - // 4J-PB - need to convert the product id to uppercase because the catalog calls come back with upper case - WCHAR wchUppercaseProductID[64]; - if(pwchProductId[0]!=0) - { - for(int i=0;i<64;i++) - { - wchUppercaseProductID[i]=towupper((wchar_t)pwchProductId[i]); - } - } - - // check if we already have this info from the local DLC file - wstring wsTemp=wchUppercaseProductID; - - auto it = DLCInfo_Full.find(wsTemp); - if( it == DLCInfo_Full.end() ) - { - // Not found - - DLC_INFO *pDLCData=new DLC_INFO; - ZeroMemory(pDLCData,sizeof(DLC_INFO)); - - pDLCData->eDLCType=e_DLC_NotDefined; - pDLCData->uiSortIndex=uiSortIndex; - pDLCData->iConfig=iConfig; - - if(pwchProductId[0]!=0) - { - pDLCData->wsProductId=wchUppercaseProductID; - } - - // ignore the names if we don't recognize them - if(pwchBannerName!=L"") - { - wcsncpy_s( pDLCData->wchBanner, pwchBannerName, MAX_BANNERNAME_SIZE); - } - - if(pwchProductName[0]!=0) - { - pDLCData->wsDisplayName=pwchProductName; - } - - pDLCData->eDLCType=eType; - - switch(eType) - { - case e_DLC_MashupPacks: - case e_DLC_TexturePacks: - DLCTextures_PackID[iConfig]=pDLCData->wsProductId; - break; - } - - if(pwchFirstSkin[0]!=0) DLCInfo_SkinName[pwchFirstSkin]=pDLCData->wsProductId; - -#ifdef _XBOX_ONE - // ignore the names, and use the product id instead - DLCInfo_Full[pDLCData->wsProductId]=pDLCData; -#else - DLCInfo_Full[pDLCData->wsDisplayName]=pDLCData; -#endif - } - app.DebugPrintf("DLCInfo - type - %d, productID - %ls, name - %ls , banner - %ls, iconfig - %d, sort index - %d\n",eType,pwchProductId, pwchProductName,pwchBannerName, iConfig, uiSortIndex); - return hr; -} -#else - -HRESULT CMinecraftApp::RegisterDLCData(char *pchDLCName, unsigned int uiSortIndex,char *pchImageURL) -{ - // on PS3 we get all the required info from the name - char chDLCType[3]; - HRESULT hr=S_OK; - DLC_INFO *pDLCData=new DLC_INFO; - ZeroMemory(pDLCData,sizeof(DLC_INFO)); - - chDLCType[0]=pchDLCName[0]; - chDLCType[1]=pchDLCName[1]; - chDLCType[2]=0; - - pDLCData->iConfig = app.GetiConfigFromName(pchDLCName); - pDLCData->uiSortIndex=uiSortIndex; - pDLCData->eDLCType = app.GetDLCTypeFromName(pchDLCName); - strcpy(pDLCData->chImageURL,pchImageURL); - //bool bIsTrialDLC = app.GetTrialFromName(pchDLCName); - - switch(pDLCData->eDLCType) - { - case e_DLC_TexturePacks: - { - char *pchName=(char *)malloc(strlen(pchDLCName)+1); - strcpy(pchName,pchDLCName); - DLCTextures_PackID[pDLCData->iConfig]=pchName; - } - break; - case e_DLC_MashupPacks: - { - char *pchName=(char *)malloc(strlen(pchDLCName)+1); - strcpy(pchName,pchDLCName); - DLCTextures_PackID[pDLCData->iConfig]=pchName; - } - break; - default: - break; - } - - app.DebugPrintf(5,"Adding DLC - %s\n",pchDLCName); - DLCInfo[pchDLCName]=pDLCData; - - // if(ullOfferID_Trial!=0ll) DLCInfo_Trial[ullOfferID_Trial]=pDLCData; - // if(ullOfferID_Full!=0ll) DLCInfo_Full[ullOfferID_Full]=pDLCData; - // if(pFirstSkin[0]!=0) DLCInfo_SkinName[pFirstSkin]=ullOfferID_Full; - - // DLCInfo[ullOfferID_Trial]=pDLCData; - - return hr; -} -#endif - - - -#if defined( __PS3__) || defined(__ORBIS__) || defined(__PSVITA__) -bool CMinecraftApp::GetDLCFullOfferIDForSkinID(const wstring &FirstSkin,ULONGLONG *pullVal) -{ - auto it = DLCInfo_SkinName.find(FirstSkin); - if( it == DLCInfo_SkinName.end() ) - { - return false; - } - else - { - *pullVal=(ULONGLONG)it->second; - return true; - } -} -bool CMinecraftApp::GetDLCNameForPackID(const int iPackID,char **ppchKeyID) -{ - auto it = DLCTextures_PackID.find(iPackID); - if( it == DLCTextures_PackID.end() ) - { - *ppchKeyID=nullptr; - return false; - } - else - { - *ppchKeyID=(char *)it->second; - return true; - } -} -DLC_INFO *CMinecraftApp::GetDLCInfo(char *pchDLCName) -{ - string tempString=pchDLCName; - - if(DLCInfo.size()>0) - { - auto it = DLCInfo.find(tempString); - - if( it == DLCInfo.end() ) - { - // nothing for this - return nullptr; - } - else - { - return it->second; - } - } - else return nullptr; -} - -DLC_INFO *CMinecraftApp::GetDLCInfoFromTPackID(int iTPID) -{ - unordered_map::iterator it= DLCInfo.begin(); - - for(size_t i=0;isecond)->iConfig==iTPID) - { - return it->second; - } - ++it; - } - return nullptr; -} - -DLC_INFO *CMinecraftApp::GetDLCInfo(int iIndex) -{ - unordered_map::iterator it= DLCInfo.begin(); - - for(int i=0;isecond; -} - -char *CMinecraftApp::GetDLCInfoTextures(int iIndex) -{ - unordered_map::iterator it= DLCTextures_PackID.begin(); - - for(int i=0;isecond; -} - -#elif defined _XBOX_ONE -bool CMinecraftApp::GetDLCFullOfferIDForSkinID(const wstring &FirstSkin,wstring &ProductId) -{ - auto it = DLCInfo_SkinName.find(FirstSkin); - if( it == DLCInfo_SkinName.end() ) - { - return false; - } - else - { - ProductId=it->second; - return true; - } -} -bool CMinecraftApp::GetDLCFullOfferIDForPackID(const int iPackID,wstring &ProductId) -{ - auto it = DLCTextures_PackID.find(iPackID); - if( it == DLCTextures_PackID.end() ) - { - return false; - } - else - { - ProductId=it->second; - return true; - } -} -// DLC_INFO *CMinecraftApp::GetDLCInfoForTrialOfferID(wstring &ProductId) -// { -// return nullptr; -// } - -DLC_INFO *CMinecraftApp::GetDLCInfoTrialOffer(int iIndex) -{ - return nullptr; -} -DLC_INFO *CMinecraftApp::GetDLCInfoFullOffer(int iIndex) -{ - unordered_map::iterator it= DLCInfo_Full.begin(); - - for(int i=0;isecond; -} -wstring CMinecraftApp::GetDLCInfoTexturesFullOffer(int iIndex) -{ - unordered_map::iterator it= DLCTextures_PackID.begin(); - - for(int i=0;isecond; -} -#else -bool CMinecraftApp::GetDLCFullOfferIDForSkinID(const wstring &FirstSkin,ULONGLONG *pullVal) -{ - auto it = DLCInfo_SkinName.find(FirstSkin); - if( it == DLCInfo_SkinName.end() ) - { - return false; - } - else - { - *pullVal=(ULONGLONG)it->second; - return true; - } -} -bool CMinecraftApp::GetDLCFullOfferIDForPackID(const int iPackID,ULONGLONG *pullVal) -{ - auto it = DLCTextures_PackID.find(iPackID); - if( it == DLCTextures_PackID.end() ) - { - *pullVal=0ULL; - return false; - } - else - { - *pullVal=it->second; - return true; - } -} -DLC_INFO *CMinecraftApp::GetDLCInfoForTrialOfferID(ULONGLONG ullOfferID_Trial) -{ - //DLC_INFO *pDLCInfo=nullptr; - if(DLCInfo_Trial.size()>0) - { - auto it = DLCInfo_Trial.find(ullOfferID_Trial); - - if( it == DLCInfo_Trial.end() ) - { - // nothing for this - return nullptr; - } - else - { - return it->second; - } - } - else return nullptr; -} - -DLC_INFO *CMinecraftApp::GetDLCInfoTrialOffer(int iIndex) -{ - unordered_map::iterator it= DLCInfo_Trial.begin(); - - for(int i=0;isecond; -} -DLC_INFO *CMinecraftApp::GetDLCInfoFullOffer(int iIndex) -{ - unordered_map::iterator it= DLCInfo_Full.begin(); - - for(int i=0;isecond; -} -ULONGLONG CMinecraftApp::GetDLCInfoTexturesFullOffer(int iIndex) -{ - unordered_map::iterator it= DLCTextures_PackID.begin(); - - for(int i=0;isecond; -} -#endif - -#ifdef _XBOX_ONE - -DLC_INFO *CMinecraftApp::GetDLCInfoForFullOfferID(WCHAR *pwchProductID) -{ - wstring wsTemp = pwchProductID; - if(DLCInfo_Full.size()>0) - { - auto it = DLCInfo_Full.find(wsTemp); - - if( it == DLCInfo_Full.end() ) - { - // nothing for this - return nullptr; - } - else - { - return it->second; - } - } - else return nullptr; -} -DLC_INFO *CMinecraftApp::GetDLCInfoForProductName(WCHAR *pwchProductName) -{ - unordered_map::iterator it= DLCInfo_Full.begin(); - wstring wsProductName=pwchProductName; - - for(size_t i=0;isecond; - if(wsProductName==pDLCInfo->wsDisplayName) - { - return pDLCInfo; - } - ++it; - } - - return nullptr; -} - -#elif defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) -#else - -DLC_INFO *CMinecraftApp::GetDLCInfoForFullOfferID(ULONGLONG ullOfferID_Full) -{ - - if(DLCInfo_Full.size()>0) - { - auto it = DLCInfo_Full.find(ullOfferID_Full); - - if( it == DLCInfo_Full.end() ) - { - // nothing for this - return nullptr; - } - else - { - return it->second; - } - } - else return nullptr; -} -#endif - -void CMinecraftApp::EnterSaveNotificationSection() -{ - EnterCriticalSection(&m_saveNotificationCriticalSection); - if( m_saveNotificationDepth++ == 0 ) - { - if(g_NetworkManager.IsInSession()) // this can be triggered from the front end if we're downloading a save - { - MinecraftServer::getInstance()->broadcastStartSavingPacket(); - - if( g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 ) - { - app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)TRUE); - } - } - } - LeaveCriticalSection(&m_saveNotificationCriticalSection); -} - -void CMinecraftApp::LeaveSaveNotificationSection() -{ - EnterCriticalSection(&m_saveNotificationCriticalSection); - if( --m_saveNotificationDepth == 0 ) - { - if(g_NetworkManager.IsInSession()) // this can be triggered from the front end if we're downloading a save - { - MinecraftServer::getInstance()->broadcastStopSavingPacket(); - - if( g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 ) - { - app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)FALSE); - } - } - } - LeaveCriticalSection(&m_saveNotificationCriticalSection); -} - - -int CMinecraftApp::RemoteSaveThreadProc( void* lpParameter ) -{ - // The game should be stopped while we are doing this, but the connections ticks may try to create some AABB's or Vec3's - AABB::UseDefaultThreadStorage(); - Vec3::UseDefaultThreadStorage(); - Compression::UseDefaultThreadStorage(); - - // 4J-PB - Xbox 360 - 163153 - [CRASH] TU17: Code: Multiplayer: During the Autosave in an online Multiplayer session, the game occasionally crashes for one or more Clients - // callstack - > if(tls->tileId != this->id) updateDefaultShape(); - // callstack - > default.exe!WaterlilyTile::getAABB(Level * level, int x, int y, int z) line 38 + 8 bytes C++ - // ... - // default.exe!CMinecraftApp::RemoteSaveThreadProc(void * lpParameter) line 6694 C++ - // host autosave, and the clients can crash on receiving handleMoveEntity when it's a tile within this thread, so need to do the tls for tiles - Tile::CreateNewThreadStorage(); - - Minecraft *pMinecraft = Minecraft::GetInstance(); - - pMinecraft->progressRenderer->progressStartNoAbort( IDS_PROGRESS_HOST_SAVING ); - pMinecraft->progressRenderer->progressStage( -1 ); - pMinecraft->progressRenderer->progressStagePercentage(0); - - while( !app.GetGameStarted() && app.GetXuiAction( ProfileManager.GetPrimaryPad() ) == eAppAction_WaitRemoteServerSaveComplete ) - { - // Tick all the games connections - pMinecraft->tickAllConnections(); - Sleep( 100 ); - } - - if( app.GetXuiAction( ProfileManager.GetPrimaryPad() ) != eAppAction_WaitRemoteServerSaveComplete ) - { - // Something cancelled us? - return ERROR_CANCELLED; - } - app.SetAction(ProfileManager.GetPrimaryPad(),eAppAction_Idle); - - ui.UpdatePlayerBasePositions(); - - Tile::ReleaseThreadStorage(); - - return S_OK; -} - -void CMinecraftApp::ExitGameFromRemoteSave( LPVOID lpParameter ) -{ - int primaryPad = ProfileManager.GetPrimaryPad(); - - UINT uiIDA[3]; - uiIDA[0]=IDS_CONFIRM_CANCEL; - uiIDA[1]=IDS_CONFIRM_OK; - - ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 2, primaryPad,&CMinecraftApp::ExitGameFromRemoteSaveDialogReturned,nullptr); -} - -int CMinecraftApp::ExitGameFromRemoteSaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) -{ - //CScene_Pause* pClass = (CScene_Pause*)pParam; - - // results switched for this dialog - if(result==C4JStorage::EMessage_ResultDecline) - { - app.SetAction(iPad,eAppAction_ExitWorld); - } - else - { -#ifndef _XBOX - // Inform fullscreen progress scene that it's not being cancelled after all - UIScene_FullscreenProgress *pScene = static_cast(ui.FindScene(eUIScene_FullscreenProgress)); -#ifdef __PS3__ - if(pScene!=nullptr) -#else - if (pScene != nullptr) -#endif - { - pScene->SetWasCancelled(false); - } -#else - // Don't have to worry about this on Xbox -#endif - } - return 0; -} - -void CMinecraftApp::SetSpecialTutorialCompletionFlag(int iPad, int index) -{ - if(index >= 0 && index < 32 && GameSettingsA[iPad] != nullptr) - { - GameSettingsA[iPad]->uiSpecialTutorialBitmask |= (1<clear(); - - if(BannedListA[iPad].pBannedList) - { - delete [] BannedListA[iPad].pBannedList; - BannedListA[iPad].pBannedList=nullptr; - } - } -} - -#ifdef _XBOX_ONE -void CMinecraftApp::AddLevelToBannedLevelList(int iPad, PBANNEDLISTDATA pBannedListData, bool bWriteToTMS) -{ - PlayerUID xuid= pBannedListData->wchPlayerUID; - - AddLevelToBannedLevelList(iPad,xuid,pBannedListData->pszLevelName,bWriteToTMS); -} -#endif - -void CMinecraftApp::AddLevelToBannedLevelList(int iPad, PlayerUID xuid, char *pszLevelName, bool bWriteToTMS) -{ - // we will have retrieved the banned level list from TMS, so add this one to it and write it back to TMS - - BANNEDLISTDATA *pBannedListData = new BANNEDLISTDATA; - memset(pBannedListData,0,sizeof(BANNEDLISTDATA)); - -#ifdef _DURANGO - memcpy(&pBannedListData->wchPlayerUID, xuid.toString().c_str(), sizeof(WCHAR)*64); -#else - memcpy(&pBannedListData->xuid, &xuid, sizeof(PlayerUID)); -#endif - strcpy(pBannedListData->pszLevelName,pszLevelName); - m_vBannedListA[iPad]->push_back(pBannedListData); - - if (bWriteToTMS) - { - DWORD dwDataBytes = static_cast(sizeof(BANNEDLISTDATA)* m_vBannedListA[iPad]->size()); - PBANNEDLISTDATA pBannedList = reinterpret_cast(new CHAR [dwDataBytes]); - int iCount=0; - for (PBANNEDLISTDATA pData : *m_vBannedListA[iPad] ) - { - memcpy(&pBannedList[iCount++],pData,sizeof(BANNEDLISTDATA)); - } - - // 4J-PB - write to TMS++ now - - //bool bRes=StorageManager.WriteTMSFile(iPad,C4JStorage::eGlobalStorage_TitleUser,L"BannedList",(PBYTE)pBannedList, dwDataBytes); -#ifdef _XBOX - StorageManager.TMSPP_WriteFile(iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,C4JStorage::TMS_UGCTYPE_NONE,"BannedList",(PCHAR) pBannedList, dwDataBytes,nullptr,nullptr, 0); -#elif defined _XBOX_ONE - StorageManager.TMSPP_WriteFile(iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,L"BannedList",(PBYTE) pBannedList, dwDataBytes,nullptr,nullptr, 0); -#endif - } - // update telemetry too -} - -bool CMinecraftApp::IsInBannedLevelList(int iPad, PlayerUID xuid, char *pszLevelName) -{ - for( PBANNEDLISTDATA pData : *m_vBannedListA[iPad] ) - { -#ifdef _XBOX_ONE - PlayerUID bannedPlayerUID = pData->wchPlayerUID; - if(IsEqualXUID (bannedPlayerUID,xuid) && (strcmp(pData->pszLevelName,pszLevelName)==0)) -#else - if(IsEqualXUID (pData->xuid,xuid) && (strcmp(pData->pszLevelName,pszLevelName)==0)) -#endif - { - return true; - } - } - - return false; -} - -void CMinecraftApp::RemoveLevelFromBannedLevelList(int iPad, PlayerUID xuid, char *pszLevelName) -{ - //bool bFound=false; - //bool bRes; - - // we will have retrieved the banned level list from TMS, so remove this one from it and write it back to TMS - for (auto it = m_vBannedListA[iPad]->begin(); it != m_vBannedListA[iPad]->end(); ) - { - PBANNEDLISTDATA pBannedListData = *it; - - if(pBannedListData!=nullptr) - { -#ifdef _XBOX_ONE - PlayerUID bannedPlayerUID = pBannedListData->wchPlayerUID; - if(IsEqualXUID (bannedPlayerUID,xuid) && (strcmp(pBannedListData->pszLevelName,pszLevelName)==0)) -#else - if(IsEqualXUID (pBannedListData->xuid,xuid) && (strcmp(pBannedListData->pszLevelName,pszLevelName)==0)) -#endif - { - TelemetryManager->RecordUnBanLevel(iPad); - - // match found, so remove this entry - it = m_vBannedListA[iPad]->erase(it); - } - else - { - ++it; - } - } - else - { - ++it; - } - } - - DWORD dwDataBytes=static_cast(sizeof(BANNEDLISTDATA) * m_vBannedListA[iPad]->size()); - if(dwDataBytes==0) - { - // wipe the file -#ifdef _XBOX - StorageManager.DeleteTMSFile(iPad,C4JStorage::eGlobalStorage_TitleUser,L"BannedList"); -#elif defined _XBOX_ONE - StorageManager.TMSPP_DeleteFile(iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,L"BannedList",nullptr,nullptr, 0); -#endif - } - else - { - PBANNEDLISTDATA pBannedList = (BANNEDLISTDATA *)(new BYTE [dwDataBytes]); - - size_t iSize=m_vBannedListA[iPad]->size(); - for(size_t i=0;iat(i); - - memcpy(&pBannedList[i],pBannedListData,sizeof(BANNEDLISTDATA)); - } -#ifdef _XBOX - StorageManager.WriteTMSFile(iPad,C4JStorage::eGlobalStorage_TitleUser,L"BannedList",(PBYTE)pBannedList, dwDataBytes); -#elif defined _XBOX_ONE - StorageManager.TMSPP_WriteFile(iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,L"BannedList",(PBYTE) pBannedList, dwDataBytes,nullptr,nullptr, 0); -#endif - delete [] pBannedList; - } - - // update telemetry too -} - -// function to add credits for the DLC packs -void CMinecraftApp::AddCreditText(LPCWSTR lpStr) -{ - DebugPrintf("ADDING CREDIT - %ls\n",lpStr); - // add a string from the DLC to a credits vector - SCreditTextItemDef *pCreditStruct = new SCreditTextItemDef; - pCreditStruct->m_eType=eSmallText; - pCreditStruct->m_iStringID[0]=NO_TRANSLATED_STRING; - pCreditStruct->m_iStringID[1]=NO_TRANSLATED_STRING; - pCreditStruct->m_Text=new WCHAR [wcslen(lpStr)+1]; - wcscpy((WCHAR *)pCreditStruct->m_Text,lpStr); - - vDLCCredits.push_back(pCreditStruct); -} - -bool CMinecraftApp::AlreadySeenCreditText(const wstring &wstemp) -{ - - for(unsigned int i=0;i(vDLCCredits.size()); -} - -SCreditTextItemDef * CMinecraftApp::GetDLCCredits(int iIndex) -{ - return vDLCCredits.at(iIndex); -} - -// Game Host options - -void CMinecraftApp::SetGameHostOption(eGameHostOption eVal,unsigned int uiVal) -{ - SetGameHostOption(m_uiGameHostSettings,eVal,uiVal); -} - - -void CMinecraftApp::SetGameHostOption(unsigned int &uiHostSettings, eGameHostOption eVal, unsigned int uiVal) -{ - switch(eVal) - { - case eGameHostOption_FriendsOfFriends: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_FRIENDSOFFRIENDS; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_FRIENDSOFFRIENDS; - } - break; - case eGameHostOption_Difficulty: - // clear the difficulty first - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_DIFFICULTY; - uiHostSettings|=(GAME_HOST_OPTION_BITMASK_DIFFICULTY&uiVal); - break; - case eGameHostOption_Gamertags: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_GAMERTAGS; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_GAMERTAGS; - } - - break; - case eGameHostOption_GameType: - // clear the game type first - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_GAMETYPE; - uiHostSettings|=(GAME_HOST_OPTION_BITMASK_GAMETYPE&(uiVal<<4)); - break; - case eGameHostOption_LevelType: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_LEVELTYPE; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_LEVELTYPE; - } - - break; - case eGameHostOption_Structures: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_STRUCTURES; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_STRUCTURES; - } - - break; - case eGameHostOption_BonusChest: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_BONUSCHEST; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_BONUSCHEST; - } - - break; - case eGameHostOption_HasBeenInCreative: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_BEENINCREATIVE; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_BEENINCREATIVE; - } - - break; - case eGameHostOption_PvP: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_PVP; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_PVP; - } - - break; - case eGameHostOption_TrustPlayers: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_TRUSTPLAYERS; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_TRUSTPLAYERS; - } - - break; - case eGameHostOption_TNT: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_TNT; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_TNT; - } - - break; - case eGameHostOption_FireSpreads: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_FIRESPREADS; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_FIRESPREADS; - } - break; - case eGameHostOption_CheatsEnabled: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTFLY; - uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTHUNGER; - uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTFLY; - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTHUNGER; - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE; - } - break; - case eGameHostOption_HostCanFly: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTFLY; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTFLY; - } - break; - case eGameHostOption_HostCanChangeHunger: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTHUNGER; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTHUNGER; - } - break; - case eGameHostOption_HostCanBeInvisible: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE; - } - break; - - case eGameHostOption_BedrockFog: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_BEDROCKFOG; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_BEDROCKFOG; - } - break; - case eGameHostOption_DisableSaving: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_DISABLESAVE; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_DISABLESAVE; - } - break; - case eGameHostOption_WasntSaveOwner: - if(uiVal!=0) - { - uiHostSettings|=GAME_HOST_OPTION_BITMASK_NOTOWNER; - } - else - { - // off - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_NOTOWNER; - } - break; - case eGameHostOption_MobGriefing: - if(uiVal!=1) - { - uiHostSettings |= GAME_HOST_OPTION_BITMASK_MOBGRIEFING; - } - else - { - // off - uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_MOBGRIEFING; - } - break; - case eGameHostOption_KeepInventory: - if(uiVal!=0) - { - uiHostSettings |= GAME_HOST_OPTION_BITMASK_KEEPINVENTORY; - } - else - { - // off - uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_KEEPINVENTORY; - } - break; - case eGameHostOption_DoMobSpawning: - if(uiVal!=1) - { - uiHostSettings |= GAME_HOST_OPTION_BITMASK_DOMOBSPAWNING; - } - else - { - // off - uiHostSettings &=~ GAME_HOST_OPTION_BITMASK_DOMOBSPAWNING; - } - break; - case eGameHostOption_DoMobLoot: - if(uiVal!=1) - { - uiHostSettings |= GAME_HOST_OPTION_BITMASK_DOMOBLOOT; - } - else - { - // off - uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_DOMOBLOOT; - } - break; - case eGameHostOption_DoTileDrops: - if(uiVal!=1) - { - uiHostSettings |= GAME_HOST_OPTION_BITMASK_DOTILEDROPS; - } - else - { - // off - uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_DOTILEDROPS; - } - break; - case eGameHostOption_NaturalRegeneration: - if(uiVal!=1) - { - uiHostSettings |= GAME_HOST_OPTION_BITMASK_NATURALREGEN; - } - else - { - // off - uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_NATURALREGEN; - } - break; - case eGameHostOption_DoDaylightCycle: - if(uiVal!=1) - { - uiHostSettings |= GAME_HOST_OPTION_BITMASK_DODAYLIGHTCYCLE; - } - else - { - // off - uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_DODAYLIGHTCYCLE; - } - break; - case eGameHostOption_WorldSize: - // clear the difficulty first - uiHostSettings&=~GAME_HOST_OPTION_BITMASK_WORLDSIZE; - uiHostSettings|=(GAME_HOST_OPTION_BITMASK_WORLDSIZE & (uiVal<>4; - break; - case eGameHostOption_All: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_ALL); - break; - case eGameHostOption_Tutorial: - // special case - tutorial is offline, but we want the gamertag option, and set Easy mode, structures on, fire on, tnt on, pvp on, trust players on - return ((uiHostSettings&GAME_HOST_OPTION_BITMASK_GAMERTAGS)| - GAME_HOST_OPTION_BITMASK_TRUSTPLAYERS| - GAME_HOST_OPTION_BITMASK_FIRESPREADS| - GAME_HOST_OPTION_BITMASK_TNT| - GAME_HOST_OPTION_BITMASK_PVP| - GAME_HOST_OPTION_BITMASK_STRUCTURES|1); - break; - case eGameHostOption_LevelType: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_LEVELTYPE); - break; - case eGameHostOption_Structures: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_STRUCTURES); - break; - case eGameHostOption_BonusChest: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_BONUSCHEST); - break; - case eGameHostOption_HasBeenInCreative: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_BEENINCREATIVE); - break; - case eGameHostOption_PvP: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_PVP); - break; - case eGameHostOption_TrustPlayers: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_TRUSTPLAYERS); - break; - case eGameHostOption_TNT: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_TNT); - break; - case eGameHostOption_FireSpreads: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_FIRESPREADS); - break; - case eGameHostOption_CheatsEnabled: - return (uiHostSettings&(GAME_HOST_OPTION_BITMASK_HOSTFLY|GAME_HOST_OPTION_BITMASK_HOSTHUNGER|GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE)); - break; - case eGameHostOption_HostCanFly: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_HOSTFLY); - break; - case eGameHostOption_HostCanChangeHunger: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_HOSTHUNGER); - break; - case eGameHostOption_HostCanBeInvisible: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE); - break; - case eGameHostOption_BedrockFog: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_BEDROCKFOG); - break; - case eGameHostOption_DisableSaving: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_DISABLESAVE); - break; - case eGameHostOption_WasntSaveOwner: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_NOTOWNER); - case eGameHostOption_WorldSize: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_WORLDSIZE) >> GAME_HOST_OPTION_BITMASK_WORLDSIZE_BITSHIFT; - case eGameHostOption_MobGriefing: - return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_MOBGRIEFING); - case eGameHostOption_KeepInventory: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_KEEPINVENTORY); - case eGameHostOption_DoMobSpawning: - return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DOMOBSPAWNING); - case eGameHostOption_DoMobLoot: - return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DOMOBLOOT); - case eGameHostOption_DoTileDrops: - return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DOTILEDROPS); - case eGameHostOption_NaturalRegeneration: - return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_NATURALREGEN); - case eGameHostOption_DoDaylightCycle: - return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DODAYLIGHTCYCLE); - break; - case eGameHostOption_Hardcore: // 4J Added - for hardcore mode - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_HARDCORE) ? 1 : 0; - break; - } - - return false; -} - -bool CMinecraftApp::CanRecordStatsAndAchievements() -{ - bool isTutorial = Minecraft::GetInstance() != nullptr && Minecraft::GetInstance()->isTutorial(); - // 4J Stu - All of these options give the host player some advantage, so should not allow achievements - return !(app.GetGameHostOption(eGameHostOption_HasBeenInCreative) || - app.GetGameHostOption(eGameHostOption_HostCanBeInvisible) || - app.GetGameHostOption(eGameHostOption_HostCanChangeHunger) || - app.GetGameHostOption(eGameHostOption_HostCanFly) || - app.GetGameHostOption(eGameHostOption_WasntSaveOwner) || - !app.GetGameHostOption(eGameHostOption_MobGriefing) || - app.GetGameHostOption(eGameHostOption_KeepInventory) || - !app.GetGameHostOption(eGameHostOption_DoMobSpawning) || - (!app.GetGameHostOption(eGameHostOption_DoDaylightCycle) && !isTutorial ) - ); -} - -void CMinecraftApp::processSchematics(LevelChunk *levelChunk) -{ - m_gameRules.processSchematics(levelChunk); -} - -void CMinecraftApp::processSchematicsLighting(LevelChunk *levelChunk) -{ - m_gameRules.processSchematicsLighting(levelChunk); -} - -void CMinecraftApp::loadDefaultGameRules() -{ - m_gameRules.loadDefaultGameRules(); -} - -void CMinecraftApp::setLevelGenerationOptions(LevelGenerationOptions *levelGen) -{ - m_gameRules.setLevelGenerationOptions(levelGen); -} - -LPCWSTR CMinecraftApp::GetGameRulesString(const wstring &key) -{ - return m_gameRules.GetGameRulesString(key); -} - -unsigned char CMinecraftApp::m_szPNG[8]= -{ - 137,80,78,71,13,10,26,10 -}; - -#define PNG_TAG_tEXt 0x74455874 - -unsigned int CMinecraftApp::FromBigEndian(unsigned int uiValue) -{ -#if defined(__PS3__) || defined(_XBOX) - // Keep it in big endian - return uiValue; -#else - unsigned int uiReturn = ( ( uiValue >> 24 ) & 0x000000ff ) | - ( ( uiValue >> 8 ) & 0x0000ff00 ) | - ( ( uiValue << 8 ) & 0x00ff0000 ) | - ( ( uiValue << 24 ) & 0xff000000 ); - return uiReturn; -#endif -} - -void CMinecraftApp::GetImageTextData(PBYTE pbImageData, DWORD dwImageBytes,unsigned char *pszSeed,unsigned int &uiHostOptions,bool &bHostOptionsRead,DWORD &uiTexturePack) -{ - unsigned char *ucPtr=pbImageData; - unsigned int uiCount=0; - unsigned int uiChunkLen; - unsigned int uiChunkType; - unsigned int uiCRC; - char szKeyword[80]; - - // check it's a png - for(int i=0;i<8;i++) - { - if(m_szPNG[i]!=ucPtr[i]) return; - } - - uiCount+=8; - - while(uiCount> std::hex >> uiHostOptions; - } - else if(strcmp(szKeyword,"4J_TEXTUREPACK")==0) - { - // read the texture pack value - unsigned int uiValueC=0; - unsigned char pszTexturePack[9]; // Hex representation of unsigned int - ZeroMemory(&pszTexturePack,9); - while(*pszKeyword!=0 && (pszKeyword < ucPtr + uiCount + uiChunkLen) && uiValueC < 8) - { - pszTexturePack[uiValueC++]=*pszKeyword; - pszKeyword++; - } - - std::stringstream ss; - ss << pszTexturePack; - ss >> std::hex >> uiTexturePack; - } - } - } - uiCount+=uiChunkLen; - uiCRC=*(unsigned int*)&ucPtr[uiCount]; - uiCRC=FromBigEndian(uiCRC); - uiCount+=sizeof(int); - } - - return; -} - -unsigned int CMinecraftApp::CreateImageTextData(PBYTE bTextMetadata, int64_t seed, bool hasSeed, unsigned int uiHostOptions, unsigned int uiTexturePackId) -{ - int iTextMetadataBytes = 0; - if(hasSeed) - { - strcpy((char *)bTextMetadata,"4J_SEED"); - _i64toa_s(seed,(char *)&bTextMetadata[8],42,10); - - // get the length - iTextMetadataBytes+=8; - while(bTextMetadata[iTextMetadataBytes]!=0) iTextMetadataBytes++; - ++iTextMetadataBytes; // Add a null terminator at the end of the seed value - } - - // Save the host options that this world was last played with - strcpy((char *)&bTextMetadata[iTextMetadataBytes],"4J_HOSTOPTIONS"); - _itoa_s(uiHostOptions,(char *)&bTextMetadata[iTextMetadataBytes+15],9,16); - - iTextMetadataBytes += 15; - while(bTextMetadata[iTextMetadataBytes]!=0) iTextMetadataBytes++; - ++iTextMetadataBytes; // Add a null terminator at the end of the host options value - - // Save the texture pack id - strcpy((char *)&bTextMetadata[iTextMetadataBytes],"4J_TEXTUREPACK"); - _itoa_s(uiTexturePackId,(char *)&bTextMetadata[iTextMetadataBytes+15],9,16); - - iTextMetadataBytes += 15; - while(bTextMetadata[iTextMetadataBytes]!=0) iTextMetadataBytes++; - - return iTextMetadataBytes; -} - -void CMinecraftApp::AddTerrainFeaturePosition(_eTerrainFeatureType eFeatureType,int x,int z) -{ - // check we don't already have this in - for( FEATURE_DATA *pFeatureData : m_vTerrainFeatures ) - { - if((pFeatureData->eTerrainFeature==eFeatureType) &&(pFeatureData->x==x) && (pFeatureData->z==z)) return; - } - - FEATURE_DATA *pFeatureData= new FEATURE_DATA; - pFeatureData->eTerrainFeature=eFeatureType; - pFeatureData->x=x; - pFeatureData->z=z; - - m_vTerrainFeatures.push_back(pFeatureData); -} - -_eTerrainFeatureType CMinecraftApp::IsTerrainFeature(int x,int z) -{ - for(FEATURE_DATA *pFeatureData : m_vTerrainFeatures ) - { - if((pFeatureData->x==x) && (pFeatureData->z==z)) return pFeatureData->eTerrainFeature; - } - - return eTerrainFeature_None; -} - -bool CMinecraftApp::GetTerrainFeaturePosition(_eTerrainFeatureType eType,int *pX, int *pZ) -{ - for ( const FEATURE_DATA *pFeatureData : m_vTerrainFeatures ) - { - if(pFeatureData->eTerrainFeature==eType) - { - *pX=pFeatureData->x; - *pZ=pFeatureData->z; - return true; - } - } - - return false; -} - -void CMinecraftApp::ClearTerrainFeaturePosition() -{ - FEATURE_DATA *pFeatureData; - while(m_vTerrainFeatures.size()>0) - { - pFeatureData = m_vTerrainFeatures.back(); - m_vTerrainFeatures.pop_back(); - delete pFeatureData; - } -} - -void CMinecraftApp::UpdatePlayerInfo(BYTE networkSmallId, SHORT playerColourIndex, unsigned int playerGamePrivileges) -{ - for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) - { - if(m_playerColours[i]==networkSmallId) - { - m_playerColours[i] = 0; - m_playerGamePrivileges[i] = 0; - } - } - if(playerColourIndex >=0 && playerColourIndex < MINECRAFT_NET_MAX_PLAYERS) - { - m_playerColours[playerColourIndex] = networkSmallId; - m_playerGamePrivileges[playerColourIndex] = playerGamePrivileges; - } -} - -short CMinecraftApp::GetPlayerColour(BYTE networkSmallId) -{ - short index = -1; - for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) - { - if(m_playerColours[i]==networkSmallId) - { - index = i; - break; - } - } - return index; -} - -void CMinecraftApp::SetPlayerMapIcon(const wchar_t* name, char icon) -{ - if (name == nullptr) return; - // Update existing entry or use first empty slot - int emptySlot = -1; - for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) - { - if (m_playerMapIcons[i].name[0] != 0 && _wcsicmp(m_playerMapIcons[i].name, name) == 0) - { - m_playerMapIcons[i].icon = icon; - return; - } - if (emptySlot < 0 && m_playerMapIcons[i].name[0] == 0) - emptySlot = i; - } - if (emptySlot >= 0) - { - wcsncpy_s(m_playerMapIcons[emptySlot].name, 32, name, _TRUNCATE); - m_playerMapIcons[emptySlot].icon = icon; - } -} - -char CMinecraftApp::GetPlayerMapIconByName(const wchar_t* name) -{ - if (name == nullptr) return 0; - for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) - { - if (m_playerMapIcons[i].name[0] != 0 && _wcsicmp(m_playerMapIcons[i].name, name) == 0) - return m_playerMapIcons[i].icon; - } - return 0; -} - - -unsigned int CMinecraftApp::GetPlayerPrivileges(BYTE networkSmallId) -{ - unsigned int privileges = 0; - for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) - { - if(m_playerColours[i]==networkSmallId) - { - privileges = m_playerGamePrivileges[i]; - break; - } - } - return privileges; -} - -wstring CMinecraftApp::getEntityName(eINSTANCEOF type) -{ - switch(type) - { - case eTYPE_WOLF: - return app.GetString(IDS_WOLF); - case eTYPE_CREEPER: - return app.GetString(IDS_CREEPER); - case eTYPE_SKELETON: - return app.GetString(IDS_SKELETON); - case eTYPE_SPIDER: - return app.GetString(IDS_SPIDER); - case eTYPE_ZOMBIE: - return app.GetString(IDS_ZOMBIE); - case eTYPE_PIGZOMBIE: - return app.GetString(IDS_PIGZOMBIE); - case eTYPE_ENDERMAN: - return app.GetString(IDS_ENDERMAN); - case eTYPE_SILVERFISH: - return app.GetString(IDS_SILVERFISH); - case eTYPE_CAVESPIDER: - return app.GetString(IDS_CAVE_SPIDER); - case eTYPE_GHAST: - return app.GetString(IDS_GHAST); - case eTYPE_SLIME: - return app.GetString(IDS_SLIME); - case eTYPE_ARROW: - return app.GetString(IDS_ITEM_ARROW); - case eTYPE_ENDERDRAGON: - return app.GetString(IDS_ENDERDRAGON); - case eTYPE_BLAZE: - return app.GetString(IDS_BLAZE); - case eTYPE_LAVASLIME: - return app.GetString(IDS_LAVA_SLIME); - // 4J-PB - fix for #107167 - Customer Encountered: TU12: Content: UI: There is no information what killed Player after being slain by Iron Golem. - case eTYPE_VILLAGERGOLEM: - return app.GetString(IDS_IRONGOLEM); - case eTYPE_HORSE: - return app.GetString(IDS_HORSE); - case eTYPE_WITCH: - return app.GetString(IDS_WITCH); - case eTYPE_WITHERBOSS: - return app.GetString(IDS_WITHER); - case eTYPE_BAT: - return app.GetString(IDS_BAT); - case eTYPE_RABBIT: - return app.GetString(IDS_RABBIT); - - }; - - return L""; -} - -DWORD CMinecraftApp::m_dwContentTypeA[e_Marketplace_MAX]= -{ - XMARKETPLACE_OFFERING_TYPE_CONTENT, // e_DLC_SkinPack, e_DLC_TexturePacks, e_DLC_MashupPacks -#ifndef _XBOX_ONE - XMARKETPLACE_OFFERING_TYPE_THEME, // e_DLC_Themes - XMARKETPLACE_OFFERING_TYPE_AVATARITEM, // e_DLC_AvatarItems - XMARKETPLACE_OFFERING_TYPE_TILE, // e_DLC_Gamerpics -#endif -}; - -unsigned int CMinecraftApp::AddDLCRequest(eDLCMarketplaceType eType, bool bPromote) -{ - // lock access - EnterCriticalSection(&csDLCDownloadQueue); - - // If it's already in there, promote it to the top of the list - int iPosition=0; - for( DLCRequest *pCurrent : m_DLCDownloadQueue ) - { - if(pCurrent->dwType==m_dwContentTypeA[eType]) - { - // already got this in the list - if(pCurrent->eState == e_DLC_ContentState_Retrieving || pCurrent->eState == e_DLC_ContentState_Retrieved) - { - // already retrieved this - LeaveCriticalSection(&csDLCDownloadQueue); - return 0; - } - else - { - // promote - if(bPromote) - { - m_DLCDownloadQueue.erase(m_DLCDownloadQueue.begin()+iPosition); - m_DLCDownloadQueue.insert(m_DLCDownloadQueue.begin(),pCurrent); - } - LeaveCriticalSection(&csDLCDownloadQueue); - return 0; - } - } - iPosition++; - } - - DLCRequest *pDLCreq = new DLCRequest; - pDLCreq->dwType=m_dwContentTypeA[eType]; - pDLCreq->eState=e_DLC_ContentState_Idle; - - m_DLCDownloadQueue.push_back(pDLCreq); - - m_bAllDLCContentRetrieved=false; - LeaveCriticalSection(&csDLCDownloadQueue); - - app.DebugPrintf("[Consoles_App] Added DLC request.\n"); - return 1; -} - -unsigned int CMinecraftApp::AddTMSPPFileTypeRequest(eDLCContentType eType, bool bPromote) -{ -#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__) - // lock access - EnterCriticalSection(&csTMSPPDownloadQueue); - - // If it's already in there, promote it to the top of the list - int iPosition=0; - //ignore promoting for now - /* - bool bPromoted=false; - - - for ( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) - { - TMSPPRequest *pCurrent = *it; - - if(pCurrent->eType==eType) - { - if(!(pCurrent->eState == e_TMS_ContentState_Retrieving || pCurrent->eState == e_TMS_ContentState_Retrieved)) - { - // promote - if(bPromote) - { - m_TMSPPDownloadQueue.erase(m_TMSPPDownloadQueue.begin()+iPosition); - m_TMSPPDownloadQueue.insert(m_TMSPPDownloadQueue.begin(),pCurrent); - bPromoted=true; - } - } - } - iPosition++; - } - - if(bPromoted) - { - // re-ordered the list, so leave now - LeaveCriticalSection(&csTMSPPDownloadQueue); - return 0; - } - */ - - // special case for data files (not image files) - if(eType==e_DLC_TexturePackData) - { - - - int iCount=GetDLCInfoFullOffersCount(); - - for(int i=0;ieDLCType==e_DLC_TexturePacks) || (pDLC->eDLCType==e_DLC_MashupPacks)) - { - // first check if the image is already in the memory textures, since we might be loading some from the Title Update partition - if(pDLC->wchDataFile[0]!=0) - { - //WCHAR *cString = pDLC->wchDataFile; - // 4J-PB - shouldn't check this here - let the TMS files override it, so if they are on TMS, we'll take them first - //int iIndex = app.GetLocalTMSFileIndex(pDLC->wchDataFile,true); - - //if(iIndex!=-1) - { - bool bPresent = app.IsFileInTPD(pDLC->iConfig); - - if(!bPresent) - { - // this may already be present in the vector because of a previous trial/full offer - - bool bAlreadyInQueue=false; - for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) - { - if(wcscmp(pDLC->wchDataFile,pCurrent->wchFilename)==0) - { - bAlreadyInQueue=true; - break; - } - } - - if(!bAlreadyInQueue) - { - TMSPPRequest *pTMSPPreq = new TMSPPRequest; - - pTMSPPreq->CallbackFunc=&CMinecraftApp::TMSPPFileReturned; - pTMSPPreq->lpCallbackParam=this; - pTMSPPreq->eStorageFacility=C4JStorage::eGlobalStorage_Title; - pTMSPPreq->eFileTypeVal=C4JStorage::TMS_FILETYPE_BINARY; - memcpy(pTMSPPreq->wchFilename,pDLC->wchDataFile,sizeof(WCHAR)*MAX_BANNERNAME_SIZE); - pTMSPPreq->eType=e_DLC_TexturePackData; - pTMSPPreq->eState=e_TMS_ContentState_Queued; - m_bAllTMSContentRetrieved=false; - m_TMSPPDownloadQueue.push_back(pTMSPPreq); - } - } - else - { - app.DebugPrintf("Texture data already present in the TPD\n"); - } - } - } - } - } - } - else - { // for all the files of type eType, add them to the download list - - // run through the trial offers first, then the full offers. Any duplicates won't be added to the download queue - int iCount; -#ifdef _XBOX // Only trial offers on Xbox 360 - iCount=GetDLCInfoTrialOffersCount(); - for(int i=0;ieDLCType==eType) - { - - WCHAR *cString = pDLC->wchBanner; - - // 4J-PB - shouldn't check this here - let the TMS files override it, so if they are on TMS, we'll take them first - // is the file in the TMS XZP? - //int iIndex = app.GetLocalTMSFileIndex(cString,true); - - //if(iIndex!=-1) - { - bool bPresent = app.IsFileInMemoryTextures(cString); - - if(!bPresent) // retrieve it from TMSPP - { - bool bAlreadyInQueue=false; - for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) - { - if(wcscmp(pDLC->wchBanner,pCurrent->wchFilename)==0) - { - bAlreadyInQueue=true; - break; - } - } - - if(!bAlreadyInQueue) - { - TMSPPRequest *pTMSPPreq = new TMSPPRequest; - - pTMSPPreq->CallbackFunc=&CMinecraftApp::TMSPPFileReturned; - pTMSPPreq->lpCallbackParam=this; - pTMSPPreq->eStorageFacility=C4JStorage::eGlobalStorage_Title; - pTMSPPreq->eFileTypeVal=C4JStorage::TMS_FILETYPE_BINARY; - //wcstombs(pTMSPPreq->szFilename,pDLC->wchBanner,MAX_TMSFILENAME_SIZE); - memcpy(pTMSPPreq->wchFilename,pDLC->wchBanner,sizeof(WCHAR)*MAX_BANNERNAME_SIZE); - pTMSPPreq->eType=eType; - pTMSPPreq->eState=e_TMS_ContentState_Queued; - - m_bAllTMSContentRetrieved=false; - m_TMSPPDownloadQueue.push_back(pTMSPPreq); - app.DebugPrintf("===m_TMSPPDownloadQueue Adding %ls, q size is %d\n",pTMSPPreq->wchFilename,m_TMSPPDownloadQueue.size()); - } - } - } - } - } -#endif - // and the full offers - - iCount=GetDLCInfoFullOffersCount(); - for(int i=0;iwchType,wchDLCTypeNames[eType])==0) - if(pDLC->eDLCType==eType) - { - // first check if the image is already in the memory textures, since we might be loading some from the Title Update partition - - WCHAR *cString = pDLC->wchBanner; - // 4J-PB - shouldn't check this here - let the TMS files override it, so if they are on TMS, we'll take them first - //int iIndex = app.GetLocalTMSFileIndex(cString,true); - - //if(iIndex!=-1) - { - bool bPresent = app.IsFileInMemoryTextures(cString); - - if(!bPresent) - { - // this may already be present in the vector because of a previous trial/full offer - - bool bAlreadyInQueue=false; - for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) - { - if(wcscmp(pDLC->wchBanner,pCurrent->wchFilename)==0) - { - bAlreadyInQueue=true; - break; - } - } - - if(!bAlreadyInQueue) - { - //app.DebugPrintf("Adding a request to the TMSPP download queue - %ls\n",pDLC->wchBanner); - TMSPPRequest *pTMSPPreq = new TMSPPRequest; - ZeroMemory(pTMSPPreq,sizeof(TMSPPRequest)); - - pTMSPPreq->CallbackFunc=&CMinecraftApp::TMSPPFileReturned; - pTMSPPreq->lpCallbackParam=this; - // 4J-PB - testing for now - //pTMSPPreq->eStorageFacility=C4JStorage::eGlobalStorage_TitleUser; - pTMSPPreq->eStorageFacility=C4JStorage::eGlobalStorage_Title; - pTMSPPreq->eFileTypeVal=C4JStorage::TMS_FILETYPE_BINARY; - //wcstombs(pTMSPPreq->szFilename,pDLC->wchBanner,MAX_TMSFILENAME_SIZE); - - memcpy(pTMSPPreq->wchFilename,pDLC->wchBanner,sizeof(WCHAR)*MAX_BANNERNAME_SIZE); - pTMSPPreq->eType=eType; - pTMSPPreq->eState=e_TMS_ContentState_Queued; - m_bAllTMSContentRetrieved=false; - m_TMSPPDownloadQueue.push_back(pTMSPPreq); - app.DebugPrintf("===m_TMSPPDownloadQueue Adding %ls, q size is %d\n",pTMSPPreq->wchFilename,m_TMSPPDownloadQueue.size()); - } - } - } - } - } - } - - LeaveCriticalSection(&csTMSPPDownloadQueue); -#endif - return 1; -} - -bool CMinecraftApp::CheckTMSDLCCanStop() -{ - EnterCriticalSection(&csTMSPPDownloadQueue); - for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) - { - if(pCurrent->eState==e_TMS_ContentState_Retrieving) - { - LeaveCriticalSection(&csTMSPPDownloadQueue); - return false; - } - } - LeaveCriticalSection(&csTMSPPDownloadQueue); - - return true; -} - - -bool CMinecraftApp::RetrieveNextDLCContent() -{ - // If there's already a retrieve in progress, quit - // we may have re-ordered the list, so need to check every item - - // is there a primary player and a network connection? - int primPad = ProfileManager.GetPrimaryPad(); - if ( primPad == -1 || !ProfileManager.IsSignedInLive(primPad) ) - { - return true; // 4J-JEV: We need to wait until the primary player is online. - } - - EnterCriticalSection(&csDLCDownloadQueue); - for( const DLCRequest* pCurrent : m_DLCDownloadQueue ) - { - if(pCurrent->eState==e_DLC_ContentState_Retrieving) - { - LeaveCriticalSection(&csDLCDownloadQueue); - return true; - } - } - - // Now look for the next retrieval - for( DLCRequest *pCurrent : m_DLCDownloadQueue ) - { - if(pCurrent->eState==e_DLC_ContentState_Idle) - { -#ifdef _DEBUG - app.DebugPrintf("RetrieveNextDLCContent - type = %d\n",pCurrent->dwType); -#endif - - C4JStorage::EDLCStatus status = StorageManager.GetDLCOffers(ProfileManager.GetPrimaryPad(), &CMinecraftApp::DLCOffersReturned, this, pCurrent->dwType); - if(status==C4JStorage::EDLC_Pending) - { - pCurrent->eState=e_DLC_ContentState_Retrieving; - } - else - { - // no content of this type, or some other problem - app.DebugPrintf("RetrieveNextDLCContent - PROBLEM\n"); - pCurrent->eState=e_DLC_ContentState_Retrieved; - } - LeaveCriticalSection(&csDLCDownloadQueue); - return true; - } - } - LeaveCriticalSection(&csDLCDownloadQueue); - - app.DebugPrintf("[Consoles_App] Finished downloading dlc content.\n"); - return false; -} - -#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__) -#ifdef _XBOX_ONE -int CMinecraftApp::TMSPPFileReturned(LPVOID pParam,int iPad,int iUserData,LPVOID lpvData, WCHAR* wchFilename) -{ - C4JStorage::PTMSPP_FILEDATA pFileData=(C4JStorage::PTMSPP_FILEDATA)lpvData; -#else -int CMinecraftApp::TMSPPFileReturned(LPVOID pParam,int iPad,int iUserData,C4JStorage::PTMSPP_FILEDATA pFileData, LPCSTR szFilename) -{ -#endif - - CMinecraftApp* pClass = static_cast(pParam); - - // find the right one in the vector - EnterCriticalSection(&pClass->csTMSPPDownloadQueue); - for( TMSPPRequest *pCurrent : pClass->m_TMSPPDownloadQueue ) - { -#if defined(_XBOX) || defined(_WINDOWS64) - char szFile[MAX_TMSFILENAME_SIZE]; - wcstombs(szFile,pCurrent->wchFilename,MAX_TMSFILENAME_SIZE); - - - if(strcmp(szFilename,szFile)==0) -#elif _XBOX_ONE - if(wcscmp(wchFilename,pCurrent->wchFilename)==0) -#endif - { - // set this to retrieved whether it found it or not - pCurrent->eState=e_TMS_ContentState_Retrieved; - - if(pFileData!=nullptr) - { -#ifdef _XBOX_ONE - - - switch(pCurrent->eType) - { - case e_DLC_TexturePackData: - { - // 4J-PB - we need to allocate memory for the file data and copy into it, since the current data is a reference into the blob download memory - PBYTE pbData = new BYTE [pFileData->dwSize]; - memcpy(pbData,pFileData->pbData,pFileData->dwSize); - - pClass->m_vTMSPPData.push_back(pbData); - app.DebugPrintf("Got texturepack data\n"); - // get the config value for the texture pack - int iConfig=app.GetTPConfigVal(pCurrent->wchFilename); - app.AddMemoryTPDFile(iConfig, pbData, pFileData->dwSize); - } - break; - default: - // 4J-PB - check the data is an image - if(pFileData->pbData[0]==0x89) - { - // 4J-PB - we need to allocate memory for the file data and copy into it, since the current data is a reference into the blob download memory - PBYTE pbData = new BYTE [pFileData->dwSize]; - memcpy(pbData,pFileData->pbData,pFileData->dwSize); - - pClass->m_vTMSPPData.push_back(pbData); - app.DebugPrintf("Got image data - %ls\n",pCurrent->wchFilename); - app.AddMemoryTextureFile(pCurrent->wchFilename, pbData, pFileData->dwSize); - } - else - { - app.DebugPrintf("Got image data, but it's not a png - %ls\n",pCurrent->wchFilename); - } - break; - } - -#else - switch(pCurrent->eType) - { - case e_DLC_TexturePackData: - { - app.DebugPrintf("--- Got texturepack data %ls\n",pCurrent->wchFilename); - // get the config value for the texture pack - int iConfig=app.GetTPConfigVal(pCurrent->wchFilename); - app.AddMemoryTPDFile(iConfig, pFileData->pbData, pFileData->dwSize); - } - break; - default: - app.DebugPrintf("--- Got image data - %ls\n",pCurrent->wchFilename); - app.AddMemoryTextureFile(pCurrent->wchFilename, pFileData->pbData, pFileData->dwSize); - break; - } -#endif - } - else - { -#ifdef _XBOX_ONE - app.DebugPrintf("TMSImageReturned failed (%ls)...\n",wchFilename); -#else - app.DebugPrintf("TMSImageReturned failed (%s)...\n",szFilename); -#endif - } - break; - } - - } - LeaveCriticalSection(&pClass->csTMSPPDownloadQueue); - - return 0; -} -#endif - -bool CMinecraftApp::RetrieveNextTMSPPContent() -{ -#if defined _XBOX || defined _XBOX_ONE - // If there's already a retrieve in progress, quit - // we may have re-ordered the list, so need to check every item - - // is there a primary player and a network connection? - if(ProfileManager.GetPrimaryPad()==-1) return false; - - if(ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad())==false) return false; - - for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) - { - TMSPPRequest *pCurrent = *it; - - if(pCurrent->eState==e_TMS_ContentState_Retrieving) - { - app.DebugPrintf("."); - LeaveCriticalSection(&csTMSPPDownloadQueue); - return true; - } - } - - // Now look for the next retrieval - for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) - { - TMSPPRequest *pCurrent = *it; - - if(pCurrent->eState==e_TMS_ContentState_Queued) - { - // 4J-PB - the file may be in the local TMS files, but try to retrieve it from the remote TMS in case it's been changed. If it's not in the list of TMS files, this will - // return right away with a ETMSStatus_Fail_ReadDetailsNotRetrieved -#ifdef _XBOX - char szFilename[MAX_TMSFILENAME_SIZE]; - wcstombs(szFilename,pCurrent->wchFilename,MAX_TMSFILENAME_SIZE); - - app.DebugPrintf("\nRetrieveNextTMSPPContent - type = %d, %s\n",pCurrent->eType,szFilename); - - C4JStorage::ETMSStatus status=StorageManager.TMSPP_ReadFile(ProfileManager.GetPrimaryPad(),pCurrent->eStorageFacility,pCurrent->eFileTypeVal,szFilename,pCurrent->CallbackFunc,this); - switch(status) - { - case C4JStorage::ETMSStatus_Pending: - pCurrent->eState=e_TMS_ContentState_Retrieving; - break; - case C4JStorage::ETMSStatus_Idle: - pCurrent->eState=e_TMS_ContentState_Retrieved; - break; - case C4JStorage::ETMSStatus_Fail_ReadInProgress: - case C4JStorage::ETMSStatus_ReadInProgress: - pCurrent->eState=e_TMS_ContentState_Retrieving; - if(pCurrent->eState==C4JStorage::ETMSStatus_Fail_ReadInProgress) - { - app.DebugPrintf("TMSPP_ReadFile failed - read in progress\n"); - Sleep(50); - LeaveCriticalSection(&csTMSPPDownloadQueue); - return false; - } - break; - default: - pCurrent->eState=e_TMS_ContentState_Retrieved; - break; - } -#else - eTitleStorageState status; - app.DebugPrintf("RetrieveNextTMSPPContent - type = %d, %ls\n",pCurrent->eType,pCurrent->wchFilename); - //eTitleStorageState status=StorageManager.TMSPP_ReadFile(ProfileManager.GetPrimaryPad(),pCurrent->eStorageFacility,pCurrent->eFileTypeVal,pCurrent->wchFilename,pCurrent->CallbackFunc,this,0); - if(0)//wcscmp(pCurrent->wchFilename,L"TP01.png")==0) - { - // TP01 fails because the blob size returned is bigger than the global metadata says it should be - status=eTitleStorage_readerror; - } - else - { - status=StorageManager.TMSPP_ReadFile(ProfileManager.GetPrimaryPad(),pCurrent->eStorageFacility,pCurrent->eFileTypeVal,pCurrent->wchFilename,pCurrent->CallbackFunc,this,0); - } - switch(status) - { - case eTitleStorage_pending: - pCurrent->eState=e_TMS_ContentState_Retrieving; - break; - case eTitleStorage_idle: - pCurrent->eState=e_TMS_ContentState_Retrieved; - break; - case eTitleStorage_busy: - // try again next time - { - app.DebugPrintf("@@@@@@@@@@@@@@@@@ TMSPP_ReadFile failed - busy (probably reading already)\n"); - Sleep(50); - LeaveCriticalSection(&csTMSPPDownloadQueue); - return false; - } - break; - default: - pCurrent->eState=e_TMS_ContentState_Retrieved; - break; - } -#endif - - - - LeaveCriticalSection(&csTMSPPDownloadQueue); - return true; - } - } - - LeaveCriticalSection(&csTMSPPDownloadQueue); - -#endif - return false; -} - -void CMinecraftApp::TickDLCOffersRetrieved() -{ - if(!m_bAllDLCContentRetrieved) - { - if (!app.RetrieveNextDLCContent()) - { - app.DebugPrintf("[Consoles_App] All content retrieved.\n"); - m_bAllDLCContentRetrieved=true; - } - } -} -void CMinecraftApp::ClearAndResetDLCDownloadQueue() -{ - app.DebugPrintf("[Consoles_App] Clear and reset download queue.\n"); - - int iPosition=0; - EnterCriticalSection(&csTMSPPDownloadQueue); - for( DLCRequest *pCurrent : m_DLCDownloadQueue ) - { - if ( pCurrent ) - delete pCurrent; - iPosition++; - } - m_DLCDownloadQueue.clear(); - m_bAllDLCContentRetrieved=true; - LeaveCriticalSection(&csTMSPPDownloadQueue); -} - -void CMinecraftApp::TickTMSPPFilesRetrieved() -{ - if(m_bTickTMSDLCFiles && !m_bAllTMSContentRetrieved) - { - if(app.RetrieveNextTMSPPContent()==false) - { - m_bAllTMSContentRetrieved=true; - } - } -} -void CMinecraftApp::ClearTMSPPFilesRetrieved() -{ - int iPosition=0; - EnterCriticalSection(&csTMSPPDownloadQueue); - for ( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) - { - if ( pCurrent ) - delete pCurrent; - iPosition++; - } - m_TMSPPDownloadQueue.clear(); - m_bAllTMSContentRetrieved=true; - LeaveCriticalSection(&csTMSPPDownloadQueue); -} - -int CMinecraftApp::DLCOffersReturned(void *pParam, int iOfferC, DWORD dwType, int iPad) -{ - CMinecraftApp* pClass = static_cast(pParam); - - // find the right one in the vector - EnterCriticalSection(&pClass->csTMSPPDownloadQueue); - for( DLCRequest *pCurrent : pClass->m_DLCDownloadQueue ) - { - // avatar items are coming back as type Content, so we can't trust the type setting - if(pCurrent->dwType==dwType) - { - pClass->m_iDLCOfferC = iOfferC; - app.DebugPrintf("DLCOffersReturned - type %d, count %d - setting to retrieved\n",dwType,iOfferC); - pCurrent->eState=e_DLC_ContentState_Retrieved; - break; - } - } - LeaveCriticalSection(&pClass->csTMSPPDownloadQueue); - return 0; -} - -eDLCContentType CMinecraftApp::Find_eDLCContentType(DWORD dwType) -{ - for(int i=0;i(i); - } - } - return static_cast(0); -} -bool CMinecraftApp::DLCContentRetrieved(eDLCMarketplaceType eType) -{ - // If there's already a retrieve in progress, quit - // we may have re-ordered the list, so need to check every item - EnterCriticalSection(&csDLCDownloadQueue); - for( DLCRequest *pCurrent : m_DLCDownloadQueue ) - { - if((pCurrent->dwType==m_dwContentTypeA[eType]) && (pCurrent->eState==e_DLC_ContentState_Retrieved)) - { - LeaveCriticalSection(&csDLCDownloadQueue); - return true; - } - } - LeaveCriticalSection(&csDLCDownloadQueue); - return false; -} - -void CMinecraftApp::SetAdditionalSkinBoxes(DWORD dwSkinID, SKIN_BOX *SkinBoxA, DWORD dwSkinBoxC) -{ - EntityRenderDispatcher *dispatcher = EntityRenderDispatcher::instance; - EntityRenderer *renderer = dispatcher ? dispatcher->getRenderer(eTYPE_PLAYER) : nullptr; - unsigned int m_uiAnimOverrideBitmask = GetAnimOverrideBitmask(dwSkinID); - Model *pModel; - if (m_uiAnimOverrideBitmask & (1 << HumanoidModel::eAnim_SlimModel)) - pModel = renderer ? renderer->getModel(2) : nullptr; - else if (m_uiAnimOverrideBitmask & (1 << HumanoidModel::eAnim_WideModel)) - pModel = renderer ? renderer->getModel(1) : nullptr; - else - pModel = renderer ? renderer->getModel(0) : nullptr; - vector *pvModelPart = new vector; - vector *pvSkinBoxes = new vector; - - EnterCriticalSection( &csAdditionalModelParts ); - EnterCriticalSection( &csAdditionalSkinBoxes ); - - app.DebugPrintf("*** SetAdditionalSkinBoxes - Inserting model parts for skin %d from array of Skin Boxes\n",dwSkinID&0x0FFFFFFF); - - // convert the skin boxes into model parts, and add to the humanoid model - for(unsigned int i=0;iAddOrRetrievePart(&SkinBoxA[i]); - pvModelPart->push_back(pModelPart); - pvSkinBoxes->push_back(&SkinBoxA[i]); - } - } - - - m_AdditionalModelParts.insert( std::pair *>(dwSkinID, pvModelPart) ); - m_AdditionalSkinBoxes.insert( std::pair *>(dwSkinID, pvSkinBoxes) ); - - LeaveCriticalSection( &csAdditionalSkinBoxes ); - LeaveCriticalSection( &csAdditionalModelParts ); - -} - -vector * CMinecraftApp::SetAdditionalSkinBoxes(DWORD dwSkinID, vector *pvSkinBoxA) -{ - EntityRenderDispatcher *dispatcher = EntityRenderDispatcher::instance; - EntityRenderer *renderer = dispatcher ? dispatcher->getRenderer(eTYPE_PLAYER) : nullptr; - unsigned int m_uiAnimOverrideBitmask = GetAnimOverrideBitmask(dwSkinID); - Model *pModel; - if (m_uiAnimOverrideBitmask & (1 << HumanoidModel::eAnim_SlimModel)) - pModel = renderer ? renderer->getModel(2) : nullptr; - else if (m_uiAnimOverrideBitmask & (1 << HumanoidModel::eAnim_WideModel)) - pModel = renderer ? renderer->getModel(1) : nullptr; - else - pModel = renderer ? renderer->getModel(0) : nullptr; - vector *pvModelPart = new vector; - - EnterCriticalSection( &csAdditionalModelParts ); - EnterCriticalSection( &csAdditionalSkinBoxes ); - app.DebugPrintf("*** SetAdditionalSkinBoxes - Inserting model parts for skin %d from array of Skin Boxes\n",dwSkinID&0x0FFFFFFF); - - // convert the skin boxes into model parts, and add to the humanoid model - for( auto& it : *pvSkinBoxA ) - { - if(pModel) - { - ModelPart *pModelPart=pModel->AddOrRetrievePart(it); - pvModelPart->push_back(pModelPart); - } - } - - m_AdditionalModelParts.emplace(dwSkinID, pvModelPart); - m_AdditionalSkinBoxes.emplace(dwSkinID, pvSkinBoxA); - - LeaveCriticalSection( &csAdditionalSkinBoxes ); - LeaveCriticalSection( &csAdditionalModelParts ); - return pvModelPart; -} - -void CMinecraftApp::SetSkinOffsets(DWORD dwSkinID, SKIN_OFFSET *SkinOffsetA, DWORD dwSkinOffsetC) -{ - vector *pvSkinOffset = new vector; - - EnterCriticalSection( &csSkinOffsets ); - - app.DebugPrintf("*** SetSkinOffsets - Adding skin offsets for skin %d from array of Skin Offsets\n",dwSkinID&0x0FFFFFFF); - - for(unsigned int i=0;ipush_back(&SkinOffsetA[i]); - } - - - m_SkinOffsets.insert( std::pair *>(dwSkinID, pvSkinOffset) ); - - LeaveCriticalSection( &csSkinOffsets ); - -} - -vector * CMinecraftApp::SetSkinOffsets(DWORD dwSkinID, vector *pvSkinOffsetA) -{ - vector *pvSkinOffset = new vector; - - EnterCriticalSection( &csSkinOffsets ); - app.DebugPrintf("*** SetSkinOffsets - Inserting skin offsets for skin %d from array of Skin Offsets\n",dwSkinID&0x0FFFFFFF); - - for( auto& it : *pvSkinOffsetA ) - { - pvSkinOffset->push_back(it); - } - - m_SkinOffsets.emplace(dwSkinID, pvSkinOffsetA); - - LeaveCriticalSection( &csSkinOffsets ); - return pvSkinOffset; -} - - -vector *CMinecraftApp::GetAdditionalModelParts(DWORD dwSkinID) -{ - EnterCriticalSection( &csAdditionalModelParts ); - vector *pvModelParts=nullptr; - if(m_AdditionalModelParts.size()>0) - { - auto it = m_AdditionalModelParts.find(dwSkinID); - if(it!=m_AdditionalModelParts.end()) - { - pvModelParts = (*it).second; - } - } - - LeaveCriticalSection( &csAdditionalModelParts ); - return pvModelParts; -} - -vector *CMinecraftApp::GetAdditionalSkinBoxes(DWORD dwSkinID) -{ - EnterCriticalSection( &csAdditionalSkinBoxes ); - vector *pvSkinBoxes=nullptr; - if(m_AdditionalSkinBoxes.size()>0) - { - auto it = m_AdditionalSkinBoxes.find(dwSkinID); - if(it!=m_AdditionalSkinBoxes.end()) - { - pvSkinBoxes = (*it).second; - } - } - - LeaveCriticalSection( &csAdditionalSkinBoxes ); - return pvSkinBoxes; -} - -vector *CMinecraftApp::GetSkinOffsets(DWORD dwSkinID) -{ - EnterCriticalSection( &csSkinOffsets ); - vector *pvSkinOffsets=nullptr; - if(m_SkinOffsets.size()>0) - { - auto it = m_SkinOffsets.find(dwSkinID); - if(it!=m_SkinOffsets.end()) - { - pvSkinOffsets = (*it).second; - } - } - - LeaveCriticalSection( &csSkinOffsets ); - return pvSkinOffsets; -} - -unsigned int CMinecraftApp::GetAnimOverrideBitmask(DWORD dwSkinID) -{ - EnterCriticalSection( &csAnimOverrideBitmask ); - unsigned int uiAnimOverrideBitmask=0L; - - if(m_AnimOverrides.size()>0) - { - auto it = m_AnimOverrides.find(dwSkinID); - if(it!=m_AnimOverrides.end()) - { - uiAnimOverrideBitmask = (*it).second; - } - } - - LeaveCriticalSection( &csAnimOverrideBitmask ); - return uiAnimOverrideBitmask; -} - -void CMinecraftApp::SetAnimOverrideBitmask(DWORD dwSkinID,unsigned int uiAnimOverrideBitmask) -{ - // Make thread safe - EnterCriticalSection( &csAnimOverrideBitmask ); - - if(m_AnimOverrides.size()>0) - { - auto it = m_AnimOverrides.find(dwSkinID); - if(it!=m_AnimOverrides.end()) - { - LeaveCriticalSection( &csAnimOverrideBitmask ); - return; // already in here - } - } - m_AnimOverrides.insert( std::pair(dwSkinID, uiAnimOverrideBitmask) ); - LeaveCriticalSection( &csAnimOverrideBitmask ); -} - -DWORD CMinecraftApp::getSkinIdFromPath(const wstring &skin) -{ - bool dlcSkin = false; - unsigned int skinId = 0; - - if(skin.size() >= 14) - { - dlcSkin = skin.substr(0,3).compare(L"dlc") == 0; - - wstring skinValue = skin.substr(7,skin.size()); - skinValue = skinValue.substr(0,skinValue.find_first_of(L'.')); - - std::wstringstream ss; - // 4J Stu - dlc skins are numbered using decimal to make it easier for artists/people to number manually - // Everything else is numbered using hex - if(dlcSkin) - ss << std::dec << skinValue.c_str(); - else - ss << std::hex << skinValue.c_str(); - ss >> skinId; - - skinId = MAKE_SKIN_BITMASK(dlcSkin, skinId); - } - return skinId; -} - -wstring CMinecraftApp::getSkinPathFromId(DWORD skinId) -{ - // 4J Stu - This function maps the encoded DWORD we store in the player profile - // to a filename that is stored as a memory texture and shared between systems in game - wchar_t chars[256]; - if( GET_IS_DLC_SKIN_FROM_BITMASK(skinId) ) - { - // 4J Stu - DLC skins are numbered using decimal rather than hex to make it easier to number manually - swprintf(chars, 256, L"dlcskin%08d.png", GET_DLC_SKIN_ID_FROM_BITMASK(skinId)); - - } - else - { - DWORD ugcSkinIndex = GET_UGC_SKIN_ID_FROM_BITMASK(skinId); - DWORD defaultSkinIndex = GET_DEFAULT_SKIN_ID_FROM_BITMASK(skinId); - if( ugcSkinIndex == 0 ) - { - swprintf(chars, 256, L"defskin%08X.png",defaultSkinIndex); - } - else - { - swprintf(chars, 256, L"ugcskin%08X.png",ugcSkinIndex); - } - } - return chars; -} - - -int CMinecraftApp::TexturePackDialogReturned(void* pParam, int iPad, C4JStorage::EMessageResult result) -{ - -#if defined __PSVITA__ || defined __PS3__ || defined __ORBIS__ - if (result == C4JStorage::EMessage_ResultAccept) - { - Minecraft* pMinecraft = Minecraft::GetInstance(); - if (pMinecraft->skins->selectTexturePackById(app.GetRequiredTexturePackID())) - { - // it's been installed already - } - else - { - // we need to enable background downloading for the DLC - XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); - - SONYDLC* pSONYDLCInfo = app.GetSONYDLCInfo(app.GetRequiredTexturePackID()); - if (pSONYDLCInfo != nullptr) - { - char chName[42]; - char chKeyName[20]; - char chSkuID[SCE_NP_COMMERCE2_SKU_ID_LEN]; - - memset(chSkuID, 0, SCE_NP_COMMERCE2_SKU_ID_LEN); - - memset(chKeyName, 0, sizeof(chKeyName)); - strncpy(chKeyName, pSONYDLCInfo->chDLCKeyname, 16); - - #ifdef __ORBIS__ - strcpy(chName, chKeyName); - #else - sprintf(chName, "%s-%s", app.GetCommerceCategory(), chKeyName); - #endif - - app.GetDLCSkuIDFromProductList(chName, chSkuID); - - if (app.CheckForEmptyStore(iPad) == false) - { - if (app.DLCAlreadyPurchased(chSkuID)) - { - app.DownloadAlreadyPurchased(chSkuID); - } - else - { - app.Checkout(chSkuID); - } - } - } - } - } - else - { - app.DebugPrintf("Continuing without installing texture pack\n"); - } -#endif - -#ifdef _XBOX - if (result != C4JStorage::EMessage_Cancelled) - { - if (app.GetRequiredTexturePackID() != 0) - { - XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); - - ULONGLONG ullOfferID_Full; - ULONGLONG ullIndexA[1]; - app.GetDLCFullOfferIDForPackID(app.GetRequiredTexturePackID(), &ullOfferID_Full); - - if (result == C4JStorage::EMessage_ResultAccept) - { - ullIndexA[0] = ullOfferID_Full; - StorageManager.InstallOffer(1, ullIndexA, nullptr, nullptr); - } - else - { - DLC_INFO* pDLCInfo = app.GetDLCInfoForFullOfferID(ullOfferID_Full); - ullIndexA[0] = pDLCInfo->ullOfferID_Trial; - StorageManager.InstallOffer(1, ullIndexA, nullptr, nullptr); - } - } - } -#endif - return 0; -} -int CMinecraftApp::getArchiveFileSize(const wstring &filename) -{ - TexturePack *tPack = nullptr; - Minecraft *pMinecraft = Minecraft::GetInstance(); - if(pMinecraft && pMinecraft->skins) tPack = pMinecraft->skins->getSelected(); - if(tPack && tPack->hasData() && tPack->getArchiveFile() && tPack->getArchiveFile()->hasFile(filename)) - { - return tPack->getArchiveFile()->getFileSize(filename); - } - else return m_mediaArchive->getFileSize(filename); -} - -bool CMinecraftApp::hasArchiveFile(const wstring &filename) -{ - TexturePack *tPack = nullptr; - Minecraft *pMinecraft = Minecraft::GetInstance(); - if(pMinecraft && pMinecraft->skins) tPack = pMinecraft->skins->getSelected(); - if(tPack && tPack->hasData() && tPack->getArchiveFile() && tPack->getArchiveFile()->hasFile(filename)) return true; - else return m_mediaArchive->hasFile(filename); -} - -byteArray CMinecraftApp::getArchiveFile(const wstring &filename) -{ - TexturePack *tPack = nullptr; - Minecraft *pMinecraft = Minecraft::GetInstance(); - if(pMinecraft && pMinecraft->skins) tPack = pMinecraft->skins->getSelected(); - if(tPack && tPack->hasData() && tPack->getArchiveFile() && tPack->getArchiveFile()->hasFile(filename)) - { - return tPack->getArchiveFile()->getFile(filename); - } - else return m_mediaArchive->getFile(filename); -} - -// DLC - -#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) -int CMinecraftApp::GetDLCInfoCount() -{ - return (int)DLCInfo.size(); -} -#elif defined _XBOX_ONE -int CMinecraftApp::GetDLCInfoTrialOffersCount() -{ - return 0; -} - -int CMinecraftApp::GetDLCInfoFullOffersCount() -{ - return (int)DLCInfo_Full.size(); -} -#else -int CMinecraftApp::GetDLCInfoTrialOffersCount() -{ - return static_cast(DLCInfo_Trial.size()); -} - -int CMinecraftApp::GetDLCInfoFullOffersCount() -{ - return static_cast(DLCInfo_Full.size()); -} -#endif - -int CMinecraftApp::GetDLCInfoTexturesOffersCount() -{ - return static_cast(DLCTextures_PackID.size()); -} - -// AUTOSAVE -void CMinecraftApp::SetAutosaveTimerTime(void) -{ -#if defined(_XBOX_ONE) || defined(__ORBIS__) - m_uiAutosaveTimer= GetTickCount()+1000*60; -#else - m_uiAutosaveTimer= GetTickCount()+GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_Autosave)*1000*60*15; -#endif -}// value x 15 to get mins, x60 for secs - -bool CMinecraftApp::AutosaveDue(void) -{ - return (GetTickCount()>m_uiAutosaveTimer); -} - -unsigned int CMinecraftApp::SecondsToAutosave() -{ - return (m_uiAutosaveTimer - GetTickCount() ) / 1000; -} - -void CMinecraftApp::SetTrialTimerStart(void) -{ - m_fTrialTimerStart=m_Time.fAppTime; mfTrialPausedTime=0.0f; -} - -float CMinecraftApp::getTrialTimer(void) -{ - return m_Time.fAppTime-m_fTrialTimerStart-mfTrialPausedTime; -} - -bool CMinecraftApp::IsLocalMultiplayerAvailable() -{ - DWORD connectedControllers = 0; - for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) - { - if( InputManager.IsPadConnected(i) || ProfileManager.IsSignedIn(i) ) ++connectedControllers; - } - -#ifdef _WINDOWS64 - bool available = connectedControllers > 1; -#else - bool available = RenderManager.IsHiDef() && connectedControllers > 1; -#endif - -#ifdef __ORBIS__ - // Check for remote play - available = available && InputManager.IsLocalMultiplayerAvailable(); -#endif - - return available; - - // Found this in GameNetworkManager? - //#ifdef _DURANGO - // iOtherConnectedControllers = InputManager.GetConnectedGamepadCount(); - // if((InputManager.IsPadConnected(userIndex) || ProfileManager.IsSignedIn(userIndex))) - // { - // --iOtherConnectedControllers; - // } - //#else - // for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) - // { - // if( (i!=userIndex) && (InputManager.IsPadConnected(i) || ProfileManager.IsSignedIn(i)) ) - // { - // iOtherConnectedControllers++; - // } - // } - //#endif -} - - -// 4J-PB - language and locale function - -void CMinecraftApp::getLocale(vector &vecWstrLocales) -{ - vector locales; - - DWORD dwSystemLanguage = XGetLanguage( ); - - // 4J-PB - restrict the 360 language until we're ready to have them in - -#ifdef _XBOX - switch(dwSystemLanguage) - { - case XC_LANGUAGE_FRENCH : - locales.push_back(eMCLang_frFR); - break; - case XC_LANGUAGE_ITALIAN : - locales.push_back(eMCLang_itIT); - break; - case XC_LANGUAGE_GERMAN : - locales.push_back(eMCLang_deDE); - break; - case XC_LANGUAGE_SPANISH : - locales.push_back(eMCLang_esES); - break; - case XC_LANGUAGE_PORTUGUESE : - if(XGetLocale()==XC_LOCALE_BRAZIL) - { - locales.push_back(eMCLang_ptBR); - } - locales.push_back(eMCLang_ptPT); - break; - case XC_LANGUAGE_JAPANESE : - locales.push_back(eMCLang_jaJP); - break; - case XC_LANGUAGE_KOREAN : - locales.push_back(eMCLang_koKR); - break; - case XC_LANGUAGE_TCHINESE : - locales.push_back(eMCLang_zhCHT); - break; - } -#else - switch(dwSystemLanguage) - { - - case XC_LANGUAGE_ENGLISH: - switch(XGetLocale()) - { - case XC_LOCALE_AUSTRALIA: - case XC_LOCALE_CANADA: - case XC_LOCALE_CZECH_REPUBLIC: - case XC_LOCALE_GREECE: - case XC_LOCALE_HONG_KONG: - case XC_LOCALE_HUNGARY: - case XC_LOCALE_INDIA: - case XC_LOCALE_IRELAND: - case XC_LOCALE_ISRAEL: - case XC_LOCALE_NEW_ZEALAND: - case XC_LOCALE_SAUDI_ARABIA: - case XC_LOCALE_SINGAPORE: - case XC_LOCALE_SLOVAK_REPUBLIC: - case XC_LOCALE_SOUTH_AFRICA: - case XC_LOCALE_UNITED_ARAB_EMIRATES: - case XC_LOCALE_GREAT_BRITAIN: - locales.push_back(eMCLang_enGB); - break; - default: //XC_LOCALE_UNITED_STATES - break; - } - break; - case XC_LANGUAGE_JAPANESE : - locales.push_back(eMCLang_jaJP); - break; - case XC_LANGUAGE_GERMAN : - switch(XGetLocale()) - { - case XC_LOCALE_AUSTRIA: - locales.push_back(eMCLang_deAT); - break; - case XC_LOCALE_SWITZERLAND: - locales.push_back(eMCLang_deCH); - break; - default:// XC_LOCALE_GERMANY: - break; - } - locales.push_back(eMCLang_deDE); - break; - case XC_LANGUAGE_FRENCH : - switch(XGetLocale()) - { - case XC_LOCALE_BELGIUM: - locales.push_back(eMCLang_frBE); - break; - case XC_LOCALE_CANADA: - locales.push_back(eMCLang_frCA); - break; - case XC_LOCALE_SWITZERLAND: - locales.push_back(eMCLang_frCH); - break; - default:// XC_LOCALE_FRANCE: - break; - } - locales.push_back(eMCLang_frFR); - break; - case XC_LANGUAGE_SPANISH : - switch(XGetLocale()) - { - case XC_LOCALE_MEXICO: - case XC_LOCALE_ARGENTINA: - case XC_LOCALE_CHILE: - case XC_LOCALE_COLOMBIA: - case XC_LOCALE_UNITED_STATES: - case XC_LOCALE_LATIN_AMERICA: - locales.push_back(eMCLang_laLAS); - locales.push_back(eMCLang_esMX); - break; - default://XC_LOCALE_SPAIN - break; - } - locales.push_back(eMCLang_esES); - break; - case XC_LANGUAGE_ITALIAN : - locales.push_back(eMCLang_itIT); - break; - case XC_LANGUAGE_KOREAN : - locales.push_back(eMCLang_koKR); - break; - case XC_LANGUAGE_TCHINESE : - switch(XGetLocale()) - { - case XC_LOCALE_HONG_KONG: - locales.push_back(eMCLang_zhHK); - locales.push_back(eMCLang_zhTW); - break; - case XC_LOCALE_TAIWAN: - locales.push_back(eMCLang_zhTW); - locales.push_back(eMCLang_zhHK); - default: - break; - } - locales.push_back(eMCLang_hant); - locales.push_back(eMCLang_zhCHT); - break; - case XC_LANGUAGE_PORTUGUESE : - if(XGetLocale()==XC_LOCALE_BRAZIL) - { - locales.push_back(eMCLang_ptBR); - } - locales.push_back(eMCLang_ptPT); - break; - case XC_LANGUAGE_POLISH : - locales.push_back(eMCLang_plPL); - break; - case XC_LANGUAGE_RUSSIAN : - locales.push_back(eMCLang_ruRU); - break; - case XC_LANGUAGE_SWEDISH : - locales.push_back(eMCLang_svSV); - locales.push_back(eMCLang_svSE); - break; - case XC_LANGUAGE_TURKISH : - locales.push_back(eMCLang_trTR); - break; - case XC_LANGUAGE_BNORWEGIAN : - locales.push_back(eMCLang_nbNO); - locales.push_back(eMCLang_noNO); - locales.push_back(eMCLang_nnNO); - break; - case XC_LANGUAGE_DUTCH : - switch(XGetLocale()) - { - case XC_LOCALE_BELGIUM: - locales.push_back(eMCLang_nlBE); - break; - default: - break; - } - locales.push_back(eMCLang_nlNL); - break; - case XC_LANGUAGE_SCHINESE : - switch(XGetLocale()) - { - case XC_LOCALE_SINGAPORE: - locales.push_back(eMCLang_zhSG); - break; - default: - break; - } - locales.push_back(eMCLang_hans); - locales.push_back(eMCLang_csCS); - locales.push_back(eMCLang_zhCN); - break; - -#if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ || defined _DURANGO - case XC_LANGUAGE_DANISH: - locales.push_back(eMCLang_daDA); - locales.push_back(eMCLang_daDK); - break; - - case XC_LANGUAGE_FINISH : - locales.push_back(eMCLang_fiFI); - break; - - case XC_LANGUAGE_CZECH : - locales.push_back(eMCLang_csCZ); - locales.push_back(eMCLang_enCZ); - break; - - case XC_LANGUAGE_SLOVAK : - locales.push_back(eMCLang_skSK); - locales.push_back(eMCLang_enSK); - break; - - case XC_LANGUAGE_GREEK : - locales.push_back(eMCLang_elEL); - locales.push_back(eMCLang_elGR); - locales.push_back(eMCLang_enGR); - locales.push_back(eMCLang_enGB); - break; -#endif - } -#endif - - locales.push_back(eMCLang_enUS); - locales.push_back(eMCLang_null); - - for (size_t i=0; i +#endif +#ifdef __ORBIS__ +#include +#endif + +#include "../Common/Leaderboards/LeaderboardManager.h" +#include + +//CMinecraftApp app; +unsigned int CMinecraftApp::m_uiLastSignInData = 0; + +const float CMinecraftApp::fSafeZoneX = 64.0f; // 5% of 1280 +const float CMinecraftApp::fSafeZoneY = 36.0f; // 5% of 720 + +int CMinecraftApp::s_iHTMLFontSizesA[eHTMLSize_COUNT] = +{ +#ifdef _XBOX + 14,12,14,24 +#else + //20,15,20,24 + 20,13,20,26 +#endif +}; + + +CMinecraftApp::CMinecraftApp() +{ + if(GAME_SETTINGS_PROFILE_DATA_BYTES != sizeof(GAME_SETTINGS)) + { + // 4J Stu - See comment for GAME_SETTINGS_PROFILE_DATA_BYTES in Xbox_App.h + DebugPrintf("WARNING: The size of the profile GAME_SETTINGS struct has changed, so all stat data is likely incorrect. Is: %d, Should be: %d\n",sizeof(GAME_SETTINGS),GAME_SETTINGS_PROFILE_DATA_BYTES); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + } + + for(int i=0;i; + } + + LocaleAndLanguageInit(); + +#ifdef _XBOX_ONE + m_hasReachedMainMenu = false; +#endif +} + + +void CMinecraftApp::GetSkinAdjustments(_SkinAdjustments* out, unsigned int skinId) +{ + _SkinAdjustments adj; + + EnterCriticalSection(&csAdditionalSkinBoxes); + + if (!m_SkinAdjustmentsMap.empty()) + { + auto it = m_SkinAdjustmentsMap.find(skinId); + if (it != m_SkinAdjustmentsMap.end()) + adj = it->second; + } + + LeaveCriticalSection(&csAdditionalSkinBoxes); + + *out = adj; +} + +void CMinecraftApp::SetSkinAdjustments(unsigned int skinId, const _SkinAdjustments& adj) +{ + EnterCriticalSection(&csAdditionalSkinBoxes); + + m_SkinAdjustmentsMap[skinId] = adj; + + LeaveCriticalSection(&csAdditionalSkinBoxes); +} + +void CMinecraftApp::DebugPrintf(const char *szFormat, ...) +{ + +#ifndef _FINAL_BUILD + va_list ap; + va_start(ap, szFormat); +#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) + // Dedicated server routes client debug spew through ServerLogger so CLI output stays prompt-safe. + if (ServerRuntime::ServerLogManager::ShouldForwardClientDebugLogs()) + { + ServerRuntime::ServerLogManager::ForwardClientAppDebugLogV(szFormat, ap); + va_end(ap); + return; + } +#endif + char buf[1024]; + vsnprintf(buf, sizeof(buf), szFormat, ap); + va_end(ap); + OutputDebugStringA(buf); +#endif + +} + +void CMinecraftApp::DebugPrintf(int user, const char *szFormat, ...) +{ +#ifndef _FINAL_BUILD + if(user == USER_NONE) + return; + va_list ap; + va_start(ap, szFormat); +#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) + // Dedicated server routes client debug spew through ServerLogger so CLI output stays prompt-safe. + if (ServerRuntime::ServerLogManager::ShouldForwardClientDebugLogs()) + { + ServerRuntime::ServerLogManager::ForwardClientUserDebugLogV(user, szFormat, ap); + va_end(ap); + return; + } +#endif + char buf[1024]; + vsnprintf(buf, sizeof(buf), szFormat, ap); + va_end(ap); +#ifdef __PS3__ + unsigned int writelen; + sys_tty_write(SYS_TTYP_USER1 + ( user - 1 ), buf, strlen(buf), &writelen ); +#elif defined __PSVITA__ + switch(user) + { + case 0: + { + SceUID tty2 = sceIoOpen("tty2:", SCE_O_WRONLY, 0); + if(tty2>=0) + { + std::string string1(buf); + sceIoWrite(tty2, string1.c_str(), string1.length()); + sceIoClose(tty2); + } + } + break; + case 1: + { + SceUID tty3 = sceIoOpen("tty3:", SCE_O_WRONLY, 0); + if(tty3>=0) + { + std::string string1(buf); + sceIoWrite(tty3, string1.c_str(), string1.length()); + sceIoClose(tty3); + } + } + break; + default: + OutputDebugStringA(buf); + break; + } +#else + OutputDebugStringA(buf); +#endif +#ifndef _XBOX + if(user == USER_UI) + { + ui.logDebugString(buf); + } +#endif +#endif +} + +namespace +{ +const wchar_t *ResolveStringKeyFromId(int iID) +{ +#ifdef _WINDOWS64 + switch(iID) + { + #include "StringIdLookup.generated.inc" + default: + return nullptr; + } +#else + (void)iID; + return nullptr; +#endif +} +} + +LPCWSTR CMinecraftApp::GetString(int iID) +{ + if(app.m_stringTable == nullptr) + { + const wchar_t *key = ResolveStringKeyFromId(iID); + return key != nullptr ? key : L""; + } + + LPCWSTR byIndex = app.m_stringTable->getString(iID); + if(byIndex != nullptr && byIndex[0] != L'\0') + { + return byIndex; + } + + const wchar_t *key = ResolveStringKeyFromId(iID); + if(key != nullptr) + { + LPCWSTR byKey = app.m_stringTable->getString(key); + if(byKey != nullptr && byKey[0] != L'\0') + { + return byKey; + } + + // Prefer visible fallback text instead of returning an empty string. + return key; + } + + return L""; +} + +LPCWSTR CMinecraftApp::GetString(const wchar_t *id) +{ + if(id == nullptr) + { + return L""; + } + + if(app.m_stringTable == nullptr) + { + return id; + } + + LPCWSTR byKey = app.m_stringTable->getString(id); + if(byKey != nullptr && byKey[0] != L'\0') + { + return byKey; + } + + return id; +} + +void CMinecraftApp::SetAction(int iPad, eXuiAction action, LPVOID param) +{ + if( ( m_eXuiAction[iPad] == eAppAction_ReloadTexturePack ) && ( action == eAppAction_EthernetDisconnected ) ) + { + app.DebugPrintf("Invalid change of App action for pad %d from %d to %d, ignoring\n", iPad, m_eXuiAction[iPad], action); + } + else if( ( m_eXuiAction[iPad] == eAppAction_ReloadTexturePack ) && ( action == eAppAction_ExitWorld ) ) + { + app.DebugPrintf("Invalid change of App action for pad %d from %d to %d, ignoring\n", iPad, m_eXuiAction[iPad], action); + } + else if(m_eXuiAction[iPad] == eAppAction_ExitWorldCapturedThumbnail && action != eAppAction_Idle) + { + app.DebugPrintf("Invalid change of App action for pad %d from %d to %d, ignoring\n", iPad, m_eXuiAction[iPad], action); + } + else + { + app.DebugPrintf("Changing App action for pad %d from %d to %d\n", iPad, m_eXuiAction[iPad], action); + m_eXuiAction[iPad]=action; + m_eXuiActionParam[iPad] = param; + } +} + +bool CMinecraftApp::IsAppPaused() +{ +#if defined(_XBOX_ONE) || defined(__ORBIS__) || defined(_WINDOWS64) + bool paused = m_bIsAppPaused; + EnterCriticalSection(&m_saveNotificationCriticalSection); + if( g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 ) + { + paused |= m_saveNotificationDepth > 0; + } + LeaveCriticalSection(&m_saveNotificationCriticalSection); + return paused; +#else + return m_bIsAppPaused; +#endif +} + +void CMinecraftApp::SetAppPaused(bool val) +{ + m_bIsAppPaused = val; +} + +void CMinecraftApp::HandleButtonPresses() +{ + for(int i=0;i<4;i++) + { + HandleButtonPresses(i); + } +} + +void CMinecraftApp::HandleButtonPresses(int iPad) +{ + + // // test an update of the profile data + // void *pData=ProfileManager.GetGameDefinedProfileData(iPad); + // + // unsigned char *pchData= (unsigned char *)pData; + // int iCount=0; + // for(int i=0;i player,bool bNavigateBack) +{ + bool success = true; + + InventoryScreenInput* initData = new InventoryScreenInput(); + initData->player = player; + initData->bNavigateBack=bNavigateBack; + initData->iPad = iPad; + + if(app.GetLocalPlayerCount()>1) + { + initData->bSplitscreen=true; + success = ui.NavigateToScene(iPad,eUIScene_InventoryMenu,initData); + } + else + { + initData->bSplitscreen=false; + success = ui.NavigateToScene(iPad,eUIScene_InventoryMenu,initData); + } + + return success; +} + +bool CMinecraftApp::LoadCreativeMenu(int iPad,shared_ptr player,bool bNavigateBack) +{ + bool success = true; + + InventoryScreenInput* initData = new InventoryScreenInput(); + initData->player = player; + initData->bNavigateBack=bNavigateBack; + initData->iPad = iPad; + + if(app.GetLocalPlayerCount()>1) + { + initData->bSplitscreen=true; + success = ui.NavigateToScene(iPad,eUIScene_CreativeMenu,initData); + } + else + { + initData->bSplitscreen=false; + success = ui.NavigateToScene(iPad,eUIScene_CreativeMenu,initData); + } + + return success; +} + +bool CMinecraftApp::LoadCrafting2x2Menu(int iPad,shared_ptr player) +{ + bool success = true; + + CraftingPanelScreenInput* initData = new CraftingPanelScreenInput(); + initData->player = player; + initData->iContainerType=RECIPE_TYPE_2x2; + initData->iPad = iPad; + initData->x = 0; + initData->y = 0; + initData->z = 0; + + if(app.GetLocalPlayerCount()>1) + { + initData->bSplitscreen=true; + success = ui.NavigateToScene(iPad,eUIScene_Crafting2x2Menu, initData); + } + else + { + initData->bSplitscreen=false; + success = ui.NavigateToScene(iPad,eUIScene_Crafting2x2Menu, initData); + } + + return success; +} + +bool CMinecraftApp::LoadCrafting3x3Menu(int iPad,shared_ptr player, int x, int y, int z) +{ + bool success = true; + + CraftingPanelScreenInput* initData = new CraftingPanelScreenInput(); + initData->player = player; + initData->iContainerType=RECIPE_TYPE_3x3; + initData->iPad = iPad; + initData->x = x; + initData->y = y; + initData->z = z; + + if (app.GetLocalPlayerCount() > 1) + initData->bSplitscreen = true; + else + initData->bSplitscreen = false; + + if (app.GetGameSettings(iPad, eGameSetting_ClassicCrafting)) + success = ui.NavigateToScene(iPad, eUIScene_ClassicCraftingMenu, initData); + else + success = ui.NavigateToScene(iPad, eUIScene_Crafting3x3Menu, initData); + + return success; +} + +bool CMinecraftApp::LoadFireworksMenu(int iPad,shared_ptr player, int x, int y, int z) +{ + bool success = true; + + FireworksScreenInput* initData = new FireworksScreenInput(); + initData->player = player; + initData->iPad = iPad; + initData->x = x; + initData->y = y; + initData->z = z; + + if(app.GetLocalPlayerCount()>1) + { + initData->bSplitscreen=true; + success = ui.NavigateToScene(iPad,eUIScene_FireworksMenu, initData); + } + else + { + initData->bSplitscreen=false; + success = ui.NavigateToScene(iPad,eUIScene_FireworksMenu, initData); + } + + return success; +} + +bool CMinecraftApp::LoadEnchantingMenu(int iPad,shared_ptr inventory, int x, int y, int z, Level *level, const wstring &name) +{ + bool success = true; + + EnchantingScreenInput* initData = new EnchantingScreenInput(); + initData->inventory = inventory; + initData->level = level; + initData->x = x; + initData->y = y; + initData->z = z; + initData->iPad = iPad; + initData->name = name; + + if(app.GetLocalPlayerCount()>1) + { + initData->bSplitscreen=true; + success = ui.NavigateToScene(iPad,eUIScene_EnchantingMenu, initData); + } + else + { + initData->bSplitscreen=false; + success = ui.NavigateToScene(iPad,eUIScene_EnchantingMenu, initData); + } + + return success; +} + +bool CMinecraftApp::LoadFurnaceMenu(int iPad,shared_ptr inventory, shared_ptr furnace) +{ + bool success = true; + + FurnaceScreenInput* initData = new FurnaceScreenInput(); + + initData->furnace = furnace; + initData->inventory = inventory; + initData->iPad = iPad; + + // Load the scene. + if(app.GetLocalPlayerCount()>1) + { + initData->bSplitscreen=true; + success = ui.NavigateToScene(iPad,eUIScene_FurnaceMenu, initData); + } + else + { + initData->bSplitscreen=false; + success = ui.NavigateToScene(iPad,eUIScene_FurnaceMenu, initData); + } + + return success; +} + +bool CMinecraftApp::LoadBrewingStandMenu(int iPad,shared_ptr inventory, shared_ptr brewingStand) +{ + bool success = true; + + BrewingScreenInput* initData = new BrewingScreenInput(); + + initData->brewingStand = brewingStand; + initData->inventory = inventory; + initData->iPad = iPad; + + // Load the scene. + if(app.GetLocalPlayerCount()>1) + { + initData->bSplitscreen=true; + success = ui.NavigateToScene(iPad,eUIScene_BrewingStandMenu, initData); + } + else + { + initData->bSplitscreen=false; + success = ui.NavigateToScene(iPad,eUIScene_BrewingStandMenu, initData); + } + + return success; +} + + +bool CMinecraftApp::LoadContainerMenu(int iPad,shared_ptr inventory, shared_ptr container) +{ + bool success = true; + + ContainerScreenInput* initData = new ContainerScreenInput(); + + initData->inventory = inventory; + initData->container = container; + initData->iPad = iPad; + + // Load the scene. + if(app.GetLocalPlayerCount()>1) + { + initData->bSplitscreen=true; + + bool bLargeChest = (initData->container->getContainerSize() > 3*9)?true:false; + if(bLargeChest) + { + success = ui.NavigateToScene(iPad,eUIScene_LargeContainerMenu,initData); + } + else + { + success = ui.NavigateToScene(iPad,eUIScene_ContainerMenu,initData); + } + } + else + { + initData->bSplitscreen=false; + success = ui.NavigateToScene(iPad,eUIScene_ContainerMenu,initData); + } + + return success; +} + +bool CMinecraftApp::LoadTrapMenu(int iPad,shared_ptr inventory, shared_ptr trap) +{ + bool success = true; + + TrapScreenInput* initData = new TrapScreenInput(); + + initData->inventory = inventory; + initData->trap = trap; + initData->iPad = iPad; + + // Load the scene. + if(app.GetLocalPlayerCount()>1) + { + initData->bSplitscreen=true; + success = ui.NavigateToScene(iPad,eUIScene_DispenserMenu, initData); + } + else + { + initData->bSplitscreen=false; + success = ui.NavigateToScene(iPad,eUIScene_DispenserMenu, initData); + } + + return success; +} + +bool CMinecraftApp::LoadSignEntryMenu(int iPad,shared_ptr sign) +{ + bool success = true; + + SignEntryScreenInput* initData = new SignEntryScreenInput(); + + initData->sign = sign; + initData->iPad = iPad; + + success = ui.NavigateToScene(iPad,eUIScene_SignEntryMenu, initData); + + delete initData; + + return success; +} + +bool CMinecraftApp::LoadRepairingMenu(int iPad,shared_ptr inventory, Level *level, int x, int y, int z) +{ + bool success = true; + + AnvilScreenInput *initData = new AnvilScreenInput(); + initData->inventory = inventory; + initData->level = level; + initData->x = x; + initData->y = y; + initData->z = z; + initData->iPad = iPad; + if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; + else initData->bSplitscreen=false; + + success = ui.NavigateToScene(iPad,eUIScene_AnvilMenu, initData); + + return success; +} + +bool CMinecraftApp::LoadTradingMenu(int iPad, shared_ptr inventory, shared_ptr trader, Level *level, const wstring &name) +{ + bool success = true; + + TradingScreenInput *initData = new TradingScreenInput(); + initData->inventory = inventory; + initData->trader = trader; + initData->level = level; + initData->iPad = iPad; + if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; + else initData->bSplitscreen=false; + + success = ui.NavigateToScene(iPad,eUIScene_TradingMenu, initData); + + return success; +} + +bool CMinecraftApp::LoadHopperMenu(int iPad ,shared_ptr inventory, shared_ptr hopper) +{ + bool success = true; + + HopperScreenInput *initData = new HopperScreenInput(); + initData->inventory = inventory; + initData->hopper = hopper; + initData->iPad = iPad; + if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; + else initData->bSplitscreen=false; + + success = ui.NavigateToScene(iPad,eUIScene_HopperMenu, initData); + + return success; +} + +bool CMinecraftApp::LoadHopperMenu(int iPad ,shared_ptr inventory, shared_ptr hopper) +{ + bool success = true; + + HopperScreenInput *initData = new HopperScreenInput(); + initData->inventory = inventory; + initData->hopper = dynamic_pointer_cast(hopper); + initData->iPad = iPad; + if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; + else initData->bSplitscreen=false; + + success = ui.NavigateToScene(iPad,eUIScene_HopperMenu, initData); + + return success; +} + + +bool CMinecraftApp::LoadHorseMenu(int iPad ,shared_ptr inventory, shared_ptr container, shared_ptr horse) +{ + bool success = true; + + HorseScreenInput *initData = new HorseScreenInput(); + initData->inventory = inventory; + initData->container = container; + initData->horse = horse; + initData->iPad = iPad; + if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; + else initData->bSplitscreen=false; + + success = ui.NavigateToScene(iPad,eUIScene_HorseMenu, initData); + + return success; +} + +bool CMinecraftApp::LoadBeaconMenu(int iPad ,shared_ptr inventory, shared_ptr beacon) +{ + bool success = true; + + BeaconScreenInput *initData = new BeaconScreenInput(); + initData->inventory = inventory; + initData->beacon = beacon; + initData->iPad = iPad; + if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; + else initData->bSplitscreen=false; + + success = ui.NavigateToScene(iPad,eUIScene_BeaconMenu, initData); + + return success; +} + +bool CMinecraftApp::LoadWritingBookMenu(int iPad, shared_ptr instance, shared_ptr player, bool editable) +{ + bool success = true; + + WritingBookMenuParams* initData = new WritingBookMenuParams(); + initData->itemInstance = instance; + initData->player = player; + initData->iPad = iPad; + initData->isEditable = editable; + + success = ui.NavigateToScene(iPad, eUIScene_BookMenu, initData); + + return success; +} + +////////////////////////////////////////////// +// GAME SETTINGS +////////////////////////////////////////////// + +#ifdef _WINDOWS64 +static void Win64_GetSettingsPath(char *outPath, DWORD size) +{ + GetModuleFileNameA(nullptr, outPath, size); + char *lastSlash = strrchr(outPath, '\\'); + if (lastSlash) *(lastSlash + 1) = '\0'; + strncat_s(outPath, size, "settings.dat", _TRUNCATE); +} +static void Win64_SaveSettings(GAME_SETTINGS *gs) +{ + if (!gs) return; + char filePath[MAX_PATH] = {}; + Win64_GetSettingsPath(filePath, MAX_PATH); + FILE *f = nullptr; + if (fopen_s(&f, filePath, "wb") == 0 && f) + { + fwrite(gs, sizeof(GAME_SETTINGS), 1, f); + fclose(f); + } +} +static void Win64_LoadSettings(GAME_SETTINGS *gs) +{ + if (!gs) return; + char filePath[MAX_PATH] = {}; + Win64_GetSettingsPath(filePath, MAX_PATH); + FILE *f = nullptr; + if (fopen_s(&f, filePath, "rb") == 0 && f) + { + GAME_SETTINGS temp = {}; + if (fread(&temp, sizeof(GAME_SETTINGS), 1, f) == 1) + memcpy(gs, &temp, sizeof(GAME_SETTINGS)); + fclose(f); + } +} +#endif + +void CMinecraftApp::InitGameSettings() +{ + for(int i=0;i(ProfileManager.GetGameDefinedProfileData(i)); +#endif + // clear the flag to say the settings have changed + GameSettingsA[i]->bSettingsChanged=false; + + //SetDefaultGameSettings(i); - done on a callback from the profile manager + + // 4J-PB - adding in for Windows & PS3 to set the defaults for the joypad +#if defined _WINDOWS64// || defined __PSVITA__ + C_4JProfile::PROFILESETTINGS *pProfileSettings=ProfileManager.GetDashboardProfileSettings(i); + // clear this for now - it will come from reading the system values + memset(pProfileSettings,0,sizeof(C_4JProfile::PROFILESETTINGS)); + SetDefaultOptions(pProfileSettings,i); + Win64_LoadSettings(GameSettingsA[i]); +#ifndef MINECRAFT_SERVER_BUILD + ApplyGameSettingsChanged(i); +#endif +#elif defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__ + C4JStorage::PROFILESETTINGS *pProfileSettings=StorageManager.GetDashboardProfileSettings(i); + // 4J-PB - don't cause an options write to happen here + SetDefaultOptions(pProfileSettings,i,false); + +#endif + + Minecraft* minecraft = Minecraft::GetInstance(); + if (minecraft != nullptr && minecraft->stats[i] != nullptr) + { + minecraft->stats[i]->clear(); + minecraft->stats[i]->parse(GameSettingsA[i]); + } + } +} + +#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) +int CMinecraftApp::SetDefaultOptions(C4JStorage::PROFILESETTINGS *pSettings,const int iPad,bool bWriteProfile) +#else +int CMinecraftApp::SetDefaultOptions(C_4JProfile::PROFILESETTINGS *pSettings,const int iPad) +#endif +{ + SetGameSettings(iPad,eGameSetting_MusicVolume,DEFAULT_VOLUME_LEVEL); + SetGameSettings(iPad,eGameSetting_SoundFXVolume,DEFAULT_VOLUME_LEVEL); + SetGameSettings(iPad,eGameSetting_RenderDistance,16); + SetGameSettings(iPad,eGameSetting_Gamma,50); + SetGameSettings(iPad,eGameSetting_FOV,0); + + // 4J-PB - Don't reset the difficult level if we're in-game + if(Minecraft::GetInstance()->level==nullptr) + { + app.DebugPrintf("SetDefaultOptions - Difficulty = 1\n"); + SetGameSettings(iPad,eGameSetting_Difficulty,1); + } + SetGameSettings(iPad,eGameSetting_Sensitivity_InGame,100); + SetGameSettings(iPad,eGameSetting_ViewBob,1); + SetGameSettings(iPad,eGameSetting_ControlScheme,0); + SetGameSettings(iPad,eGameSetting_ControlInvertLook,(pSettings->iYAxisInversion!=0)?1:0); + SetGameSettings(iPad,eGameSetting_ControlSouthPaw,pSettings->bSwapSticks?1:0); + SetGameSettings(iPad,eGameSetting_SplitScreenVertical,0); + SetGameSettings(iPad,eGameSetting_GamertagsVisible,1); + + // Interim TU 1.6.6 + SetGameSettings(iPad,eGameSetting_Sensitivity_InMenu,100); + SetGameSettings(iPad,eGameSetting_DisplaySplitscreenGamertags,1); + SetGameSettings(iPad,eGameSetting_Hints,1); + SetGameSettings(iPad,eGameSetting_Autosave,2); + SetGameSettings(iPad,eGameSetting_Tooltips,1); + SetGameSettings(iPad,eGameSetting_InterfaceOpacity,80); + + // TU 5 + SetGameSettings(iPad,eGameSetting_Clouds,1); + SetGameSettings(iPad,eGameSetting_Online,1); + SetGameSettings(iPad,eGameSetting_InviteOnly,0); + SetGameSettings(iPad,eGameSetting_FriendsOfFriends,1); + + // default the update changes message to zero + // 4J-PB - We'll only display the message if the profile is pre-TU5 + //SetGameSettings(iPad,eGameSetting_DisplayUpdateMessage,0); + + // TU 6 + SetGameSettings(iPad,eGameSetting_BedrockFog,0); + SetGameSettings(iPad,eGameSetting_DisplayHUD,1); + SetGameSettings(iPad,eGameSetting_DisplayHand,1); + + // TU 7 + SetGameSettings(iPad,eGameSetting_CustomSkinAnim,1); + + // TU 9 + SetGameSettings(iPad,eGameSetting_DeathMessages,1); + SetGameSettings(iPad,eGameSetting_UISize,1); + SetGameSettings(iPad,eGameSetting_UISizeSplitscreen,2); + SetGameSettings(iPad,eGameSetting_AnimatedCharacter,1); + + // TU 12 + GameSettingsA[iPad]->ucCurrentFavoriteSkinPos=0; + for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; + } + + // TU 13 + GameSettingsA[iPad]->uiMashUpPackWorldsDisplay=0xFFFFFFFF; + + // 1.6.4 + app.SetGameHostOption(eGameHostOption_MobGriefing, 1); + app.SetGameHostOption(eGameHostOption_KeepInventory, 0); + app.SetGameHostOption(eGameHostOption_DoMobSpawning, 1 ); + app.SetGameHostOption(eGameHostOption_DoMobLoot, 1 ); + app.SetGameHostOption(eGameHostOption_DoTileDrops, 1 ); + app.SetGameHostOption(eGameHostOption_NaturalRegeneration, 1 ); + app.SetGameHostOption(eGameHostOption_DoDaylightCycle, 1 ); + + //TU25 + SetGameSettings(iPad, eGameSetting_ClassicCrafting, 0); + SetGameSettings(iPad, eGameSetting_CaveSounds, 1); + + //TU34 + SetGameSettings(iPad, eGameSetting_MinecartSounds, 1); + + // 4J-PB - leave these in, or remove from everywhere they are referenced! + // Although probably best to leave in unless we split the profile settings into platform specific classes - having different meaning per platform for the same bitmask could get confusing + //#ifdef __PS3__ + // PS3DEC13 + SetGameSettings(iPad,eGameSetting_PS3_EULA_Read,0); // EULA not read + + // PS3 1.05 - added Greek + + // 4J-JEV: We cannot change these in-game, as they could affect localised strings and font. + // XB1: Fix for #172947 - Content: Gameplay: While playing in language different form system default one and resetting options to their defaults in active gameplay causes in-game language to change and HUD to disappear + if (!app.GetGameStarted()) + { + GameSettingsA[iPad]->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language + GameSettingsA[iPad]->ucLocale = MINECRAFT_LANGUAGE_DEFAULT; // use the system locale + } + + //#endif + +#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) + GameSettingsA[iPad]->bSettingsChanged=bWriteProfile; +#endif + + return 0; +} + +#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) +int CMinecraftApp::DefaultOptionsCallback(LPVOID pParam,C4JStorage::PROFILESETTINGS *pSettings, const int iPad) +#else +int CMinecraftApp::DefaultOptionsCallback(LPVOID pParam,C_4JProfile::PROFILESETTINGS *pSettings, const int iPad) +#endif +{ + CMinecraftApp *pApp=static_cast(pParam); + + // flag the default options to be set + + pApp->DebugPrintf("Setting default options for player %d", iPad); + pApp->SetAction(iPad,eAppAction_SetDefaultOptions, (LPVOID)pSettings); + //pApp->SetDefaultOptions(pSettings,iPad); + + // if the profile data has been changed, then force a profile write + // It seems we're allowed to break the 5 minute rule if it's the result of a user action + //pApp->CheckGameSettingsChanged(); + + return 0; +} + +#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) + +wstring CMinecraftApp::toStringOptionsStatus(const C4JStorage::eOptionsCallback &eStatus) +{ +#ifndef _CONTENT_PACKAGE + switch(eStatus) + { + case C4JStorage::eOptions_Callback_Idle: return L"Idle"; + case C4JStorage::eOptions_Callback_Write: return L"Write"; + case C4JStorage::eOptions_Callback_Write_Fail_NoSpace: return L"Write_Fail_NoSpace"; + case C4JStorage::eOptions_Callback_Write_Fail: return L"Write_Fail"; + case C4JStorage::eOptions_Callback_Read: return L"Read"; + case C4JStorage::eOptions_Callback_Read_Fail: return L"Read_Fail"; + case C4JStorage::eOptions_Callback_Read_FileNotFound: return L"Read_FileNotFound"; + case C4JStorage::eOptions_Callback_Read_Corrupt: return L"Read_Corrupt"; + case C4JStorage::eOptions_Callback_Read_CorruptDeletePending: return L"Read_CorruptDeletePending"; + case C4JStorage::eOptions_Callback_Read_CorruptDeleted: return L"Read_CorruptDeleted"; + default: return L"[UNRECOGNISED_OPTIONS_STATUS]"; + } +#else + return L""; +#endif +} + +#ifdef __ORBIS__ +int CMinecraftApp::OptionsDataCallback(LPVOID pParam,int iPad,unsigned short usVersion,C4JStorage::eOptionsCallback eStatus,int iBlocksRequired) +{ + CMinecraftApp *pApp=(CMinecraftApp *)pParam; + pApp->m_eOptionsStatusA[iPad]=eStatus; + pApp->m_eOptionsBlocksRequiredA[iPad]=iBlocksRequired; + return 0; +} + +int CMinecraftApp::GetOptionsBlocksRequired(int iPad) +{ + return m_eOptionsBlocksRequiredA[iPad]; +} + +#else +int CMinecraftApp::OptionsDataCallback(LPVOID pParam,int iPad,unsigned short usVersion,C4JStorage::eOptionsCallback eStatus) +{ + CMinecraftApp *pApp=(CMinecraftApp *)pParam; + +#ifndef _CONTENT_PACKAGE + pApp->DebugPrintf("[OptionsDataCallback] Pad_%i: new status == %ls(%i).\n", iPad, pApp->toStringOptionsStatus(eStatus).c_str(), (int) eStatus); +#endif + + pApp->m_eOptionsStatusA[iPad] = eStatus; + + return 0; +} +#endif + +C4JStorage::eOptionsCallback CMinecraftApp::GetOptionsCallbackStatus(int iPad) +{ + return m_eOptionsStatusA[iPad]; +} + +void CMinecraftApp::SetOptionsCallbackStatus(int iPad, C4JStorage::eOptionsCallback eStatus) +{ + m_eOptionsStatusA[iPad]=eStatus; +} +#endif + +int CMinecraftApp::OldProfileVersionCallback(LPVOID pParam,unsigned char *pucData, const unsigned short usVersion, const int iPad) +{ + // check what needs to be done with this version to update to the current one + + switch(usVersion) + { +#ifdef _XBOX + case PROFILE_VERSION_1: + case PROFILE_VERSION_2: + // need to fill in values for the new profile data. No need to save the profile - that'll happen if they get changed, or if the auto save for the profile kicks in + { + GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; + pGameSettings->ucMenuSensitivity=100; //eGameSetting_Sensitivity_InMenu + pGameSettings->ucInterfaceOpacity=80; //eGameSetting_Sensitivity_InMenu + pGameSettings->usBitmaskValues|=0x0200; //eGameSetting_DisplaySplitscreenGamertags - on + pGameSettings->usBitmaskValues|=0x0400; //eGameSetting_Hints - on + pGameSettings->usBitmaskValues|=0x1000; //eGameSetting_Autosave - 2 + pGameSettings->usBitmaskValues|=0x8000; //eGameSetting_Tooltips - on + + // 4J-PB - Let's also award all the achievements they have again because of the profile bug that seemed to stop the awards of some + // Changing this to check the system achievements at sign-in and award any that the game says we have and the system says we haven't + //ProfileManager.ReAwardAchievements(iPad); + + pGameSettings->uiBitmaskValues=0L; // reset + pGameSettings->uiBitmaskValues|=GAMESETTING_CLOUDS; //eGameSetting_Clouds - on + pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on + //eGameSetting_GameSetting_Invite - off + pGameSettings->uiBitmaskValues|=GAMESETTING_FRIENDSOFFRIENDS; //eGameSetting_GameSetting_FriendsOfFriends - on + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) + // TU6 + pGameSettings->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on + // TU7 + pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on + // TU9 + pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on + pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 + pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 + pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on + // TU12 + // favorite skins added, but only set in TU12 - set to FFs + for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; + } + pGameSettings->ucCurrentFavoriteSkinPos=0; + // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list + pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; + + // PS3 1.05 - added Greek + pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language + } + break; + case PROFILE_VERSION_3: + + { + GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; + pGameSettings->uiBitmaskValues=0L; // reset + pGameSettings->uiBitmaskValues|=GAMESETTING_CLOUDS; //eGameSetting_Clouds - on + pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on + //eGameSetting_GameSetting_Invite - off + pGameSettings->uiBitmaskValues|=GAMESETTING_FRIENDSOFFRIENDS; //eGameSetting_GameSetting_FriendsOfFriends - on + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) + // TU6 + pGameSettings->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on + // TU7 + pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on + // TU9 + pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on + pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 + pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 + pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on + // TU12 + // favorite skins added, but only set in TU12 - set to FFs + for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; + } + pGameSettings->ucCurrentFavoriteSkinPos=0; + // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list + pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; + + // PS3 1.05 - added Greek + pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language + + } + break; + case PROFILE_VERSION_4: + { + GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; + + pGameSettings->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on + // TU7 + pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on + // TU9 + pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on + pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 + pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 + pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on + + // Set the online flag to on, so it's not saved if a game starts offline when the user didn't change it to be offline (xbox disconnected from LIVE) + pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on + // TU12 + // favorite skins added, but only set in TU12 - set to FFs + for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; + } + pGameSettings->ucCurrentFavoriteSkinPos=0; + // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list + pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; + + // PS3 1.05 - added Greek + pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language + + } + + break; + case PROFILE_VERSION_5: + { + GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; + + // reset the display new message counter + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) + // TU7 + pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on + // TU9 + pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on + pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 + pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 + pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on + // Set the online flag to on, so it's not saved if a game starts offline when the user didn't change it to be offline (xbox disconnected from LIVE) + pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on + // TU12 + // favorite skins added, but only set in TU12 - set to FFs + for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; + } + pGameSettings->ucCurrentFavoriteSkinPos=0; + // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list + pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; + + // PS3 1.05 - added Greek + pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language + + + } + + break; + case PROFILE_VERSION_6: + { + GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; + + // Added gui size for splitscreen and fullscreen + // Added death messages toggle + + // reset the display new message counter + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) + // TU9 + pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on + pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 + pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 + pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on + // Set the online flag to on, so it's not saved if a game starts offline when the user didn't change it to be offline (xbox disconnected from LIVE) + pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on + // TU12 + // favorite skins added, but only set in TU12 - set to FFs + for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; + } + pGameSettings->ucCurrentFavoriteSkinPos=0; + // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list + pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; + + // PS3 1.05 - added Greek + pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language + + + } + + break; + + case PROFILE_VERSION_7: + { + GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; + // reset the display new message counter + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) + + // TU12 + // favorite skins added, but only set in TU12 - set to FFs + for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; + } + pGameSettings->ucCurrentFavoriteSkinPos=0; + // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list + pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; + + // PS3 1.05 - added Greek + pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language + + + } + break; +#endif + case PROFILE_VERSION_8: + { + GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; + // reset the display new message counter + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) + + // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list + pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; + + // PS3DEC13 + pGameSettings->uiBitmaskValues&=~GAMESETTING_PS3EULAREAD; //eGameSetting_PS3_EULA_Read - off + + // PS3 1.05 - added Greek + pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language + + } + break; + case PROFILE_VERSION_9: + // PS3DEC13 + { + GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) + pGameSettings->uiBitmaskValues&=~GAMESETTING_PS3EULAREAD; //eGameSetting_PS3_EULA_Read - off + + // PS3 1.05 - added Greek + pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language + + } + break; + case PROFILE_VERSION_10: + { + GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) + pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language + } + break; + case PROFILE_VERSION_11: + { + GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) + } + break; + case PROFILE_VERSION_12: + { + GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) + } + break; + default: + { + // This might be from a version during testing of new profile updates + app.DebugPrintf("Don't know what to do with this profile version!\n"); + + GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; + pGameSettings->ucMenuSensitivity=100; //eGameSetting_Sensitivity_InMenu + pGameSettings->ucInterfaceOpacity=80; //eGameSetting_Sensitivity_InMenu + pGameSettings->usBitmaskValues|=0x0200; //eGameSetting_DisplaySplitscreenGamertags - on + pGameSettings->usBitmaskValues|=0x0400; //eGameSetting_Hints - on + pGameSettings->usBitmaskValues|=0x1000; //eGameSetting_Autosave - 2 + pGameSettings->usBitmaskValues|=0x8000; //eGameSetting_Tooltips - on + + pGameSettings->uiBitmaskValues=0L; // reset + pGameSettings->uiBitmaskValues|=GAMESETTING_CLOUDS; //eGameSetting_Clouds - on + pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on + //eGameSetting_GameSetting_Invite - off + pGameSettings->uiBitmaskValues|=GAMESETTING_FRIENDSOFFRIENDS; //eGameSetting_GameSetting_FriendsOfFriends - on + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) + pGameSettings->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on + pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on + pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on + pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on + pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 + pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 + pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on + pGameSettings->uiBitmaskValues |= GAMESETTING_CLASSICCRAFTING; //eGameSetting_ClassicCrafting - off + // TU12 + // favorite skins added, but only set in TU12 - set to FFs + for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; + } + pGameSettings->ucCurrentFavoriteSkinPos=0; + // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list + pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; + + // PS3DEC13 + pGameSettings->uiBitmaskValues&=~GAMESETTING_PS3EULAREAD; //eGameSetting_PS3_EULA_Read - off + + // PS3 1.05 - added Greek + pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language + + } + break; + } + + return 0; +} + +void CMinecraftApp::ApplyGameSettingsChanged(int iPad) +{ + ActionGameSettings(iPad,eGameSetting_MusicVolume ); + ActionGameSettings(iPad,eGameSetting_SoundFXVolume ); + ActionGameSettings(iPad,eGameSetting_RenderDistance ); + ActionGameSettings(iPad,eGameSetting_Gamma ); + ActionGameSettings(iPad,eGameSetting_FOV ); + ActionGameSettings(iPad,eGameSetting_Difficulty ); + ActionGameSettings(iPad,eGameSetting_Sensitivity_InGame ); + ActionGameSettings(iPad,eGameSetting_ViewBob ); + ActionGameSettings(iPad,eGameSetting_ControlScheme ); + ActionGameSettings(iPad,eGameSetting_ControlInvertLook); + ActionGameSettings(iPad,eGameSetting_ControlSouthPaw); + ActionGameSettings(iPad,eGameSetting_ControlType); + ActionGameSettings(iPad,eGameSetting_SplitScreenVertical); + ActionGameSettings(iPad,eGameSetting_GamertagsVisible); + + // Interim TU 1.6.6 + ActionGameSettings(iPad,eGameSetting_Sensitivity_InMenu ); + ActionGameSettings(iPad,eGameSetting_DisplaySplitscreenGamertags); + ActionGameSettings(iPad,eGameSetting_Hints); + ActionGameSettings(iPad,eGameSetting_InterfaceOpacity); + ActionGameSettings(iPad,eGameSetting_Tooltips); + + ActionGameSettings(iPad,eGameSetting_Clouds); + ActionGameSettings(iPad,eGameSetting_BedrockFog); + ActionGameSettings(iPad,eGameSetting_DisplayHUD); + ActionGameSettings(iPad,eGameSetting_DisplayHand); + ActionGameSettings(iPad,eGameSetting_CustomSkinAnim); + ActionGameSettings(iPad,eGameSetting_DeathMessages); + ActionGameSettings(iPad,eGameSetting_UISize); + ActionGameSettings(iPad,eGameSetting_UISizeSplitscreen); + ActionGameSettings(iPad,eGameSetting_AnimatedCharacter); + + ActionGameSettings(iPad,eGameSetting_PS3_EULA_Read); + ActionGameSettings(iPad,eGameSetting_VSync); + + //TU25 + ActionGameSettings(iPad, eGameSetting_ClassicCrafting); + ActionGameSettings(iPad, eGameSetting_CaveSounds); + ActionGameSettings(iPad, eGameSetting_MinecartSounds); + ActionGameSettings(iPad, eGameSetting_HideSaveSizeBar); + ActionGameSettings(iPad, eGameSetting_SafeCam); + ActionGameSettings(iPad, eGameSetting_Swap); +} + +void CMinecraftApp::ActionGameSettings(int iPad,eGameSetting eVal) +{ + Minecraft *pMinecraft=Minecraft::GetInstance(); + switch(eVal) + { + case eGameSetting_MusicVolume: + if(iPad==ProfileManager.GetPrimaryPad()) + { + pMinecraft->options->set(Options::Option::MUSIC,static_cast(GameSettingsA[iPad]->ucMusicVolume)/100.0f); + } + break; + case eGameSetting_SoundFXVolume: + if (iPad == ProfileManager.GetPrimaryPad()) + { + pMinecraft->options->set(Options::Option::SOUND, static_cast(GameSettingsA[iPad]->ucSoundFXVolume) / 100.0f); + } + break; + case eGameSetting_RenderDistance: + if (iPad == ProfileManager.GetPrimaryPad()) + { + int dist = (GameSettingsA[iPad]->uiBitmaskValues >> 16) & 0xFF; + + int level = UIScene_SettingsGraphicsMenu::DistanceToLevel(dist); + pMinecraft->options->set(Options::Option::RENDER_DISTANCE, 3 - level); + }; + break; + case eGameSetting_Gamma: + if(iPad==ProfileManager.GetPrimaryPad()) + { +#if defined(_WIN64) || defined(_WINDOWS64) + pMinecraft->options->set(Options::Option::GAMMA, static_cast(GameSettingsA[iPad]->ucGamma) / 100.0f); +#else + // ucGamma range is 0-100, UpdateGamma is 0 - 32768 + float fVal=((float)GameSettingsA[iPad]->ucGamma)*327.68f; + RenderManager.UpdateGamma((unsigned short)fVal); +#endif + } + + break; + case eGameSetting_FOV: + if(iPad==ProfileManager.GetPrimaryPad()) + { + float fovDeg = 70.0f + (float)GameSettingsA[iPad]->ucFov * 40.0f / 100.0f; + pMinecraft->gameRenderer->SetFovVal(fovDeg); + pMinecraft->options->set(Options::Option::FOV, (float)GameSettingsA[iPad]->ucFov / 100.0f); + } + break; + case eGameSetting_Difficulty: + if(iPad==ProfileManager.GetPrimaryPad()) + { + pMinecraft->options->toggle(Options::Option::DIFFICULTY,GameSettingsA[iPad]->usBitmaskValues&0x03); + app.DebugPrintf("Difficulty toggle to %d\n",GameSettingsA[iPad]->usBitmaskValues&0x03); + + // Update the Game Host setting + app.SetGameHostOption(eGameHostOption_Difficulty,pMinecraft->options->difficulty); + + // send this to the other players if we are in-game + bool bInGame=pMinecraft->level!=nullptr; + + // Game Host only (and for now we can't change the diff while in game, so this shouldn't happen) + if(bInGame && g_NetworkManager.IsHost() && (iPad==ProfileManager.GetPrimaryPad())) + { + app.SetXuiServerAction(iPad,eXuiServerAction_ServerSettingChanged_Difficulty); + } + } + else + { + app.DebugPrintf("NOT ACTIONING DIFFICULTY - Primary pad is %d, This pad is %d\n",ProfileManager.GetPrimaryPad(),iPad); + } + + break; + case eGameSetting_Sensitivity_InGame: + // 4J-PB - we don't use the options value + // tell the input that we've changed the sensitivity - range of the slider is 0 to 200, default is 100 + pMinecraft->options->set(Options::Option::SENSITIVITY,static_cast(GameSettingsA[iPad]->ucSensitivity)/100.0f); + //InputManager.SetJoypadSensitivity(iPad,((float)GameSettingsA[iPad]->ucSensitivity)/100.0f); + + break; + case eGameSetting_ViewBob: + // 4J-PB - not handled here any more - it's read from the gamesettings per player + //pMinecraft->options->toggle(Options::Option::VIEW_BOBBING,GameSettingsA[iPad]->usBitmaskValues&0x04); + break; + case eGameSetting_ControlScheme: + InputManager.SetJoypadMapVal(iPad,(GameSettingsA[iPad]->usBitmaskValues&0x30)>>4); + break; + + case eGameSetting_ControlInvertLook: + // Nothing specific to do for this setting. + break; + + case eGameSetting_ControlSouthPaw: + // What is the setting? + if ( GameSettingsA[iPad]->usBitmaskValues & 0x80 ) + { + // Southpaw. + InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_LX, AXIS_MAP_RX ); + InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_LY, AXIS_MAP_RY ); + InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_RX, AXIS_MAP_LX ); + InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_RY, AXIS_MAP_LY ); + InputManager.SetJoypadStickTriggerMap( iPad, TRIGGER_MAP_0, TRIGGER_MAP_1 ); + InputManager.SetJoypadStickTriggerMap( iPad, TRIGGER_MAP_1, TRIGGER_MAP_0 ); + } + else + { + // Right handed. + InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_LX, AXIS_MAP_LX ); + InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_LY, AXIS_MAP_LY ); + InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_RX, AXIS_MAP_RX ); + InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_RY, AXIS_MAP_RY ); + InputManager.SetJoypadStickTriggerMap( iPad, TRIGGER_MAP_0, TRIGGER_MAP_0 ); + InputManager.SetJoypadStickTriggerMap( iPad, TRIGGER_MAP_1, TRIGGER_MAP_1 ); + } + break; + case eGameSetting_SplitScreenVertical: + if(iPad==ProfileManager.GetPrimaryPad()) + { + pMinecraft->updatePlayerViewportAssignments(); + } + break; + case eGameSetting_GamertagsVisible: + { + bool bInGame=pMinecraft->level!=nullptr; + + // Game Host only + if(bInGame && g_NetworkManager.IsHost() && (iPad==ProfileManager.GetPrimaryPad())) + { + // Update the Game Host setting if you are the host and you are in-game + app.SetGameHostOption(eGameHostOption_Gamertags,((GameSettingsA[iPad]->usBitmaskValues&0x0008)!=0)?1:0); + app.SetXuiServerAction(iPad,eXuiServerAction_ServerSettingChanged_Gamertags); + + PlayerList *players = MinecraftServer::getInstance()->getPlayerList(); + for( auto& decorationPlayer : players->players ) + { + decorationPlayer->setShowOnMaps((app.GetGameHostOption(eGameHostOption_Gamertags)!=0)?true:false); + } + } + } + break; + // Interim TU 1.6.6 + case eGameSetting_Sensitivity_InMenu: + // 4J-PB - we don't use the options value + // tell the input that we've changed the sensitivity - range of the slider is 0 to 200, default is 100 + //pMinecraft->options->set(Options::Option::SENSITIVITY,((float)GameSettingsA[iPad]->ucSensitivity)/100.0f); + //InputManager.SetJoypadSensitivity(iPad,((float)GameSettingsA[iPad]->ucSensitivity)/100.0f); + + break; + + case eGameSetting_DisplaySplitscreenGamertags: + for( BYTE idx = 0; idx < XUSER_MAX_COUNT; ++idx) + { + if(pMinecraft->localplayers[idx] != nullptr) + { + if(pMinecraft->localplayers[idx]->m_iScreenSection==C4JRender::VIEWPORT_TYPE_FULLSCREEN) + { + ui.DisplayGamertag(idx,false); + } + else + { + ui.DisplayGamertag(idx,true); + } + } + } + + break; + case eGameSetting_InterfaceOpacity: + // update the tooltips display + ui.RefreshTooltips( iPad); + + break; + case eGameSetting_Hints: + //nothing to do here + break; + case eGameSetting_Tooltips: + if((GameSettingsA[iPad]->usBitmaskValues&0x8000)!=0) + { + ui.SetEnableTooltips(iPad,TRUE); + } + else + { + ui.SetEnableTooltips(iPad,FALSE); + } + break; + case eGameSetting_Clouds: + //nothing to do here + break; + case eGameSetting_Online: + //nothing to do here + break; + case eGameSetting_InviteOnly: + //nothing to do here + break; + case eGameSetting_FriendsOfFriends: + //nothing to do here + break; + case eGameSetting_BedrockFog: + { + bool bInGame = pMinecraft->level != nullptr; + + if (bInGame && g_NetworkManager.IsHost() && (iPad == ProfileManager.GetPrimaryPad())) + { + app.SetGameHostOption(eGameHostOption_BedrockFog, GetGameSettings(iPad, eGameSetting_BedrockFog) ? 1 : 0); + app.SetXuiServerAction(iPad, eXuiServerAction_ServerSettingChanged_BedrockFog); + } + } + break; + case eGameSetting_DisplayHUD: + //nothing to do here + break; + case eGameSetting_DisplayHand: + //nothing to do here + break; + case eGameSetting_CustomSkinAnim: + //nothing to do here + break; + case eGameSetting_DeathMessages: + //nothing to do here + break; + case eGameSetting_UISize: + //nothing to do here + break; + case eGameSetting_UISizeSplitscreen: + //nothing to do here + break; + case eGameSetting_AnimatedCharacter: + //nothing to do here + break; + case eGameSetting_PS3_EULA_Read: + //nothing to do here + break; + case eGameSetting_PSVita_NetworkModeAdhoc: + //nothing to do here + break; + case eGameSetting_VSync: +#ifdef _WINDOWS64 + { + extern bool g_bVSync; + g_bVSync = (GetGameSettings(iPad, eGameSetting_VSync) != 0); + } +#endif + break; + case eGameSetting_ExclusiveFullscreen: +#ifdef _WINDOWS64 + { + extern void SetExclusiveFullscreen(bool enabled); + SetExclusiveFullscreen(GetGameSettings(iPad, eGameSetting_ExclusiveFullscreen) != 0); + } +#endif + break; + case eGameSetting_ClassicCrafting: + //nothing to do here + break; + case eGameSetting_HideSaveSizeBar: + //nothing to do here + break; + case eGameSetting_SafeCam: + { + int iVal = GetGameSettings(iPad, eGameSetting_SafeCam); + InputManager.SetButtonSwapEnabled(iPad, 0, iVal != 0); + } + break; + case eGameSetting_Swap: + { + int iVal = GetGameSettings(iPad, eGameSetting_Swap); + InputManager.SetButtonSwapEnabled(iPad, 1, iVal != 0); + } + break; + } +} + +void CMinecraftApp::SetPlayerSkin(int iPad,const wstring &name) +{ + DWORD skinId = app.getSkinIdFromPath(name); + + SetPlayerSkin(iPad,skinId); +} + +void CMinecraftApp::SetPlayerSkin(int iPad,DWORD dwSkinId) +{ + DebugPrintf("Setting skin for %d to %08X\n", iPad, dwSkinId); + + GameSettingsA[iPad]->dwSelectedSkin = dwSkinId; + GameSettingsA[iPad]->bSettingsChanged = true; + + TelemetryManager->RecordSkinChanged(iPad, GameSettingsA[iPad]->dwSelectedSkin); + + if(Minecraft::GetInstance()->localplayers[iPad]!=nullptr) Minecraft::GetInstance()->localplayers[iPad]->setAndBroadcastCustomSkin(dwSkinId); +} + + +wstring CMinecraftApp::GetPlayerSkinName(int iPad) +{ + return app.getSkinPathFromId(GameSettingsA[iPad]->dwSelectedSkin); +} + +DWORD CMinecraftApp::GetPlayerSkinId(int iPad) +{ + // 4J-PB -check the user has rights to use this skin - they may have had at some point but the entitlement has been removed. + DLCPack *Pack=nullptr; + DLCSkinFile *skinFile=nullptr; + DWORD dwSkin=GameSettingsA[iPad]->dwSelectedSkin; + wchar_t chars[256]; + + if( GET_IS_DLC_SKIN_FROM_BITMASK(dwSkin) ) + { + // 4J Stu - DLC skins are numbered using decimal rather than hex to make it easier to number manually + swprintf(chars, 256, L"dlcskin%08d.png", GET_DLC_SKIN_ID_FROM_BITMASK(dwSkin)); + + Pack=app.m_dlcManager.getPackContainingSkin(chars); + + if(Pack) + { + skinFile = Pack->getSkinFile(chars); + + bool bSkinIsFree = skinFile->getParameterAsBool( DLCManager::e_DLCParamType_Free ); + bool bLicensed = Pack->hasPurchasedFile( DLCManager::e_DLCType_Skin, skinFile->getPath() ); + + if(bSkinIsFree || bLicensed) + { + return dwSkin; + } + else + { + return 0; + } + } + } + + + return dwSkin; +} + +DWORD CMinecraftApp::GetAdditionalModelParts(int iPad) +{ + return m_dwAdditionalModelParts[iPad]; +} + + +void CMinecraftApp::SetPlayerCape(int iPad,const wstring &name) +{ + DWORD capeId = Player::getCapeIdFromPath(name); + + SetPlayerCape(iPad,capeId); +} + +void CMinecraftApp::SetPlayerCape(int iPad,DWORD dwCapeId) +{ + DebugPrintf("Setting cape for %d to %08X\n", iPad, dwCapeId); + + GameSettingsA[iPad]->dwSelectedCape = dwCapeId; + GameSettingsA[iPad]->bSettingsChanged = true; + + //SentientManager.RecordSkinChanged(iPad, GameSettingsA[iPad]->dwSelectedSkin); + + if(Minecraft::GetInstance()->localplayers[iPad]!=nullptr) Minecraft::GetInstance()->localplayers[iPad]->setAndBroadcastCustomCape(dwCapeId); +} + +wstring CMinecraftApp::GetPlayerCapeName(int iPad) +{ + return Player::getCapePathFromId(GameSettingsA[iPad]->dwSelectedCape); +} + +DWORD CMinecraftApp::GetPlayerCapeId(int iPad) +{ + return GameSettingsA[iPad]->dwSelectedCape; +} + +void CMinecraftApp::SetPlayerFavoriteSkin(int iPad, int iIndex,unsigned int uiSkinID) +{ + DebugPrintf("Setting favorite skin for %d to %08X\n", iPad, uiSkinID); + + GameSettingsA[iPad]->uiFavoriteSkinA[iIndex] = uiSkinID; + GameSettingsA[iPad]->bSettingsChanged = true; +} + +unsigned int CMinecraftApp::GetPlayerFavoriteSkin(int iPad,int iIndex) +{ + return GameSettingsA[iPad]->uiFavoriteSkinA[iIndex]; +} + +unsigned char CMinecraftApp::GetPlayerFavoriteSkinsPos(int iPad) +{ + return GameSettingsA[iPad]->ucCurrentFavoriteSkinPos; +} + +void CMinecraftApp::SetPlayerFavoriteSkinsPos(int iPad, int iPos) +{ + GameSettingsA[iPad]->ucCurrentFavoriteSkinPos=static_cast(iPos); + GameSettingsA[iPad]->bSettingsChanged = true; +} + +unsigned int CMinecraftApp::GetPlayerFavoriteSkinsCount(int iPad) +{ + unsigned int uiCount=0; + for(int i=0;iuiFavoriteSkinA[i]!=0xFFFFFFFF) + { + uiCount++; + } + else + { + break; + } + } + return uiCount; +} + +void CMinecraftApp::ValidateFavoriteSkins(int iPad) +{ + unsigned int uiCount=GetPlayerFavoriteSkinsCount(iPad); + + // remove invalid skins + unsigned int uiValidSkin=0; + wchar_t chars[256]; + + for(unsigned int i=0;igetSkinFile(chars); + + if( pDLCPack->hasPurchasedFile(DLCManager::e_DLCType_Skin, L"") || (pSkinFile && pSkinFile->isFree())) + { + GameSettingsA[iPad]->uiFavoriteSkinA[uiValidSkin++]=uiFavoriteSkin; + } + } + } + else + { + DWORD defaultSkinIndex = GET_DEFAULT_SKIN_ID_FROM_BITMASK(uiFavoriteSkin); + if(defaultSkinIndex < eDefaultSkins_Count) + { + GameSettingsA[iPad]->uiFavoriteSkinA[uiValidSkin++]=uiFavoriteSkin; + } + } + } + + for(unsigned int i=uiValidSkin;iuiFavoriteSkinA[i]=0xFFFFFFFF; + } +} + +// Mash-up pack worlds +void CMinecraftApp::HideMashupPackWorld(int iPad, unsigned int iMashupPackID) +{ + unsigned int uiPackID=iMashupPackID - 1024; // mash-up ids start at 1024 + GameSettingsA[iPad]->uiMashUpPackWorldsDisplay&=~(1<bSettingsChanged = true; +} + +void CMinecraftApp::EnableMashupPackWorlds(int iPad) +{ + GameSettingsA[iPad]->uiMashUpPackWorldsDisplay=0xFFFFFFFF; + GameSettingsA[iPad]->bSettingsChanged = true; +} + +unsigned int CMinecraftApp::GetMashupPackWorlds(int iPad) +{ + return GameSettingsA[iPad]->uiMashUpPackWorldsDisplay; +} + +void CMinecraftApp::SetMinecraftLanguage(int iPad, unsigned char ucLanguage) +{ + GameSettingsA[iPad]->ucLanguage = ucLanguage; + GameSettingsA[iPad]->bSettingsChanged = true; +} + +unsigned char CMinecraftApp::GetMinecraftLanguage(int iPad) +{ + // if there are no game settings read yet, return the default language + if(GameSettingsA[iPad]==nullptr) + { + return 0; + } + else + { + return GameSettingsA[iPad]->ucLanguage; + } +} + +void CMinecraftApp::SetMinecraftLocale(int iPad, unsigned char ucLocale) +{ + GameSettingsA[iPad]->ucLocale = ucLocale; + GameSettingsA[iPad]->bSettingsChanged = true; +} + +unsigned char CMinecraftApp::GetMinecraftLocale(int iPad) +{ + // if there are no game settings read yet, return the default language + if(GameSettingsA[iPad]==nullptr) + { + return 0; + } + else + { + return GameSettingsA[iPad]->ucLocale; + } +} + +void CMinecraftApp::SetGameSettings(int iPad,eGameSetting eVal,unsigned char ucVal) +{ + //Minecraft *pMinecraft=Minecraft::GetInstance(); + + switch(eVal) + { + case eGameSetting_MusicVolume: + if(GameSettingsA[iPad]->ucMusicVolume!=ucVal) + { + GameSettingsA[iPad]->ucMusicVolume=ucVal; + if(iPad==ProfileManager.GetPrimaryPad()) + { + ActionGameSettings(iPad,eVal); + } + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_SoundFXVolume: + if(GameSettingsA[iPad]->ucSoundFXVolume!=ucVal) + { + GameSettingsA[iPad]->ucSoundFXVolume=ucVal; + if(iPad==ProfileManager.GetPrimaryPad()) + { + ActionGameSettings(iPad,eVal); + } + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_RenderDistance: + { + unsigned int val = ucVal & 0xFF; + + GameSettingsA[iPad]->uiBitmaskValues &= ~(0xFF << 16); + GameSettingsA[iPad]->uiBitmaskValues |= val << 16; + if(iPad == ProfileManager.GetPrimaryPad()) + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged = true; + } + break; + case eGameSetting_Gamma: + if(GameSettingsA[iPad]->ucGamma!=ucVal) + { + GameSettingsA[iPad]->ucGamma=ucVal; + if(iPad==ProfileManager.GetPrimaryPad()) + { + ActionGameSettings(iPad,eVal); + } + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_FOV: + if(GameSettingsA[iPad]->ucFov!=ucVal) + { + GameSettingsA[iPad]->ucFov=ucVal; + if(iPad==ProfileManager.GetPrimaryPad()) + { + ActionGameSettings(iPad,eVal); + } + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_Difficulty: + if((GameSettingsA[iPad]->usBitmaskValues&0x03)!=(ucVal&0x03)) + { + GameSettingsA[iPad]->usBitmaskValues&=~0x03; + GameSettingsA[iPad]->usBitmaskValues|=ucVal&0x03; + if(iPad==ProfileManager.GetPrimaryPad()) + { + ActionGameSettings(iPad,eVal); + } + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_Sensitivity_InGame: + if(GameSettingsA[iPad]->ucSensitivity!=ucVal) + { + GameSettingsA[iPad]->ucSensitivity=ucVal; + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_ViewBob: + if((GameSettingsA[iPad]->usBitmaskValues&0x0004)!=((ucVal&0x01)<<2)) + { + if(ucVal!=0) + { + GameSettingsA[iPad]->usBitmaskValues|=0x0004; + } + else + { + GameSettingsA[iPad]->usBitmaskValues&=~0x0004; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_ControlScheme: // bits 5 and 6 + if((GameSettingsA[iPad]->usBitmaskValues&0x30)!=((ucVal&0x03)<<4)) + { + GameSettingsA[iPad]->usBitmaskValues&=~0x0030; + if(ucVal!=0) + { + GameSettingsA[iPad]->usBitmaskValues|=(ucVal&0x03)<<4; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + + case eGameSetting_ControlInvertLook: + if((GameSettingsA[iPad]->usBitmaskValues&0x0040)!=((ucVal&0x01)<<6)) + { + if(ucVal!=0) + { + GameSettingsA[iPad]->usBitmaskValues|=0x0040; + } + else + { + GameSettingsA[iPad]->usBitmaskValues&=~0x0040; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + + case eGameSetting_ControlSouthPaw: + if((GameSettingsA[iPad]->usBitmaskValues&0x0080)!=((ucVal&0x01)<<7)) + { + if(ucVal!=0) + { + GameSettingsA[iPad]->usBitmaskValues|=0x0080; + } + else + { + GameSettingsA[iPad]->usBitmaskValues&=~0x0080; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_ControlType: + if((GameSettingsA[iPad]->uiBitmaskValues & 0x00070000) != ((ucVal & 0x07) << 16)) + { + GameSettingsA[iPad]->uiBitmaskValues &= ~0x00070000; + GameSettingsA[iPad]->uiBitmaskValues |= (ucVal & 0x07) << 16; + GameSettingsA[iPad]->bSettingsChanged = true; + } + break; + case eGameSetting_SplitScreenVertical: + if((GameSettingsA[iPad]->usBitmaskValues&0x0100)!=((ucVal&0x01)<<8)) + { + if(ucVal!=0) + { + GameSettingsA[iPad]->usBitmaskValues|=0x0100; + } + else + { + GameSettingsA[iPad]->usBitmaskValues&=~0x0100; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_GamertagsVisible: + if((GameSettingsA[iPad]->usBitmaskValues&0x0008)!=((ucVal&0x01)<<3)) + { + if(ucVal!=0) + { + GameSettingsA[iPad]->usBitmaskValues|=0x0008; + } + else + { + GameSettingsA[iPad]->usBitmaskValues&=~0x0008; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + + // 4J-PB - Added for Interim TU for 1.6.6 + case eGameSetting_Sensitivity_InMenu: + if(GameSettingsA[iPad]->ucMenuSensitivity!=ucVal) + { + GameSettingsA[iPad]->ucMenuSensitivity=ucVal; + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_DisplaySplitscreenGamertags: + if((GameSettingsA[iPad]->usBitmaskValues&0x0200)!=((ucVal&0x01)<<9)) + { + if(ucVal!=0) + { + GameSettingsA[iPad]->usBitmaskValues|=0x0200; + } + else + { + GameSettingsA[iPad]->usBitmaskValues&=~0x0200; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_Hints: + if((GameSettingsA[iPad]->usBitmaskValues&0x0400)!=((ucVal&0x01)<<10)) + { + if(ucVal!=0) + { + GameSettingsA[iPad]->usBitmaskValues|=0x0400; + } + else + { + GameSettingsA[iPad]->usBitmaskValues&=~0x0400; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_Autosave: + if((GameSettingsA[iPad]->usBitmaskValues&0x7800)!=((ucVal&0x0F)<<11)) + { + GameSettingsA[iPad]->usBitmaskValues&=~0x7800; + if(ucVal!=0) + { + GameSettingsA[iPad]->usBitmaskValues|=(ucVal&0x0F)<<11; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + + case eGameSetting_Tooltips: + if((GameSettingsA[iPad]->usBitmaskValues&0x8000)!=((ucVal&0x01)<<15)) + { + if(ucVal!=0) + { + GameSettingsA[iPad]->usBitmaskValues|=0x8000; + } + else + { + GameSettingsA[iPad]->usBitmaskValues&=~0x8000; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_InterfaceOpacity: + if(GameSettingsA[iPad]->ucInterfaceOpacity!=ucVal) + { + GameSettingsA[iPad]->ucInterfaceOpacity=ucVal; + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + + break; + case eGameSetting_Clouds: + if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_CLOUDS)!=(ucVal&0x01)) + { + if(ucVal==1) + { + GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_CLOUDS; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_CLOUDS; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + + break; + + case eGameSetting_Online: + if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_ONLINE)!=(ucVal&0x01)<<1) + { + if(ucVal==1) + { + GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_ONLINE; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_ONLINE; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + + break; + case eGameSetting_InviteOnly: + if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_INVITEONLY)!=(ucVal&0x01)<<2) + { + if(ucVal==1) + { + GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_INVITEONLY; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_INVITEONLY; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + + break; + case eGameSetting_FriendsOfFriends: + if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_FRIENDSOFFRIENDS)!=(ucVal&0x01)<<3) + { + if(ucVal==1) + { + GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_FRIENDSOFFRIENDS; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_FRIENDSOFFRIENDS; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + + break; + case eGameSetting_DisplayUpdateMessage: + if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYUPDATEMSG)!=(ucVal&0x03)<<4) + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_DISPLAYUPDATEMSG; + if(ucVal>0) + { + GameSettingsA[iPad]->uiBitmaskValues|=(ucVal&0x03)<<4; + } + + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + + break; + + case eGameSetting_BedrockFog: + if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_BEDROCKFOG)!=(ucVal&0x01)<<6) + { + if(ucVal==1) + { + GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_BEDROCKFOG; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + + break; + case eGameSetting_DisplayHUD: + if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYHUD)!=(ucVal&0x01)<<7) + { + if(ucVal==1) + { + GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_DISPLAYHUD; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + + break; + case eGameSetting_DisplayHand: + if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYHAND)!=(ucVal&0x01)<<8) + { + if(ucVal==1) + { + GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_DISPLAYHAND; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + + break; + + case eGameSetting_CustomSkinAnim: + if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_CUSTOMSKINANIM)!=(ucVal&0x01)<<9) + { + if(ucVal==1) + { + GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_CUSTOMSKINANIM; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + + break; + // TU9 + case eGameSetting_DeathMessages: + if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DEATHMESSAGES)!=(ucVal&0x01)<<10) + { + if(ucVal==1) + { + GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_DEATHMESSAGES; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_UISize: + if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_UISIZE)!=((ucVal&0x03)<<11)) + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_UISIZE; + if(ucVal!=0) + { + GameSettingsA[iPad]->uiBitmaskValues|=(ucVal&0x03)<<11; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_UISizeSplitscreen: + if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_UISIZE_SPLITSCREEN)!=((ucVal&0x03)<<13)) + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_UISIZE_SPLITSCREEN; + if(ucVal!=0) + { + GameSettingsA[iPad]->uiBitmaskValues|=(ucVal&0x03)<<13; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_AnimatedCharacter: + if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_ANIMATEDCHARACTER)!=(ucVal&0x01)<<15) + { + if(ucVal==1) + { + GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_ANIMATEDCHARACTER; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_PS3_EULA_Read: + if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PS3EULAREAD)!=(ucVal&0x01)<<16) + { + if(ucVal==1) + { + GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_PS3EULAREAD; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_PS3EULAREAD; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_PSVita_NetworkModeAdhoc: + if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PSVITANETWORKMODEADHOC)!=(ucVal&0x01)<<17) + { + if(ucVal==1) + { + GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_PSVITANETWORKMODEADHOC; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_PSVITANETWORKMODEADHOC; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + + case eGameSetting_VSync: + if(((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_VSYNC)>>24)!=(ucVal&0x01)) + { + if(ucVal==1) + { + GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_VSYNC; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_VSYNC; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + + case eGameSetting_ExclusiveFullscreen: + if(((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_EXCLUSIVEFULLSCREEN)>>25)!=(ucVal&0x01)) + { + if(ucVal==1) + { + GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_EXCLUSIVEFULLSCREEN; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_EXCLUSIVEFULLSCREEN; + } + ActionGameSettings(iPad,eVal); + GameSettingsA[iPad]->bSettingsChanged=true; + } + break; + case eGameSetting_ClassicCrafting: + if ((GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_CLASSICCRAFTING) != (ucVal & 0x01) << 19) + { + if (ucVal == 1) + { + GameSettingsA[iPad]->uiBitmaskValues |= GAMESETTING_CLASSICCRAFTING; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues &= ~GAMESETTING_CLASSICCRAFTING; + } + ActionGameSettings(iPad, eVal); + GameSettingsA[iPad]->bSettingsChanged = true; + } + break; + case eGameSetting_CaveSounds: + if ((GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_CAVESOUNDS) != (ucVal & 0x01) << 27) + { + if (ucVal == 1) + { + GameSettingsA[iPad]->uiBitmaskValues |= GAMESETTING_CAVESOUNDS; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues &= ~GAMESETTING_CAVESOUNDS; + } + ActionGameSettings(iPad, eVal); + GameSettingsA[iPad]->bSettingsChanged = true; + } + break; + case eGameSetting_MinecartSounds: + if ((GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_MINECARTSOUNDS) != (ucVal & 0x01) << 28) + { + if (ucVal == 1) + { + GameSettingsA[iPad]->uiBitmaskValues |= GAMESETTING_MINECARTSOUNDS; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues &= ~GAMESETTING_MINECARTSOUNDS; + } + ActionGameSettings(iPad, eVal); + GameSettingsA[iPad]->bSettingsChanged = true; + } + break; + case eGameSetting_HideSaveSizeBar: + if ((GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_HIDESAVESIZEBAR) != (ucVal & 0x01) << 27) + { + if (ucVal == 1) + { + GameSettingsA[iPad]->uiBitmaskValues |= GAMESETTING_HIDESAVESIZEBAR; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues &= ~GAMESETTING_HIDESAVESIZEBAR; + } + ActionGameSettings(iPad, eVal); + GameSettingsA[iPad]->bSettingsChanged = true; + } + break; + case eGameSetting_SafeCam: + if ((GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_SAFECAM) != ((unsigned int)(ucVal & 0x01) << 30)) + { + if (ucVal == 1) + { + GameSettingsA[iPad]->uiBitmaskValues |= GAMESETTING_SAFECAM; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues &= ~GAMESETTING_SAFECAM; + } + ActionGameSettings(iPad, eVal); + GameSettingsA[iPad]->bSettingsChanged = true; + } + break; + case eGameSetting_Swap: + if ((GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_SWAP) != ((unsigned int)(ucVal & 0x01) << 31)) + { + if (ucVal == 1) + { + GameSettingsA[iPad]->uiBitmaskValues |= GAMESETTING_SWAP; + } + else + { + GameSettingsA[iPad]->uiBitmaskValues &= ~GAMESETTING_SWAP; + } + ActionGameSettings(iPad, eVal); + GameSettingsA[iPad]->bSettingsChanged = true; + } + break; + } +} + +unsigned char CMinecraftApp::GetGameSettings(eGameSetting eVal) +{ + int iPad=ProfileManager.GetPrimaryPad(); + + return GetGameSettings(iPad,eVal); +} + +unsigned char CMinecraftApp::GetGameSettings(int iPad,eGameSetting eVal) +{ + if (iPad < 0 || iPad >= XUSER_MAX_COUNT || GameSettingsA[iPad] == nullptr) + { + return 0; + } + + switch(eVal) + { + case eGameSetting_MusicVolume: + return GameSettingsA[iPad]->ucMusicVolume; + break; + case eGameSetting_SoundFXVolume: + return GameSettingsA[iPad]->ucSoundFXVolume; + break; + case eGameSetting_RenderDistance: + { + int val = (GameSettingsA[iPad]->uiBitmaskValues >> 16) & 0xFF; + if(val == 0) return val = 16; //brain + return val; + break; + } + case eGameSetting_Gamma: + return GameSettingsA[iPad]->ucGamma; + break; + case eGameSetting_FOV: + return GameSettingsA[iPad]->ucFov; + break; + case eGameSetting_Difficulty: + return GameSettingsA[iPad]->usBitmaskValues&0x0003; + break; + case eGameSetting_Sensitivity_InGame: + return GameSettingsA[iPad]->ucSensitivity; + break; + case eGameSetting_ViewBob: + return ((GameSettingsA[iPad]->usBitmaskValues&0x0004)>>2); + break; + case eGameSetting_GamertagsVisible: + return ((GameSettingsA[iPad]->usBitmaskValues&0x0008)>>3); + break; + case eGameSetting_ControlScheme: + return ((GameSettingsA[iPad]->usBitmaskValues&0x0030)>>4); // 2 bits + break; + case eGameSetting_ControlInvertLook: + return ((GameSettingsA[iPad]->usBitmaskValues&0x0040)>>6); + break; + case eGameSetting_ControlSouthPaw: + return ((GameSettingsA[iPad]->usBitmaskValues&0x0080)>>7); + break; + case eGameSetting_SplitScreenVertical: + return ((GameSettingsA[iPad]->usBitmaskValues&0x0100)>>8); + break; + // 4J-PB - Added for Interim TU for 1.6.6 + case eGameSetting_Sensitivity_InMenu: + return GameSettingsA[iPad]->ucMenuSensitivity; + break; + + case eGameSetting_DisplaySplitscreenGamertags: + return ((GameSettingsA[iPad]->usBitmaskValues&0x0200)>>9); + break; + + case eGameSetting_Hints: + return ((GameSettingsA[iPad]->usBitmaskValues&0x0400)>>10); + break; + case eGameSetting_Autosave: + { + unsigned char ucVal=(GameSettingsA[iPad]->usBitmaskValues&0x7800)>>11; + return ucVal; + } + break; + case eGameSetting_Tooltips: + return ((GameSettingsA[iPad]->usBitmaskValues&0x8000)>>15); + break; + + case eGameSetting_InterfaceOpacity: + return GameSettingsA[iPad]->ucInterfaceOpacity; + break; + + case eGameSetting_Clouds: + return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_CLOUDS); + break; + case eGameSetting_Online: + return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_ONLINE)>>1; + break; + case eGameSetting_InviteOnly: + return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_INVITEONLY)>>2; + break; + case eGameSetting_FriendsOfFriends: + return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_FRIENDSOFFRIENDS)>>3; + break; + case eGameSetting_DisplayUpdateMessage: + return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYUPDATEMSG)>>4; + break; + case eGameSetting_BedrockFog: + return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_BEDROCKFOG)>>6; + break; + case eGameSetting_DisplayHUD: + return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYHUD)>>7; + break; + case eGameSetting_DisplayHand: + return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYHAND)>>8; + break; + case eGameSetting_CustomSkinAnim: + return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_CUSTOMSKINANIM)>>9; + break; + // TU9 + case eGameSetting_DeathMessages: + return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DEATHMESSAGES)>>10; + break; + case eGameSetting_UISize: + { + unsigned char ucVal=(GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_UISIZE)>>11; + return ucVal; + } + break; + case eGameSetting_UISizeSplitscreen: + { + unsigned char ucVal=(GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_UISIZE_SPLITSCREEN)>>13; + return ucVal; + } + break; + case eGameSetting_AnimatedCharacter: + return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_ANIMATEDCHARACTER)>>15; + + case eGameSetting_PS3_EULA_Read: + return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PS3EULAREAD)>>16; + + case eGameSetting_PSVita_NetworkModeAdhoc: + return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PSVITANETWORKMODEADHOC)>>17; + + case eGameSetting_ClassicCrafting: + return (GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_CLASSICCRAFTING) >> 26; + + case eGameSetting_CaveSounds: + return (GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_CAVESOUNDS) >> 27; + + case eGameSetting_MinecartSounds: + return (GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_MINECARTSOUNDS) >> 28; + + case eGameSetting_HideSaveSizeBar: + return (GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_HIDESAVESIZEBAR) >> 27; + + case eGameSetting_VSync: + return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_VSYNC)>>24; + + case eGameSetting_ExclusiveFullscreen: + return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_EXCLUSIVEFULLSCREEN)>>25; + case eGameSetting_ControlType: + return (GameSettingsA[iPad]->uiBitmaskValues & 0x00070000) >> 16; + + case eGameSetting_SafeCam: + return (GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_SAFECAM) >> 30; + + case eGameSetting_Swap: + return (GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_SWAP) >> 31; + + } + return 0; +} + +void CMinecraftApp::CheckGameSettingsChanged(bool bOverride5MinuteTimer, int iPad) +{ + // If the settings have changed, write them to the profile + + if(iPad==XUSER_INDEX_ANY) + { + for(int i=0;ibSettingsChanged) + { +#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__ ) + StorageManager.WriteToProfile(i,true, bOverride5MinuteTimer); +#else + ProfileManager.WriteToProfile(i,true, bOverride5MinuteTimer); +#ifdef _WINDOWS64 + Win64_SaveSettings(GameSettingsA[i]); +#endif +#endif + GameSettingsA[i]->bSettingsChanged=false; + } + } + } + else + { + if(GameSettingsA[iPad]->bSettingsChanged) + { +#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) + StorageManager.WriteToProfile(iPad,true, bOverride5MinuteTimer); +#else + ProfileManager.WriteToProfile(iPad,true, bOverride5MinuteTimer); +#ifdef _WINDOWS64 + Win64_SaveSettings(GameSettingsA[iPad]); +#endif +#endif + GameSettingsA[iPad]->bSettingsChanged=false; + } + } +} + +void CMinecraftApp::ClearGameSettingsChangedFlag(int iPad) +{ + GameSettingsA[iPad]->bSettingsChanged=false; +} + +/////////////////////////// +// +// Remove the debug settings in the release build +// +//////////////////////////// +#ifndef _DEBUG +unsigned int CMinecraftApp::GetGameSettingsDebugMask(int iPad,bool bOverridePlayer) //bOverridePlayer is to force the send for the server to get the read options +{ + return 0; +} + +void CMinecraftApp::SetGameSettingsDebugMask(int iPad, unsigned int uiVal) +{ +} + +void CMinecraftApp::ActionDebugMask(int iPad,bool bSetAllClear) +{ +} + +#else + +unsigned int CMinecraftApp::GetGameSettingsDebugMask(int iPad,bool bOverridePlayer) //bOverridePlayer is to force the send for the server to get the read options +{ + if(iPad==-1) + { + iPad=ProfileManager.GetPrimaryPad(); + } + if(iPad < 0) iPad = 0; + + shared_ptr player = Minecraft::GetInstance()->localplayers[iPad]; + + if(bOverridePlayer || player==nullptr) + { + return GameSettingsA[iPad]->uiDebugBitmask; + } + else + { + return player->GetDebugOptions(); + } +} + + +void CMinecraftApp::SetGameSettingsDebugMask(int iPad, unsigned int uiVal) +{ +#ifndef _CONTENT_PACKAGE + GameSettingsA[iPad]->bSettingsChanged=true; + GameSettingsA[iPad]->uiDebugBitmask=uiVal; + + // update the value so the network server can use it + shared_ptr player = Minecraft::GetInstance()->localplayers[iPad]; + + if(player) + { + Minecraft::GetInstance()->localgameModes[iPad]->handleDebugOptions(uiVal,player); + } +#endif +} + +void CMinecraftApp::ActionDebugMask(int iPad,bool bSetAllClear) +{ + unsigned int ulBitmask=app.GetGameSettingsDebugMask(iPad); + + if(bSetAllClear) ulBitmask=0L; + + + + // these settings should only be actioned for the primary player + if(ProfileManager.GetPrimaryPad()!=iPad) return; + + for(int i=0;i(param); + app.SetAction(actionInfo->iPad, actionInfo->action); +} + + +void CMinecraftApp::HandleXuiActions(void) +{ + eXuiAction eAction; + eTMSAction eTMS; + LPVOID param; + Minecraft *pMinecraft=Minecraft::GetInstance(); + shared_ptr player; + + // are there any global actions to deal with? + eAction = app.GetGlobalXuiAction(); + if(eAction!=eAppAction_Idle) + { + switch(eAction) + { + case eAppAction_DisplayLavaMessage: + // Display a warning about placing lava in the spawn area + { + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + C4JStorage::EMessageResult result = ui.RequestErrorMessage( IDS_CANT_PLACE_NEAR_SPAWN_TITLE, IDS_CANT_PLACE_NEAR_SPAWN_TEXT, uiIDA,1,XUSER_INDEX_ANY); + if(result != C4JStorage::EMessage_Busy) SetGlobalXuiAction(eAppAction_Idle); + + } + break; + default: + break; + } + } + + // are there any app actions to deal with? + for(int i=0;iIsTitleAllowedToPostImages() && CSocialManager::Instance()->AreAllUsersAllowedToPostImages() ) + { + // disable character name tags for the shot + //m_bwasHidingGui = pMinecraft->options->hideGui; // 4J Stu - Removed 1.8.2 bug fix (TU6) as don't need this + pMinecraft->options->hideGui = true; + + SetAction(i,eAppAction_SocialPostScreenshot); + } + else + { + SetAction(i,eAppAction_Idle); + } + } + else + { + SetAction(i,eAppAction_Idle); + } + break; + case eAppAction_SocialPostScreenshot: + { + SetAction(i,eAppAction_Idle); + bool bKeepHiding = false; + for(int j=0; j < XUSER_MAX_COUNT;++j) + { + if(app.GetXuiAction(j) == eAppAction_SocialPostScreenshot) + { + bKeepHiding = true; + break; + } + } + pMinecraft->options->hideGui=bKeepHiding; + + // Facebook Share + + if(app.GetLocalPlayerCount()>1) + { + ui.NavigateToScene(i,eUIScene_SocialPost); + } + else + { + ui.NavigateToScene(i,eUIScene_SocialPost); + } + } + break; + case eAppAction_SaveGame: + SetAction(i,eAppAction_Idle); + if(!GetChangingSessionType()) + { + // If this is the trial game, do an upsell + if(ProfileManager.IsFullVersion()) + { + + // flag the render to capture the screenshot for the save + SetAction(i,eAppAction_SaveGameCapturedThumbnail); + } + else + { + // ask the player if they would like to upgrade, or they'll lose the level + + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_OK; + uiIDA[1]=IDS_CONFIRM_CANCEL; + ui.RequestErrorMessage(IDS_UNLOCK_TITLE, IDS_UNLOCK_TOSAVE_TEXT, uiIDA, 2,i,&CMinecraftApp::UnlockFullSaveReturned,this); + } + } + + break; + case eAppAction_AutosaveSaveGame: + { + // Need to run a check to see if the save exists in order to stop the dialog asking if we want to overwrite it coming up on an autosave + bool bSaveExists; + StorageManager.DoesSaveExist(&bSaveExists); + + SetAction(i,eAppAction_Idle); + if(!GetChangingSessionType()) + { + + // flag the render to capture the screenshot for the save + SetAction(i,eAppAction_AutosaveSaveGameCapturedThumbnail); + } + } + + break; + + case eAppAction_SaveGameCapturedThumbnail: + // reset the autosave timer + app.SetAutosaveTimerTime(); + SetAction(i,eAppAction_Idle); + // Check that there is a name for the save - if we're saving from the tutorial and this is the first save from the tutorial, we'll not have a name + /*if(StorageManager.GetSaveName()==nullptr) + { + app.NavigateToScene(i,eUIScene_SaveWorld); + } + else*/ + { + // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen + ui.HideAllGameUIElements(); + + // Hide the other players scenes + ui.ShowOtherPlayersBaseScene(ProfileManager.GetPrimaryPad(), false); + + //INT saveOrCheckpointId = 0; + //bool validSave = StorageManager.GetSaveUniqueNumber(&saveOrCheckpointId); + //SentientManager.RecordLevelSaveOrCheckpoint(ProfileManager.GetPrimaryPad(), saveOrCheckpointId); + + LoadingInputParams *loadingParams = new LoadingInputParams(); + loadingParams->func = &UIScene_PauseMenu::SaveWorldThreadProc; + loadingParams->lpParam = static_cast(false); + + // 4J-JEV - PS4: Fix for #5708 - [ONLINE] - If the user pulls their network cable out while saving the title will hang. + loadingParams->waitForThreadToDelete = true; + + UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); + completionData->bShowBackground=TRUE; + completionData->bShowLogo=TRUE; + completionData->type = e_ProgressCompletion_NavigateBackToScene; + completionData->iPad = ProfileManager.GetPrimaryPad(); + + if( ui.IsSceneInStack( ProfileManager.GetPrimaryPad(), eUIScene_EndPoem ) ) + { + completionData->scene = eUIScene_EndPoem; + } + else + { + completionData->scene = eUIScene_PauseMenu; + } + + loadingParams->completionData = completionData; + + // 4J Stu - Xbox only +#ifdef _XBOX + // Temporarily make this scene fullscreen + CXuiSceneBase::SetPlayerBaseScenePosition( ProfileManager.GetPrimaryPad(), CXuiSceneBase::e_BaseScene_Fullscreen ); +#endif + + ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams , eUILayer_Fullscreen, eUIGroup_Fullscreen); + + } + break; + case eAppAction_AutosaveSaveGameCapturedThumbnail: + + { + app.SetAutosaveTimerTime(); + SetAction(i,eAppAction_Idle); + +#if defined(_XBOX_ONE) || defined(__ORBIS__) + app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_AutoSaveGame); + + if(app.GetGameHostOption(eGameHostOption_DisableSaving)) StorageManager.SetSaveDisabled(true); +#else + // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen + ui.HideAllGameUIElements(); + + //app.CloseAllPlayersXuiScenes(); + // Hide the other players scenes + ui.ShowOtherPlayersBaseScene(ProfileManager.GetPrimaryPad(), false); + + // This just allows it to be shown + if(pMinecraft->localgameModes[ProfileManager.GetPrimaryPad()] != nullptr) pMinecraft->localgameModes[ProfileManager.GetPrimaryPad()]->getTutorial()->showTutorialPopup(false); + + //INT saveOrCheckpointId = 0; + //bool validSave = StorageManager.GetSaveUniqueNumber(&saveOrCheckpointId); + //SentientManager.RecordLevelSaveOrCheckpoint(ProfileManager.GetPrimaryPad(), saveOrCheckpointId); + + + LoadingInputParams *loadingParams = new LoadingInputParams(); + loadingParams->func = &UIScene_PauseMenu::SaveWorldThreadProc; + + loadingParams->lpParam = (LPVOID)(true); + + UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); + completionData->bShowBackground=TRUE; + completionData->bShowLogo=TRUE; + completionData->type = e_ProgressCompletion_AutosaveNavigateBack; + completionData->iPad = ProfileManager.GetPrimaryPad(); + //completionData->bAutosaveWasMenuDisplayed=ui.GetMenuDisplayed(ProfileManager.GetPrimaryPad()); + loadingParams->completionData = completionData; + + // 4J Stu - Xbox only +#ifdef _XBOX + // Temporarily make this scene fullscreen + CXuiSceneBase::SetPlayerBaseScenePosition( ProfileManager.GetPrimaryPad(), CXuiSceneBase::e_BaseScene_Fullscreen ); +#endif + + ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams , eUILayer_Fullscreen, eUIGroup_Fullscreen); +#endif + } + break; + case eAppAction_ExitPlayer: + // a secondary player has chosen to quit + { + int iPlayerC=g_NetworkManager.GetPlayerCount(); + + // Since the player is exiting, let's flush any profile writes for them, and hope we're not breaking TCR 136... +#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) + StorageManager.ForceQueuedProfileWrites(i); + LeaderboardManager::Instance()->OpenSession(); + for (int j = 0; j < XUSER_MAX_COUNT; j++) + { + if( ProfileManager.IsSignedIn(j) ) + { + app.DebugPrintf("Stats save for an offline game for the player at index %d\n", 0); + Minecraft::GetInstance()->forceStatsSave(j); + } + } + LeaderboardManager::Instance()->CloseSession(); +#else + ProfileManager.ForceQueuedProfileWrites(i); +#endif + + // not required - it's done within the removeLocalPlayerIdx + // if(pMinecraft->level->isClientSide) + // { + // // we need to remove the qnetplayer, or this player won't be able to get back into the game until qnet times out and removes them + // g_NetworkManager.NotifyPlayerLeaving(g_NetworkManager.GetLocalPlayerByUserIndex(i)); + // } + + // if there are any tips showing, we need to close them + + pMinecraft->gui->clearMessages(i); + + // Make sure we've not got this player selected as current - this shouldn't be the case anyway + pMinecraft->setLocalPlayerIdx(ProfileManager.GetPrimaryPad()); + pMinecraft->removeLocalPlayerIdx(i); + +#ifdef _XBOX + // tell the xui scenes a splitscreen player left - has to come after removeLocalPlayerIdx which calls updatePlayerViewportAssignments + XUIMessage xuiMsg; + CustomMessage_Splitscreenplayer_Struct myMsgData; + CustomMessage_Splitscreenplayer( &xuiMsg, &myMsgData, false); + + // send the message + for(int idx=0;idxlocalplayers[idx]!=nullptr)) + { + XuiBroadcastMessage( CXuiSceneBase::GetPlayerBaseScene(idx), &xuiMsg ); + } + } +#endif + +#ifndef _XBOX + // Wipe out the tooltips + ui.SetTooltips(i, -1); +#endif + + // Change the presence info + // Are we offline or online, and how many players are there + if(iPlayerC>2) // one player is about to leave here - they'll be set to idle in the qnet manager player leave + { + for(int iPlayer=0;iPlayerlocalplayers[iPlayer]) + { + if(g_NetworkManager.IsLocalGame()) + { + ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); + } + else + { + ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER,false); + } + } + } + } + else + { + for(int iPlayer=0;iPlayerlocalplayers[iPlayer]) + { + if(g_NetworkManager.IsLocalGame()) + { + ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); + } + else + { + ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); + } + } + } + } + +#ifdef _DURANGO + ProfileManager.RemoveGamepadFromGame(i); +#endif + + SetAction(i,eAppAction_Idle); + } + break; + case eAppAction_ExitPlayerPreLogin: + { + int iPlayerC=g_NetworkManager.GetPlayerCount(); + // Since the player is exiting, let's flush any profile writes for them, and hope we're not breaking TCR 136... +#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) + StorageManager.ForceQueuedProfileWrites(i); +#else + ProfileManager.ForceQueuedProfileWrites(i); +#endif + // if there are any tips showing, we need to close them + + pMinecraft->gui->clearMessages(i); + + // Make sure we've not got this player selected as current - this shouldn't be the case anyway + pMinecraft->setLocalPlayerIdx(ProfileManager.GetPrimaryPad()); + pMinecraft->removeLocalPlayerIdx(i); + +#ifdef _XBOX + // tell the xui scenes a splitscreen player left - has to come after removeLocalPlayerIdx which calls updatePlayerViewportAssignments + XUIMessage xuiMsg; + CustomMessage_Splitscreenplayer_Struct myMsgData; + CustomMessage_Splitscreenplayer( &xuiMsg, &myMsgData, false); + + // send the message + for(int idx=0;idxlocalplayers[idx]!=nullptr)) + { + XuiBroadcastMessage( CXuiSceneBase::GetPlayerBaseScene(idx), &xuiMsg ); + } + } +#endif + +#ifndef _XBOX + // Wipe out the tooltips + ui.SetTooltips(i, -1); +#endif + + // Change the presence info + // Are we offline or online, and how many players are there + if(iPlayerC>2) // one player is about to leave here - they'll be set to idle in the qnet manager player leave + { + for(int iPlayer=0;iPlayerlocalplayers[iPlayer]) + { + if(g_NetworkManager.IsLocalGame()) + { + ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); + } + else + { + ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER,false); + } + } + } + } + else + { + for(int iPlayer=0;iPlayerlocalplayers[iPlayer]) + { + if(g_NetworkManager.IsLocalGame()) + { + ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); + } + else + { + ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); + } + } + } + } + SetAction(i,eAppAction_Idle); + } + break; + +#ifdef __ORBIS__ + case eAppAction_OptionsSaveNoSpace: + { + SetAction(i,eAppAction_Idle); + + SceSaveDataDialogParam param; + SceSaveDataDialogSystemMessageParam sysParam; + SceSaveDataDialogItems items; + SceSaveDataDirName dirName; + + sceSaveDataDialogParamInitialize(¶m); + param.mode = SCE_SAVE_DATA_DIALOG_MODE_SYSTEM_MSG; + param.dispType = SCE_SAVE_DATA_DIALOG_TYPE_SAVE; + memset(&sysParam,0,sizeof(sysParam)); + param.sysMsgParam = &sysParam; + param.sysMsgParam->sysMsgType = SCE_SAVE_DATA_DIALOG_SYSMSG_TYPE_NOSPACE_CONTINUABLE; + param.sysMsgParam->value = app.GetOptionsBlocksRequired(i); + memset(&items, 0, sizeof(items)); + param.items = &items; + param.items->userId = ProfileManager.getUserID(i); + + int ret = sceSaveDataDialogInitialize(); + ret = sceSaveDataDialogOpen(¶m); + + app.SetOptionsSaveDataDialogRunning(true);//m_bOptionsSaveDataDialogRunning = true; + //pClass->m_eSaveIncompleteType = saveIncompleteType; + + //StorageManager.SetSaveDisabled(true); + //pClass->EnterSaveNotificationSection(); + + } + break; +#endif + + case eAppAction_ExitWorld: + + SetAction(i,eAppAction_Idle); + + // HUCKLE - added for quit game on disconnect +#ifdef _WINDOWS64 + if(g_Win64MultiplayerQuitOnDisconnect == true) + { + app.ExitGame(); + return; + } +#endif + + // If we're already leaving don't exit + if (g_NetworkManager.IsLeavingGame()) + { + break; + } + + pMinecraft->gui->clearMessages(); + + // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen + ui.HideAllGameUIElements(); + + // reset the flag stopping new dlc message being shown if you've seen the message before + DisplayNewDLCTipAgain(); + + // clear the autosave timer that might be on screen + ui.ShowAutosaveCountdownTimer(false); + + // Hide the selected item text + ui.HideAllGameUIElements(); + + // Since the player forced the exit, let's flush any profile writes, and hope we're not breaking TCR 136... +#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) + StorageManager.ForceQueuedProfileWrites(); + LeaderboardManager::Instance()->OpenSession(); + for (int j = 0; j < XUSER_MAX_COUNT; j++) + { + if( ProfileManager.IsSignedIn(j) ) + { + app.DebugPrintf("Stats save for an offline game for the player at index %d\n", 0); + Minecraft::GetInstance()->forceStatsSave(j); + } + } + LeaderboardManager::Instance()->CloseSession(); +#elif (defined _XBOX) + ProfileManager.ForceQueuedProfileWrites(); +#endif + + // 4J-PB - cancel any possible string verifications queued with LIVE + //InputManager.CancelAllVerifyInProgress(); + + if(ProfileManager.IsFullVersion()) + { + + // In a split screen, only the primary player actually quits the game, others just remove their players + if( i != ProfileManager.GetPrimaryPad() ) + { + // Make sure we've not got this player selected as current - this shouldn't be the case anyway + pMinecraft->setLocalPlayerIdx(ProfileManager.GetPrimaryPad()); + pMinecraft->removeLocalPlayerIdx(i); + +#ifdef _DURANGO + ProfileManager.RemoveGamepadFromGame(i); +#endif + SetAction(i,eAppAction_Idle); + return; + } + // flag to capture the save thumbnail + SetAction(i,eAppAction_ExitWorldCapturedThumbnail, param); + } + else + { + // ask the player if they would like to upgrade, or they'll lose the level + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_OK; + uiIDA[1]=IDS_CONFIRM_CANCEL; + ui.RequestErrorMessage(IDS_UNLOCK_TITLE, IDS_UNLOCK_TOSAVE_TEXT, uiIDA, 2, i,&CMinecraftApp::UnlockFullExitReturned,this); + } + + // Change the presence info + // Are we offline or online, and how many players are there + + if(g_NetworkManager.GetPlayerCount()>1) + { + for(int j=0;jlocalplayers[j]) + { + if(g_NetworkManager.IsLocalGame()) + { + app.SetRichPresenceContext(j,CONTEXT_GAME_STATE_BLANK); + ProfileManager.SetCurrentGameActivity(j,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); + } + else + { + app.SetRichPresenceContext(j,CONTEXT_GAME_STATE_BLANK); + ProfileManager.SetCurrentGameActivity(j,CONTEXT_PRESENCE_MULTIPLAYER,false); + } + TelemetryManager->RecordLevelExit(j, eSen_LevelExitStatus_Exited); + } + } + } + else + { + app.SetRichPresenceContext(i,CONTEXT_GAME_STATE_BLANK); + if(g_NetworkManager.IsLocalGame()) + { + ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); + } + else + { + ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); + } + TelemetryManager->RecordLevelExit(i, eSen_LevelExitStatus_Exited); + } + break; + case eAppAction_ExitWorldCapturedThumbnail: + { + SetAction(i,eAppAction_Idle); + // Stop app running + SetGameStarted(false); + SetChangingSessionType(true); // Added to stop handling ethernet disconnects + + ui.CloseAllPlayersScenes(); + + // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen + ui.HideAllGameUIElements(); + + // 4J Stu - Fix for #12368 - Crash: Game crashes when saving then exiting and selecting to save + for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) + { +#ifdef _XBOX + app.TutorialSceneNavigateBack(idx,true); +#endif + + // 4J Stu - Fix for #13257 - CRASH: Gameplay: Title crashed after exiting the tutorial + // It doesn't matter if they were in the tutorial already + pMinecraft->playerLeftTutorial( idx ); + } + + LoadingInputParams *loadingParams = new LoadingInputParams(); + loadingParams->func = &UIScene_PauseMenu::ExitWorldThreadProc; + loadingParams->lpParam = param; + + UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); + // If param is non-null then this is a forced exit by the server, so make sure the player knows why + // 4J Stu - Changed - Don't use the FullScreenProgressScreen for action, use a dialog instead + completionData->bRequiresUserAction = FALSE;//(param != nullptr) ? TRUE : FALSE; + completionData->bShowTips = (param != nullptr) ? FALSE : TRUE; + completionData->bShowBackground=TRUE; + completionData->bShowLogo=TRUE; + completionData->type = e_ProgressCompletion_NavigateToHomeMenu; + completionData->iPad = DEFAULT_XUI_MENU_USER; + loadingParams->completionData = completionData; + + ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); + } + break; + case eAppAction_ExitWorldTrial: + { + SetAction(i,eAppAction_Idle); + + pMinecraft->gui->clearMessages(); + + // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen + ui.HideAllGameUIElements(); + + // Stop app running + SetGameStarted(false); + + ui.CloseAllPlayersScenes(); + + // 4J Stu - Fix for #12368 - Crash: Game crashes when saving then exiting and selecting to save + for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) + { +#ifdef _XBOX + app.TutorialSceneNavigateBack(idx,true); +#endif + + // 4J Stu - Fix for #13257 - CRASH: Gameplay: Title crashed after exiting the tutorial + // It doesn't matter if they were in the tutorial already + pMinecraft->playerLeftTutorial( idx ); + } + + LoadingInputParams *loadingParams = new LoadingInputParams(); + loadingParams->func = &UIScene_PauseMenu::ExitWorldThreadProc; + loadingParams->lpParam = param; + + UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); + completionData->bShowBackground=TRUE; + completionData->bShowLogo=TRUE; + completionData->type = e_ProgressCompletion_NavigateToHomeMenu; + completionData->iPad = DEFAULT_XUI_MENU_USER; + loadingParams->completionData = completionData; + + ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); + } + + break; + case eAppAction_ExitTrial: + //XLaunchNewImage(XLAUNCH_KEYWORD_DASH_ARCADE, 0); + ExitGame(); + break; + + case eAppAction_Respawn: + { + ConnectionProgressParams *param = new ConnectionProgressParams(); + param->iPad = i; + param->stringId = IDS_PROGRESS_RESPAWNING; + param->showTooltips = false; + param->setFailTimer = false; + ui.NavigateToScene(i,eUIScene_ConnectingProgress, param); + + // Need to reset this incase the player has already died and respawned + pMinecraft->localplayers[i]->SetPlayerRespawned(false); + + SetAction(i,eAppAction_WaitForRespawnComplete); + if( app.GetLocalPlayerCount()>1 ) + { + // In split screen mode, we don't want to do any async loading or flushing of the cache, just a simple respawn + pMinecraft->localplayers[i]->respawn(); + + // If the respawn requires a dimension change then the action will have changed + //if(app.GetXuiAction(i) == eAppAction_Respawn) + //{ + // SetAction(i,eAppAction_Idle); + // CloseXuiScenes(i); + //} + } + else + { + //SetAction(i,eAppAction_WaitForRespawnComplete); + + //LoadingInputParams *loadingParams = new LoadingInputParams(); + //loadingParams->func = &CScene_Death::RespawnThreadProc; + //loadingParams->lpParam = (LPVOID)i; + + // Disable game & update thread whilst we do any of this + //app.SetGameStarted(false); + pMinecraft->gameRenderer->DisableUpdateThread(); + + // 4J Stu - We don't need this on a thread in multiplayer as respawning is asynchronous. + pMinecraft->localplayers[i]->respawn(); + + //app.SetGameStarted(true); + pMinecraft->gameRenderer->EnableUpdateThread(); + + //UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); + //completionData->bShowBackground=TRUE; + //completionData->bShowLogo=TRUE; + //completionData->type = e_ProgressCompletion_CloseUIScenes; + //completionData->iPad = i; + //loadingParams->completionData = completionData; + + //app.NavigateToScene(i,eUIScene_FullscreenProgress, loadingParams, true); + } + } + break; + case eAppAction_WaitForRespawnComplete: + player = pMinecraft->localplayers[i]; + if(player != nullptr && player->GetPlayerRespawned()) + { + SetAction(i,eAppAction_Idle); + + if(ui.IsSceneInStack(i, eUIScene_EndPoem)) + { + ui.NavigateBack(i,false,eUIScene_EndPoem); + } + else + { + ui.CloseUIScenes(i); + } + + // clear the progress messages + + // pMinecraft->progressRenderer->progressStart(-1); + // pMinecraft->progressRenderer->progressStage(-1); + } + else if(!g_NetworkManager.IsInGameplay()) + { + SetAction(i,eAppAction_Idle); + } + break; + case eAppAction_WaitForDimensionChangeComplete: + player = pMinecraft->localplayers[i]; + if(player != nullptr && player->connection && player->connection->isStarted()) + { + SetAction(i,eAppAction_Idle); + ui.CloseUIScenes(i); + } + else if(!g_NetworkManager.IsInGameplay()) + { + SetAction(i,eAppAction_Idle); + } + break; + case eAppAction_PrimaryPlayerSignedOut: + { + //SetAction(i,eAppAction_Idle); + + // clear the autosavetimer that might be displayed + ui.ShowAutosaveCountdownTimer(false); + + // If the player signs out before the game started the server can be killed a bit earlier to stop + // the loading or saving of a new game continuing running while the UI/Guide is up + if(!app.GetGameStarted()) MinecraftServer::HaltServer(true); + + // inform the player they are being returned to the menus because they signed out + StorageManager.SetSaveDeviceSelected(i,false); + // need to clear the player stats - can't assume it'll be done in setlevel - we may not be in the game + StatsCounter* pStats = Minecraft::GetInstance()->stats[ i ]; + pStats->clear(); + + // 4J-PB - the libs will display the Returned to Title screen + // UINT uiIDA[1]; + // uiIDA[0]=IDS_CONFIRM_OK; + // + // ui.RequestMessageBox(IDS_RETURNEDTOMENU_TITLE, IDS_RETURNEDTOTITLESCREEN_TEXT, uiIDA, 1, i,&CMinecraftApp::PrimaryPlayerSignedOutReturned,this,app.GetStringTable()); + if( g_NetworkManager.IsInSession() ) + { + app.SetAction(i,eAppAction_PrimaryPlayerSignedOutReturned); + } + else + { + app.SetAction(i,eAppAction_PrimaryPlayerSignedOutReturned_Menus); + MinecraftServer::resetFlags(); + } + } + break; + case eAppAction_EthernetDisconnected: + { + app.DebugPrintf("Handling eAppAction_EthernetDisconnected\n"); + SetAction(i,eAppAction_Idle); + + // 4J Stu - Fix for #12530 -TCR 001 BAS Game Stability: Title will crash if the player disconnects while starting a new world and then opts to play the tutorial once they have been returned to the Main Menu. + if(!g_NetworkManager.IsLeavingGame()) + { + app.DebugPrintf("Handling eAppAction_EthernetDisconnected - Not leaving game\n"); + // 4J-PB - not the same as a signout. We should only leave the game if this machine is not the host. We shouldn't get rid of the save device either. + if( g_NetworkManager.IsHost() ) + { + app.DebugPrintf("Handling eAppAction_EthernetDisconnected - Is Host\n"); + // If it's already a local game, then an ethernet disconnect should have no effect + if( !g_NetworkManager.IsLocalGame() && g_NetworkManager.IsInGameplay() ) + { + // Change the session to an offline session + SetAction(i,eAppAction_ChangeSessionType); + } + else if(!g_NetworkManager.IsLocalGame() && !g_NetworkManager.IsInGameplay() ) + { + // There are two cases here, either: + // 1. We're early enough in the create/load game that we can do a really minimal shutdown or + // 2. We're far enough in (game has started but the actual game started flag hasn't been set) that we should just wait until we're in the game and switch to offline mode + + // If there's a non-null level then, for our purposes, the game has started + bool gameStarted = false; + for(int j = 0; j < pMinecraft->levels.length; j++) + { + if (pMinecraft->levels.data[i] != nullptr) + { + gameStarted = true; + break; + } + } + + if (!gameStarted) + { + // 1. Exit + MinecraftServer::HaltServer(); + + // Fix for #12530 - TCR 001 BAS Game Stability: Title will crash if the player disconnects while starting a new world and then opts to play the tutorial once they have been returned to the Main Menu. + // 4J Stu - Leave the session + g_NetworkManager.LeaveGame(FALSE); + + // need to clear the player stats - can't assume it'll be done in setlevel - we may not be in the game + StatsCounter* pStats = Minecraft::GetInstance()->stats[ i ]; + pStats->clear(); + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + + ui.RequestErrorMessage(g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST), g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST_LIVE), uiIDA, 1, i,&CMinecraftApp::EthernetDisconnectReturned,this); + } + else + { + // 2. Switch to offline + SetAction(i,eAppAction_ChangeSessionType); + } + } + } + else + { +#if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ + if(UIScene_LoadOrJoinMenu::isSaveTransferRunning()) + { + // the save transfer is still in progress, delay jumping back to the main menu until we've cleaned up + SetAction(i,eAppAction_EthernetDisconnected); + } + else +#endif + { + app.DebugPrintf("Handling eAppAction_EthernetDisconnected - Not host\n"); + // need to clear the player stats - can't assume it'll be done in setlevel - we may not be in the game + StatsCounter* pStats = Minecraft::GetInstance()->stats[ i ]; + pStats->clear(); + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + + ui.RequestErrorMessage(g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST), g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST_LIVE), uiIDA, 1, i,&CMinecraftApp::EthernetDisconnectReturned,this); + + } + } + } + } + break; + // We currently handle both these returns the same way. + case eAppAction_EthernetDisconnectedReturned: + case eAppAction_PrimaryPlayerSignedOutReturned: + { + SetAction(i,eAppAction_Idle); + + pMinecraft->gui->clearMessages(); + + // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen + ui.HideAllGameUIElements(); + + // set the state back to pre-game + ProfileManager.ResetProfileProcessState(); + + + if( g_NetworkManager.IsLeavingGame() ) + { + // 4J Stu - If we are already leaving the game, then we just need to signal that the player signed out to stop saves + pMinecraft->progressRenderer->progressStartNoAbort( IDS_EXITING_GAME ); + pMinecraft->progressRenderer->progressStage(-1); + // This has no effect on client machines + MinecraftServer::HaltServer(true); + } + else + { + // Stop app running + SetGameStarted(false); + + // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen + ui.HideAllGameUIElements(); + + ui.CloseAllPlayersScenes(); + + // 4J Stu - Fix for #12368 - Crash: Game crashes when saving then exiting and selecting to save + for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) + { +#ifdef _XBOX + app.TutorialSceneNavigateBack(idx,true); +#endif + + // 4J Stu - Fix for #13257 - CRASH: Gameplay: Title crashed after exiting the tutorial + // It doesn't matter if they were in the tutorial already + pMinecraft->playerLeftTutorial( idx ); + } + + LoadingInputParams *loadingParams = new LoadingInputParams(); + loadingParams->func = &CMinecraftApp::SignoutExitWorldThreadProc; + + UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); + completionData->bShowBackground=TRUE; + completionData->bShowLogo=TRUE; + completionData->iPad=DEFAULT_XUI_MENU_USER; + completionData->type = e_ProgressCompletion_NavigateToHomeMenu; + loadingParams->completionData = completionData; + + ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); + } + } + break; + case eAppAction_PrimaryPlayerSignedOutReturned_Menus: + SetAction(i,eAppAction_Idle); + // set the state back to pre-game + ProfileManager.ResetProfileProcessState(); + // clear the save device + StorageManager.SetSaveDeviceSelected(i,false); + + ui.UpdatePlayerBasePositions(); + // there are multiple layers in the help menu, so a navigate back isn't enough + ui.NavigateToHomeMenu(); + + break; + case eAppAction_EthernetDisconnectedReturned_Menus: + SetAction(i,eAppAction_Idle); + // set the state back to pre-game + ProfileManager.ResetProfileProcessState(); + + ui.UpdatePlayerBasePositions(); + + // there are multiple layers in the help menu, so a navigate back isn't enough + ui.NavigateToHomeMenu(); + + break; + + case eAppAction_TrialOver: + { + SetAction(i,eAppAction_Idle); + UINT uiIDA[2]; + uiIDA[0]=IDS_UNLOCK_TITLE; + uiIDA[1]=IDS_EXIT_GAME; + + ui.RequestErrorMessage(IDS_TRIALOVER_TITLE, IDS_TRIALOVER_TEXT, uiIDA, 2, i,&CMinecraftApp::TrialOverReturned,this); + } + break; + + // INVITES + case eAppAction_DashboardTrialJoinFromInvite: + { + TelemetryManager->RecordUpsellPresented(i, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID); + + SetAction(i,eAppAction_Idle); + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_OK; + uiIDA[1]=IDS_CONFIRM_CANCEL; + + ui.RequestErrorMessage(IDS_UNLOCK_TITLE, IDS_UNLOCK_ACCEPT_INVITE, uiIDA, 2, i,&CMinecraftApp::UnlockFullInviteReturned,this); + } + break; + case eAppAction_ExitAndJoinFromInvite: + { + UINT uiIDA[3]; + + SetAction(i,eAppAction_Idle); + // Check the player really wants to do this + +#if defined(_XBOX_ONE) || defined(__ORBIS__) + // Show save option is saves ARE disabled + if(ProfileManager.IsFullVersion() && StorageManager.GetSaveDisabled() && i==ProfileManager.GetPrimaryPad() && g_NetworkManager.IsHost() && GetGameStarted() ) + { + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_EXIT_GAME_SAVE; + uiIDA[2]=IDS_EXIT_GAME_NO_SAVE; + + ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_LEAVE_VIA_INVITE, uiIDA, 3, i,&CMinecraftApp::ExitAndJoinFromInviteSaveDialogReturned,this); + } + else +#else + if(ProfileManager.IsFullVersion() && !StorageManager.GetSaveDisabled() && i==ProfileManager.GetPrimaryPad() && g_NetworkManager.IsHost() && GetGameStarted() ) + { + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_EXIT_GAME_SAVE; + uiIDA[2]=IDS_EXIT_GAME_NO_SAVE; + + ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_LEAVE_VIA_INVITE, uiIDA, 3, i,&CMinecraftApp::ExitAndJoinFromInviteSaveDialogReturned,this); + } + else +#endif + { + if(!ProfileManager.IsFullVersion()) + { + TelemetryManager->RecordUpsellPresented(i, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID); + + // upsell + uiIDA[0]=IDS_CONFIRM_OK; + uiIDA[1]=IDS_CONFIRM_CANCEL; + ui.RequestErrorMessage(IDS_UNLOCK_TITLE, IDS_UNLOCK_ACCEPT_INVITE, uiIDA, 2, i,&CMinecraftApp::UnlockFullInviteReturned,this); + } + else + { + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_CONFIRM_OK; + ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_LEAVE_VIA_INVITE, uiIDA, 2,i,&CMinecraftApp::ExitAndJoinFromInvite,this); + } + } + } + break; + case eAppAction_ExitAndJoinFromInviteConfirmed: + { + SetAction(i,eAppAction_Idle); + + pMinecraft->gui->clearMessages(); + + // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen + ui.HideAllGameUIElements(); + + // Stop app running + SetGameStarted(false); + + ui.CloseAllPlayersScenes(); + + // 4J Stu - Fix for #12368 - Crash: Game crashes when saving then exiting and selecting to save + for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) + { +#ifdef _XBOX + app.TutorialSceneNavigateBack(idx,true); +#endif + + // 4J Stu - Fix for #13257 - CRASH: Gameplay: Title crashed after exiting the tutorial + // It doesn't matter if they were in the tutorial already + pMinecraft->playerLeftTutorial( idx ); + } + + // 4J-PB - may have been using a texture pack with audio , so clean up anything texture pack related here + + // unload any texture pack audio + // if there is audio in use, clear out the audio, and unmount the pack + TexturePack *pTexPack=Minecraft::GetInstance()->skins->getSelected(); + DLCTexturePack *pDLCTexPack=nullptr; + + if(pTexPack->hasAudio()) + { + // get the dlc texture pack, and store it + pDLCTexPack=static_cast(pTexPack); + } + + // change to the default texture pack + pMinecraft->skins->selectTexturePackById(TexturePackRepository::DEFAULT_TEXTURE_PACK_ID); + + if(pTexPack->hasAudio()) + { + // need to stop the streaming audio - by playing streaming audio from the default texture pack now + // reset the streaming sounds back to the normal ones +#ifndef _XBOX + pMinecraft->soundEngine->SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3, + eStream_Nether1,eStream_Nether4, + eStream_end_dragon,eStream_end_end, + eStream_Overworld_Creative1,eStream_Overworld_Creative6, + eStream_Overworld_Menu1,eStream_Overworld_Menu4, + eStream_BattleMode1,eStream_BattleMode4, + eStream_CD_1); +#endif + pMinecraft->soundEngine->playStreaming(L"", 0, 0, 0, 1, 1); + +#ifdef _XBOX + if(pDLCTexPack->m_pStreamedWaveBank!=nullptr) + { + pDLCTexPack->m_pStreamedWaveBank->Destroy(); + } + if(pDLCTexPack->m_pSoundBank!=nullptr) + { + pDLCTexPack->m_pSoundBank->Destroy(); + } +#endif +#ifdef _DURANGO + DWORD result = StorageManager.UnmountInstalledDLC(L"TPACK"); +#else + DWORD result = StorageManager.UnmountInstalledDLC("TPACK"); +#endif + app.DebugPrintf("Unmount result is %d\n",result); + } + +#ifdef _XBOX_ONE + // 4J Stu - It's possible that we can sign in/remove players between the mask initially being set and this point + m_InviteData.dwLocalUsersMask = 0; + for(unsigned int index = 0; index < XUSER_MAX_COUNT; ++index) + { + if(ProfileManager.IsSignedIn(index) ) + { + if (index == i || pMinecraft->localplayers[index] != nullptr) + { + m_InviteData.dwLocalUsersMask |= g_NetworkManager.GetLocalPlayerMask(index); + } + } + } +#endif + + LoadingInputParams *loadingParams = new LoadingInputParams(); + loadingParams->func = &CGameNetworkManager::ExitAndJoinFromInviteThreadProc; + loadingParams->lpParam = static_cast(&m_InviteData); + + UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); + completionData->bShowBackground=TRUE; + completionData->bShowLogo=TRUE; + completionData->iPad=DEFAULT_XUI_MENU_USER; + completionData->type = e_ProgressCompletion_NoAction; + loadingParams->completionData = completionData; + + ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); + } + + break; + case eAppAction_JoinFromInvite: + { + SetAction(i,eAppAction_Idle); + + // 4J Stu - Move this state block from CPlatformNetworkManager::ExitAndJoinFromInviteThreadProc, as g_NetworkManager.JoinGameFromInviteInfo ultimately can call NavigateToScene, + /// and we should only be calling that from the main thread + app.SetTutorialMode( false ); + + g_NetworkManager.SetLocalGame(false); + + JoinFromInviteData *inviteData = static_cast(param); + // 4J-PB - clear any previous connection errors + Minecraft::GetInstance()->clearConnectionFailed(); + + app.DebugPrintf( "Changing Primary Pad on an invite accept - pad was %d, and is now %d\n", ProfileManager.GetPrimaryPad(), inviteData->dwUserIndex ); + ProfileManager.SetLockedProfile(inviteData->dwUserIndex); + ProfileManager.SetPrimaryPad(inviteData->dwUserIndex); + +#ifdef _XBOX_ONE + // 4J Stu - If a player is signed in (i.e. locked) but not in the mask, unlock them + for(unsigned int index = 0; index < XUSER_MAX_COUNT; ++index) + { + if( index != inviteData->dwUserIndex && ProfileManager.IsSignedIn(index) ) + { + if( (m_InviteData.dwLocalUsersMask & g_NetworkManager.GetLocalPlayerMask( index ) ) == 0 ) + { + ProfileManager.RemoveGamepadFromGame(index); + } + } + } +#endif + + // change the minecraft player name + Minecraft::GetInstance()->user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); + + bool success = g_NetworkManager.JoinGameFromInviteInfo( + inviteData->dwUserIndex, // dwUserIndex + inviteData->dwLocalUsersMask, // dwUserMask + inviteData->pInviteInfo ); // pInviteInfo + + if( !success ) + { + app.DebugPrintf( "Failed joining game from invite\n" ); + //return hr; + + // 4J Stu - Copied this from XUI_FullScreenProgress to properly handle the fail case, as the thread will no longer be failing + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + ui.RequestErrorMessage( IDS_CONNECTION_FAILED, IDS_CONNECTION_LOST_SERVER, uiIDA,1,ProfileManager.GetPrimaryPad()); + + ui.NavigateToHomeMenu(); + ui.UpdatePlayerBasePositions(); + } + } + break; + case eAppAction_ChangeSessionType: + { + // If we are not in gameplay yet, then wait until the server is setup before changing the session type + if( g_NetworkManager.IsInGameplay() ) + { + // This kicks off a thread that waits for the server to end, then closes the current session, starts a new one and joins the local players into it + + SetAction(i,eAppAction_Idle); + + if( !GetChangingSessionType() && !g_NetworkManager.IsLocalGame() ) + { + SetGameStarted(false); + SetChangingSessionType(true); + SetReallyChangingSessionType(true); + + // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen + ui.HideAllGameUIElements(); + + if( !ui.IsSceneInStack( ProfileManager.GetPrimaryPad(), eUIScene_EndPoem ) ) + { + ui.CloseAllPlayersScenes(); + } + ui.ShowOtherPlayersBaseScene(ProfileManager.GetPrimaryPad(), true); + + // Remove this line to fix: + // #49084 - TU5: Code: Gameplay: The title crashes every time client navigates to 'Play game' menu and loads/creates new game after a "Connection to Xbox LIVE was lost" message has appeared. + //app.NavigateToScene(0,eUIScene_Main); + + LoadingInputParams *loadingParams = new LoadingInputParams(); + loadingParams->func = &CGameNetworkManager::ChangeSessionTypeThreadProc; + loadingParams->lpParam = nullptr; + + UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); +#ifdef __PS3__ + completionData->bRequiresUserAction=FALSE; +#else + completionData->bRequiresUserAction=TRUE; +#endif + completionData->bShowBackground=TRUE; + completionData->bShowLogo=TRUE; + completionData->iPad=DEFAULT_XUI_MENU_USER; + if( ui.IsSceneInStack( ProfileManager.GetPrimaryPad(), eUIScene_EndPoem ) ) + { + completionData->type = e_ProgressCompletion_NavigateBackToScene; + completionData->scene = eUIScene_EndPoem; + } + else + { + completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes; + } + loadingParams->completionData = completionData; + + ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); + } + } + else if( g_NetworkManager.IsLeavingGame() ) + { + // If we are leaving the game, then ignore the state change + SetAction(i,eAppAction_Idle); + } +#if 0 + // 4J-HG - Took this out since ChangeSessionType is only set in two places (both in EthernetDisconnected) and this case is handled there, plus this breaks + // this if statements original purpose (to allow us to wait for IsInGameplay before actioning switching to offline + + // QNet must do this kind of thing automatically by itself, but on PS3 at least, we need the disconnection to definitely end up with us out of the game one way or another, + // and the other two cases above don't catch the case where we are just starting the game and get a disconnection during the loading/creation + else + { + if( g_NetworkManager.IsInSession() ) + { + g_NetworkManager._LeaveGame(); + } + } +#endif + } + break; + case eAppAction_SetDefaultOptions: + SetAction(i,eAppAction_Idle); +#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) + SetDefaultOptions((C4JStorage::PROFILESETTINGS *)param,i); +#else + SetDefaultOptions(static_cast(param), i); +#endif + + // if the profile data has been changed, then force a profile write + // It seems we're allowed to break the 5 minute rule if it's the result of a user action + CheckGameSettingsChanged(true,i); + + break; + + case eAppAction_RemoteServerSave: + { + // If the remote server save has already finished, don't complete the action + if (GetGameStarted()) + { + SetAction(ProfileManager.GetPrimaryPad(), eAppAction_Idle); + break; + } + + SetAction(i,eAppAction_WaitRemoteServerSaveComplete); + + for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) + { + ui.CloseUIScenes(i, true); + } + + // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen + ui.HideAllGameUIElements(); + + LoadingInputParams *loadingParams = new LoadingInputParams(); + loadingParams->func = &CMinecraftApp::RemoteSaveThreadProc; + loadingParams->lpParam = nullptr; + + UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); + completionData->bRequiresUserAction=FALSE; + completionData->bShowBackground=TRUE; + completionData->bShowLogo=TRUE; + completionData->iPad=DEFAULT_XUI_MENU_USER; + if( ui.IsSceneInStack( ProfileManager.GetPrimaryPad(), eUIScene_EndPoem ) ) + { + completionData->type = e_ProgressCompletion_NavigateBackToScene; + completionData->scene = eUIScene_EndPoem; + } + else + { + completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes; + } + loadingParams->completionData = completionData; + + loadingParams->cancelFunc = &CMinecraftApp::ExitGameFromRemoteSave; + loadingParams->cancelText = IDS_TOOLTIPS_EXIT; + + ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); + } + break; + case eAppAction_WaitRemoteServerSaveComplete: + // Do nothing + break; + case eAppAction_FailedToJoinNoPrivileges: + { + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + C4JStorage::EMessageResult result = ui.RequestErrorMessage( IDS_NO_MULTIPLAYER_PRIVILEGE_TITLE, IDS_NO_MULTIPLAYER_PRIVILEGE_JOIN_TEXT, uiIDA,1,ProfileManager.GetPrimaryPad()); + if(result != C4JStorage::EMessage_Busy) SetAction(i,eAppAction_Idle); + } + break; + case eAppAction_ProfileReadError: + // Return player to the main menu - code largely copied from that for handling + // eAppAction_PrimaryPlayerSignedOut, although I don't think we should have got as + // far as needing to halt the server, or running the game, before returning to the menu + if(!app.GetGameStarted()) MinecraftServer::HaltServer(true); + + if( g_NetworkManager.IsInSession() ) + { + app.SetAction(i,eAppAction_PrimaryPlayerSignedOutReturned); + } + else + { + app.SetAction(i,eAppAction_PrimaryPlayerSignedOutReturned_Menus); + MinecraftServer::resetFlags(); + } + break; + + case eAppAction_BanLevel: + { + // It's possible that this state can get set after the game has been exited (e.g. by network disconnection) so we can't ban the level at that point + if(g_NetworkManager.IsInGameplay() && !g_NetworkManager.IsLeavingGame()) + { + TelemetryManager->RecordBanLevel(i); + +#if defined _XBOX + INetworkPlayer *pHost=g_NetworkManager.GetHostPlayer(); + // write the level to the banned level list, and exit the world + AddLevelToBannedLevelList(i,((NetworkPlayerXbox *)pHost)->GetUID(),GetUniqueMapName(),true); +#elif defined _XBOX_ONE + INetworkPlayer *pHost=g_NetworkManager.GetHostPlayer(); + AddLevelToBannedLevelList(i,pHost->GetUID(),GetUniqueMapName(),true); +#endif + // primary player would exit the world, secondary would exit the player + if(ProfileManager.GetPrimaryPad()==i) + { + SetAction(i,eAppAction_ExitWorld); + } + else + { + SetAction(i,eAppAction_ExitPlayer); + } + } + } + break; + case eAppAction_LevelInBanLevelList: + { + UINT uiIDA[2]; + uiIDA[0]=IDS_BUTTON_REMOVE_FROM_BAN_LIST; + uiIDA[1]=IDS_EXIT_GAME; + + // pass in the gamertag format string + WCHAR wchFormat[40]; + INetworkPlayer *player = g_NetworkManager.GetLocalPlayerByUserIndex(i); + + // If not the primary player, but the primary player has banned this level and decided not to unban + // then we may have left the game by now + if(player) + { + swprintf(wchFormat, 40, L"%ls\n\n%%ls",player->GetOnlineName()); + + C4JStorage::EMessageResult result = ui.RequestErrorMessage( IDS_BANNED_LEVEL_TITLE, IDS_PLAYER_BANNED_LEVEL, uiIDA,2,i,&CMinecraftApp::BannedLevelDialogReturned,this, wchFormat); + if(result != C4JStorage::EMessage_Busy) SetAction(i,eAppAction_Idle); + } + else + { + SetAction(i,eAppAction_Idle); + } + } + break; + case eAppAction_DebugText: + // launch the xui for text entry + { +#ifdef _XBOX + CScene_TextEntry::XuiTextInputParams *pDebugTextParams= new CScene_TextEntry::XuiTextInputParams; + pDebugTextParams->iPad=i; + pDebugTextParams->wch=(WCHAR)param; + + app.NavigateToScene(i,eUIScene_TextEntry,pDebugTextParams); +#endif + SetAction(i,eAppAction_Idle); + } + break; + + case eAppAction_ReloadTexturePack: + { + SetAction(i,eAppAction_Idle); + Minecraft *pMinecraft = Minecraft::GetInstance(); + pMinecraft->textures->reloadAll(); + pMinecraft->skins->updateUI(); + + if(!pMinecraft->skins->isUsingDefaultSkin()) + { + TexturePack *pTexturePack = pMinecraft->skins->getSelected(); + + DLCPack *pDLCPack=pTexturePack->getDLCPack(); + + bool purchased = false; + // do we have a license? + if(pDLCPack && pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) + { + purchased = true; + } +#ifdef _XBOX + TelemetryManager->RecordTexturePackLoaded(i, pTexturePack->getId(), purchased?1:0); +#endif + } + + // 4J-PB - If the texture pack has audio, we need to switch to this + if(pMinecraft->skins->getSelected()->hasAudio()) + { + Minecraft::GetInstance()->soundEngine->playStreaming(L"", 0, 0, 0, 1, 1); + } + } + break; + + case eAppAction_ReloadFont: + { +#ifndef _XBOX + app.DebugPrintf( + "[Consoles_App] eAppAction_ReloadFont, ingame='%s'.\n", + app.GetGameStarted() ? "Yes" : "No" ); + + SetAction(i,eAppAction_Idle); + + ui.SetTooltips(i, -1); + + ui.ReloadSkin(); + ui.StartReloadSkinThread(); + + ui.setCleanupOnReload(); +#endif + } + break; + + case eAppAction_TexturePackRequired: + { +#if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ + UINT uiIDA[2]; + uiIDA[0]=IDS_TEXTUREPACK_FULLVERSION; + uiIDA[1]=IDS_CONFIRM_CANCEL; // let them continue without the texture pack here (as this is only really for r + // Give the player a warning about the texture pack missing + ui.RequestErrorMessage(IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE, IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::TexturePackDialogReturned,this); + SetAction(i,eAppAction_Idle); +#else +#ifdef _XBOX + ULONGLONG ullOfferID_Full; + app.GetDLCFullOfferIDForPackID(app.GetRequiredTexturePackID(),&ullOfferID_Full); + + TelemetryManager->RecordUpsellPresented(ProfileManager.GetPrimaryPad(), eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF); +#endif + UINT uiIDA[2]; + + uiIDA[0]=IDS_TEXTUREPACK_FULLVERSION; + uiIDA[1]=IDS_TEXTURE_PACK_TRIALVERSION; + + // Give the player a warning about the texture pack missing + ui.RequestErrorMessage(IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE, IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::TexturePackDialogReturned,this); + SetAction(i,eAppAction_Idle); +#endif + } + + break; + } + } + + // Any TMS actions? + + eTMS = app.GetTMSAction(i); + + if(eTMS!=eTMSAction_Idle) + { + switch(eTMS) + { + // TMS++ actions + case eTMSAction_TMSPP_RetrieveFiles_CreateLoad_SignInReturned: + case eTMSAction_TMSPP_RetrieveFiles_RunPlayGame: +#ifdef _XBOX + app.TMSPP_SetTitleGroupID(GROUP_ID); + SetTMSAction(i,eTMSAction_TMSPP_GlobalFileList); +#elif defined _XBOX_ONE + SetTMSAction(i,eTMSAction_TMSPP_GlobalFileList_Waiting); + app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_Title,eTMSAction_TMSPP_UserFileList); +#else + SetTMSAction(i,eTMSAction_TMSPP_UserFileList); +#endif + break; + +#ifdef _XBOX + case eTMSAction_TMSPP_GlobalFileList: + SetTMSAction(i,eTMSAction_TMSPP_GlobalFileList_Waiting); + app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_Title,"\\",eTMSAction_TMSPP_UserFileList); + break; +#endif + case eTMSAction_TMSPP_UserFileList: + // retrieve the file list first +#if defined _XBOX + SetTMSAction(i,eTMSAction_TMSPP_UserFileList_Waiting); + app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_TitleUser,"\\",eTMSAction_TMSPP_XUIDSFile); +#elif defined _XBOX_ONE + SetTMSAction(i,eTMSAction_TMSPP_UserFileList_Waiting); + app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_TitleUser,eTMSAction_TMSPP_DLCFile); +#else + SetTMSAction(i,eTMSAction_TMSPP_XUIDSFile); +#endif + break; + case eTMSAction_TMSPP_XUIDSFile: +#ifdef _XBOX + SetTMSAction(i,eTMSAction_TMSPP_XUIDSFile_Waiting); + // pass in the next app action on the call or callback completing + app.TMSPP_ReadXuidsFile(i,eTMSAction_TMSPP_DLCFile); +#else + SetTMSAction(i,eTMSAction_TMSPP_DLCFile); +#endif + + break; + case eTMSAction_TMSPP_DLCFile: +#if defined _XBOX || defined _XBOX_ONE + SetTMSAction(i,eTMSAction_TMSPP_DLCFile_Waiting); + // pass in the next app action on the call or callback completing + app.TMSPP_ReadDLCFile(i,eTMSAction_TMSPP_BannedListFile); +#else + SetTMSAction(i,eTMSAction_TMSPP_BannedListFile); +#endif + break; + case eTMSAction_TMSPP_BannedListFile: + // If we have one in TMSPP, then we can assume we can ignore TMS +#if defined _XBOX + SetTMSAction(i,eTMSAction_TMSPP_BannedListFile_Waiting); + // pass in the next app action on the call or callback completing + if(app.TMSPP_ReadBannedList(i,eTMSAction_TMS_RetrieveFiles_Complete)==false) + { + // we don't have a banned list in TMSPP, so we should check TMS + app.ReadBannedList(i, eTMSAction_TMS_RetrieveFiles_Complete,true); + } +#elif defined _XBOX_ONE + SetTMSAction(i,eTMSAction_TMSPP_BannedListFile_Waiting); + // pass in the next app action on the call or callback completing + app.TMSPP_ReadBannedList(i,eTMSAction_TMS_RetrieveFiles_Complete); + +#else + SetTMSAction(i,eTMSAction_TMS_RetrieveFiles_Complete); +#endif + break; + + // SPECIAL CASE - where the user goes directly in to Help & Options from the main menu + case eTMSAction_TMSPP_RetrieveFiles_HelpAndOptions: + case eTMSAction_TMSPP_RetrieveFiles_DLCMain: + // retrieve the file list first +#if defined _XBOX + // pass in the next app action on the call or callback completing + SetTMSAction(i,eTMSAction_TMSPP_XUIDSFile_Waiting); + app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_Title,"\\",eTMSAction_TMSPP_DLCFileOnly); +#elif defined _XBOX_ONE + SetTMSAction(i,eTMSAction_TMSPP_GlobalFileList_Waiting); + app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_Title,eTMSAction_TMSPP_RetrieveUserFilelist_DLCFileOnly); +#else + SetTMSAction(i,eTMSAction_TMSPP_DLCFileOnly); +#endif + break; + case eTMSAction_TMSPP_RetrieveUserFilelist_DLCFileOnly: +#if defined _XBOX + SetTMSAction(i,eTMSAction_TMSPP_UserFileList_Waiting); + app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_TitleUser,"\\",eTMSAction_TMSPP_XUIDSFile); +#elif defined _XBOX_ONE + //StorageManager.TMSPP_DeleteFile(i,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,L"TP06.png",nullptr,nullptr, 0); + SetTMSAction(i,eTMSAction_TMSPP_UserFileList_Waiting); + app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_TitleUser,eTMSAction_TMSPP_DLCFileOnly); +#else + SetTMSAction(i,eTMSAction_TMSPP_DLCFileOnly); +#endif + + break; + + case eTMSAction_TMSPP_DLCFileOnly: +#if defined _XBOX || defined _XBOX_ONE + SetTMSAction(i,eTMSAction_TMSPP_DLCFile_Waiting); + // pass in the next app action on the call or callback completing + app.TMSPP_ReadDLCFile(i,eTMSAction_TMSPP_RetrieveFiles_Complete); +#else + SetTMSAction(i,eTMSAction_TMSPP_RetrieveFiles_Complete); +#endif + break; + + + case eTMSAction_TMSPP_RetrieveFiles_Complete: + SetTMSAction(i,eTMSAction_Idle); + break; + + + // TMS files + /* case eTMSAction_TMS_RetrieveFiles_CreateLoad_SignInReturned: + case eTMSAction_TMS_RetrieveFiles_RunPlayGame: + #ifdef _XBOX + SetTMSAction(i,eTMSAction_TMS_XUIDSFile_Waiting); + // pass in the next app action on the call or callback completing + app.ReadXuidsFileFromTMS(i,eTMSAction_TMS_DLCFile,true); + #else + SetTMSAction(i,eTMSAction_TMS_DLCFile); + #endif + break; + + case eTMSAction_TMS_DLCFile: + #ifdef _XBOX + SetTMSAction(i,eTMSAction_TMS_DLCFile_Waiting); + // pass in the next app action on the call or callback completing + app.ReadDLCFileFromTMS(i,eTMSAction_TMS_BannedListFile,true); + #else + SetTMSAction(i,eTMSAction_TMS_BannedListFile); + #endif + + break; + + case eTMSAction_TMS_RetrieveFiles_HelpAndOptions: + case eTMSAction_TMS_RetrieveFiles_DLCMain: + #ifdef _XBOX + SetTMSAction(i,eTMSAction_TMS_DLCFile_Waiting); + // pass in the next app action on the call or callback completing + app.ReadDLCFileFromTMS(i,eTMSAction_Idle,true); + #else + SetTMSAction(i,eTMSAction_Idle); + #endif + + break; + case eTMSAction_TMS_BannedListFile: + #ifdef _XBOX + SetTMSAction(i,eTMSAction_TMS_BannedListFile_Waiting); + // pass in the next app action on the call or callback completing + app.ReadBannedList(i, eTMSAction_TMS_RetrieveFiles_Complete,true); + #else + SetTMSAction(i,eTMSAction_TMS_RetrieveFiles_Complete); + #endif + + break; + + */ + case eTMSAction_TMS_RetrieveFiles_Complete: + SetTMSAction(i,eTMSAction_Idle); + // if(StorageManager.SetSaveDevice(&CScene_Main::DeviceSelectReturned,pClass)) + // { + // // save device already selected + // // ensure we've applied this player's settings + // app.ApplyGameSettingsChanged(ProfileManager.GetPrimaryPad()); + // app.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_MultiGameJoinLoad); + // } + break; + } + } + + } +} + +int CMinecraftApp::BannedLevelDialogReturned(void *pParam,int iPad,const C4JStorage::EMessageResult result) +{ + CMinecraftApp* pApp = static_cast(pParam); + //Minecraft *pMinecraft=Minecraft::GetInstance(); + + if(result==C4JStorage::EMessage_ResultAccept) + { +#if defined _XBOX || defined _XBOX_ONE + INetworkPlayer *pHost = g_NetworkManager.GetHostPlayer(); + // unban the level + if (pHost != nullptr) + { +#if defined _XBOX + pApp->RemoveLevelFromBannedLevelList(iPad,((NetworkPlayerXbox *)pHost)->GetUID(),pApp->GetUniqueMapName()); +#else + pApp->RemoveLevelFromBannedLevelList(iPad,pHost->GetUID(),pApp->GetUniqueMapName()); +#endif + } +#endif + } + else + { + if( iPad == ProfileManager.GetPrimaryPad() ) + { + pApp->SetAction(iPad,eAppAction_ExitWorld); + } + else + { + pApp->SetAction(iPad,eAppAction_ExitPlayer); + } + } + + return 0; +} + +void CMinecraftApp::loadMediaArchive() +{ + wstring mediapath = L""; + +#ifdef __PS3__ + mediapath = L"Common\\Media\\MediaPS3"; +#elif _WINDOWS64 + mediapath = L"Common\\Media\\MediaWindows64"; +#elif __ORBIS__ + mediapath = L"Common\\Media\\MediaOrbis"; +#elif _DURANGO + mediapath = L"Common\\Media\\MediaDurango"; +#elif __PSVITA__ + mediapath = L"Common\\Media\\MediaPSVita"; +#endif + + if (!mediapath.empty()) + { + m_mediaArchive = new FolderFile(mediapath); + } +#if 0 + string path = "Common\\media.arc"; + HANDLE hFile = CreateFile( path.c_str(), + GENERIC_READ, + FILE_SHARE_READ, + nullptr, + OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, + nullptr ); + + if( hFile != INVALID_HANDLE_VALUE ) + { + File fileHelper(convStringToWstring(path)); + DWORD dwFileSize = fileHelper.length(); + + // Initialize memory. + PBYTE m_fBody = new BYTE[ dwFileSize ]; + ZeroMemory(m_fBody, dwFileSize); + + DWORD m_fSize = 0; + BOOL hr = ReadFile( hFile, + m_fBody, + dwFileSize, + &m_fSize, + nullptr ); + + assert( m_fSize == dwFileSize ); + + CloseHandle( hFile ); + + m_mediaArchive = new ArchiveFile(m_fBody, m_fSize); + } + else + { + assert( false ); + // AHHHHHHHHHHHH + m_mediaArchive = nullptr; + } +#endif +} + +void CMinecraftApp::loadStringTable() +{ +#ifndef _XBOX + + if(m_stringTable!=nullptr) + { + // we need to unload the current string table, this is a reload + delete m_stringTable; + } +#ifdef _WINDOWS64 + m_stringTable = nullptr; + const wstring localisationCandidates[] = + { + L"Common\\Localization", // Fireblade - check multiple directories before resulting to .loc usage + L"Windows64Media\\loc", + L"..\\Minecraft.Client\\Windows64Media\\loc" + }; + + for (const auto &localisationFolder : localisationCandidates) + { + File localisationDirectory(localisationFolder); + if (localisationDirectory.exists() && localisationDirectory.isDirectory()) + { + StringTable *candidateTable = new StringTable(localisationFolder); // Fireblade - xml before loc + + const bool hasKeyString = candidateTable->hasStringKey(L"IDS_OK"); + bool hasIndexString = false; + #ifdef IDS_OK + LPCWSTR indexedString = candidateTable->getString(IDS_OK); + hasIndexString = (indexedString != nullptr && indexedString[0] != L'\0'); + #endif + + if (hasKeyString || hasIndexString) + { + m_stringTable = candidateTable; + app.DebugPrintf("Loaded language data from '%ls'\n", localisationFolder.c_str()); + break; + } + + app.DebugPrintf("Ignoring localisation path '%ls' (missing expected IDs)\n", localisationFolder.c_str()); + delete candidateTable; + } + } + + if (m_stringTable == nullptr && m_mediaArchive != nullptr) // Fireblade - fallback to previous behavior + { + const wstring localisationFile = L"languages.loc"; + if (m_mediaArchive->hasFile(localisationFile)) + { + byteArray locFile = m_mediaArchive->getFile(localisationFile); + m_stringTable = new StringTable(locFile.data, locFile.length); + delete locFile.data; + } + } + + if (m_stringTable == nullptr) + { + app.DebugPrintf("Failed to initialize language data\n"); + assert(false); + } +#else // Fireblade - other platforms keep same logic + wstring localisationFile = L"languages.loc"; + if (m_mediaArchive->hasFile(localisationFile)) + { + byteArray locFile = m_mediaArchive->getFile(localisationFile); + m_stringTable = new StringTable(locFile.data, locFile.length); + delete locFile.data; + } + else + { + m_stringTable = nullptr; + assert(false); + // AHHHHHHHHH. + } +#endif +#endif +} + +int CMinecraftApp::PrimaryPlayerSignedOutReturned(void *pParam,int iPad,const C4JStorage::EMessageResult) +{ + //CMinecraftApp* pApp = (CMinecraftApp*)pParam; + //Minecraft *pMinecraft=Minecraft::GetInstance(); + + // if the player is null, we're in the menus + //if(Minecraft::GetInstance()->player!=nullptr) + + // We always create a session before kicking of any of the game code, so even though we may still be joining/creating a game + // at this point we want to handle it differently from just being in a menu + if( g_NetworkManager.IsInSession() ) + { + app.SetAction(iPad,eAppAction_PrimaryPlayerSignedOutReturned); + } + else + { + app.SetAction(iPad,eAppAction_PrimaryPlayerSignedOutReturned_Menus); + } + return 0; +} + +int CMinecraftApp::EthernetDisconnectReturned(void *pParam,int iPad,const C4JStorage::EMessageResult) +{ + //CMinecraftApp* pApp = (CMinecraftApp*)pParam; + Minecraft *pMinecraft=Minecraft::GetInstance(); + + // if the player is null, we're in the menus + if (Minecraft::GetInstance()->player != nullptr) + { + app.SetAction(pMinecraft->player->GetXboxPad(), eAppAction_EthernetDisconnectedReturned); + } + else + { + // 4J-PB - turn off the PSN store icon just in case this happened when we were in one of the DLC menus +#if defined __ORBIS__ || defined __PSVITA__ + app.GetCommerce()->HidePsStoreIcon(); +#endif + app.SetAction(iPad,eAppAction_EthernetDisconnectedReturned_Menus); + } + return 0; +} + +int CMinecraftApp::SignoutExitWorldThreadProc( void* lpParameter ) +{ + + // Share AABB & Vec3 pools with default (main thread) - should be ok as long as we don't tick the main thread whilst this thread is running + AABB::UseDefaultThreadStorage(); + Vec3::UseDefaultThreadStorage(); + Compression::UseDefaultThreadStorage(); + + //app.SetGameStarted(false); + + Minecraft *pMinecraft=Minecraft::GetInstance(); + + int exitReasonStringId = -1; + + bool saveStats = false; + if (pMinecraft->isClientSide() || g_NetworkManager.IsInSession() ) + { + if(lpParameter != nullptr ) + { + switch( app.GetDisconnectReason() ) + { + case DisconnectPacket::eDisconnect_Kicked: + exitReasonStringId = IDS_DISCONNECTED_KICKED; + break; + case DisconnectPacket::eDisconnect_NoUGC_AllLocal: + exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_ALL_LOCAL; + break; + case DisconnectPacket::eDisconnect_NoUGC_Single_Local: + exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL; + break; +#ifdef _XBOX + case DisconnectPacket::eDisconnect_NoUGC_Remote: + exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_REMOTE; + break; +#endif + case DisconnectPacket::eDisconnect_NoFlying: + exitReasonStringId = IDS_DISCONNECTED_FLYING; + break; + case DisconnectPacket::eDisconnect_OutdatedServer: + exitReasonStringId = IDS_DISCONNECTED_SERVER_OLD; + break; + case DisconnectPacket::eDisconnect_OutdatedClient: + exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD; + break; + default: + exitReasonStringId = IDS_DISCONNECTED; + } + pMinecraft->progressRenderer->progressStartNoAbort( exitReasonStringId ); + // 4J - Force a disconnection, this handles the situation that the server has already disconnected + if( pMinecraft->levels[0] != nullptr ) pMinecraft->levels[0]->disconnect(false); + if( pMinecraft->levels[1] != nullptr ) pMinecraft->levels[1]->disconnect(false); + } + else + { + exitReasonStringId = IDS_EXITING_GAME; + pMinecraft->progressRenderer->progressStartNoAbort( IDS_EXITING_GAME ); + + if( pMinecraft->levels[0] != nullptr ) pMinecraft->levels[0]->disconnect(); + if( pMinecraft->levels[1] != nullptr ) pMinecraft->levels[1]->disconnect(); + } + + // 4J Stu - This only does something if we actually have a server, so don't need to do any other checks + MinecraftServer::HaltServer(true); + + // We need to call the stats & leaderboards save before we exit the session + //pMinecraft->forceStatsSave(); + saveStats = false; + + // 4J Stu - Leave the session once the disconnect packet has been sent + g_NetworkManager.LeaveGame(FALSE); + } + else + { + if(lpParameter != nullptr ) + { + switch( app.GetDisconnectReason() ) + { + case DisconnectPacket::eDisconnect_Kicked: + exitReasonStringId = IDS_DISCONNECTED_KICKED; + break; + case DisconnectPacket::eDisconnect_NoUGC_AllLocal: + exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_ALL_LOCAL; + break; + case DisconnectPacket::eDisconnect_NoUGC_Single_Local: + exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL; + break; +#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) + case DisconnectPacket::eDisconnect_ContentRestricted_AllLocal: + exitReasonStringId = IDS_CONTENT_RESTRICTION_MULTIPLAYER; + break; + case DisconnectPacket::eDisconnect_ContentRestricted_Single_Local: + exitReasonStringId = IDS_CONTENT_RESTRICTION; + break; +#endif +#ifdef _XBOX + case DisconnectPacket::eDisconnect_NoUGC_Remote: + exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_REMOTE; + break; +#endif + case DisconnectPacket::eDisconnect_OutdatedServer: + exitReasonStringId = IDS_DISCONNECTED_SERVER_OLD; + break; + case DisconnectPacket::eDisconnect_OutdatedClient: + exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD; + default: + exitReasonStringId = IDS_DISCONNECTED; + } + pMinecraft->progressRenderer->progressStartNoAbort( exitReasonStringId ); + } + } + pMinecraft->setLevel(nullptr,exitReasonStringId,nullptr,saveStats,true); + + // 4J-JEV: Fix for #106402 - TCR #014 BAS Debug Output: + // TU12: Mass Effect Mash-UP: Save file "Default_DisplayName" is created on all storage devices after signing out from a re-launched pre-generated world + app.m_gameRules.unloadCurrentGameRules(); // + + MinecraftServer::resetFlags(); + + // We can't start/join a new game until the session is destroyed, so wait for it to be idle again + while( g_NetworkManager.IsInSession() ) + { + Sleep(1); + } + + return S_OK; +} + +int CMinecraftApp::UnlockFullInviteReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + //CMinecraftApp* pApp = (CMinecraftApp*)pParam; + Minecraft *pMinecraft=Minecraft::GetInstance(); + bool bNoPlayer; + + // bug 11285 - TCR 001: BAS Game Stability: CRASH - When trying to join a full version game with a trial version, the trial crashes + // 4J-PB - we may be in the main menus here, and we don't have a pMinecraft->player + + if(pMinecraft->player==nullptr) + { + bNoPlayer=true; + } + + if(result==C4JStorage::EMessage_ResultAccept) + { + if(ProfileManager.IsSignedInLive(iPad)) + { + // 4J-PB - need to check this user can access the store +#if defined(__PS3__) || defined(__PSVITA__) + bool bContentRestricted; + ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,nullptr,&bContentRestricted,nullptr); + if(bContentRestricted) + { + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); + } + else +#endif + { + ProfileManager.DisplayFullVersionPurchase(false,iPad,eSen_UpsellID_Full_Version_Of_Game); + } + } +#if defined(__PS3__) + else + { + // you're not signed in to PSN! + UINT uiIDA[2]; + uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; + uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; + ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); + + } +#endif + } + else + { + TelemetryManager->RecordUpsellResponded(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, eSen_UpsellOutcome_Declined); + } + + return 0; +} + +int CMinecraftApp::UnlockFullSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + //CMinecraftApp* pApp = (CMinecraftApp*)pParam; + Minecraft *pMinecraft=Minecraft::GetInstance(); + + if(result==C4JStorage::EMessage_ResultAccept) + { + if(ProfileManager.IsSignedInLive(pMinecraft->player->GetXboxPad())) + { + // 4J-PB - need to check this user can access the store +#if defined(__PS3__) || defined(__PSVITA__) + bool bContentRestricted; + ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,nullptr,&bContentRestricted,nullptr); + if(bContentRestricted) + { + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); + } + else +#endif + { + ProfileManager.DisplayFullVersionPurchase(false,pMinecraft->player->GetXboxPad(),eSen_UpsellID_Full_Version_Of_Game); + } + } +#if defined(__PS3__) + else + { + // you're not signed in to PSN! + UINT uiIDA[2]; + uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; + uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; + ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); + } +#elif defined(__ORBIS__) + else + { + // Determine why they're not "signed in live" + if (ProfileManager.isSignedInPSN(iPad)) + { + // Signed in to PSN but not connected (no internet access) + assert(!ProfileManager.isConnectedToPSN(iPad)); + + UINT uiIDA[1]; + uiIDA[0] = IDS_OK; + ui.RequestErrorMessage( IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, iPad); + } + else + { + // Not signed in to PSN + UINT uiIDA[1]; + uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; + ui.RequestAlertMessage( IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, iPad, &CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); + } + } +#endif + } + else + { + TelemetryManager->RecordUpsellResponded(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, eSen_UpsellOutcome_Declined); + } + + return 0; +} + +int CMinecraftApp::UnlockFullExitReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + CMinecraftApp* pApp = static_cast(pParam); + Minecraft *pMinecraft=Minecraft::GetInstance(); + + if(result==C4JStorage::EMessage_ResultAccept) + { + if(ProfileManager.IsSignedInLive(pMinecraft->player->GetXboxPad())) + { + // 4J-PB - need to check this user can access the store +#if defined(__PS3__) || defined(__PSVITA__) + bool bContentRestricted; + ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,nullptr,&bContentRestricted,nullptr); + if(bContentRestricted) + { + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); + } + else +#endif + { + ProfileManager.DisplayFullVersionPurchase(false,pMinecraft->player->GetXboxPad(),eSen_UpsellID_Full_Version_Of_Game); +#if defined __ORBIS__ || defined __PS3__ || defined __PSVITA__ + // still need to exit the trial or we'll be in the Pause menu with input ignored + pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); +#endif + } + } +#if defined(__PS3__) || defined __PSVITA__ + else + { + // you're not signed in to PSN! + UINT uiIDA[2]; + uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; + uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; + ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturnedExitTrial,&app); + } +#elif defined(__ORBIS__) + else + { + // Determine why they're not "signed in live" + if (ProfileManager.isSignedInPSN(iPad)) + { + // Signed in to PSN but not connected (no internet access) + assert(!ProfileManager.isConnectedToPSN(iPad)); + + UINT uiIDA[1]; + uiIDA[0] = IDS_OK; + ui.RequestErrorMessage( IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, iPad); + // still need to exit the trial or we'll be in the Pause menu with input ignored + pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); + } + else + { + // Not signed in to PSN + UINT uiIDA[1]; + uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; + ui.RequestAlertMessage( IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, iPad, &CMinecraftApp::MustSignInFullVersionPurchaseReturnedExitTrial,&app); + } + } +#endif + } + else + { + TelemetryManager->RecordUpsellResponded(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, eSen_UpsellOutcome_Declined); + pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); + } + + return 0; +} + +int CMinecraftApp::TrialOverReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + CMinecraftApp* pApp = static_cast(pParam); + Minecraft *pMinecraft=Minecraft::GetInstance(); + + if(result==C4JStorage::EMessage_ResultAccept) + { + // we need a signed in user for the unlock + if(ProfileManager.IsSignedInLive(pMinecraft->player->GetXboxPad())) + { + // 4J-PB - need to check this user can access the store +#if defined(__PS3__) || defined(__PSVITA__) + bool bContentRestricted; + ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,nullptr,&bContentRestricted,nullptr); + if(bContentRestricted) + { + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); + } + else +#endif + { + ProfileManager.DisplayFullVersionPurchase(false,pMinecraft->player->GetXboxPad(),eSen_UpsellID_Full_Version_Of_Game); + } + } + else + { +#if defined(__PS3__) + + // you're not signed in to PSN! + UINT uiIDA[2]; + uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; + uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; + ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); + + // 4J Stu - We can't actually exit the game, so just exit back to the main menu + //pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); +#else + pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitTrial); +#endif + } + } + else + { + TelemetryManager->RecordUpsellResponded(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, eSen_UpsellOutcome_Declined); + +#if defined(__PS3__) || defined(__ORBIS__) + // 4J Stu - We can't actually exit the game, so just exit back to the main menu + pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); +#else + pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitTrial); +#endif + } + + return 0; +} + +void CMinecraftApp::ProfileReadErrorCallback(void *pParam) +{ + CMinecraftApp *pApp=static_cast(pParam); + int iPrimaryPlayer=ProfileManager.GetPrimaryPad(); + pApp->SetAction(iPrimaryPlayer, eAppAction_ProfileReadError); +} + +void CMinecraftApp::ClearSignInChangeUsersMask() +{ + // 4J-PB - When in the main menu, the user is on pad 0, and any change they make to their profile will be to pad 0 data + // If they then go in as a secondary player to a splitscreen game, their profile will not be read again on pad 1 if they were previously in a splitscreen game + // This is because m_uiLastSignInData remembers they were in previously, and doesn't read the profile data for them again + // Fix this by resetting the m_uiLastSignInData on pressing play game for secondary users. The Primary user does a read profile on play game anyway + int iPrimaryPlayer=ProfileManager.GetPrimaryPad(); + + if(m_uiLastSignInData!=0) + { + if(iPrimaryPlayer>=0) + { + m_uiLastSignInData=1<user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); +#endif + + CMinecraftApp *pApp=static_cast(pParam); + // check if the primary player signed out + int iPrimaryPlayer=ProfileManager.GetPrimaryPad(); + + if((ProfileManager.GetLockedProfile()!=-1) && iPrimaryPlayer!=-1) + { + if ( ((uiSignInData & (1<SetAction(iPrimaryPlayer,eAppAction_PrimaryPlayerSignedOut); + + // 4J-PB - invalidate their banned level list + pApp->InvalidateBannedList(iPrimaryPlayer); + + // need to ditch any DLCOffers info + StorageManager.ClearDLCOffers(); + pApp->ClearAndResetDLCDownloadQueue(); + pApp->ClearDLCInstalled(); + } + else + { + unsigned int uiChangedPlayers = uiSignInData ^ m_uiLastSignInData; + + if( g_NetworkManager.IsInSession() ) + { + bool hasGuestIdChanged = false; + for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) + { + DWORD guestNumber = 0; + if(ProfileManager.IsSignedIn(i)) + { + XUSER_SIGNIN_INFO info; + XUserGetSigninInfo(i,XUSER_GET_SIGNIN_INFO_OFFLINE_XUID_ONLY ,&info); + pApp->DebugPrintf("Player at index %d has guest number %d\n", i,info.dwGuestNumber ); + guestNumber = info.dwGuestNumber; + } + if( pApp->m_currentSigninInfo[i].dwGuestNumber != 0 && guestNumber != 0 && pApp->m_currentSigninInfo[i].dwGuestNumber != guestNumber ) + { + hasGuestIdChanged = true; + } + } + + if( hasGuestIdChanged ) + { + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + ui.RequestErrorMessage(IDS_GUEST_ORDER_CHANGED_TITLE, IDS_GUEST_ORDER_CHANGED_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad()); + } + + // 4J Stu - On PS4 we can also cause to exit players if they are signed out here, but we shouldn't do that if + // we are going to switch to an offline game as it will likely crash due to incompatible parallel processes + bool switchToOffline = false; + // If it's an online game, and the primary profile is no longer signed into LIVE then we act as if disconnected + if( !ProfileManager.IsSignedInLive( ProfileManager.GetLockedProfile() ) && !g_NetworkManager.IsLocalGame() ) + { + switchToOffline = true; + } + + //printf("Old: %x, New: %x, Changed: %x\n", m_ulLastSignInData, ulSignInData, changedPlayers); + for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) + { + // Primary player shouldn't be subjected to these checks, and shouldn't call ExitPlayer + if(i == iPrimaryPlayer) continue; + + // A guest a signed in or out, out of order which invalidates all the guest players we have in the game + if(hasGuestIdChanged && pApp->m_currentSigninInfo[i].dwGuestNumber != 0 && g_NetworkManager.GetLocalPlayerByUserIndex(i)!=nullptr) + { + pApp->DebugPrintf("Recommending removal of player at index %d because their guest id changed\n",i); + pApp->SetAction(i, eAppAction_ExitPlayer); + } + else + { + XUSER_SIGNIN_INFO info; + XUserGetSigninInfo(i,XUSER_GET_SIGNIN_INFO_OFFLINE_XUID_ONLY ,&info); + // 4J Stu - Also need to detect the case where the sign in mask is the same, but the player has swapped users (eg still signed in but xuid different) + // Fix for #48451 - TU5: Code: UI: Splitscreen: Title crashes when switching to a profile previously signed out via splitscreen profile selection + + // 4J-PB - compiler complained about if below ('&&' within '||') - making it easier to read + bool bPlayerChanged=(uiChangedPlayers&(1<m_currentSigninInfo[i].xuid, info.xuid) ) )) + { + // 4J-PB - invalidate their banned level list + pApp->DebugPrintf("Player at index %d Left - invalidating their banned list\n",i); + pApp->InvalidateBannedList(i); + + // 4J-HG: If either the player is in the network manager or in the game, need to exit player + // TODO: Do we need to check the network manager? + if (g_NetworkManager.GetLocalPlayerByUserIndex(i) != nullptr || Minecraft::GetInstance()->localplayers[i] != nullptr) + { + pApp->DebugPrintf("Player %d signed out\n", i); + pApp->SetAction(i, eAppAction_ExitPlayer); + } + } + } +#ifdef __ORBIS__ + // check if any of the addition players have signed out of PSN (primary player is handled below) + if(!switchToOffline && i != ProfileManager.GetLockedProfile() && !g_NetworkManager.IsLocalGame()) + { + if(g_NetworkManager.GetLocalPlayerByUserIndex(i)!=nullptr) + { + if(ProfileManager.IsSignedInLive(i) == false) + { + pApp->DebugPrintf("Recommending removal of player at index %d because they're no longer signed into PSNd\n",i); + pApp->SetAction(i,eAppAction_ExitPlayer); + } + } + } +#endif + } + + // If it's an online game, and the primary profile is no longer signed into LIVE then we act as if disconnected + if( switchToOffline ) + { + pApp->SetAction(iPrimaryPlayer,eAppAction_EthernetDisconnected); + } + + + g_NetworkManager.HandleSignInChange(); + } + // Some menus require the player to be signed in to live, so if this callback happens and the primary player is + // no longer signed in then nav back + else if ( pApp->GetLiveLinkRequired() && !ProfileManager.IsSignedInLive( ProfileManager.GetLockedProfile() ) ) + { +#ifdef __PSVITA__ + if(!CGameNetworkManager::usingAdhocMode()) // if we're in adhoc mode, we can ignore this +#endif + { + pApp->SetAction(iPrimaryPlayer,eAppAction_EthernetDisconnected); + } + } + +#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__ ) + // 4J-JEV: Need to kick of loading of profile data for sub-sign in players. + for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) + { + if( i != iPrimaryPlayer + && ( uiChangedPlayers & (1<InvalidateBannedList(iPrimaryPlayer); + + // need to ditch any DLCOffers info + StorageManager.ClearDLCOffers(); + pApp->ClearAndResetDLCDownloadQueue(); + pApp->ClearDLCInstalled(); + + } + + // Update the guest numbers to the current state + for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) + { + if(FAILED(XUserGetSigninInfo(i,XUSER_GET_SIGNIN_INFO_OFFLINE_XUID_ONLY,&pApp->m_currentSigninInfo[i]))) + { + pApp->m_currentSigninInfo[i].xuid = INVALID_XUID; + pApp->m_currentSigninInfo[i].dwGuestNumber = 0; + } + app.DebugPrintf("Player at index %d has guest number %d\n", i,pApp->m_currentSigninInfo[i].dwGuestNumber ); + } +} + +void CMinecraftApp::NotificationsCallback(LPVOID pParam,DWORD dwNotification, unsigned int uiParam) +{ + CMinecraftApp* pClass = static_cast(pParam); + + // push these on to the notifications to be handled in qnet's dowork + + PNOTIFICATION pNotification = new NOTIFICATION; + + pNotification->dwNotification=dwNotification; + pNotification->uiParam=uiParam; + + switch( dwNotification ) + { + case XN_SYS_SIGNINCHANGED: + { + pClass->DebugPrintf("Signing changed - %d\n", uiParam ); + } + break; + case XN_SYS_INPUTDEVICESCHANGED: + if(app.GetGameStarted() && g_NetworkManager.IsInSession()) + { + for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) + { + if(!InputManager.IsPadConnected(i) && + Minecraft::GetInstance()->localplayers[i] != nullptr && + !ui.IsPauseMenuDisplayed(i) && !ui.IsSceneInStack(i, eUIScene_EndPoem) ) + { + ui.CloseUIScenes(i); + ui.NavigateToScene(i,eUIScene_PauseMenu); + } + } + } + break; + case XN_LIVE_CONTENT_INSTALLED: + // Need to inform xuis that we've possibly had DLC installed + { + //app.m_dlcManager.SetNeedsUpdated(true); + // Clear the DLC installed flag to cause a GetDLC to run if it's called + app.ClearDLCInstalled(); + + ui.HandleDLCInstalled(ProfileManager.GetPrimaryPad()); + } + break; + case XN_SYS_STORAGEDEVICESCHANGED: + { +#ifdef _XBOX + // If the devices have changed, and we've got a dlc pack with audio selected, and that pack's content device is no longer valid... then pull the plug on + // audio streaming, as if we leave this until later xact gets locked up attempting to destroy the streamed wave bank. + TexturePack *pTexPack=Minecraft::GetInstance()->skins->getSelected(); + if(pTexPack->hasAudio()) + { + DLCTexturePack *pDLCTexPack=(DLCTexturePack *)pTexPack; + XCONTENTDEVICEID deviceID = pDLCTexPack->GetDLCDeviceID(); + if( XContentGetDeviceState( deviceID, nullptr ) != ERROR_SUCCESS ) + { + // Set texture pack flag so that it is now considered as not having audio - this is critical so that the next playStreaming does what it is meant to do, + // and also so that we don't try and unmount this again, or play any sounds from it in the future + pTexPack->setHasAudio(false); + // need to stop the streaming audio - by playing streaming audio from the default texture pack now + Minecraft::GetInstance()->soundEngine->playStreaming(L"", 0, 0, 0, 0, 0); + + if(pDLCTexPack->m_pStreamedWaveBank!=nullptr) + { + pDLCTexPack->m_pStreamedWaveBank->Destroy(); + } + if(pDLCTexPack->m_pSoundBank!=nullptr) + { + pDLCTexPack->m_pSoundBank->Destroy(); + } + DWORD result = StorageManager.UnmountInstalledDLC("TPACK"); + app.DebugPrintf("Unmount result is %d\n",result); + } + } +#endif + } + break; + } + + pClass->m_vNotifications.push_back(pNotification); +} + +#if defined __PS3__ || defined __PSVITA__ || defined __ORBIS__ +int CMinecraftApp::MustSignInFullVersionPurchaseReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + if(result==C4JStorage::EMessage_ResultAccept) + { +#ifdef __PS3__ + SQRNetworkManager_PS3::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); +#elif defined __PSVITA__ + SQRNetworkManager_Vita::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); +#else // __PS4__ + SQRNetworkManager_Orbis::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); +#endif + } + + return 0; +} + +#if defined __PS3__ || defined __PSVITA__ || defined __ORBIS__ +int CMinecraftApp::MustSignInFullVersionPurchaseReturnedExitTrial(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + if(result==C4JStorage::EMessage_ResultAccept) + { +#ifdef __PS3__ + SQRNetworkManager_PS3::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); +#elif defined __PSVITA__ + SQRNetworkManager_Vita::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); +#else // __PS4__ + SQRNetworkManager_Orbis::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); +#endif + } + + //4J-PB - we need to exit the trial, or we'll be in the pause menu with ignore input true + app.SetAction(iPad,eAppAction_ExitWorldTrial); + + return 0; +} +#endif + +int CMinecraftApp::NowDisplayFullVersionPurchase(void *pParam, bool bContinue, int iPad) +{ + app.m_bDisplayFullVersionPurchase=true; + return 0; +} +#endif +void CMinecraftApp::UpsellReturnedCallback(LPVOID pParam, eUpsellType type, eUpsellResponse result, int iUserData) +{ + ESen_UpsellID senType; + ESen_UpsellOutcome senResponse; +#ifdef __PS3__ + UINT uiIDA[2]; +#endif + + // Map the eUpsellResponse to the enum we use for sentient + switch(result) + { + case eUpsellResponse_Accepted_NoPurchase: + senResponse = eSen_UpsellOutcome_Went_To_Guide; + break; + case eUpsellResponse_Accepted_Purchase: + senResponse = eSen_UpsellOutcome_Accepted; + break; +#ifdef __PS3__ + // special case for people who are not signed in to the PSN while playing the trial game + case eUpsellResponse_UserNotSignedInPSN: + + uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; + uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; + ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); + + return; + + case eUpsellResponse_NotAllowedOnline: // On earning a trophy in the trial version, where the user is underage and can't go online to buy the game, but they selected to buy the game on the trophy upsell + uiIDA[0]=IDS_CONFIRM_OK; + ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); + break; +#endif + case eUpsellResponse_Declined: + default: + senResponse = eSen_UpsellOutcome_Declined; + break; + }; + + // Map the eUpsellType to the enum we use for sentient + switch(type) + { + case eUpsellType_Custom: + senType = eSen_UpsellID_Full_Version_Of_Game; + break; + default: + senType = eSen_UpsellID_Undefined; + break; + }; + + // Always the primary pad that gets an upsell + TelemetryManager->RecordUpsellResponded(ProfileManager.GetPrimaryPad(), eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, senResponse); +} + +#ifdef _DEBUG_MENUS_ENABLED +bool CMinecraftApp::DebugArtToolsOn() +{ + return DebugSettingsOn() && (GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<(pParam); + //printf("sequence matched\n"); + pClass->m_bDebugOptions=!pClass->m_bDebugOptions; + + for(int i=0;ilocalplayers[i] != nullptr) + { + iPlayerC++; + } + } + + return iPlayerC; +} + +int CMinecraftApp::MarketplaceCountsCallback(LPVOID pParam,C4JStorage::DLC_TMS_DETAILS *pTMSDetails, int iPad) +{ + app.DebugPrintf("Marketplace Counts= New - %d Total - %d\n",pTMSDetails->dwNewOffers,pTMSDetails->dwTotalOffers); + + if(pTMSDetails->dwNewOffers>0) + { + app.m_bNewDLCAvailable=true; + app.m_bSeenNewDLCTip=false; + } + else + { + app.m_bNewDLCAvailable=false; + app.m_bSeenNewDLCTip=true; + } + + return 0; +} + +bool CMinecraftApp::StartInstallDLCProcess(int iPad) +{ + app.DebugPrintf("--- CMinecraftApp::StartInstallDLCProcess: pad=%i.\n", iPad); + + // If there is already a call to this in progress, then do nothing + // If the app says dlc is installed, then there has been no new system message to tell us there's new DLC since the last call to StartInstallDLCProcess + if((app.DLCInstallProcessCompleted()==false) && (m_bDLCInstallPending==false)) + { + app.m_dlcManager.resetUnnamedCorruptCount(); + m_bDLCInstallPending = true; + m_iTotalDLC = 0; + m_iTotalDLCInstalled = 0; + app.DebugPrintf("--- CMinecraftApp::StartInstallDLCProcess - StorageManager.GetInstalledDLC\n"); + + StorageManager.GetInstalledDLC(iPad,&CMinecraftApp::DLCInstalledCallback,this); + return true; + } + else + { + app.DebugPrintf("--- CMinecraftApp::StartInstallDLCProcess - nothing to do\n"); + + return false; + } + +} + +// Installed DLC callback +int CMinecraftApp::DLCInstalledCallback(LPVOID pParam,int iInstalledC,int iPad) +{ + app.DebugPrintf("--- CMinecraftApp::DLCInstalledCallback: totalDLC=%i, pad=%i.\n", iInstalledC, iPad); + app.m_iTotalDLC = iInstalledC; + app.MountNextDLC(iPad); + return 0; +} + +void CMinecraftApp::MountNextDLC(int iPad) +{ + app.DebugPrintf("--- CMinecraftApp::MountNextDLC: pad=%i.\n", iPad); + if(m_iTotalDLCInstalled < m_iTotalDLC) + { + // Mount it + // We also need to match the ones the user wants to mount with the installed DLC + // We're supposed to use a generic save game as a cache of these to do this, with XUSER_ANY + + if(StorageManager.MountInstalledDLC(iPad,m_iTotalDLCInstalled,&CMinecraftApp::DLCMountedCallback,this)!=ERROR_IO_PENDING ) + { + // corrupt DLC + app.DebugPrintf("Failed to mount DLC %d for pad %d\n",m_iTotalDLCInstalled,iPad); + ++m_iTotalDLCInstalled; + app.MountNextDLC(iPad); + } + else + { + app.DebugPrintf("StorageManager.MountInstalledDLC ok\n"); + } + } + else + { + /* Removed - now loading these on demand instead of as each pack is mounted + if(m_iTotalDLCInstalled > 0) + { + Minecraft *pMinecraft=Minecraft::GetInstance(); + pMinecraft->levelRenderer->AddDLCSkinsToMemTextures(); + } + */ + + m_bDLCInstallPending = false; + m_bDLCInstallProcessCompleted=true; + + ui.HandleDLCMountingComplete(); + +#if defined(_XBOX_ONE) || defined(__ORBIS__) + // Check if the current texture pack is now installed + if(!Minecraft::GetInstance()->skins->isUsingDefaultSkin()) + { + TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); + DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; + + DLCPack *pParentPack=pDLCTexPack->getDLCInfoParentPack();//tPack->getDLCPack(); + + if(pParentPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) + { + StorageManager.SetSaveDisabled(false); + } + } +#endif +#if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ + { + TexturePack* currentTPack = Minecraft::GetInstance()->skins->getSelected(); + TexturePack* requiredTPack = Minecraft::GetInstance()->skins->getTexturePackById(app.GetRequiredTexturePackID()); + if(currentTPack != requiredTPack) + { + Minecraft::GetInstance()->skins->selectTexturePackById(app.GetRequiredTexturePackID()); + } + } +#endif + } +} + +// 4J-JEV: For the sake of clarity in DLCMountedCallback. +#if defined(_XBOX) || defined(__PS3__) || defined(_WINDOWS64) +#define CONTENT_DATA_DISPLAY_NAME(a) (a.szDisplayName) +#else +#define CONTENT_DATA_DISPLAY_NAME(a) (a.wszDisplayName) +#endif + +int CMinecraftApp::DLCMountedCallback(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicenceMask) +{ +#if defined(_XBOX) || defined(_DURANGO) || defined(__PS3__) || defined(__ORBIS__) || defined(_WINDOWS64) || defined (__PSVITA__) //Chris TODO + app.DebugPrintf("--- CMinecraftApp::DLCMountedCallback\n"); + + if(dwErr!=ERROR_SUCCESS) + { + // corrupt DLC + app.DebugPrintf("Failed to mount DLC for pad %d: %d\n",iPad,dwErr); + app.m_dlcManager.incrementUnnamedCorruptCount(); + } + else + { + XCONTENT_DATA ContentData = StorageManager.GetDLC(app.m_iTotalDLCInstalled); + + DLCPack *pack = app.m_dlcManager.getPack( CONTENT_DATA_DISPLAY_NAME(ContentData) ); + + if( pack != nullptr && pack->IsCorrupt() ) + { + app.DebugPrintf("Pack '%ls' is corrupt, removing it from the DLC Manager.\n", CONTENT_DATA_DISPLAY_NAME(ContentData)); + + app.m_dlcManager.removePack(pack); + pack = nullptr; + } + + if(pack == nullptr) + { + app.DebugPrintf("Pack \"%ls\" is not installed, so adding it\n", CONTENT_DATA_DISPLAY_NAME(ContentData)); + +#if defined(_XBOX) || defined(__PS3__) || defined(_WINDOWS64) + pack = new DLCPack(ContentData.szDisplayName,dwLicenceMask); +#elif defined _XBOX_ONE + pack = new DLCPack(ContentData.wszDisplayName,ContentData.wszProductID,dwLicenceMask); +#else + pack = new DLCPack(ContentData.wszDisplayName,dwLicenceMask); +#endif + pack->SetDLCMountIndex(app.m_iTotalDLCInstalled); + pack->SetDLCDeviceID(ContentData.DeviceID); + app.m_dlcManager.addPack(pack); + + app.HandleDLC(pack); + + if(pack->getDLCItemsCount(DLCManager::e_DLCType_Texture) > 0) + { + Minecraft::GetInstance()->skins->addTexturePackFromDLC(pack, pack->GetPackId() ); + } + } + else + { + app.DebugPrintf("Pack \"%ls\" is already installed. Updating license to %d\n", CONTENT_DATA_DISPLAY_NAME(ContentData), dwLicenceMask); + + pack->SetDLCMountIndex(app.m_iTotalDLCInstalled); + pack->SetDLCDeviceID(ContentData.DeviceID); + pack->updateLicenseMask(dwLicenceMask); + } + + StorageManager.UnmountInstalledDLC(); + } + ++app.m_iTotalDLCInstalled; + app.MountNextDLC(iPad); + +#endif // __PSVITA__ + return 0; +} +#undef CONTENT_DATA_DISPLAY_NAME + +// void CMinecraftApp::InstallDefaultCape() +// { +// if(!m_bDefaultCapeInstallAttempted) +// { +// // we only attempt to install the cape once per launch of the game +// m_bDefaultCapeInstallAttempted=true; +// +// wstring wTemp=L"Default_Cape.png"; +// bool bRes=app.IsFileInMemoryTextures(wTemp); +// // if the file is not already in the memory textures, then read it from TMS +// if(!bRes) +// { +// BYTE* pBuffer = nullptr; +// DWORD dwSize=0; +// // 4J-PB - out for now for DaveK so he doesn't get the birthday cape +// #ifdef _CONTENT_PACKAGE +// C4JStorage::ETMSStatus eTMSStatus; +// eTMSStatus=StorageManager.ReadTMSFile(ProfileManager.GetPrimaryPad(),C4JStorage::eGlobalStorage_Title,C4JStorage::eTMS_FileType_Graphic, L"Default_Cape.png",&pBuffer, &dwSize); +// if(eTMSStatus==C4JStorage::ETMSStatus_Idle) +// { +// app.AddMemoryTextureFile(wTemp,pBuffer,dwSize); +// } +// #endif +// } +// } +// } + +void CMinecraftApp::HandleDLC(DLCPack *pack) +{ + DWORD dwFilesProcessed = 0; +#ifndef _XBOX +#if defined(__PS3__) || defined(__ORBIS__) || defined(_WINDOWS64) || defined (__PSVITA__) + std::vector dlcFilenames; +#elif defined _DURANGO + std::vector dlcFilenames; +#endif + StorageManager.GetMountedDLCFileList("DLCDrive", dlcFilenames); +#ifdef __ORBIS__ + // 4J Stu - I don't know why we handle more than one file here any more, however this doesn't seem to work with the PS4 patches + if(dlcFilenames.size() > 0) m_dlcManager.readDLCDataFile(dwFilesProcessed, dlcFilenames[0], pack); +#else + for(size_t i=0; i(qwTicksPerSec.QuadPart); + + // Save the start time + QueryPerformanceCounter( &m_Time.qwTime ); + + // Zero out the elapsed and total time + m_Time.qwAppTime.QuadPart = 0; + m_Time.fAppTime = 0.0f; + m_Time.fElapsedTime = 0.0f; +} + +//------------------------------------------------------------------------------------- +// Name: UpdateTime() +// Desc: Updates the elapsed time since our last frame. +//------------------------------------------------------------------------------------- +void CMinecraftApp::UpdateTime() +{ + LARGE_INTEGER qwNewTime; + LARGE_INTEGER qwDeltaTime; + + QueryPerformanceCounter( &qwNewTime ); + qwDeltaTime.QuadPart = qwNewTime.QuadPart - m_Time.qwTime.QuadPart; + + m_Time.qwAppTime.QuadPart += qwDeltaTime.QuadPart; + m_Time.qwTime.QuadPart = qwNewTime.QuadPart; + + m_Time.fElapsedTime = m_Time.fSecsPerTick * static_cast(qwDeltaTime.QuadPart); + m_Time.fAppTime = m_Time.fSecsPerTick * static_cast(m_Time.qwAppTime.QuadPart); +} + +bool CMinecraftApp::isXuidNotch(PlayerUID xuid) +{ + if(m_xuidNotch != INVALID_XUID && xuid != INVALID_XUID) + { + return ProfileManager.AreXUIDSEqual(xuid, m_xuidNotch) == TRUE; + } + return false; +} + +bool CMinecraftApp::isXuidDeadmau5(PlayerUID xuid) +{ + auto it = MojangData.find(xuid); // 4J Stu - The .at and [] accessors insert elements if they don't exist + if (it != MojangData.end() ) + { + MOJANG_DATA *pMojangData=MojangData[xuid]; + if(pMojangData && pMojangData->eXuid==eXUID_Deadmau5) + { + return true; + } + } + + return false; +} + +void CMinecraftApp::AddMemoryTextureFile(const wstring &wName,PBYTE pbData,DWORD dwBytes) +{ + EnterCriticalSection(&csMemFilesLock); + // check it's not already in + PMEMDATA pData=nullptr; + auto it = m_MEM_Files.find(wName); + if(it != m_MEM_Files.end()) + { +#ifndef _CONTENT_PACKAGE + wprintf(L"Incrementing the memory texture file count for %ls\n", wName.c_str()); +#endif + pData = (*it).second; + + if(pData->dwBytes == 0 && dwBytes != 0) + { + // This should never be nullptr if dwBytes is 0 + if(pData->pbData!=nullptr) delete [] pData->pbData; + + pData->pbData=pbData; + pData->dwBytes=dwBytes; + } + + ++pData->ucRefCount; + LeaveCriticalSection(&csMemFilesLock); + return; + } + +#ifndef _CONTENT_PACKAGE + //wprintf(L"Adding the memory texture file data for %ls\n", wName.c_str()); +#endif + // this is a texture (png) file + + // add this texture to the list of memory texture files - it will then be picked up by the level renderer's AddEntity + + pData = (PMEMDATA)new BYTE[sizeof(MEMDATA)]; + ZeroMemory( pData, sizeof(MEMDATA) ); + pData->pbData=pbData; + pData->dwBytes=dwBytes; + pData->ucRefCount = 1; + + // use the xuid to access the skin data + m_MEM_Files[wName]=pData; + + LeaveCriticalSection(&csMemFilesLock); +} + +void CMinecraftApp::RemoveMemoryTextureFile(const wstring &wName) +{ + EnterCriticalSection(&csMemFilesLock); + + auto it = m_MEM_Files.find(wName); + if(it != m_MEM_Files.end()) + { +#ifndef _CONTENT_PACKAGE + wprintf(L"Decrementing the memory texture file count for %ls\n", wName.c_str()); +#endif + PMEMDATA pData = (*it).second; + --pData->ucRefCount; + if(pData->ucRefCount <= 0) + { +#ifndef _CONTENT_PACKAGE + wprintf(L"Erasing the memory texture file data for %ls\n", wName.c_str()); +#endif + delete [] pData; + m_MEM_Files.erase(wName); + } + } + LeaveCriticalSection(&csMemFilesLock); +} + +bool CMinecraftApp::DefaultCapeExists() +{ + wstring wTex=L"Special_Cape.png"; + bool val = false; + + EnterCriticalSection(&csMemFilesLock); + auto it = m_MEM_Files.find(wTex); + if(it != m_MEM_Files.end()) val = true; + LeaveCriticalSection(&csMemFilesLock); + + return val; +} + +bool CMinecraftApp::IsFileInMemoryTextures(const wstring &wName) +{ + bool val = false; + + EnterCriticalSection(&csMemFilesLock); + auto it = m_MEM_Files.find(wName); + if(it != m_MEM_Files.end()) val = true; + LeaveCriticalSection(&csMemFilesLock); + + return val; +} + +void CMinecraftApp::GetMemFileDetails(const wstring &wName,PBYTE *ppbData,DWORD *pdwBytes) +{ + EnterCriticalSection(&csMemFilesLock); + auto it = m_MEM_Files.find(wName); + if(it != m_MEM_Files.end()) + { + PMEMDATA pData = (*it).second; + *ppbData=pData->pbData; + *pdwBytes=pData->dwBytes; + } + LeaveCriticalSection(&csMemFilesLock); +} + +void CMinecraftApp::AddMemoryTPDFile(int iConfig,PBYTE pbData,DWORD dwBytes) +{ + EnterCriticalSection(&csMemTPDLock); + // check it's not already in + PMEMDATA pData=nullptr; + auto it = m_MEM_TPD.find(iConfig); + if(it == m_MEM_TPD.end()) + { + pData = (PMEMDATA)new BYTE[sizeof(MEMDATA)]; + ZeroMemory( pData, sizeof(MEMDATA) ); + pData->pbData=pbData; + pData->dwBytes=dwBytes; + pData->ucRefCount = 1; + + m_MEM_TPD[iConfig]=pData; + } + + LeaveCriticalSection(&csMemTPDLock); +} + +void CMinecraftApp::RemoveMemoryTPDFile(int iConfig) +{ + EnterCriticalSection(&csMemTPDLock); + // check it's not already in + PMEMDATA pData=nullptr; + auto it = m_MEM_TPD.find(iConfig); + if(it != m_MEM_TPD.end()) + { + pData=m_MEM_TPD[iConfig]; + delete [] pData; + m_MEM_TPD.erase(iConfig); + } + + LeaveCriticalSection(&csMemTPDLock); +} + +#ifdef _XBOX +int CMinecraftApp::GetTPConfigVal(WCHAR *pwchDataFile) +{ + DLC_INFO *pDLCInfo=nullptr; + // run through the DLC info to find the right texture pack/mash-up pack + for(unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i) + { + ULONGLONG ull=app.GetDLCInfoTexturesFullOffer(i); + pDLCInfo=app.GetDLCInfoForFullOfferID(ull); + + if(wcscmp(pwchDataFile,pDLCInfo->wchDataFile)==0) + { + return pDLCInfo->iConfig; + } + } + + return -1; +} +#elif defined _XBOX_ONE +int CMinecraftApp::GetTPConfigVal(WCHAR *pwchDataFile) +{ + DLC_INFO *pDLCInfo=nullptr; + // run through the DLC info to find the right texture pack/mash-up pack + for(unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i) + { + pDLCInfo=app.GetDLCInfoForFullOfferID((WCHAR *)app.GetDLCInfoTexturesFullOffer(i).c_str()); + + if(wcscmp(pwchDataFile,pDLCInfo->wchDataFile)==0) + { + return pDLCInfo->iConfig; + } + } + + return -1; +} +#elif defined _WINDOWS64 +int CMinecraftApp::GetTPConfigVal(WCHAR *pwchDataFile) +{ + return -1; +} +#endif +bool CMinecraftApp::IsFileInTPD(int iConfig) +{ + bool val = false; + + EnterCriticalSection(&csMemTPDLock); + auto it = m_MEM_TPD.find(iConfig); + if(it != m_MEM_TPD.end()) val = true; + LeaveCriticalSection(&csMemTPDLock); + + return val; +} + +void CMinecraftApp::GetTPD(int iConfig,PBYTE *ppbData,DWORD *pdwBytes) +{ + EnterCriticalSection(&csMemTPDLock); + auto it = m_MEM_TPD.find(iConfig); + if(it != m_MEM_TPD.end()) + { + PMEMDATA pData = (*it).second; + *ppbData=pData->pbData; + *pdwBytes=pData->dwBytes; + } + LeaveCriticalSection(&csMemTPDLock); +} + + +// bool CMinecraftApp::UploadFileToGlobalStorage(int iQuadrant, C4JStorage::eGlobalStorage eStorageFacility, wstring *wsFile ) +// { +// bool bRes=false; +// #ifndef _CONTENT_PACKAGE +// // read the local file +// File gtsFile( wsFile->c_str() ); +// +// int64_t fileSize = gtsFile.length(); +// +// if(fileSize!=0) +// { +// FileInputStream fis(gtsFile); +// byteArray ba((int)fileSize); +// fis.read(ba); +// fis.close(); +// +// bRes=StorageManager.WriteTMSFile(iQuadrant,eStorageFacility,(WCHAR *)wsFile->c_str(),ba.data, ba.length); +// +// } +// #endif +// return bRes; +// } + + + + + + +void CMinecraftApp::StoreLaunchData() +{ + +} + +void CMinecraftApp::ExitGame() +{ +} + +// Invites + +void CMinecraftApp::ProcessInvite(DWORD dwUserIndex, DWORD dwLocalUsersMask, const INVITE_INFO * pInviteInfo) +{ + m_InviteData.dwUserIndex=dwUserIndex; + m_InviteData.dwLocalUsersMask=dwLocalUsersMask; + m_InviteData.pInviteInfo=pInviteInfo; + //memcpy(&m_InviteData,pJoinData,sizeof(JoinFromInviteData)); + SetAction(dwUserIndex,eAppAction_ExitAndJoinFromInvite); +} + +int CMinecraftApp::ExitAndJoinFromInvite(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + CMinecraftApp* pApp = static_cast(pParam); + //Minecraft *pMinecraft=Minecraft::GetInstance(); + + // buttons are swapped on this menu + if(result==C4JStorage::EMessage_ResultDecline) + { + pApp->SetAction(iPad,eAppAction_ExitAndJoinFromInviteConfirmed); + } + + return 0; +} + +int CMinecraftApp::ExitAndJoinFromInviteSaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + CMinecraftApp *pClass = static_cast(pParam); + // Exit with or without saving + // Decline means save in this dialog + if(result==C4JStorage::EMessage_ResultDecline || result==C4JStorage::EMessage_ResultThirdOption) + { + if( result==C4JStorage::EMessage_ResultDecline ) // Save + { + // Check they have the full texture pack if they are using one + // 4J-PB - Is the player trying to save but they are using a trial texturepack ? + if(!Minecraft::GetInstance()->skins->isUsingDefaultSkin()) + { + TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); + + DLCPack * pDLCPack=tPack->getDLCPack(); + if(!pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) + { + // upsell + // get the dlc texture pack + +#ifdef _XBOX + DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; + ULONGLONG ullOfferID_Full; + app.GetDLCFullOfferIDForPackID(pDLCTexPack->getDLCParentPackId(),&ullOfferID_Full); + + // tell sentient about the upsell of the full version of the skin pack + TelemetryManager->RecordUpsellPresented(iPad, eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF); +#endif + + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_OK; + uiIDA[1]=IDS_CONFIRM_CANCEL; + + // Give the player a warning about the trial version of the texture pack + ui.RequestErrorMessage(IDS_WARNING_DLC_TRIALTEXTUREPACK_TITLE, IDS_WARNING_DLC_TRIALTEXTUREPACK_TEXT, uiIDA, 2, iPad,&CMinecraftApp::WarningTrialTexturePackReturned,pClass); + + return S_OK; + } + } +#ifndef _XBOX_ONE + // does the save exist? + bool bSaveExists; + StorageManager.DoesSaveExist(&bSaveExists); + // 4J-PB - we check if the save exists inside the libs + // we need to ask if they are sure they want to overwrite the existing game + if(bSaveExists) + { + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_CONFIRM_OK; + ui.RequestErrorMessage(IDS_TITLE_SAVE_GAME, IDS_CONFIRM_SAVE_GAME, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::ExitAndJoinFromInviteAndSaveReturned,pClass); + return 0; + } + else +#endif + { +#if defined(_XBOX_ONE) || defined(__ORBIS__) + StorageManager.SetSaveDisabled(false); +#endif + MinecraftServer::getInstance()->setSaveOnExit( true ); + } + } + else + { + // been a few requests for a confirm on exit without saving + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_CONFIRM_OK; + ui.RequestErrorMessage(IDS_TITLE_DECLINE_SAVE_GAME, IDS_CONFIRM_DECLINE_SAVE_GAME, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::ExitAndJoinFromInviteDeclineSaveReturned,pClass); + return 0; + } + + app.SetAction(ProfileManager.GetPrimaryPad(),eAppAction_ExitAndJoinFromInviteConfirmed); + } + return 0; +} + +int CMinecraftApp::WarningTrialTexturePackReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + // 4J Stu - I added this in when fixing an X1 bug. We should probably add this as well but I don't have time to test all platforms atm +#if 0 //defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) + if(result==C4JStorage::EMessage_ResultAccept) + { + if(!ProfileManager.IsSignedInLive(iPad)) + { + // you're not signed in to PSN! + + } + else + { + // 4J-PB - need to check this user can access the store + bool bContentRestricted; + ProfileManager.GetChatAndContentRestrictions(iPad,true,nullptr,&bContentRestricted,nullptr); + if(bContentRestricted) + { + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + ui.RequestAlertMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, iPad); + } + else + { + // need to get info on the pack to see if the user has already downloaded it + TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); + DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; + + // retrieve the store name for the skin pack + DLCPack *pDLCPack=pDLCTexPack->getDLCInfoParentPack();//tPack->getDLCPack(); + const char *pchPackName=wstringtofilename(pDLCPack->getName()); + app.DebugPrintf("Texture Pack - %s\n",pchPackName); + SONYDLC *pSONYDLCInfo=app.GetSONYDLCInfo((char *)pchPackName); + + if(pSONYDLCInfo!=nullptr) + { + char chName[42]; + char chSkuID[SCE_NP_COMMERCE2_SKU_ID_LEN]; + + memset(chSkuID,0,SCE_NP_COMMERCE2_SKU_ID_LEN); + // find the info on the skin pack + // we have to retrieve the skuid from the store info, it can't be hardcoded since Sony may change it. + // So we assume the first sku for the product is the one we want +#ifdef __ORBIS__ + sprintf(chName,"%s",pSONYDLCInfo->chDLCKeyname); +#else + sprintf(chName,"%s-%s",app.GetCommerceCategory(),pSONYDLCInfo->chDLCKeyname); +#endif + app.GetDLCSkuIDFromProductList(chName,chSkuID); + // 4J-PB - need to check for an empty store +#if defined __ORBIS__ || defined __PSVITA__ || defined __PS3__ + if(app.CheckForEmptyStore(iPad)==false) +#endif + { + if(app.DLCAlreadyPurchased(chSkuID)) + { + app.DownloadAlreadyPurchased(chSkuID); + } + else + { + app.Checkout(chSkuID); + } + } + } + } + } + } +#endif // + +#ifdef _XBOX_ONE + if(result==C4JStorage::EMessage_ResultAccept) + { + if(ProfileManager.IsSignedIn(iPad)) + { + if (ProfileManager.IsSignedInLive(iPad)) + { + TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); + // get the dlc texture pack + DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; + + DLCPack *pDLCPack=pDLCTexPack->getDLCInfoParentPack(); + + DLC_INFO *pDLCInfo=app.GetDLCInfoForProductName((WCHAR *)pDLCPack->getName().c_str()); + + StorageManager.InstallOffer(1,(WCHAR *)pDLCInfo->wsProductId.c_str(),nullptr,nullptr); + + // the license change coming in when the offer has been installed will cause this scene to refresh + } + else + { + // 4J-JEV: Fix for XB1: #165863 - XR-074: Compliance: With no active network connection user is unable to convert from Trial to Full texture pack and is not messaged why. + UINT uiIDA[1] = { IDS_CONFIRM_OK }; + ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_XBOXLIVE_NOTIFICATION, uiIDA, 1, iPad); + } + } + } + +#endif +#ifdef _XBOX + + CMinecraftApp* pClass = (CMinecraftApp*)pParam; + + TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); + // get the dlc texture pack + DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; + ULONGLONG ullIndexA[1]; + + // Need to get the parent packs id, since this may be one of many child packs with their own ids + app.GetDLCFullOfferIDForPackID(pDLCTexPack->getDLCParentPackId(),&ullIndexA[0]); + + if(result==C4JStorage::EMessage_ResultAccept) + { + if(ProfileManager.IsSignedIn(iPad)) + { + // need to allow downloads here, or the player would need to quit the game to let the download of a texture pack happen. This might affect the network traffic, since the download could take all the bandwidth... + XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); + + StorageManager.InstallOffer(1,ullIndexA,nullptr,nullptr); + } + } + else + { + TelemetryManager->RecordUpsellResponded(iPad, eSet_UpsellID_Texture_DLC, ( ullIndexA[0] & 0xFFFFFFFF ), eSen_UpsellOutcome_Declined); + } +#endif + return 0; +} + +int CMinecraftApp::ExitAndJoinFromInviteAndSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + //CMinecraftApp* pClass = (CMinecraftApp*)pParam; + + // results switched for this dialog + if(result==C4JStorage::EMessage_ResultDecline) + { + INT saveOrCheckpointId = 0; + + // Check they have the full texture pack if they are using one + // 4J-PB - Is the player trying to save but they are using a trial texturepack ? + if(!Minecraft::GetInstance()->skins->isUsingDefaultSkin()) + { + TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); + + DLCPack * pDLCPack=tPack->getDLCPack(); + if(!pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) + { + // upsell + // get the dlc texture pack + +#ifdef _XBOX + DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; + ULONGLONG ullOfferID_Full; + app.GetDLCFullOfferIDForPackID(pDLCTexPack->getDLCParentPackId(),&ullOfferID_Full); + + // tell sentient about the upsell of the full version of the skin pack + TelemetryManager->RecordUpsellPresented(iPad, eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF); +#endif + + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_OK; + uiIDA[1]=IDS_CONFIRM_CANCEL; + + // Give the player a warning about the trial version of the texture pack + ui.RequestErrorMessage(IDS_WARNING_DLC_TRIALTEXTUREPACK_TITLE, IDS_WARNING_DLC_TRIALTEXTUREPACK_TEXT, uiIDA, 2, iPad,&CMinecraftApp::WarningTrialTexturePackReturned,nullptr); + + return S_OK; + } + } + //bool validSave = StorageManager.GetSaveUniqueNumber(&saveOrCheckpointId); + //SentientManager.RecordLevelSaveOrCheckpoint(ProfileManager.GetPrimaryPad(), saveOrCheckpointId); + MinecraftServer::getInstance()->setSaveOnExit( true ); + // flag a app action of exit and join game from invite + app.SetAction(iPad,eAppAction_ExitAndJoinFromInviteConfirmed); + } + return 0; +} + +int CMinecraftApp::ExitAndJoinFromInviteDeclineSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + // results switched for this dialog + if(result==C4JStorage::EMessage_ResultDecline) + { +#if defined(_XBOX_ONE) || defined(__ORBIS__) + StorageManager.SetSaveDisabled(false); +#endif + MinecraftServer::getInstance()->setSaveOnExit( false ); + // flag a app action of exit and join game from invite + app.SetAction(iPad,eAppAction_ExitAndJoinFromInviteConfirmed); + } + return 0; +} + +////////////////////////////////////////////////////////////////////////// +// +// FatalLoadError +// +// This is called when we can't load one of the required files at startup +// It tends to mean the files have been corrupted. +// We have to assume that we've not been able to load the text for the game. +// +////////////////////////////////////////////////////////////////////////// +void CMinecraftApp::FatalLoadError() +{ + +} + +TIPSTRUCT CMinecraftApp::m_GameTipA[MAX_TIPS_GAMETIP]= +{ + { 0, IDS_TIPS_GAMETIP_1}, + { 0, IDS_TIPS_GAMETIP_2}, + { 0, IDS_TIPS_GAMETIP_3}, + { 0, IDS_TIPS_GAMETIP_4}, + { 0, IDS_TIPS_GAMETIP_5}, + { 0, IDS_TIPS_GAMETIP_6}, + { 0, IDS_TIPS_GAMETIP_7}, + { 0, IDS_TIPS_GAMETIP_8}, + { 0, IDS_TIPS_GAMETIP_9}, + { 0, IDS_TIPS_GAMETIP_10}, + { 0, IDS_TIPS_GAMETIP_11}, + { 0, IDS_TIPS_GAMETIP_12}, + { 0, IDS_TIPS_GAMETIP_13}, + { 0, IDS_TIPS_GAMETIP_14}, + { 0, IDS_TIPS_GAMETIP_15}, + { 0, IDS_TIPS_GAMETIP_16}, + { 0, IDS_TIPS_GAMETIP_17}, + { 0, IDS_TIPS_GAMETIP_18}, + { 0, IDS_TIPS_GAMETIP_19}, + { 0, IDS_TIPS_GAMETIP_20}, + { 0, IDS_TIPS_GAMETIP_21}, + { 0, IDS_TIPS_GAMETIP_22}, + { 0, IDS_TIPS_GAMETIP_23}, + { 0, IDS_TIPS_GAMETIP_24}, + { 0, IDS_TIPS_GAMETIP_25}, + { 0, IDS_TIPS_GAMETIP_26}, + { 0, IDS_TIPS_GAMETIP_27}, + { 0, IDS_TIPS_GAMETIP_28}, + { 0, IDS_TIPS_GAMETIP_29}, + { 0, IDS_TIPS_GAMETIP_30}, + { 0, IDS_TIPS_GAMETIP_31}, + { 0, IDS_TIPS_GAMETIP_32}, + { 0, IDS_TIPS_GAMETIP_33}, + { 0, IDS_TIPS_GAMETIP_34}, + { 0, IDS_TIPS_GAMETIP_35}, + { 0, IDS_TIPS_GAMETIP_36}, + { 0, IDS_TIPS_GAMETIP_37}, + { 0, IDS_TIPS_GAMETIP_38}, + { 0, IDS_TIPS_GAMETIP_39}, + { 0, IDS_TIPS_GAMETIP_40}, + { 0, IDS_TIPS_GAMETIP_41}, + { 0, IDS_TIPS_GAMETIP_42}, + { 0, IDS_TIPS_GAMETIP_43}, + { 0, IDS_TIPS_GAMETIP_44}, + { 0, IDS_TIPS_GAMETIP_45}, + { 0, IDS_TIPS_GAMETIP_46}, + { 0, IDS_TIPS_GAMETIP_47}, + { 0, IDS_TIPS_GAMETIP_48}, + { 0, IDS_TIPS_GAMETIP_49}, + { 0, IDS_TIPS_GAMETIP_50}, +}; + +TIPSTRUCT CMinecraftApp::m_TriviaTipA[MAX_TIPS_TRIVIATIP]= +{ + { 0, IDS_TIPS_TRIVIA_1}, + { 0, IDS_TIPS_TRIVIA_2}, + { 0, IDS_TIPS_TRIVIA_3}, + { 0, IDS_TIPS_TRIVIA_4}, + { 0, IDS_TIPS_TRIVIA_5}, + { 0, IDS_TIPS_TRIVIA_6}, + { 0, IDS_TIPS_TRIVIA_7}, + { 0, IDS_TIPS_TRIVIA_8}, + { 0, IDS_TIPS_TRIVIA_9}, + { 0, IDS_TIPS_TRIVIA_10}, + { 0, IDS_TIPS_TRIVIA_11}, + { 0, IDS_TIPS_TRIVIA_12}, + { 0, IDS_TIPS_TRIVIA_13}, + { 0, IDS_TIPS_TRIVIA_14}, + { 0, IDS_TIPS_TRIVIA_15}, + { 0, IDS_TIPS_TRIVIA_16}, + { 0, IDS_TIPS_TRIVIA_17}, + { 0, IDS_TIPS_TRIVIA_18}, + { 0, IDS_TIPS_TRIVIA_19}, + { 0, IDS_TIPS_TRIVIA_20}, +}; + +Random *CMinecraftApp::TipRandom = new Random(); + +int CMinecraftApp::TipsSortFunction(const void* a, const void* b) +{ + return ((TIPSTRUCT*)a)->iSortValue - ((TIPSTRUCT*)b)->iSortValue; +} + +void CMinecraftApp::InitialiseTips() +{ + // We'll randomise the tips at start up based on their priority + + ZeroMemory(m_TipIDA,sizeof(UINT)*MAX_TIPS_GAMETIP+MAX_TIPS_TRIVIATIP); + + // Make the first tip tell you that you can play splitscreen in HD modes if you are in SD + if(!RenderManager.IsHiDef()) + { + m_GameTipA[0].uiStringID=IDS_TIPS_GAMETIP_0; + } + // randomise then quicksort + // going to leave the multiplayer tip so it is always first + + // Only randomise the content package build +#ifdef _CONTENT_PACKAGE + + for(int i=1;inextInt(); + } + qsort( &m_GameTipA[1], MAX_TIPS_GAMETIP-1, sizeof(TIPSTRUCT), TipsSortFunction ); +#endif + + for(int i=0;inextInt(); + } + qsort( m_TriviaTipA, MAX_TIPS_TRIVIATIP, sizeof(TIPSTRUCT), TipsSortFunction ); + + + int iCurrentGameTip=0; + int iCurrentTriviaTip=0; + + for(int i=0;iskins->getSelected()->getColourTable()->getColour(colour); +} + +int CMinecraftApp::GetHTMLFontSize(EHTMLFontSize size) +{ + return s_iHTMLFontSizesA[size]; +} + +wstring CMinecraftApp::FormatHTMLString(int iPad, const wstring &desc, int shadowColour /*= 0xFFFFFFFF*/, bool override) +{ + wstring text(desc); + + wchar_t replacements[64]; + // We will also insert line breaks here as couldn't figure out how to get them to come through from strings.resx ! + text = replaceAll(text, L"{*B*}", L"
" ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_T1)); + text = replaceAll(text, L"{*T1*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_T2)); + text = replaceAll(text, L"{*T2*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_T3)); + text = replaceAll(text, L"{*T3*}", replacements ); // for How To Play + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_Black)); + text = replaceAll(text, L"{*ETB*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_White)); + text = replaceAll(text, L"{*ETW*}", replacements ); + text = replaceAll(text, L"{*EF*}", L"" ); + + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_0), shadowColour); + text = replaceAll(text, L"{*C0*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_1), shadowColour); + text = replaceAll(text, L"{*C1*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_2), shadowColour); + text = replaceAll(text, L"{*C2*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_3), shadowColour); + text = replaceAll(text, L"{*C3*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_4), shadowColour); + text = replaceAll(text, L"{*C4*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_5), shadowColour); + text = replaceAll(text, L"{*C5*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_6), shadowColour); + text = replaceAll(text, L"{*C6*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_7), shadowColour); + text = replaceAll(text, L"{*C7*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_8), shadowColour); + text = replaceAll(text, L"{*C8*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_9), shadowColour); + text = replaceAll(text, L"{*C9*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_a), shadowColour); + text = replaceAll(text, L"{*CA*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_b), shadowColour); + text = replaceAll(text, L"{*CB*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_c), shadowColour); + text = replaceAll(text, L"{*CC*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_d), shadowColour); + text = replaceAll(text, L"{*CD*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_e), shadowColour); + text = replaceAll(text, L"{*CE*}", replacements ); + swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_f), shadowColour); + text = replaceAll(text, L"{*CF*}", replacements ); + + // Swap for southpaw. + if ( app.GetGameSettings(iPad,eGameSetting_ControlSouthPaw) ) + { + text = replaceAll(text, L"{*CONTROLLER_ACTION_MOVE*}", GetActionReplacement(iPad,MINECRAFT_ACTION_LOOK_RIGHT ) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_LOOK*}", GetActionReplacement(iPad,MINECRAFT_ACTION_RIGHT ) ); + + text = replaceAll(text, L"{*CONTROLLER_MENU_NAVIGATE*}", GetVKReplacement(VK_PAD_RTHUMB_LEFT) ); + } + else // Normal right handed. + { + text = replaceAll(text, L"{*CONTROLLER_ACTION_MOVE*}", GetActionReplacement(iPad,MINECRAFT_ACTION_RIGHT ) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_LOOK*}", GetActionReplacement(iPad,MINECRAFT_ACTION_LOOK_RIGHT ) ); + + text = replaceAll(text, L"{*CONTROLLER_MENU_NAVIGATE*}", GetVKReplacement(VK_PAD_LTHUMB_LEFT) ); + } + + text = replaceAll(text, L"{*CONTROLLER_ACTION_JUMP*}", GetActionReplacement(iPad,MINECRAFT_ACTION_JUMP ) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_SNEAK*}", GetActionReplacement(iPad,MINECRAFT_ACTION_SNEAK_TOGGLE ) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_USE*}", GetActionReplacement(iPad,MINECRAFT_ACTION_USE ) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_ACTION*}", GetActionReplacement(iPad,MINECRAFT_ACTION_ACTION ) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_LEFT_SCROLL*}", GetActionReplacement(iPad,MINECRAFT_ACTION_LEFT_SCROLL ) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_RIGHT_SCROLL*}", GetActionReplacement(iPad,MINECRAFT_ACTION_RIGHT_SCROLL ) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_INVENTORY*}", GetActionReplacement(iPad,MINECRAFT_ACTION_INVENTORY ) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_CRAFTING*}", GetActionReplacement(iPad,MINECRAFT_ACTION_CRAFTING ) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_DROP*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DROP ) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_CAMERA*}", GetActionReplacement(iPad,MINECRAFT_ACTION_RENDER_THIRD_PERSON ) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_MENU_PAGEDOWN*}", GetActionReplacement(iPad,ACTION_MENU_PAGEDOWN ) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_DISMOUNT*}", GetActionReplacement(iPad,MINECRAFT_ACTION_SNEAK_TOGGLE ) ); + text = replaceAll(text, L"{*CONTROLLER_VK_A*}", GetVKReplacement(VK_PAD_A) ); + text = replaceAll(text, L"{*CONTROLLER_VK_B*}", GetVKReplacement(VK_PAD_B) ); + text = replaceAll(text, L"{*CONTROLLER_VK_X*}", GetVKReplacement(VK_PAD_X) ); + text = replaceAll(text, L"{*CONTROLLER_VK_Y*}", GetVKReplacement(VK_PAD_Y, override) ); + text = replaceAll(text, L"{*CONTROLLER_VK_LB*}", GetVKReplacement(VK_PAD_LSHOULDER) ); + text = replaceAll(text, L"{*CONTROLLER_VK_RB*}", GetVKReplacement(VK_PAD_RSHOULDER) ); + text = replaceAll(text, L"{*CONTROLLER_VK_LS*}", GetVKReplacement(VK_PAD_LTHUMB_UP) ); + text = replaceAll(text, L"{*CONTROLLER_VK_RS*}", GetVKReplacement(VK_PAD_RTHUMB_UP) ); + text = replaceAll(text, L"{*CONTROLLER_VK_LT*}", GetVKReplacement(VK_PAD_LTRIGGER) ); + text = replaceAll(text, L"{*CONTROLLER_VK_RT*}", GetVKReplacement(VK_PAD_RTRIGGER) ); + text = replaceAll(text, L"{*ICON_SHANK_01*}", GetIconReplacement(XZP_ICON_SHANK_01) ); + text = replaceAll(text, L"{*ICON_SHANK_03*}", GetIconReplacement(XZP_ICON_SHANK_03) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_DPAD_UP*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DPAD_UP ) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_DPAD_DOWN*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DPAD_DOWN ) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_DPAD_RIGHT*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DPAD_RIGHT ) ); + text = replaceAll(text, L"{*CONTROLLER_ACTION_DPAD_LEFT*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DPAD_LEFT ) ); +#if defined _XBOX_ONE || defined __PSVITA__ + text = replaceAll(text, L"{*CONTROLLER_VK_START*}", GetVKReplacement(VK_PAD_START ) ); + text = replaceAll(text, L"{*CONTROLLER_VK_BACK*}", GetVKReplacement(VK_PAD_BACK ) ); +#endif + +#ifdef _XBOX + wstring imageRoot = L""; + + Minecraft *pMinecraft = Minecraft::GetInstance(); + imageRoot = pMinecraft->skins->getSelected()->getXuiRootPath(); + + text = replaceAll(text, L"{*IMAGEROOT*}", imageRoot); +#endif // _XBOX + + // Fix for #8903 - UI: Localization: KOR/JPN/CHT: Button Icons are rendered with padding space, which looks no good + DWORD dwLanguage = XGetLanguage( ); + switch(dwLanguage) + { + case XC_LANGUAGE_KOREAN: + case XC_LANGUAGE_JAPANESE: + case XC_LANGUAGE_TCHINESE: + text = replaceAll(text, L" ", L"" ); + break; + } + + return text; +} + +//found list of html escapes at https://stackoverflow.com/questions/7381974/which-characters-need-to-be-escaped-in-html +wstring CMinecraftApp::EscapeHTMLString(const wstring& desc) +{ + static std::unordered_map replacementMap = { + {L'&', L"&"}, + {L'<', L"<"}, + {L'>', L">"}, + {L'\'', L"\u2019"}, + }; + + wstring finalString = L""; + for (int i = 0; i < desc.size(); i++) { + wchar_t _char = desc[i]; + auto it = replacementMap.find(_char); + + if (it != replacementMap.end()) finalString += it->second; + else finalString += _char; + } + + return finalString; +} + +eMinecraftColour GetColorFromCode(wchar_t _char) { + switch (_char) { + case L'0': return eHTMLColor_0; + case L'1': return eHTMLColor_1; + case L'2': return eHTMLColor_2; + case L'3': return eHTMLColor_3; + case L'4': return eHTMLColor_4; + case L'5': return eHTMLColor_5; + case L'6': return eHTMLColor_6; + case L'7': return eHTMLColor_7; + case L'8': return eHTMLColor_8; + case L'9': return eHTMLColor_9; + case L'a': return eHTMLColor_a; + case L'b': return eHTMLColor_b; + case L'c': return eHTMLColor_c; + case L'd': return eHTMLColor_d; + case L'e': return eHTMLColor_e; + case L'f': return eHTMLColor_f; + default: return eMinecraftColour_NOT_SET; + } +} + +wstring CMinecraftApp::FormatColoredString(const wstring& string) { + static constexpr std::wstring_view colorFormatString = L""; + + wstring result; + + bool fontOpen = false; + bool italicOpen = false; + + auto CloseItalic = [&]() { + if (italicOpen) { + result += L"
"; + italicOpen = false; + } + }; + + auto CloseFont = [&]() { + if (fontOpen) { + result += L""; + fontOpen = false; + } + }; + + wchar_t buffer[64]; + + for (size_t i = 0; i < string.length(); ++i) { + if (string[i] == L'\u00A7' && i + 1 < string.length()) { + wchar_t code = towlower(string[i + 1]); + + if (GetColorFromCode(code) != eMinecraftColour_NOT_SET) { + bool restoreItalic = italicOpen; + + CloseItalic(); + CloseFont(); + + swprintf(buffer, _countof(buffer), colorFormatString.data(), GetHTMLColour(GetColorFromCode(code))); + + result += buffer; + fontOpen = true; + + if (restoreItalic) { + result += L""; + italicOpen = true; + } + + ++i; + continue; + } + + if (code == L'o') { + if (!italicOpen) { + result += L""; + italicOpen = true; + } + + ++i; + continue; + } + + if (code == L'r') { + CloseItalic(); + CloseFont(); + + ++i; + continue; + } + } + + result += string[i]; + } + + CloseItalic(); + CloseFont(); + + return result; +} + +wstring CMinecraftApp::GetActionReplacement(int iPad, unsigned char ucAction) +{ + unsigned int input = InputManager.GetGameJoypadMaps(InputManager.GetJoypadMapVal(iPad) ,ucAction); + +#ifdef _XBOX + switch(input) + { + case _360_JOY_BUTTON_A: + return app.GetString( IDS_CONTROLLER_A ); + case _360_JOY_BUTTON_B: + return app.GetString( IDS_CONTROLLER_B ); + case _360_JOY_BUTTON_X: + return app.GetString( IDS_CONTROLLER_X ); + case _360_JOY_BUTTON_Y: + return app.GetString( IDS_CONTROLLER_Y ); + case _360_JOY_BUTTON_LSTICK_UP: + case _360_JOY_BUTTON_LSTICK_DOWN: + case _360_JOY_BUTTON_LSTICK_LEFT: + case _360_JOY_BUTTON_LSTICK_RIGHT: + return app.GetString( IDS_CONTROLLER_LEFT_STICK ); + case _360_JOY_BUTTON_RSTICK_LEFT: + case _360_JOY_BUTTON_RSTICK_RIGHT: + case _360_JOY_BUTTON_RSTICK_UP: + case _360_JOY_BUTTON_RSTICK_DOWN: + return app.GetString( IDS_CONTROLLER_RIGHT_STICK ); + case _360_JOY_BUTTON_LT: + return app.GetString( IDS_CONTROLLER_LEFT_TRIGGER ); + case _360_JOY_BUTTON_RT: + return app.GetString( IDS_CONTROLLER_RIGHT_TRIGGER ); + case _360_JOY_BUTTON_RB: + return app.GetString( IDS_CONTROLLER_RIGHT_BUMPER ); + case _360_JOY_BUTTON_LB: + return app.GetString( IDS_CONTROLLER_LEFT_BUMPER ); + case _360_JOY_BUTTON_BACK: + return app.GetString( IDS_CONTROLLER_BACK ); + case _360_JOY_BUTTON_START: + return app.GetString( IDS_CONTROLLER_START ); + case _360_JOY_BUTTON_RTHUMB: + return app.GetString( IDS_CONTROLLER_RIGHT_THUMBSTICK ); + case _360_JOY_BUTTON_LTHUMB: + return app.GetString( IDS_CONTROLLER_LEFT_THUMBSTICK ); + case _360_JOY_BUTTON_DPAD_LEFT: + return app.GetString( IDS_CONTROLLER_DPAD_L ); + case _360_JOY_BUTTON_DPAD_RIGHT: + return app.GetString( IDS_CONTROLLER_DPAD_R ); + case _360_JOY_BUTTON_DPAD_UP: + return app.GetString( IDS_CONTROLLER_DPAD_U ); + case _360_JOY_BUTTON_DPAD_DOWN: + return app.GetString( IDS_CONTROLLER_DPAD_D ); + }; + return L""; +#else + wstring replacement = L""; + + // 4J Stu - Some of our actions can be mapped to multiple physical buttons, so replaces the switch that was here + if (input & _360_JOY_BUTTON_A) replacement = L"ButtonA"; + else if(input &_360_JOY_BUTTON_B) replacement = L"ButtonB"; + else if(input &_360_JOY_BUTTON_X) replacement = L"ButtonX"; + else if(input &_360_JOY_BUTTON_Y) replacement = L"ButtonY"; + else if( + (input &_360_JOY_BUTTON_LSTICK_UP) || + (input &_360_JOY_BUTTON_LSTICK_DOWN) || + (input &_360_JOY_BUTTON_LSTICK_LEFT) || + (input &_360_JOY_BUTTON_LSTICK_RIGHT) + ) + { + replacement = L"ButtonLeftStick"; + } + else if( + (input &_360_JOY_BUTTON_RSTICK_LEFT) || + (input &_360_JOY_BUTTON_RSTICK_RIGHT) || + (input &_360_JOY_BUTTON_RSTICK_UP) || + (input &_360_JOY_BUTTON_RSTICK_DOWN) + ) + { + replacement = L"ButtonRightStick"; + } + else if(input &_360_JOY_BUTTON_DPAD_LEFT) replacement = L"ButtonDpadL"; + else if(input &_360_JOY_BUTTON_DPAD_RIGHT) replacement = L"ButtonDpadR"; + else if(input &_360_JOY_BUTTON_DPAD_UP) replacement = L"ButtonDpadU"; + else if(input &_360_JOY_BUTTON_DPAD_DOWN) replacement = L"ButtonDpadD"; + else if(input &_360_JOY_BUTTON_LT) replacement = L"ButtonLeftTrigger"; + else if(input &_360_JOY_BUTTON_RT) replacement = L"ButtonRightTrigger"; + else if(input &_360_JOY_BUTTON_RB) replacement = L"ButtonRightBumper"; + else if(input &_360_JOY_BUTTON_LB) replacement = L"ButtonLeftBumper"; + else if(input &_360_JOY_BUTTON_BACK) replacement = L"ButtonBack"; + else if(input &_360_JOY_BUTTON_START) replacement = L"ButtonStart"; + else if(input &_360_JOY_BUTTON_RTHUMB) replacement = L"ButtonRS"; + else if(input &_360_JOY_BUTTON_LTHUMB) replacement = L"ButtonLS"; + + wchar_t string[128]; + +#ifdef __PS3__ + int size = 30; +#elif defined _WIN64 + int size = 45; + if(ui.getScreenHeight() < 1080) size = 30; +#else + int size = 45; +#endif + + swprintf(string,128,L"", replacement.c_str(), size, size); + + return string; +#endif +} + +wstring CMinecraftApp::GetVKReplacement(unsigned int uiVKey, bool override) +{ +#ifdef _XBOX + switch(uiVKey) + { + case VK_PAD_A: + return app.GetString( IDS_CONTROLLER_A ); + case VK_PAD_B: + return app.GetString( IDS_CONTROLLER_B ); + case VK_PAD_X: + return app.GetString( IDS_CONTROLLER_X ); + case VK_PAD_Y: + return app.GetString( IDS_CONTROLLER_Y ); + case VK_PAD_LSHOULDER: + return app.GetString( IDS_CONTROLLER_LEFT_BUMPER ); + case VK_PAD_RSHOULDER: + return app.GetString( IDS_CONTROLLER_RIGHT_BUMPER ); + case VK_PAD_LTRIGGER: + return app.GetString( IDS_CONTROLLER_LEFT_TRIGGER ); + case VK_PAD_RTRIGGER: + return app.GetString( IDS_CONTROLLER_RIGHT_TRIGGER ); + case VK_PAD_LTHUMB_UP : + case VK_PAD_LTHUMB_DOWN : + case VK_PAD_LTHUMB_RIGHT : + case VK_PAD_LTHUMB_LEFT : + case VK_PAD_LTHUMB_UPLEFT : + case VK_PAD_LTHUMB_UPRIGHT : + case VK_PAD_LTHUMB_DOWNRIGHT: + case VK_PAD_LTHUMB_DOWNLEFT : + return app.GetString( IDS_CONTROLLER_LEFT_STICK ); + case VK_PAD_RTHUMB_UP : + case VK_PAD_RTHUMB_DOWN : + case VK_PAD_RTHUMB_RIGHT : + case VK_PAD_RTHUMB_LEFT : + case VK_PAD_RTHUMB_UPLEFT : + case VK_PAD_RTHUMB_UPRIGHT : + case VK_PAD_RTHUMB_DOWNRIGHT: + case VK_PAD_RTHUMB_DOWNLEFT : + return app.GetString( IDS_CONTROLLER_RIGHT_STICK ); + default: + break; + } + return nullptr; +#else + wstring replacement = L""; + switch(uiVKey) + { + case VK_PAD_A: +#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) + if( InputManager.IsCircleCrossSwapped() ) replacement = L"ButtonB"; + else replacement = L"ButtonA"; +#else + replacement = L"ButtonA"; +#endif + break; + case VK_PAD_B: +#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) + if( InputManager.IsCircleCrossSwapped() ) replacement = L"ButtonA"; + else replacement = L"ButtonB"; +#else + replacement = L"ButtonB"; +#endif + break; + case VK_PAD_X: + replacement = L"ButtonX"; + break; + case VK_PAD_Y: + replacement = L"ButtonY"; + break; + case VK_PAD_LSHOULDER: + replacement = L"ButtonLeftBumper"; + break; + case VK_PAD_RSHOULDER: + replacement = L"ButtonRightBumper"; + break; + case VK_PAD_LTRIGGER: + replacement = L"ButtonLeftTrigger"; + break; + case VK_PAD_RTRIGGER: + replacement = L"ButtonRightTrigger"; + break; + case VK_PAD_LTHUMB_UP : + case VK_PAD_LTHUMB_DOWN : + case VK_PAD_LTHUMB_RIGHT : + case VK_PAD_LTHUMB_LEFT : + case VK_PAD_LTHUMB_UPLEFT : + case VK_PAD_LTHUMB_UPRIGHT : + case VK_PAD_LTHUMB_DOWNRIGHT: + case VK_PAD_LTHUMB_DOWNLEFT : + replacement = L"ButtonLeftStick"; + break; + case VK_PAD_RTHUMB_UP : + case VK_PAD_RTHUMB_DOWN : + case VK_PAD_RTHUMB_RIGHT : + case VK_PAD_RTHUMB_LEFT : + case VK_PAD_RTHUMB_UPLEFT : + case VK_PAD_RTHUMB_UPRIGHT : + case VK_PAD_RTHUMB_DOWNRIGHT: + case VK_PAD_RTHUMB_DOWNLEFT : + replacement = L"ButtonRightStick"; + break; +#if defined _XBOX_ONE || defined __PSVITA__ + case VK_PAD_START: + replacement = L"ButtonStart"; + break; + case VK_PAD_BACK: + replacement = L"ButtonBack"; + break; +#endif + default: + break; + } + wchar_t string[128]; + +#ifdef __PS3__ + int size = 30; +#elif defined _WIN64 + int size = 45; + if(ui.getScreenHeight() < 1080 || override == true) size = 30; +#else + int size = 45; +#endif + + swprintf(string,128,L"", replacement.c_str(), size, size); + + return string; +#endif +} + +wstring CMinecraftApp::GetIconReplacement(unsigned int uiIcon) +{ +#ifdef _XBOX + switch(uiIcon) + { + case XZP_ICON_SHANK_01: + return app.GetString( IDS_ICON_SHANK_01 ); + case XZP_ICON_SHANK_03: + return app.GetString( IDS_ICON_SHANK_03 ); + default: + break; + } + return nullptr; +#else + wchar_t string[128]; + +#ifdef __PS3__ + int size = 22; +#elif defined _WIN64 + int size = 33; + if(ui.getScreenHeight() < 1080) size = 22; +#else + int size = 33; +#endif + + swprintf(string,128,L"", size, size); + wstring result = L""; + switch(uiIcon) + { + case XZP_ICON_SHANK_01: + result = string; + break; + case XZP_ICON_SHANK_03: + result.append(string).append(string).append(string); + break; + default: + break; + } + return result; +#endif +} + +#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) +unordered_map CMinecraftApp::MojangData; +unordered_map CMinecraftApp::DLCTextures_PackID; +unordered_map CMinecraftApp::DLCInfo; +unordered_map CMinecraftApp::DLCInfo_SkinName; +#elif defined(_DURANGO) +unordered_map CMinecraftApp::MojangData; +unordered_map CMinecraftApp::DLCTextures_PackID; // for mash-up packs & texture packs +//unordered_map CMinecraftApp::DLCInfo_Trial; // full offerid, dlc_info +unordered_map CMinecraftApp::DLCInfo_Full; // full offerid, dlc_info +unordered_map CMinecraftApp::DLCInfo_SkinName; // skin name, full offer id +#else +unordered_map CMinecraftApp::MojangData; +unordered_map CMinecraftApp::DLCTextures_PackID; +unordered_map CMinecraftApp::DLCInfo_Trial; +unordered_map CMinecraftApp::DLCInfo_Full; +unordered_map CMinecraftApp::DLCInfo_SkinName; +#endif + + + +HRESULT CMinecraftApp::RegisterMojangData(WCHAR *pXuidName, PlayerUID xuid, WCHAR *pSkin, WCHAR *pCape) +{ + HRESULT hr=S_OK; + eXUID eTempXuid=eXUID_Undefined; + MOJANG_DATA *pMojangData=nullptr; + + // ignore the names if we don't recognize them + if (pXuidName != nullptr) + { + if( wcscmp( pXuidName, L"XUID_NOTCH" ) == 0 ) + { + eTempXuid = eXUID_Notch; // might be needed for the apple at some point + } + else if( wcscmp( pXuidName, L"XUID_DEADMAU5" ) == 0 ) + { + eTempXuid = eXUID_Deadmau5; // Needed for the deadmau5 ears + } + else + { + eTempXuid=eXUID_NoName; + } + } + + if(eTempXuid!=eXUID_Undefined) + { + pMojangData = new MOJANG_DATA; + ZeroMemory(pMojangData,sizeof(MOJANG_DATA)); + pMojangData->eXuid=eTempXuid; + + wcsncpy( pMojangData->wchSkin, pSkin, MAX_CAPENAME_SIZE); + wcsncpy( pMojangData->wchCape, pCape, MAX_CAPENAME_SIZE); + MojangData[xuid]=pMojangData; + } + + return hr; +} + +MOJANG_DATA *CMinecraftApp::GetMojangDataForXuid(PlayerUID xuid) +{ + return MojangData[xuid]; +} + +HRESULT CMinecraftApp::RegisterConfigValues(WCHAR *pType, int iValue) +{ + HRESULT hr=S_OK; + + // #ifdef _XBOX + // if(pType!=nullptr) + // { + // if(wcscmp(pType,L"XboxOneTransfer")==0) + // { + // if(iValue>0) + // { + // app.m_bTransferSavesToXboxOne=true; + // } + // else + // { + // app.m_bTransferSavesToXboxOne=false; + // } + // } + // else if(wcscmp(pType,L"TransferSlotCount")==0) + // { + // app.m_uiTransferSlotC=iValue; + // } + // + // } + // #endif + + + return hr; +} + +#if (defined _XBOX || defined _WINDOWS64) +HRESULT CMinecraftApp::RegisterDLCData(WCHAR *pType, WCHAR *pBannerName, int iGender, uint64_t ullOfferID_Full, uint64_t ullOfferID_Trial, WCHAR *pFirstSkin, unsigned int uiSortIndex, int iConfig, WCHAR *pDataFile) +{ + HRESULT hr=S_OK; + DLC_INFO *pDLCData=new DLC_INFO; + ZeroMemory(pDLCData,sizeof(DLC_INFO)); + pDLCData->ullOfferID_Full=ullOfferID_Full; + pDLCData->ullOfferID_Trial=ullOfferID_Trial; + pDLCData->eDLCType=e_DLC_NotDefined; + pDLCData->iGender=iGender; + pDLCData->uiSortIndex=uiSortIndex; + pDLCData->iConfig=iConfig; + +#ifndef __ORBIS__ + // ignore the names if we don't recognize them + if(pBannerName!=L"") + { + wcsncpy_s( pDLCData->wchBanner, pBannerName, MAX_BANNERNAME_SIZE); + } + + if(pDataFile[0]!=0) + { + wcsncpy_s( pDLCData->wchDataFile, pDataFile, MAX_BANNERNAME_SIZE); + } +#endif + + if(pType!=nullptr) + { + if(wcscmp(pType,L"Skin")==0) + { + pDLCData->eDLCType=e_DLC_SkinPack; + } + else if(wcscmp(pType,L"Gamerpic")==0) + { + pDLCData->eDLCType=e_DLC_Gamerpics; + } + else if(wcscmp(pType,L"Theme")==0) + { + pDLCData->eDLCType=e_DLC_Themes; + } + else if(wcscmp(pType,L"Avatar")==0) + { + pDLCData->eDLCType=e_DLC_AvatarItems; + } + else if(wcscmp(pType,L"MashUpPack")==0) + { + pDLCData->eDLCType=e_DLC_MashupPacks; + DLCTextures_PackID[pDLCData->iConfig]=ullOfferID_Full; + } + else if(wcscmp(pType,L"TexturePack")==0) + { + pDLCData->eDLCType=e_DLC_TexturePacks; + DLCTextures_PackID[pDLCData->iConfig]=ullOfferID_Full; + } + + + } + + if(ullOfferID_Trial!=0ll) DLCInfo_Trial[ullOfferID_Trial]=pDLCData; + if(ullOfferID_Full!=0ll) DLCInfo_Full[ullOfferID_Full]=pDLCData; + if(pFirstSkin[0]!=0) DLCInfo_SkinName[pFirstSkin]=ullOfferID_Full; + + return hr; +} +#elif defined _XBOX_ONE + +unordered_map *CMinecraftApp::GetDLCInfo() +{ + return &DLCInfo_Full; +} + +HRESULT CMinecraftApp::RegisterDLCData(eDLCContentType eType, WCHAR *pwchBannerName,WCHAR *pwchProductId, WCHAR *pwchProductName, WCHAR *pwchFirstSkin, int iConfig, unsigned int uiSortIndex) +{ + HRESULT hr=S_OK; + // 4J-PB - need to convert the product id to uppercase because the catalog calls come back with upper case + WCHAR wchUppercaseProductID[64]; + if(pwchProductId[0]!=0) + { + for(int i=0;i<64;i++) + { + wchUppercaseProductID[i]=towupper((wchar_t)pwchProductId[i]); + } + } + + // check if we already have this info from the local DLC file + wstring wsTemp=wchUppercaseProductID; + + auto it = DLCInfo_Full.find(wsTemp); + if( it == DLCInfo_Full.end() ) + { + // Not found + + DLC_INFO *pDLCData=new DLC_INFO; + ZeroMemory(pDLCData,sizeof(DLC_INFO)); + + pDLCData->eDLCType=e_DLC_NotDefined; + pDLCData->uiSortIndex=uiSortIndex; + pDLCData->iConfig=iConfig; + + if(pwchProductId[0]!=0) + { + pDLCData->wsProductId=wchUppercaseProductID; + } + + // ignore the names if we don't recognize them + if(pwchBannerName!=L"") + { + wcsncpy_s( pDLCData->wchBanner, pwchBannerName, MAX_BANNERNAME_SIZE); + } + + if(pwchProductName[0]!=0) + { + pDLCData->wsDisplayName=pwchProductName; + } + + pDLCData->eDLCType=eType; + + switch(eType) + { + case e_DLC_MashupPacks: + case e_DLC_TexturePacks: + DLCTextures_PackID[iConfig]=pDLCData->wsProductId; + break; + } + + if(pwchFirstSkin[0]!=0) DLCInfo_SkinName[pwchFirstSkin]=pDLCData->wsProductId; + +#ifdef _XBOX_ONE + // ignore the names, and use the product id instead + DLCInfo_Full[pDLCData->wsProductId]=pDLCData; +#else + DLCInfo_Full[pDLCData->wsDisplayName]=pDLCData; +#endif + } + app.DebugPrintf("DLCInfo - type - %d, productID - %ls, name - %ls , banner - %ls, iconfig - %d, sort index - %d\n",eType,pwchProductId, pwchProductName,pwchBannerName, iConfig, uiSortIndex); + return hr; +} +#else + +HRESULT CMinecraftApp::RegisterDLCData(char *pchDLCName, unsigned int uiSortIndex,char *pchImageURL) +{ + // on PS3 we get all the required info from the name + char chDLCType[3]; + HRESULT hr=S_OK; + DLC_INFO *pDLCData=new DLC_INFO; + ZeroMemory(pDLCData,sizeof(DLC_INFO)); + + chDLCType[0]=pchDLCName[0]; + chDLCType[1]=pchDLCName[1]; + chDLCType[2]=0; + + pDLCData->iConfig = app.GetiConfigFromName(pchDLCName); + pDLCData->uiSortIndex=uiSortIndex; + pDLCData->eDLCType = app.GetDLCTypeFromName(pchDLCName); + strcpy(pDLCData->chImageURL,pchImageURL); + //bool bIsTrialDLC = app.GetTrialFromName(pchDLCName); + + switch(pDLCData->eDLCType) + { + case e_DLC_TexturePacks: + { + char *pchName=(char *)malloc(strlen(pchDLCName)+1); + strcpy(pchName,pchDLCName); + DLCTextures_PackID[pDLCData->iConfig]=pchName; + } + break; + case e_DLC_MashupPacks: + { + char *pchName=(char *)malloc(strlen(pchDLCName)+1); + strcpy(pchName,pchDLCName); + DLCTextures_PackID[pDLCData->iConfig]=pchName; + } + break; + default: + break; + } + + app.DebugPrintf(5,"Adding DLC - %s\n",pchDLCName); + DLCInfo[pchDLCName]=pDLCData; + + // if(ullOfferID_Trial!=0ll) DLCInfo_Trial[ullOfferID_Trial]=pDLCData; + // if(ullOfferID_Full!=0ll) DLCInfo_Full[ullOfferID_Full]=pDLCData; + // if(pFirstSkin[0]!=0) DLCInfo_SkinName[pFirstSkin]=ullOfferID_Full; + + // DLCInfo[ullOfferID_Trial]=pDLCData; + + return hr; +} +#endif + + + +#if defined( __PS3__) || defined(__ORBIS__) || defined(__PSVITA__) +bool CMinecraftApp::GetDLCFullOfferIDForSkinID(const wstring &FirstSkin,ULONGLONG *pullVal) +{ + auto it = DLCInfo_SkinName.find(FirstSkin); + if( it == DLCInfo_SkinName.end() ) + { + return false; + } + else + { + *pullVal=(ULONGLONG)it->second; + return true; + } +} +bool CMinecraftApp::GetDLCNameForPackID(const int iPackID,char **ppchKeyID) +{ + auto it = DLCTextures_PackID.find(iPackID); + if( it == DLCTextures_PackID.end() ) + { + *ppchKeyID=nullptr; + return false; + } + else + { + *ppchKeyID=(char *)it->second; + return true; + } +} +DLC_INFO *CMinecraftApp::GetDLCInfo(char *pchDLCName) +{ + string tempString=pchDLCName; + + if(DLCInfo.size()>0) + { + auto it = DLCInfo.find(tempString); + + if( it == DLCInfo.end() ) + { + // nothing for this + return nullptr; + } + else + { + return it->second; + } + } + else return nullptr; +} + +DLC_INFO *CMinecraftApp::GetDLCInfoFromTPackID(int iTPID) +{ + unordered_map::iterator it= DLCInfo.begin(); + + for(size_t i=0;isecond)->iConfig==iTPID) + { + return it->second; + } + ++it; + } + return nullptr; +} + +DLC_INFO *CMinecraftApp::GetDLCInfo(int iIndex) +{ + unordered_map::iterator it= DLCInfo.begin(); + + for(int i=0;isecond; +} + +char *CMinecraftApp::GetDLCInfoTextures(int iIndex) +{ + unordered_map::iterator it= DLCTextures_PackID.begin(); + + for(int i=0;isecond; +} + +#elif defined _XBOX_ONE +bool CMinecraftApp::GetDLCFullOfferIDForSkinID(const wstring &FirstSkin,wstring &ProductId) +{ + auto it = DLCInfo_SkinName.find(FirstSkin); + if( it == DLCInfo_SkinName.end() ) + { + return false; + } + else + { + ProductId=it->second; + return true; + } +} +bool CMinecraftApp::GetDLCFullOfferIDForPackID(const int iPackID,wstring &ProductId) +{ + auto it = DLCTextures_PackID.find(iPackID); + if( it == DLCTextures_PackID.end() ) + { + return false; + } + else + { + ProductId=it->second; + return true; + } +} +// DLC_INFO *CMinecraftApp::GetDLCInfoForTrialOfferID(wstring &ProductId) +// { +// return nullptr; +// } + +DLC_INFO *CMinecraftApp::GetDLCInfoTrialOffer(int iIndex) +{ + return nullptr; +} +DLC_INFO *CMinecraftApp::GetDLCInfoFullOffer(int iIndex) +{ + unordered_map::iterator it= DLCInfo_Full.begin(); + + for(int i=0;isecond; +} +wstring CMinecraftApp::GetDLCInfoTexturesFullOffer(int iIndex) +{ + unordered_map::iterator it= DLCTextures_PackID.begin(); + + for(int i=0;isecond; +} +#else +bool CMinecraftApp::GetDLCFullOfferIDForSkinID(const wstring &FirstSkin,ULONGLONG *pullVal) +{ + auto it = DLCInfo_SkinName.find(FirstSkin); + if( it == DLCInfo_SkinName.end() ) + { + return false; + } + else + { + *pullVal=(ULONGLONG)it->second; + return true; + } +} +bool CMinecraftApp::GetDLCFullOfferIDForPackID(const int iPackID,ULONGLONG *pullVal) +{ + auto it = DLCTextures_PackID.find(iPackID); + if( it == DLCTextures_PackID.end() ) + { + *pullVal=0ULL; + return false; + } + else + { + *pullVal=it->second; + return true; + } +} +DLC_INFO *CMinecraftApp::GetDLCInfoForTrialOfferID(ULONGLONG ullOfferID_Trial) +{ + //DLC_INFO *pDLCInfo=nullptr; + if(DLCInfo_Trial.size()>0) + { + auto it = DLCInfo_Trial.find(ullOfferID_Trial); + + if( it == DLCInfo_Trial.end() ) + { + // nothing for this + return nullptr; + } + else + { + return it->second; + } + } + else return nullptr; +} + +DLC_INFO *CMinecraftApp::GetDLCInfoTrialOffer(int iIndex) +{ + unordered_map::iterator it= DLCInfo_Trial.begin(); + + for(int i=0;isecond; +} +DLC_INFO *CMinecraftApp::GetDLCInfoFullOffer(int iIndex) +{ + unordered_map::iterator it= DLCInfo_Full.begin(); + + for(int i=0;isecond; +} +ULONGLONG CMinecraftApp::GetDLCInfoTexturesFullOffer(int iIndex) +{ + unordered_map::iterator it= DLCTextures_PackID.begin(); + + for(int i=0;isecond; +} +#endif + +#ifdef _XBOX_ONE + +DLC_INFO *CMinecraftApp::GetDLCInfoForFullOfferID(WCHAR *pwchProductID) +{ + wstring wsTemp = pwchProductID; + if(DLCInfo_Full.size()>0) + { + auto it = DLCInfo_Full.find(wsTemp); + + if( it == DLCInfo_Full.end() ) + { + // nothing for this + return nullptr; + } + else + { + return it->second; + } + } + else return nullptr; +} +DLC_INFO *CMinecraftApp::GetDLCInfoForProductName(WCHAR *pwchProductName) +{ + unordered_map::iterator it= DLCInfo_Full.begin(); + wstring wsProductName=pwchProductName; + + for(size_t i=0;isecond; + if(wsProductName==pDLCInfo->wsDisplayName) + { + return pDLCInfo; + } + ++it; + } + + return nullptr; +} + +#elif defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) +#else + +DLC_INFO *CMinecraftApp::GetDLCInfoForFullOfferID(ULONGLONG ullOfferID_Full) +{ + + if(DLCInfo_Full.size()>0) + { + auto it = DLCInfo_Full.find(ullOfferID_Full); + + if( it == DLCInfo_Full.end() ) + { + // nothing for this + return nullptr; + } + else + { + return it->second; + } + } + else return nullptr; +} +#endif + +void CMinecraftApp::EnterSaveNotificationSection() +{ + EnterCriticalSection(&m_saveNotificationCriticalSection); + if( m_saveNotificationDepth++ == 0 ) + { + if(g_NetworkManager.IsInSession()) // this can be triggered from the front end if we're downloading a save + { + MinecraftServer::getInstance()->broadcastStartSavingPacket(); + + if( g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 ) + { + app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)TRUE); + } + } + } + LeaveCriticalSection(&m_saveNotificationCriticalSection); +} + +void CMinecraftApp::LeaveSaveNotificationSection() +{ + EnterCriticalSection(&m_saveNotificationCriticalSection); + if( --m_saveNotificationDepth == 0 ) + { + if(g_NetworkManager.IsInSession()) // this can be triggered from the front end if we're downloading a save + { + MinecraftServer::getInstance()->broadcastStopSavingPacket(); + + if( g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 ) + { + app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)FALSE); + } + } + } + LeaveCriticalSection(&m_saveNotificationCriticalSection); +} + + +int CMinecraftApp::RemoteSaveThreadProc( void* lpParameter ) +{ + // The game should be stopped while we are doing this, but the connections ticks may try to create some AABB's or Vec3's + AABB::UseDefaultThreadStorage(); + Vec3::UseDefaultThreadStorage(); + Compression::UseDefaultThreadStorage(); + + // 4J-PB - Xbox 360 - 163153 - [CRASH] TU17: Code: Multiplayer: During the Autosave in an online Multiplayer session, the game occasionally crashes for one or more Clients + // callstack - > if(tls->tileId != this->id) updateDefaultShape(); + // callstack - > default.exe!WaterlilyTile::getAABB(Level * level, int x, int y, int z) line 38 + 8 bytes C++ + // ... + // default.exe!CMinecraftApp::RemoteSaveThreadProc(void * lpParameter) line 6694 C++ + // host autosave, and the clients can crash on receiving handleMoveEntity when it's a tile within this thread, so need to do the tls for tiles + Tile::CreateNewThreadStorage(); + + Minecraft *pMinecraft = Minecraft::GetInstance(); + + pMinecraft->progressRenderer->progressStartNoAbort( IDS_PROGRESS_HOST_SAVING ); + pMinecraft->progressRenderer->progressStage( -1 ); + pMinecraft->progressRenderer->progressStagePercentage(0); + + while( !app.GetGameStarted() && app.GetXuiAction( ProfileManager.GetPrimaryPad() ) == eAppAction_WaitRemoteServerSaveComplete ) + { + // Tick all the games connections + pMinecraft->tickAllConnections(); + Sleep( 100 ); + } + + if( app.GetXuiAction( ProfileManager.GetPrimaryPad() ) != eAppAction_WaitRemoteServerSaveComplete ) + { + // Something cancelled us? + return ERROR_CANCELLED; + } + app.SetAction(ProfileManager.GetPrimaryPad(),eAppAction_Idle); + + ui.UpdatePlayerBasePositions(); + + Tile::ReleaseThreadStorage(); + + return S_OK; +} + +void CMinecraftApp::ExitGameFromRemoteSave( LPVOID lpParameter ) +{ + int primaryPad = ProfileManager.GetPrimaryPad(); + + UINT uiIDA[3]; + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_CONFIRM_OK; + + ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 2, primaryPad,&CMinecraftApp::ExitGameFromRemoteSaveDialogReturned,nullptr); +} + +int CMinecraftApp::ExitGameFromRemoteSaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + //CScene_Pause* pClass = (CScene_Pause*)pParam; + + // results switched for this dialog + if(result==C4JStorage::EMessage_ResultDecline) + { + app.SetAction(iPad,eAppAction_ExitWorld); + } + else + { +#ifndef _XBOX + // Inform fullscreen progress scene that it's not being cancelled after all + UIScene_FullscreenProgress *pScene = static_cast(ui.FindScene(eUIScene_FullscreenProgress)); +#ifdef __PS3__ + if(pScene!=nullptr) +#else + if (pScene != nullptr) +#endif + { + pScene->SetWasCancelled(false); + } +#else + // Don't have to worry about this on Xbox +#endif + } + return 0; +} + +void CMinecraftApp::SetSpecialTutorialCompletionFlag(int iPad, int index) +{ + if(index >= 0 && index < 32 && GameSettingsA[iPad] != nullptr) + { + GameSettingsA[iPad]->uiSpecialTutorialBitmask |= (1<clear(); + + if(BannedListA[iPad].pBannedList) + { + delete [] BannedListA[iPad].pBannedList; + BannedListA[iPad].pBannedList=nullptr; + } + } +} + +#ifdef _XBOX_ONE +void CMinecraftApp::AddLevelToBannedLevelList(int iPad, PBANNEDLISTDATA pBannedListData, bool bWriteToTMS) +{ + PlayerUID xuid= pBannedListData->wchPlayerUID; + + AddLevelToBannedLevelList(iPad,xuid,pBannedListData->pszLevelName,bWriteToTMS); +} +#endif + +void CMinecraftApp::AddLevelToBannedLevelList(int iPad, PlayerUID xuid, char *pszLevelName, bool bWriteToTMS) +{ + // we will have retrieved the banned level list from TMS, so add this one to it and write it back to TMS + + BANNEDLISTDATA *pBannedListData = new BANNEDLISTDATA; + memset(pBannedListData,0,sizeof(BANNEDLISTDATA)); + +#ifdef _DURANGO + memcpy(&pBannedListData->wchPlayerUID, xuid.toString().c_str(), sizeof(WCHAR)*64); +#else + memcpy(&pBannedListData->xuid, &xuid, sizeof(PlayerUID)); +#endif + strcpy(pBannedListData->pszLevelName,pszLevelName); + m_vBannedListA[iPad]->push_back(pBannedListData); + + if (bWriteToTMS) + { + DWORD dwDataBytes = static_cast(sizeof(BANNEDLISTDATA)* m_vBannedListA[iPad]->size()); + PBANNEDLISTDATA pBannedList = reinterpret_cast(new CHAR [dwDataBytes]); + int iCount=0; + for (PBANNEDLISTDATA pData : *m_vBannedListA[iPad] ) + { + memcpy(&pBannedList[iCount++],pData,sizeof(BANNEDLISTDATA)); + } + + // 4J-PB - write to TMS++ now + + //bool bRes=StorageManager.WriteTMSFile(iPad,C4JStorage::eGlobalStorage_TitleUser,L"BannedList",(PBYTE)pBannedList, dwDataBytes); +#ifdef _XBOX + StorageManager.TMSPP_WriteFile(iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,C4JStorage::TMS_UGCTYPE_NONE,"BannedList",(PCHAR) pBannedList, dwDataBytes,nullptr,nullptr, 0); +#elif defined _XBOX_ONE + StorageManager.TMSPP_WriteFile(iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,L"BannedList",(PBYTE) pBannedList, dwDataBytes,nullptr,nullptr, 0); +#endif + } + // update telemetry too +} + +bool CMinecraftApp::IsInBannedLevelList(int iPad, PlayerUID xuid, char *pszLevelName) +{ + for( PBANNEDLISTDATA pData : *m_vBannedListA[iPad] ) + { +#ifdef _XBOX_ONE + PlayerUID bannedPlayerUID = pData->wchPlayerUID; + if(IsEqualXUID (bannedPlayerUID,xuid) && (strcmp(pData->pszLevelName,pszLevelName)==0)) +#else + if(IsEqualXUID (pData->xuid,xuid) && (strcmp(pData->pszLevelName,pszLevelName)==0)) +#endif + { + return true; + } + } + + return false; +} + +void CMinecraftApp::RemoveLevelFromBannedLevelList(int iPad, PlayerUID xuid, char *pszLevelName) +{ + //bool bFound=false; + //bool bRes; + + // we will have retrieved the banned level list from TMS, so remove this one from it and write it back to TMS + for (auto it = m_vBannedListA[iPad]->begin(); it != m_vBannedListA[iPad]->end(); ) + { + PBANNEDLISTDATA pBannedListData = *it; + + if(pBannedListData!=nullptr) + { +#ifdef _XBOX_ONE + PlayerUID bannedPlayerUID = pBannedListData->wchPlayerUID; + if(IsEqualXUID (bannedPlayerUID,xuid) && (strcmp(pBannedListData->pszLevelName,pszLevelName)==0)) +#else + if(IsEqualXUID (pBannedListData->xuid,xuid) && (strcmp(pBannedListData->pszLevelName,pszLevelName)==0)) +#endif + { + TelemetryManager->RecordUnBanLevel(iPad); + + // match found, so remove this entry + it = m_vBannedListA[iPad]->erase(it); + } + else + { + ++it; + } + } + else + { + ++it; + } + } + + DWORD dwDataBytes=static_cast(sizeof(BANNEDLISTDATA) * m_vBannedListA[iPad]->size()); + if(dwDataBytes==0) + { + // wipe the file +#ifdef _XBOX + StorageManager.DeleteTMSFile(iPad,C4JStorage::eGlobalStorage_TitleUser,L"BannedList"); +#elif defined _XBOX_ONE + StorageManager.TMSPP_DeleteFile(iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,L"BannedList",nullptr,nullptr, 0); +#endif + } + else + { + PBANNEDLISTDATA pBannedList = (BANNEDLISTDATA *)(new BYTE [dwDataBytes]); + + size_t iSize=m_vBannedListA[iPad]->size(); + for(size_t i=0;iat(i); + + memcpy(&pBannedList[i],pBannedListData,sizeof(BANNEDLISTDATA)); + } +#ifdef _XBOX + StorageManager.WriteTMSFile(iPad,C4JStorage::eGlobalStorage_TitleUser,L"BannedList",(PBYTE)pBannedList, dwDataBytes); +#elif defined _XBOX_ONE + StorageManager.TMSPP_WriteFile(iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,L"BannedList",(PBYTE) pBannedList, dwDataBytes,nullptr,nullptr, 0); +#endif + delete [] pBannedList; + } + + // update telemetry too +} + +// function to add credits for the DLC packs +void CMinecraftApp::AddCreditText(LPCWSTR lpStr) +{ + DebugPrintf("ADDING CREDIT - %ls\n",lpStr); + // add a string from the DLC to a credits vector + SCreditTextItemDef *pCreditStruct = new SCreditTextItemDef; + pCreditStruct->m_eType=eSmallText; + pCreditStruct->m_iStringID[0]=NO_TRANSLATED_STRING; + pCreditStruct->m_iStringID[1]=NO_TRANSLATED_STRING; + pCreditStruct->m_Text=new WCHAR [wcslen(lpStr)+1]; + wcscpy((WCHAR *)pCreditStruct->m_Text,lpStr); + + vDLCCredits.push_back(pCreditStruct); +} + +bool CMinecraftApp::AlreadySeenCreditText(const wstring &wstemp) +{ + + for(unsigned int i=0;i(vDLCCredits.size()); +} + +SCreditTextItemDef * CMinecraftApp::GetDLCCredits(int iIndex) +{ + return vDLCCredits.at(iIndex); +} + +// Game Host options + +void CMinecraftApp::SetGameHostOption(eGameHostOption eVal,unsigned int uiVal) +{ + SetGameHostOption(m_uiGameHostSettings,eVal,uiVal); +} + + +void CMinecraftApp::SetGameHostOption(unsigned int &uiHostSettings, eGameHostOption eVal, unsigned int uiVal) +{ + switch(eVal) + { + case eGameHostOption_FriendsOfFriends: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_FRIENDSOFFRIENDS; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_FRIENDSOFFRIENDS; + } + break; + case eGameHostOption_Difficulty: + // clear the difficulty first + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_DIFFICULTY; + uiHostSettings|=(GAME_HOST_OPTION_BITMASK_DIFFICULTY&uiVal); + break; + case eGameHostOption_Gamertags: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_GAMERTAGS; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_GAMERTAGS; + } + + break; + case eGameHostOption_GameType: + // clear the game type first + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_GAMETYPE; + uiHostSettings|=(GAME_HOST_OPTION_BITMASK_GAMETYPE&(uiVal<<4)); + break; + case eGameHostOption_LevelType: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_LEVELTYPE; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_LEVELTYPE; + } + + break; + case eGameHostOption_Structures: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_STRUCTURES; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_STRUCTURES; + } + + break; + case eGameHostOption_BonusChest: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_BONUSCHEST; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_BONUSCHEST; + } + + break; + case eGameHostOption_HasBeenInCreative: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_BEENINCREATIVE; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_BEENINCREATIVE; + } + + break; + case eGameHostOption_PvP: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_PVP; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_PVP; + } + + break; + case eGameHostOption_TrustPlayers: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_TRUSTPLAYERS; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_TRUSTPLAYERS; + } + + break; + case eGameHostOption_TNT: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_TNT; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_TNT; + } + + break; + case eGameHostOption_FireSpreads: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_FIRESPREADS; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_FIRESPREADS; + } + break; + case eGameHostOption_CheatsEnabled: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTFLY; + uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTHUNGER; + uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTFLY; + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTHUNGER; + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE; + } + break; + case eGameHostOption_HostCanFly: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTFLY; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTFLY; + } + break; + case eGameHostOption_HostCanChangeHunger: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTHUNGER; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTHUNGER; + } + break; + case eGameHostOption_HostCanBeInvisible: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE; + } + break; + + case eGameHostOption_BedrockFog: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_BEDROCKFOG; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_BEDROCKFOG; + } + break; + case eGameHostOption_DisableSaving: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_DISABLESAVE; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_DISABLESAVE; + } + break; + case eGameHostOption_WasntSaveOwner: + if(uiVal!=0) + { + uiHostSettings|=GAME_HOST_OPTION_BITMASK_NOTOWNER; + } + else + { + // off + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_NOTOWNER; + } + break; + case eGameHostOption_MobGriefing: + if(uiVal!=1) + { + uiHostSettings |= GAME_HOST_OPTION_BITMASK_MOBGRIEFING; + } + else + { + // off + uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_MOBGRIEFING; + } + break; + case eGameHostOption_KeepInventory: + if(uiVal!=0) + { + uiHostSettings |= GAME_HOST_OPTION_BITMASK_KEEPINVENTORY; + } + else + { + // off + uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_KEEPINVENTORY; + } + break; + case eGameHostOption_DoMobSpawning: + if(uiVal!=1) + { + uiHostSettings |= GAME_HOST_OPTION_BITMASK_DOMOBSPAWNING; + } + else + { + // off + uiHostSettings &=~ GAME_HOST_OPTION_BITMASK_DOMOBSPAWNING; + } + break; + case eGameHostOption_DoMobLoot: + if(uiVal!=1) + { + uiHostSettings |= GAME_HOST_OPTION_BITMASK_DOMOBLOOT; + } + else + { + // off + uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_DOMOBLOOT; + } + break; + case eGameHostOption_DoTileDrops: + if(uiVal!=1) + { + uiHostSettings |= GAME_HOST_OPTION_BITMASK_DOTILEDROPS; + } + else + { + // off + uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_DOTILEDROPS; + } + break; + case eGameHostOption_NaturalRegeneration: + if(uiVal!=1) + { + uiHostSettings |= GAME_HOST_OPTION_BITMASK_NATURALREGEN; + } + else + { + // off + uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_NATURALREGEN; + } + break; + case eGameHostOption_DoDaylightCycle: + if(uiVal!=1) + { + uiHostSettings |= GAME_HOST_OPTION_BITMASK_DODAYLIGHTCYCLE; + } + else + { + // off + uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_DODAYLIGHTCYCLE; + } + break; + case eGameHostOption_WorldSize: + // clear the difficulty first + uiHostSettings&=~GAME_HOST_OPTION_BITMASK_WORLDSIZE; + uiHostSettings|=(GAME_HOST_OPTION_BITMASK_WORLDSIZE & (uiVal<>4; + break; + case eGameHostOption_All: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_ALL); + break; + case eGameHostOption_Tutorial: + // special case - tutorial is offline, but we want the gamertag option, and set Easy mode, structures on, fire on, tnt on, pvp on, trust players on + return ((uiHostSettings&GAME_HOST_OPTION_BITMASK_GAMERTAGS)| + GAME_HOST_OPTION_BITMASK_TRUSTPLAYERS| + GAME_HOST_OPTION_BITMASK_FIRESPREADS| + GAME_HOST_OPTION_BITMASK_TNT| + GAME_HOST_OPTION_BITMASK_PVP| + GAME_HOST_OPTION_BITMASK_STRUCTURES|1); + break; + case eGameHostOption_LevelType: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_LEVELTYPE); + break; + case eGameHostOption_Structures: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_STRUCTURES); + break; + case eGameHostOption_BonusChest: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_BONUSCHEST); + break; + case eGameHostOption_HasBeenInCreative: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_BEENINCREATIVE); + break; + case eGameHostOption_PvP: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_PVP); + break; + case eGameHostOption_TrustPlayers: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_TRUSTPLAYERS); + break; + case eGameHostOption_TNT: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_TNT); + break; + case eGameHostOption_FireSpreads: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_FIRESPREADS); + break; + case eGameHostOption_CheatsEnabled: + return (uiHostSettings&(GAME_HOST_OPTION_BITMASK_HOSTFLY|GAME_HOST_OPTION_BITMASK_HOSTHUNGER|GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE)); + break; + case eGameHostOption_HostCanFly: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_HOSTFLY); + break; + case eGameHostOption_HostCanChangeHunger: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_HOSTHUNGER); + break; + case eGameHostOption_HostCanBeInvisible: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE); + break; + case eGameHostOption_BedrockFog: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_BEDROCKFOG); + break; + case eGameHostOption_DisableSaving: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_DISABLESAVE); + break; + case eGameHostOption_WasntSaveOwner: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_NOTOWNER); + case eGameHostOption_WorldSize: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_WORLDSIZE) >> GAME_HOST_OPTION_BITMASK_WORLDSIZE_BITSHIFT; + case eGameHostOption_MobGriefing: + return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_MOBGRIEFING); + case eGameHostOption_KeepInventory: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_KEEPINVENTORY); + case eGameHostOption_DoMobSpawning: + return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DOMOBSPAWNING); + case eGameHostOption_DoMobLoot: + return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DOMOBLOOT); + case eGameHostOption_DoTileDrops: + return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DOTILEDROPS); + case eGameHostOption_NaturalRegeneration: + return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_NATURALREGEN); + case eGameHostOption_DoDaylightCycle: + return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DODAYLIGHTCYCLE); + break; + case eGameHostOption_Hardcore: // 4J Added - for hardcore mode + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_HARDCORE) ? 1 : 0; + break; + } + + return false; +} + +bool CMinecraftApp::CanRecordStatsAndAchievements() +{ + bool isTutorial = Minecraft::GetInstance() != nullptr && Minecraft::GetInstance()->isTutorial(); + // 4J Stu - All of these options give the host player some advantage, so should not allow achievements + return !(app.GetGameHostOption(eGameHostOption_HasBeenInCreative) || + app.GetGameHostOption(eGameHostOption_HostCanBeInvisible) || + app.GetGameHostOption(eGameHostOption_HostCanChangeHunger) || + app.GetGameHostOption(eGameHostOption_HostCanFly) || + app.GetGameHostOption(eGameHostOption_WasntSaveOwner) || + !app.GetGameHostOption(eGameHostOption_MobGriefing) || + app.GetGameHostOption(eGameHostOption_KeepInventory) || + !app.GetGameHostOption(eGameHostOption_DoMobSpawning) || + (!app.GetGameHostOption(eGameHostOption_DoDaylightCycle) && !isTutorial ) + ); +} + +void CMinecraftApp::processSchematics(LevelChunk *levelChunk) +{ + m_gameRules.processSchematics(levelChunk); +} + +void CMinecraftApp::processSchematicsLighting(LevelChunk *levelChunk) +{ + m_gameRules.processSchematicsLighting(levelChunk); +} + +void CMinecraftApp::loadDefaultGameRules() +{ + m_gameRules.loadDefaultGameRules(); +} + +void CMinecraftApp::setLevelGenerationOptions(LevelGenerationOptions *levelGen) +{ + m_gameRules.setLevelGenerationOptions(levelGen); +} + +LPCWSTR CMinecraftApp::GetGameRulesString(const wstring &key) +{ + return m_gameRules.GetGameRulesString(key); +} + +unsigned char CMinecraftApp::m_szPNG[8]= +{ + 137,80,78,71,13,10,26,10 +}; + +#define PNG_TAG_tEXt 0x74455874 + +unsigned int CMinecraftApp::FromBigEndian(unsigned int uiValue) +{ +#if defined(__PS3__) || defined(_XBOX) + // Keep it in big endian + return uiValue; +#else + unsigned int uiReturn = ( ( uiValue >> 24 ) & 0x000000ff ) | + ( ( uiValue >> 8 ) & 0x0000ff00 ) | + ( ( uiValue << 8 ) & 0x00ff0000 ) | + ( ( uiValue << 24 ) & 0xff000000 ); + return uiReturn; +#endif +} + +void CMinecraftApp::GetImageTextData(PBYTE pbImageData, DWORD dwImageBytes,unsigned char *pszSeed,unsigned int &uiHostOptions,bool &bHostOptionsRead,DWORD &uiTexturePack) +{ + unsigned char *ucPtr=pbImageData; + unsigned int uiCount=0; + unsigned int uiChunkLen; + unsigned int uiChunkType; + unsigned int uiCRC; + char szKeyword[80]; + + // check it's a png + for(int i=0;i<8;i++) + { + if(m_szPNG[i]!=ucPtr[i]) return; + } + + uiCount+=8; + + while(uiCount> std::hex >> uiHostOptions; + } + else if(strcmp(szKeyword,"4J_TEXTUREPACK")==0) + { + // read the texture pack value + unsigned int uiValueC=0; + unsigned char pszTexturePack[9]; // Hex representation of unsigned int + ZeroMemory(&pszTexturePack,9); + while(*pszKeyword!=0 && (pszKeyword < ucPtr + uiCount + uiChunkLen) && uiValueC < 8) + { + pszTexturePack[uiValueC++]=*pszKeyword; + pszKeyword++; + } + + std::stringstream ss; + ss << pszTexturePack; + ss >> std::hex >> uiTexturePack; + } + } + } + uiCount+=uiChunkLen; + uiCRC=*(unsigned int*)&ucPtr[uiCount]; + uiCRC=FromBigEndian(uiCRC); + uiCount+=sizeof(int); + } + + return; +} + +unsigned int CMinecraftApp::CreateImageTextData(PBYTE bTextMetadata, int64_t seed, bool hasSeed, unsigned int uiHostOptions, unsigned int uiTexturePackId) +{ + int iTextMetadataBytes = 0; + if(hasSeed) + { + strcpy((char *)bTextMetadata,"4J_SEED"); + _i64toa_s(seed,(char *)&bTextMetadata[8],42,10); + + // get the length + iTextMetadataBytes+=8; + while(bTextMetadata[iTextMetadataBytes]!=0) iTextMetadataBytes++; + ++iTextMetadataBytes; // Add a null terminator at the end of the seed value + } + + // Save the host options that this world was last played with + strcpy((char *)&bTextMetadata[iTextMetadataBytes],"4J_HOSTOPTIONS"); + _itoa_s(uiHostOptions,(char *)&bTextMetadata[iTextMetadataBytes+15],9,16); + + iTextMetadataBytes += 15; + while(bTextMetadata[iTextMetadataBytes]!=0) iTextMetadataBytes++; + ++iTextMetadataBytes; // Add a null terminator at the end of the host options value + + // Save the texture pack id + strcpy((char *)&bTextMetadata[iTextMetadataBytes],"4J_TEXTUREPACK"); + _itoa_s(uiTexturePackId,(char *)&bTextMetadata[iTextMetadataBytes+15],9,16); + + iTextMetadataBytes += 15; + while(bTextMetadata[iTextMetadataBytes]!=0) iTextMetadataBytes++; + + return iTextMetadataBytes; +} + +void CMinecraftApp::AddTerrainFeaturePosition(_eTerrainFeatureType eFeatureType,int x,int z) +{ + // check we don't already have this in + for( FEATURE_DATA *pFeatureData : m_vTerrainFeatures ) + { + if((pFeatureData->eTerrainFeature==eFeatureType) &&(pFeatureData->x==x) && (pFeatureData->z==z)) return; + } + + FEATURE_DATA *pFeatureData= new FEATURE_DATA; + pFeatureData->eTerrainFeature=eFeatureType; + pFeatureData->x=x; + pFeatureData->z=z; + + m_vTerrainFeatures.push_back(pFeatureData); +} + +_eTerrainFeatureType CMinecraftApp::IsTerrainFeature(int x,int z) +{ + for(FEATURE_DATA *pFeatureData : m_vTerrainFeatures ) + { + if((pFeatureData->x==x) && (pFeatureData->z==z)) return pFeatureData->eTerrainFeature; + } + + return eTerrainFeature_None; +} + +bool CMinecraftApp::GetTerrainFeaturePosition(_eTerrainFeatureType eType,int *pX, int *pZ) +{ + for ( const FEATURE_DATA *pFeatureData : m_vTerrainFeatures ) + { + if(pFeatureData->eTerrainFeature==eType) + { + *pX=pFeatureData->x; + *pZ=pFeatureData->z; + return true; + } + } + + return false; +} + +void CMinecraftApp::ClearTerrainFeaturePosition() +{ + FEATURE_DATA *pFeatureData; + while(m_vTerrainFeatures.size()>0) + { + pFeatureData = m_vTerrainFeatures.back(); + m_vTerrainFeatures.pop_back(); + delete pFeatureData; + } +} + +void CMinecraftApp::UpdatePlayerInfo(BYTE networkSmallId, SHORT playerColourIndex, unsigned int playerGamePrivileges) +{ + for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) + { + if(m_playerColours[i]==networkSmallId) + { + m_playerColours[i] = 0; + m_playerGamePrivileges[i] = 0; + } + } + if(playerColourIndex >=0 && playerColourIndex < MINECRAFT_NET_MAX_PLAYERS) + { + m_playerColours[playerColourIndex] = networkSmallId; + m_playerGamePrivileges[playerColourIndex] = playerGamePrivileges; + } +} + +short CMinecraftApp::GetPlayerColour(BYTE networkSmallId) +{ + short index = -1; + for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) + { + if(m_playerColours[i]==networkSmallId) + { + index = i; + break; + } + } + return index; +} + +void CMinecraftApp::SetPlayerMapIcon(const wchar_t* name, char icon) +{ + if (name == nullptr) return; + // Update existing entry or use first empty slot + int emptySlot = -1; + for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) + { + if (m_playerMapIcons[i].name[0] != 0 && _wcsicmp(m_playerMapIcons[i].name, name) == 0) + { + m_playerMapIcons[i].icon = icon; + return; + } + if (emptySlot < 0 && m_playerMapIcons[i].name[0] == 0) + emptySlot = i; + } + if (emptySlot >= 0) + { + wcsncpy_s(m_playerMapIcons[emptySlot].name, 32, name, _TRUNCATE); + m_playerMapIcons[emptySlot].icon = icon; + } +} + +char CMinecraftApp::GetPlayerMapIconByName(const wchar_t* name) +{ + if (name == nullptr) return 0; + for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) + { + if (m_playerMapIcons[i].name[0] != 0 && _wcsicmp(m_playerMapIcons[i].name, name) == 0) + return m_playerMapIcons[i].icon; + } + return 0; +} + + +unsigned int CMinecraftApp::GetPlayerPrivileges(BYTE networkSmallId) +{ + unsigned int privileges = 0; + for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) + { + if(m_playerColours[i]==networkSmallId) + { + privileges = m_playerGamePrivileges[i]; + break; + } + } + return privileges; +} + +wstring CMinecraftApp::getEntityName(eINSTANCEOF type) +{ + switch(type) + { + case eTYPE_WOLF: + return app.GetString(IDS_WOLF); + case eTYPE_CREEPER: + return app.GetString(IDS_CREEPER); + case eTYPE_SKELETON: + return app.GetString(IDS_SKELETON); + case eTYPE_SPIDER: + return app.GetString(IDS_SPIDER); + case eTYPE_ZOMBIE: + return app.GetString(IDS_ZOMBIE); + case eTYPE_PIGZOMBIE: + return app.GetString(IDS_PIGZOMBIE); + case eTYPE_ENDERMAN: + return app.GetString(IDS_ENDERMAN); + case eTYPE_SILVERFISH: + return app.GetString(IDS_SILVERFISH); + case eTYPE_CAVESPIDER: + return app.GetString(IDS_CAVE_SPIDER); + case eTYPE_GHAST: + return app.GetString(IDS_GHAST); + case eTYPE_SLIME: + return app.GetString(IDS_SLIME); + case eTYPE_ARROW: + return app.GetString(IDS_ITEM_ARROW); + case eTYPE_ENDERDRAGON: + return app.GetString(IDS_ENDERDRAGON); + case eTYPE_BLAZE: + return app.GetString(IDS_BLAZE); + case eTYPE_LAVASLIME: + return app.GetString(IDS_LAVA_SLIME); + // 4J-PB - fix for #107167 - Customer Encountered: TU12: Content: UI: There is no information what killed Player after being slain by Iron Golem. + case eTYPE_VILLAGERGOLEM: + return app.GetString(IDS_IRONGOLEM); + case eTYPE_HORSE: + return app.GetString(IDS_HORSE); + case eTYPE_WITCH: + return app.GetString(IDS_WITCH); + case eTYPE_WITHERBOSS: + return app.GetString(IDS_WITHER); + case eTYPE_BAT: + return app.GetString(IDS_BAT); + case eTYPE_RABBIT: + return app.GetString(IDS_RABBIT); + + }; + + return L""; +} + +DWORD CMinecraftApp::m_dwContentTypeA[e_Marketplace_MAX]= +{ + XMARKETPLACE_OFFERING_TYPE_CONTENT, // e_DLC_SkinPack, e_DLC_TexturePacks, e_DLC_MashupPacks +#ifndef _XBOX_ONE + XMARKETPLACE_OFFERING_TYPE_THEME, // e_DLC_Themes + XMARKETPLACE_OFFERING_TYPE_AVATARITEM, // e_DLC_AvatarItems + XMARKETPLACE_OFFERING_TYPE_TILE, // e_DLC_Gamerpics +#endif +}; + +unsigned int CMinecraftApp::AddDLCRequest(eDLCMarketplaceType eType, bool bPromote) +{ + // lock access + EnterCriticalSection(&csDLCDownloadQueue); + + // If it's already in there, promote it to the top of the list + int iPosition=0; + for( DLCRequest *pCurrent : m_DLCDownloadQueue ) + { + if(pCurrent->dwType==m_dwContentTypeA[eType]) + { + // already got this in the list + if(pCurrent->eState == e_DLC_ContentState_Retrieving || pCurrent->eState == e_DLC_ContentState_Retrieved) + { + // already retrieved this + LeaveCriticalSection(&csDLCDownloadQueue); + return 0; + } + else + { + // promote + if(bPromote) + { + m_DLCDownloadQueue.erase(m_DLCDownloadQueue.begin()+iPosition); + m_DLCDownloadQueue.insert(m_DLCDownloadQueue.begin(),pCurrent); + } + LeaveCriticalSection(&csDLCDownloadQueue); + return 0; + } + } + iPosition++; + } + + DLCRequest *pDLCreq = new DLCRequest; + pDLCreq->dwType=m_dwContentTypeA[eType]; + pDLCreq->eState=e_DLC_ContentState_Idle; + + m_DLCDownloadQueue.push_back(pDLCreq); + + m_bAllDLCContentRetrieved=false; + LeaveCriticalSection(&csDLCDownloadQueue); + + app.DebugPrintf("[Consoles_App] Added DLC request.\n"); + return 1; +} + +unsigned int CMinecraftApp::AddTMSPPFileTypeRequest(eDLCContentType eType, bool bPromote) +{ +#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__) + // lock access + EnterCriticalSection(&csTMSPPDownloadQueue); + + // If it's already in there, promote it to the top of the list + int iPosition=0; + //ignore promoting for now + /* + bool bPromoted=false; + + + for ( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) + { + TMSPPRequest *pCurrent = *it; + + if(pCurrent->eType==eType) + { + if(!(pCurrent->eState == e_TMS_ContentState_Retrieving || pCurrent->eState == e_TMS_ContentState_Retrieved)) + { + // promote + if(bPromote) + { + m_TMSPPDownloadQueue.erase(m_TMSPPDownloadQueue.begin()+iPosition); + m_TMSPPDownloadQueue.insert(m_TMSPPDownloadQueue.begin(),pCurrent); + bPromoted=true; + } + } + } + iPosition++; + } + + if(bPromoted) + { + // re-ordered the list, so leave now + LeaveCriticalSection(&csTMSPPDownloadQueue); + return 0; + } + */ + + // special case for data files (not image files) + if(eType==e_DLC_TexturePackData) + { + + + int iCount=GetDLCInfoFullOffersCount(); + + for(int i=0;ieDLCType==e_DLC_TexturePacks) || (pDLC->eDLCType==e_DLC_MashupPacks)) + { + // first check if the image is already in the memory textures, since we might be loading some from the Title Update partition + if(pDLC->wchDataFile[0]!=0) + { + //WCHAR *cString = pDLC->wchDataFile; + // 4J-PB - shouldn't check this here - let the TMS files override it, so if they are on TMS, we'll take them first + //int iIndex = app.GetLocalTMSFileIndex(pDLC->wchDataFile,true); + + //if(iIndex!=-1) + { + bool bPresent = app.IsFileInTPD(pDLC->iConfig); + + if(!bPresent) + { + // this may already be present in the vector because of a previous trial/full offer + + bool bAlreadyInQueue=false; + for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) + { + if(wcscmp(pDLC->wchDataFile,pCurrent->wchFilename)==0) + { + bAlreadyInQueue=true; + break; + } + } + + if(!bAlreadyInQueue) + { + TMSPPRequest *pTMSPPreq = new TMSPPRequest; + + pTMSPPreq->CallbackFunc=&CMinecraftApp::TMSPPFileReturned; + pTMSPPreq->lpCallbackParam=this; + pTMSPPreq->eStorageFacility=C4JStorage::eGlobalStorage_Title; + pTMSPPreq->eFileTypeVal=C4JStorage::TMS_FILETYPE_BINARY; + memcpy(pTMSPPreq->wchFilename,pDLC->wchDataFile,sizeof(WCHAR)*MAX_BANNERNAME_SIZE); + pTMSPPreq->eType=e_DLC_TexturePackData; + pTMSPPreq->eState=e_TMS_ContentState_Queued; + m_bAllTMSContentRetrieved=false; + m_TMSPPDownloadQueue.push_back(pTMSPPreq); + } + } + else + { + app.DebugPrintf("Texture data already present in the TPD\n"); + } + } + } + } + } + } + else + { // for all the files of type eType, add them to the download list + + // run through the trial offers first, then the full offers. Any duplicates won't be added to the download queue + int iCount; +#ifdef _XBOX // Only trial offers on Xbox 360 + iCount=GetDLCInfoTrialOffersCount(); + for(int i=0;ieDLCType==eType) + { + + WCHAR *cString = pDLC->wchBanner; + + // 4J-PB - shouldn't check this here - let the TMS files override it, so if they are on TMS, we'll take them first + // is the file in the TMS XZP? + //int iIndex = app.GetLocalTMSFileIndex(cString,true); + + //if(iIndex!=-1) + { + bool bPresent = app.IsFileInMemoryTextures(cString); + + if(!bPresent) // retrieve it from TMSPP + { + bool bAlreadyInQueue=false; + for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) + { + if(wcscmp(pDLC->wchBanner,pCurrent->wchFilename)==0) + { + bAlreadyInQueue=true; + break; + } + } + + if(!bAlreadyInQueue) + { + TMSPPRequest *pTMSPPreq = new TMSPPRequest; + + pTMSPPreq->CallbackFunc=&CMinecraftApp::TMSPPFileReturned; + pTMSPPreq->lpCallbackParam=this; + pTMSPPreq->eStorageFacility=C4JStorage::eGlobalStorage_Title; + pTMSPPreq->eFileTypeVal=C4JStorage::TMS_FILETYPE_BINARY; + //wcstombs(pTMSPPreq->szFilename,pDLC->wchBanner,MAX_TMSFILENAME_SIZE); + memcpy(pTMSPPreq->wchFilename,pDLC->wchBanner,sizeof(WCHAR)*MAX_BANNERNAME_SIZE); + pTMSPPreq->eType=eType; + pTMSPPreq->eState=e_TMS_ContentState_Queued; + + m_bAllTMSContentRetrieved=false; + m_TMSPPDownloadQueue.push_back(pTMSPPreq); + app.DebugPrintf("===m_TMSPPDownloadQueue Adding %ls, q size is %d\n",pTMSPPreq->wchFilename,m_TMSPPDownloadQueue.size()); + } + } + } + } + } +#endif + // and the full offers + + iCount=GetDLCInfoFullOffersCount(); + for(int i=0;iwchType,wchDLCTypeNames[eType])==0) + if(pDLC->eDLCType==eType) + { + // first check if the image is already in the memory textures, since we might be loading some from the Title Update partition + + WCHAR *cString = pDLC->wchBanner; + // 4J-PB - shouldn't check this here - let the TMS files override it, so if they are on TMS, we'll take them first + //int iIndex = app.GetLocalTMSFileIndex(cString,true); + + //if(iIndex!=-1) + { + bool bPresent = app.IsFileInMemoryTextures(cString); + + if(!bPresent) + { + // this may already be present in the vector because of a previous trial/full offer + + bool bAlreadyInQueue=false; + for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) + { + if(wcscmp(pDLC->wchBanner,pCurrent->wchFilename)==0) + { + bAlreadyInQueue=true; + break; + } + } + + if(!bAlreadyInQueue) + { + //app.DebugPrintf("Adding a request to the TMSPP download queue - %ls\n",pDLC->wchBanner); + TMSPPRequest *pTMSPPreq = new TMSPPRequest; + ZeroMemory(pTMSPPreq,sizeof(TMSPPRequest)); + + pTMSPPreq->CallbackFunc=&CMinecraftApp::TMSPPFileReturned; + pTMSPPreq->lpCallbackParam=this; + // 4J-PB - testing for now + //pTMSPPreq->eStorageFacility=C4JStorage::eGlobalStorage_TitleUser; + pTMSPPreq->eStorageFacility=C4JStorage::eGlobalStorage_Title; + pTMSPPreq->eFileTypeVal=C4JStorage::TMS_FILETYPE_BINARY; + //wcstombs(pTMSPPreq->szFilename,pDLC->wchBanner,MAX_TMSFILENAME_SIZE); + + memcpy(pTMSPPreq->wchFilename,pDLC->wchBanner,sizeof(WCHAR)*MAX_BANNERNAME_SIZE); + pTMSPPreq->eType=eType; + pTMSPPreq->eState=e_TMS_ContentState_Queued; + m_bAllTMSContentRetrieved=false; + m_TMSPPDownloadQueue.push_back(pTMSPPreq); + app.DebugPrintf("===m_TMSPPDownloadQueue Adding %ls, q size is %d\n",pTMSPPreq->wchFilename,m_TMSPPDownloadQueue.size()); + } + } + } + } + } + } + + LeaveCriticalSection(&csTMSPPDownloadQueue); +#endif + return 1; +} + +bool CMinecraftApp::CheckTMSDLCCanStop() +{ + EnterCriticalSection(&csTMSPPDownloadQueue); + for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) + { + if(pCurrent->eState==e_TMS_ContentState_Retrieving) + { + LeaveCriticalSection(&csTMSPPDownloadQueue); + return false; + } + } + LeaveCriticalSection(&csTMSPPDownloadQueue); + + return true; +} + + +bool CMinecraftApp::RetrieveNextDLCContent() +{ + // If there's already a retrieve in progress, quit + // we may have re-ordered the list, so need to check every item + + // is there a primary player and a network connection? + int primPad = ProfileManager.GetPrimaryPad(); + if ( primPad == -1 || !ProfileManager.IsSignedInLive(primPad) ) + { + return true; // 4J-JEV: We need to wait until the primary player is online. + } + + EnterCriticalSection(&csDLCDownloadQueue); + for( const DLCRequest* pCurrent : m_DLCDownloadQueue ) + { + if(pCurrent->eState==e_DLC_ContentState_Retrieving) + { + LeaveCriticalSection(&csDLCDownloadQueue); + return true; + } + } + + // Now look for the next retrieval + for( DLCRequest *pCurrent : m_DLCDownloadQueue ) + { + if(pCurrent->eState==e_DLC_ContentState_Idle) + { +#ifdef _DEBUG + app.DebugPrintf("RetrieveNextDLCContent - type = %d\n",pCurrent->dwType); +#endif + + C4JStorage::EDLCStatus status = StorageManager.GetDLCOffers(ProfileManager.GetPrimaryPad(), &CMinecraftApp::DLCOffersReturned, this, pCurrent->dwType); + if(status==C4JStorage::EDLC_Pending) + { + pCurrent->eState=e_DLC_ContentState_Retrieving; + } + else + { + // no content of this type, or some other problem + app.DebugPrintf("RetrieveNextDLCContent - PROBLEM\n"); + pCurrent->eState=e_DLC_ContentState_Retrieved; + } + LeaveCriticalSection(&csDLCDownloadQueue); + return true; + } + } + LeaveCriticalSection(&csDLCDownloadQueue); + + app.DebugPrintf("[Consoles_App] Finished downloading dlc content.\n"); + return false; +} + +#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__) +#ifdef _XBOX_ONE +int CMinecraftApp::TMSPPFileReturned(LPVOID pParam,int iPad,int iUserData,LPVOID lpvData, WCHAR* wchFilename) +{ + C4JStorage::PTMSPP_FILEDATA pFileData=(C4JStorage::PTMSPP_FILEDATA)lpvData; +#else +int CMinecraftApp::TMSPPFileReturned(LPVOID pParam,int iPad,int iUserData,C4JStorage::PTMSPP_FILEDATA pFileData, LPCSTR szFilename) +{ +#endif + + CMinecraftApp* pClass = static_cast(pParam); + + // find the right one in the vector + EnterCriticalSection(&pClass->csTMSPPDownloadQueue); + for( TMSPPRequest *pCurrent : pClass->m_TMSPPDownloadQueue ) + { +#if defined(_XBOX) || defined(_WINDOWS64) + char szFile[MAX_TMSFILENAME_SIZE]; + wcstombs(szFile,pCurrent->wchFilename,MAX_TMSFILENAME_SIZE); + + + if(strcmp(szFilename,szFile)==0) +#elif _XBOX_ONE + if(wcscmp(wchFilename,pCurrent->wchFilename)==0) +#endif + { + // set this to retrieved whether it found it or not + pCurrent->eState=e_TMS_ContentState_Retrieved; + + if(pFileData!=nullptr) + { +#ifdef _XBOX_ONE + + + switch(pCurrent->eType) + { + case e_DLC_TexturePackData: + { + // 4J-PB - we need to allocate memory for the file data and copy into it, since the current data is a reference into the blob download memory + PBYTE pbData = new BYTE [pFileData->dwSize]; + memcpy(pbData,pFileData->pbData,pFileData->dwSize); + + pClass->m_vTMSPPData.push_back(pbData); + app.DebugPrintf("Got texturepack data\n"); + // get the config value for the texture pack + int iConfig=app.GetTPConfigVal(pCurrent->wchFilename); + app.AddMemoryTPDFile(iConfig, pbData, pFileData->dwSize); + } + break; + default: + // 4J-PB - check the data is an image + if(pFileData->pbData[0]==0x89) + { + // 4J-PB - we need to allocate memory for the file data and copy into it, since the current data is a reference into the blob download memory + PBYTE pbData = new BYTE [pFileData->dwSize]; + memcpy(pbData,pFileData->pbData,pFileData->dwSize); + + pClass->m_vTMSPPData.push_back(pbData); + app.DebugPrintf("Got image data - %ls\n",pCurrent->wchFilename); + app.AddMemoryTextureFile(pCurrent->wchFilename, pbData, pFileData->dwSize); + } + else + { + app.DebugPrintf("Got image data, but it's not a png - %ls\n",pCurrent->wchFilename); + } + break; + } + +#else + switch(pCurrent->eType) + { + case e_DLC_TexturePackData: + { + app.DebugPrintf("--- Got texturepack data %ls\n",pCurrent->wchFilename); + // get the config value for the texture pack + int iConfig=app.GetTPConfigVal(pCurrent->wchFilename); + app.AddMemoryTPDFile(iConfig, pFileData->pbData, pFileData->dwSize); + } + break; + default: + app.DebugPrintf("--- Got image data - %ls\n",pCurrent->wchFilename); + app.AddMemoryTextureFile(pCurrent->wchFilename, pFileData->pbData, pFileData->dwSize); + break; + } +#endif + } + else + { +#ifdef _XBOX_ONE + app.DebugPrintf("TMSImageReturned failed (%ls)...\n",wchFilename); +#else + app.DebugPrintf("TMSImageReturned failed (%s)...\n",szFilename); +#endif + } + break; + } + + } + LeaveCriticalSection(&pClass->csTMSPPDownloadQueue); + + return 0; +} +#endif + +bool CMinecraftApp::RetrieveNextTMSPPContent() +{ +#if defined _XBOX || defined _XBOX_ONE + // If there's already a retrieve in progress, quit + // we may have re-ordered the list, so need to check every item + + // is there a primary player and a network connection? + if(ProfileManager.GetPrimaryPad()==-1) return false; + + if(ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad())==false) return false; + + for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) + { + TMSPPRequest *pCurrent = *it; + + if(pCurrent->eState==e_TMS_ContentState_Retrieving) + { + app.DebugPrintf("."); + LeaveCriticalSection(&csTMSPPDownloadQueue); + return true; + } + } + + // Now look for the next retrieval + for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) + { + TMSPPRequest *pCurrent = *it; + + if(pCurrent->eState==e_TMS_ContentState_Queued) + { + // 4J-PB - the file may be in the local TMS files, but try to retrieve it from the remote TMS in case it's been changed. If it's not in the list of TMS files, this will + // return right away with a ETMSStatus_Fail_ReadDetailsNotRetrieved +#ifdef _XBOX + char szFilename[MAX_TMSFILENAME_SIZE]; + wcstombs(szFilename,pCurrent->wchFilename,MAX_TMSFILENAME_SIZE); + + app.DebugPrintf("\nRetrieveNextTMSPPContent - type = %d, %s\n",pCurrent->eType,szFilename); + + C4JStorage::ETMSStatus status=StorageManager.TMSPP_ReadFile(ProfileManager.GetPrimaryPad(),pCurrent->eStorageFacility,pCurrent->eFileTypeVal,szFilename,pCurrent->CallbackFunc,this); + switch(status) + { + case C4JStorage::ETMSStatus_Pending: + pCurrent->eState=e_TMS_ContentState_Retrieving; + break; + case C4JStorage::ETMSStatus_Idle: + pCurrent->eState=e_TMS_ContentState_Retrieved; + break; + case C4JStorage::ETMSStatus_Fail_ReadInProgress: + case C4JStorage::ETMSStatus_ReadInProgress: + pCurrent->eState=e_TMS_ContentState_Retrieving; + if(pCurrent->eState==C4JStorage::ETMSStatus_Fail_ReadInProgress) + { + app.DebugPrintf("TMSPP_ReadFile failed - read in progress\n"); + Sleep(50); + LeaveCriticalSection(&csTMSPPDownloadQueue); + return false; + } + break; + default: + pCurrent->eState=e_TMS_ContentState_Retrieved; + break; + } +#else + eTitleStorageState status; + app.DebugPrintf("RetrieveNextTMSPPContent - type = %d, %ls\n",pCurrent->eType,pCurrent->wchFilename); + //eTitleStorageState status=StorageManager.TMSPP_ReadFile(ProfileManager.GetPrimaryPad(),pCurrent->eStorageFacility,pCurrent->eFileTypeVal,pCurrent->wchFilename,pCurrent->CallbackFunc,this,0); + if(0)//wcscmp(pCurrent->wchFilename,L"TP01.png")==0) + { + // TP01 fails because the blob size returned is bigger than the global metadata says it should be + status=eTitleStorage_readerror; + } + else + { + status=StorageManager.TMSPP_ReadFile(ProfileManager.GetPrimaryPad(),pCurrent->eStorageFacility,pCurrent->eFileTypeVal,pCurrent->wchFilename,pCurrent->CallbackFunc,this,0); + } + switch(status) + { + case eTitleStorage_pending: + pCurrent->eState=e_TMS_ContentState_Retrieving; + break; + case eTitleStorage_idle: + pCurrent->eState=e_TMS_ContentState_Retrieved; + break; + case eTitleStorage_busy: + // try again next time + { + app.DebugPrintf("@@@@@@@@@@@@@@@@@ TMSPP_ReadFile failed - busy (probably reading already)\n"); + Sleep(50); + LeaveCriticalSection(&csTMSPPDownloadQueue); + return false; + } + break; + default: + pCurrent->eState=e_TMS_ContentState_Retrieved; + break; + } +#endif + + + + LeaveCriticalSection(&csTMSPPDownloadQueue); + return true; + } + } + + LeaveCriticalSection(&csTMSPPDownloadQueue); + +#endif + return false; +} + +void CMinecraftApp::TickDLCOffersRetrieved() +{ + if(!m_bAllDLCContentRetrieved) + { + if (!app.RetrieveNextDLCContent()) + { + app.DebugPrintf("[Consoles_App] All content retrieved.\n"); + m_bAllDLCContentRetrieved=true; + } + } +} +void CMinecraftApp::ClearAndResetDLCDownloadQueue() +{ + app.DebugPrintf("[Consoles_App] Clear and reset download queue.\n"); + + int iPosition=0; + EnterCriticalSection(&csTMSPPDownloadQueue); + for( DLCRequest *pCurrent : m_DLCDownloadQueue ) + { + if ( pCurrent ) + delete pCurrent; + iPosition++; + } + m_DLCDownloadQueue.clear(); + m_bAllDLCContentRetrieved=true; + LeaveCriticalSection(&csTMSPPDownloadQueue); +} + +void CMinecraftApp::TickTMSPPFilesRetrieved() +{ + if(m_bTickTMSDLCFiles && !m_bAllTMSContentRetrieved) + { + if(app.RetrieveNextTMSPPContent()==false) + { + m_bAllTMSContentRetrieved=true; + } + } +} +void CMinecraftApp::ClearTMSPPFilesRetrieved() +{ + int iPosition=0; + EnterCriticalSection(&csTMSPPDownloadQueue); + for ( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) + { + if ( pCurrent ) + delete pCurrent; + iPosition++; + } + m_TMSPPDownloadQueue.clear(); + m_bAllTMSContentRetrieved=true; + LeaveCriticalSection(&csTMSPPDownloadQueue); +} + +int CMinecraftApp::DLCOffersReturned(void *pParam, int iOfferC, DWORD dwType, int iPad) +{ + CMinecraftApp* pClass = static_cast(pParam); + + // find the right one in the vector + EnterCriticalSection(&pClass->csTMSPPDownloadQueue); + for( DLCRequest *pCurrent : pClass->m_DLCDownloadQueue ) + { + // avatar items are coming back as type Content, so we can't trust the type setting + if(pCurrent->dwType==dwType) + { + pClass->m_iDLCOfferC = iOfferC; + app.DebugPrintf("DLCOffersReturned - type %d, count %d - setting to retrieved\n",dwType,iOfferC); + pCurrent->eState=e_DLC_ContentState_Retrieved; + break; + } + } + LeaveCriticalSection(&pClass->csTMSPPDownloadQueue); + return 0; +} + +eDLCContentType CMinecraftApp::Find_eDLCContentType(DWORD dwType) +{ + for(int i=0;i(i); + } + } + return static_cast(0); +} +bool CMinecraftApp::DLCContentRetrieved(eDLCMarketplaceType eType) +{ + // If there's already a retrieve in progress, quit + // we may have re-ordered the list, so need to check every item + EnterCriticalSection(&csDLCDownloadQueue); + for( DLCRequest *pCurrent : m_DLCDownloadQueue ) + { + if((pCurrent->dwType==m_dwContentTypeA[eType]) && (pCurrent->eState==e_DLC_ContentState_Retrieved)) + { + LeaveCriticalSection(&csDLCDownloadQueue); + return true; + } + } + LeaveCriticalSection(&csDLCDownloadQueue); + return false; +} + +void CMinecraftApp::SetAdditionalSkinBoxes(DWORD dwSkinID, SKIN_BOX *SkinBoxA, DWORD dwSkinBoxC) +{ + EntityRenderDispatcher *dispatcher = EntityRenderDispatcher::instance; + EntityRenderer *renderer = dispatcher ? dispatcher->getRenderer(eTYPE_PLAYER) : nullptr; + unsigned int m_uiAnimOverrideBitmask = GetAnimOverrideBitmask(dwSkinID); + Model *pModel; + if (m_uiAnimOverrideBitmask & (1 << HumanoidModel::eAnim_SlimModel)) + pModel = renderer ? renderer->getModel(2) : nullptr; + else if (m_uiAnimOverrideBitmask & (1 << HumanoidModel::eAnim_WideModel)) + pModel = renderer ? renderer->getModel(1) : nullptr; + else + pModel = renderer ? renderer->getModel(0) : nullptr; + vector *pvModelPart = new vector; + vector *pvSkinBoxes = new vector; + + EnterCriticalSection( &csAdditionalModelParts ); + EnterCriticalSection( &csAdditionalSkinBoxes ); + + app.DebugPrintf("*** SetAdditionalSkinBoxes - Inserting model parts for skin %d from array of Skin Boxes\n",dwSkinID&0x0FFFFFFF); + + // convert the skin boxes into model parts, and add to the humanoid model + for(unsigned int i=0;iAddOrRetrievePart(&SkinBoxA[i]); + pvModelPart->push_back(pModelPart); + pvSkinBoxes->push_back(&SkinBoxA[i]); + } + } + + + m_AdditionalModelParts.insert( std::pair *>(dwSkinID, pvModelPart) ); + m_AdditionalSkinBoxes.insert( std::pair *>(dwSkinID, pvSkinBoxes) ); + + LeaveCriticalSection( &csAdditionalSkinBoxes ); + LeaveCriticalSection( &csAdditionalModelParts ); + +} + +vector * CMinecraftApp::SetAdditionalSkinBoxes(DWORD dwSkinID, vector *pvSkinBoxA) +{ + EntityRenderDispatcher *dispatcher = EntityRenderDispatcher::instance; + EntityRenderer *renderer = dispatcher ? dispatcher->getRenderer(eTYPE_PLAYER) : nullptr; + unsigned int m_uiAnimOverrideBitmask = GetAnimOverrideBitmask(dwSkinID); + Model *pModel; + if (m_uiAnimOverrideBitmask & (1 << HumanoidModel::eAnim_SlimModel)) + pModel = renderer ? renderer->getModel(2) : nullptr; + else if (m_uiAnimOverrideBitmask & (1 << HumanoidModel::eAnim_WideModel)) + pModel = renderer ? renderer->getModel(1) : nullptr; + else + pModel = renderer ? renderer->getModel(0) : nullptr; + vector *pvModelPart = new vector; + + EnterCriticalSection( &csAdditionalModelParts ); + EnterCriticalSection( &csAdditionalSkinBoxes ); + app.DebugPrintf("*** SetAdditionalSkinBoxes - Inserting model parts for skin %d from array of Skin Boxes\n",dwSkinID&0x0FFFFFFF); + + // convert the skin boxes into model parts, and add to the humanoid model + for( auto& it : *pvSkinBoxA ) + { + if(pModel) + { + ModelPart *pModelPart=pModel->AddOrRetrievePart(it); + pvModelPart->push_back(pModelPart); + } + } + + m_AdditionalModelParts.emplace(dwSkinID, pvModelPart); + m_AdditionalSkinBoxes.emplace(dwSkinID, pvSkinBoxA); + + LeaveCriticalSection( &csAdditionalSkinBoxes ); + LeaveCriticalSection( &csAdditionalModelParts ); + return pvModelPart; +} + +void CMinecraftApp::SetSkinOffsets(DWORD dwSkinID, SKIN_OFFSET *SkinOffsetA, DWORD dwSkinOffsetC) +{ + vector *pvSkinOffset = new vector; + + EnterCriticalSection( &csSkinOffsets ); + + app.DebugPrintf("*** SetSkinOffsets - Adding skin offsets for skin %d from array of Skin Offsets\n",dwSkinID&0x0FFFFFFF); + + for(unsigned int i=0;ipush_back(&SkinOffsetA[i]); + } + + + m_SkinOffsets.insert( std::pair *>(dwSkinID, pvSkinOffset) ); + + LeaveCriticalSection( &csSkinOffsets ); + +} + +vector * CMinecraftApp::SetSkinOffsets(DWORD dwSkinID, vector *pvSkinOffsetA) +{ + vector *pvSkinOffset = new vector; + + EnterCriticalSection( &csSkinOffsets ); + app.DebugPrintf("*** SetSkinOffsets - Inserting skin offsets for skin %d from array of Skin Offsets\n",dwSkinID&0x0FFFFFFF); + + for( auto& it : *pvSkinOffsetA ) + { + pvSkinOffset->push_back(it); + } + + m_SkinOffsets.emplace(dwSkinID, pvSkinOffsetA); + + LeaveCriticalSection( &csSkinOffsets ); + return pvSkinOffset; +} + + +vector *CMinecraftApp::GetAdditionalModelParts(DWORD dwSkinID) +{ + EnterCriticalSection( &csAdditionalModelParts ); + vector *pvModelParts=nullptr; + if(m_AdditionalModelParts.size()>0) + { + auto it = m_AdditionalModelParts.find(dwSkinID); + if(it!=m_AdditionalModelParts.end()) + { + pvModelParts = (*it).second; + } + } + + LeaveCriticalSection( &csAdditionalModelParts ); + return pvModelParts; +} + +vector *CMinecraftApp::GetAdditionalSkinBoxes(DWORD dwSkinID) +{ + EnterCriticalSection( &csAdditionalSkinBoxes ); + vector *pvSkinBoxes=nullptr; + if(m_AdditionalSkinBoxes.size()>0) + { + auto it = m_AdditionalSkinBoxes.find(dwSkinID); + if(it!=m_AdditionalSkinBoxes.end()) + { + pvSkinBoxes = (*it).second; + } + } + + LeaveCriticalSection( &csAdditionalSkinBoxes ); + return pvSkinBoxes; +} + +vector *CMinecraftApp::GetSkinOffsets(DWORD dwSkinID) +{ + EnterCriticalSection( &csSkinOffsets ); + vector *pvSkinOffsets=nullptr; + if(m_SkinOffsets.size()>0) + { + auto it = m_SkinOffsets.find(dwSkinID); + if(it!=m_SkinOffsets.end()) + { + pvSkinOffsets = (*it).second; + } + } + + LeaveCriticalSection( &csSkinOffsets ); + return pvSkinOffsets; +} + +unsigned int CMinecraftApp::GetAnimOverrideBitmask(DWORD dwSkinID) +{ + EnterCriticalSection( &csAnimOverrideBitmask ); + unsigned int uiAnimOverrideBitmask=0L; + + if(m_AnimOverrides.size()>0) + { + auto it = m_AnimOverrides.find(dwSkinID); + if(it!=m_AnimOverrides.end()) + { + uiAnimOverrideBitmask = (*it).second; + } + } + + LeaveCriticalSection( &csAnimOverrideBitmask ); + return uiAnimOverrideBitmask; +} + +void CMinecraftApp::SetAnimOverrideBitmask(DWORD dwSkinID,unsigned int uiAnimOverrideBitmask) +{ + // Make thread safe + EnterCriticalSection( &csAnimOverrideBitmask ); + + if(m_AnimOverrides.size()>0) + { + auto it = m_AnimOverrides.find(dwSkinID); + if(it!=m_AnimOverrides.end()) + { + LeaveCriticalSection( &csAnimOverrideBitmask ); + return; // already in here + } + } + m_AnimOverrides.insert( std::pair(dwSkinID, uiAnimOverrideBitmask) ); + LeaveCriticalSection( &csAnimOverrideBitmask ); +} + +DWORD CMinecraftApp::getSkinIdFromPath(const wstring &skin) +{ + bool dlcSkin = false; + unsigned int skinId = 0; + + if(skin.size() >= 14) + { + dlcSkin = skin.substr(0,3).compare(L"dlc") == 0; + + wstring skinValue = skin.substr(7,skin.size()); + skinValue = skinValue.substr(0,skinValue.find_first_of(L'.')); + + std::wstringstream ss; + // 4J Stu - dlc skins are numbered using decimal to make it easier for artists/people to number manually + // Everything else is numbered using hex + if(dlcSkin) + ss << std::dec << skinValue.c_str(); + else + ss << std::hex << skinValue.c_str(); + ss >> skinId; + + skinId = MAKE_SKIN_BITMASK(dlcSkin, skinId); + } + return skinId; +} + +wstring CMinecraftApp::getSkinPathFromId(DWORD skinId) +{ + // 4J Stu - This function maps the encoded DWORD we store in the player profile + // to a filename that is stored as a memory texture and shared between systems in game + wchar_t chars[256]; + if( GET_IS_DLC_SKIN_FROM_BITMASK(skinId) ) + { + // 4J Stu - DLC skins are numbered using decimal rather than hex to make it easier to number manually + swprintf(chars, 256, L"dlcskin%08d.png", GET_DLC_SKIN_ID_FROM_BITMASK(skinId)); + + } + else + { + DWORD ugcSkinIndex = GET_UGC_SKIN_ID_FROM_BITMASK(skinId); + DWORD defaultSkinIndex = GET_DEFAULT_SKIN_ID_FROM_BITMASK(skinId); + if( ugcSkinIndex == 0 ) + { + swprintf(chars, 256, L"defskin%08X.png",defaultSkinIndex); + } + else + { + swprintf(chars, 256, L"ugcskin%08X.png",ugcSkinIndex); + } + } + return chars; +} + + +int CMinecraftApp::TexturePackDialogReturned(void* pParam, int iPad, C4JStorage::EMessageResult result) +{ + +#if defined __PSVITA__ || defined __PS3__ || defined __ORBIS__ + if (result == C4JStorage::EMessage_ResultAccept) + { + Minecraft* pMinecraft = Minecraft::GetInstance(); + if (pMinecraft->skins->selectTexturePackById(app.GetRequiredTexturePackID())) + { + // it's been installed already + } + else + { + // we need to enable background downloading for the DLC + XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); + + SONYDLC* pSONYDLCInfo = app.GetSONYDLCInfo(app.GetRequiredTexturePackID()); + if (pSONYDLCInfo != nullptr) + { + char chName[42]; + char chKeyName[20]; + char chSkuID[SCE_NP_COMMERCE2_SKU_ID_LEN]; + + memset(chSkuID, 0, SCE_NP_COMMERCE2_SKU_ID_LEN); + + memset(chKeyName, 0, sizeof(chKeyName)); + strncpy(chKeyName, pSONYDLCInfo->chDLCKeyname, 16); + + #ifdef __ORBIS__ + strcpy(chName, chKeyName); + #else + sprintf(chName, "%s-%s", app.GetCommerceCategory(), chKeyName); + #endif + + app.GetDLCSkuIDFromProductList(chName, chSkuID); + + if (app.CheckForEmptyStore(iPad) == false) + { + if (app.DLCAlreadyPurchased(chSkuID)) + { + app.DownloadAlreadyPurchased(chSkuID); + } + else + { + app.Checkout(chSkuID); + } + } + } + } + } + else + { + app.DebugPrintf("Continuing without installing texture pack\n"); + } +#endif + +#ifdef _XBOX + if (result != C4JStorage::EMessage_Cancelled) + { + if (app.GetRequiredTexturePackID() != 0) + { + XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); + + ULONGLONG ullOfferID_Full; + ULONGLONG ullIndexA[1]; + app.GetDLCFullOfferIDForPackID(app.GetRequiredTexturePackID(), &ullOfferID_Full); + + if (result == C4JStorage::EMessage_ResultAccept) + { + ullIndexA[0] = ullOfferID_Full; + StorageManager.InstallOffer(1, ullIndexA, nullptr, nullptr); + } + else + { + DLC_INFO* pDLCInfo = app.GetDLCInfoForFullOfferID(ullOfferID_Full); + ullIndexA[0] = pDLCInfo->ullOfferID_Trial; + StorageManager.InstallOffer(1, ullIndexA, nullptr, nullptr); + } + } + } +#endif + return 0; +} +int CMinecraftApp::getArchiveFileSize(const wstring &filename) +{ + TexturePack *tPack = nullptr; + Minecraft *pMinecraft = Minecraft::GetInstance(); + if(pMinecraft && pMinecraft->skins) tPack = pMinecraft->skins->getSelected(); + if(tPack && tPack->hasData() && tPack->getArchiveFile() && tPack->getArchiveFile()->hasFile(filename)) + { + return tPack->getArchiveFile()->getFileSize(filename); + } + else return m_mediaArchive->getFileSize(filename); +} + +bool CMinecraftApp::hasArchiveFile(const wstring &filename) +{ + TexturePack *tPack = nullptr; + Minecraft *pMinecraft = Minecraft::GetInstance(); + if(pMinecraft && pMinecraft->skins) tPack = pMinecraft->skins->getSelected(); + if(tPack && tPack->hasData() && tPack->getArchiveFile() && tPack->getArchiveFile()->hasFile(filename)) return true; + else return m_mediaArchive->hasFile(filename); +} + +byteArray CMinecraftApp::getArchiveFile(const wstring &filename) +{ + TexturePack *tPack = nullptr; + Minecraft *pMinecraft = Minecraft::GetInstance(); + if(pMinecraft && pMinecraft->skins) tPack = pMinecraft->skins->getSelected(); + if(tPack && tPack->hasData() && tPack->getArchiveFile() && tPack->getArchiveFile()->hasFile(filename)) + { + return tPack->getArchiveFile()->getFile(filename); + } + else return m_mediaArchive->getFile(filename); +} + +// DLC + +#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) +int CMinecraftApp::GetDLCInfoCount() +{ + return (int)DLCInfo.size(); +} +#elif defined _XBOX_ONE +int CMinecraftApp::GetDLCInfoTrialOffersCount() +{ + return 0; +} + +int CMinecraftApp::GetDLCInfoFullOffersCount() +{ + return (int)DLCInfo_Full.size(); +} +#else +int CMinecraftApp::GetDLCInfoTrialOffersCount() +{ + return static_cast(DLCInfo_Trial.size()); +} + +int CMinecraftApp::GetDLCInfoFullOffersCount() +{ + return static_cast(DLCInfo_Full.size()); +} +#endif + +int CMinecraftApp::GetDLCInfoTexturesOffersCount() +{ + return static_cast(DLCTextures_PackID.size()); +} + +// AUTOSAVE +void CMinecraftApp::SetAutosaveTimerTime(void) +{ +#if defined(_XBOX_ONE) || defined(__ORBIS__) + m_uiAutosaveTimer= GetTickCount()+1000*60; +#else + m_uiAutosaveTimer= GetTickCount()+GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_Autosave)*1000*60*15; +#endif +}// value x 15 to get mins, x60 for secs + +bool CMinecraftApp::AutosaveDue(void) +{ + return (GetTickCount()>m_uiAutosaveTimer); +} + +unsigned int CMinecraftApp::SecondsToAutosave() +{ + return (m_uiAutosaveTimer - GetTickCount() ) / 1000; +} + +void CMinecraftApp::SetTrialTimerStart(void) +{ + m_fTrialTimerStart=m_Time.fAppTime; mfTrialPausedTime=0.0f; +} + +float CMinecraftApp::getTrialTimer(void) +{ + return m_Time.fAppTime-m_fTrialTimerStart-mfTrialPausedTime; +} + +bool CMinecraftApp::IsLocalMultiplayerAvailable() +{ + DWORD connectedControllers = 0; + for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) + { + if( InputManager.IsPadConnected(i) || ProfileManager.IsSignedIn(i) ) ++connectedControllers; + } + +#ifdef _WINDOWS64 + bool available = connectedControllers > 1; +#else + bool available = RenderManager.IsHiDef() && connectedControllers > 1; +#endif + +#ifdef __ORBIS__ + // Check for remote play + available = available && InputManager.IsLocalMultiplayerAvailable(); +#endif + + return available; + + // Found this in GameNetworkManager? + //#ifdef _DURANGO + // iOtherConnectedControllers = InputManager.GetConnectedGamepadCount(); + // if((InputManager.IsPadConnected(userIndex) || ProfileManager.IsSignedIn(userIndex))) + // { + // --iOtherConnectedControllers; + // } + //#else + // for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) + // { + // if( (i!=userIndex) && (InputManager.IsPadConnected(i) || ProfileManager.IsSignedIn(i)) ) + // { + // iOtherConnectedControllers++; + // } + // } + //#endif +} + + +// 4J-PB - language and locale function + +void CMinecraftApp::getLocale(vector &vecWstrLocales) +{ + vector locales; + + DWORD dwSystemLanguage = XGetLanguage( ); + + // 4J-PB - restrict the 360 language until we're ready to have them in + +#ifdef _XBOX + switch(dwSystemLanguage) + { + case XC_LANGUAGE_FRENCH : + locales.push_back(eMCLang_frFR); + break; + case XC_LANGUAGE_ITALIAN : + locales.push_back(eMCLang_itIT); + break; + case XC_LANGUAGE_GERMAN : + locales.push_back(eMCLang_deDE); + break; + case XC_LANGUAGE_SPANISH : + locales.push_back(eMCLang_esES); + break; + case XC_LANGUAGE_PORTUGUESE : + if(XGetLocale()==XC_LOCALE_BRAZIL) + { + locales.push_back(eMCLang_ptBR); + } + locales.push_back(eMCLang_ptPT); + break; + case XC_LANGUAGE_JAPANESE : + locales.push_back(eMCLang_jaJP); + break; + case XC_LANGUAGE_KOREAN : + locales.push_back(eMCLang_koKR); + break; + case XC_LANGUAGE_TCHINESE : + locales.push_back(eMCLang_zhCHT); + break; + } +#else + switch(dwSystemLanguage) + { + + case XC_LANGUAGE_ENGLISH: + switch(XGetLocale()) + { + case XC_LOCALE_AUSTRALIA: + case XC_LOCALE_CANADA: + case XC_LOCALE_CZECH_REPUBLIC: + case XC_LOCALE_GREECE: + case XC_LOCALE_HONG_KONG: + case XC_LOCALE_HUNGARY: + case XC_LOCALE_INDIA: + case XC_LOCALE_IRELAND: + case XC_LOCALE_ISRAEL: + case XC_LOCALE_NEW_ZEALAND: + case XC_LOCALE_SAUDI_ARABIA: + case XC_LOCALE_SINGAPORE: + case XC_LOCALE_SLOVAK_REPUBLIC: + case XC_LOCALE_SOUTH_AFRICA: + case XC_LOCALE_UNITED_ARAB_EMIRATES: + case XC_LOCALE_GREAT_BRITAIN: + locales.push_back(eMCLang_enGB); + break; + default: //XC_LOCALE_UNITED_STATES + break; + } + break; + case XC_LANGUAGE_JAPANESE : + locales.push_back(eMCLang_jaJP); + break; + case XC_LANGUAGE_GERMAN : + switch(XGetLocale()) + { + case XC_LOCALE_AUSTRIA: + locales.push_back(eMCLang_deAT); + break; + case XC_LOCALE_SWITZERLAND: + locales.push_back(eMCLang_deCH); + break; + default:// XC_LOCALE_GERMANY: + break; + } + locales.push_back(eMCLang_deDE); + break; + case XC_LANGUAGE_FRENCH : + switch(XGetLocale()) + { + case XC_LOCALE_BELGIUM: + locales.push_back(eMCLang_frBE); + break; + case XC_LOCALE_CANADA: + locales.push_back(eMCLang_frCA); + break; + case XC_LOCALE_SWITZERLAND: + locales.push_back(eMCLang_frCH); + break; + default:// XC_LOCALE_FRANCE: + break; + } + locales.push_back(eMCLang_frFR); + break; + case XC_LANGUAGE_SPANISH : + switch(XGetLocale()) + { + case XC_LOCALE_MEXICO: + case XC_LOCALE_ARGENTINA: + case XC_LOCALE_CHILE: + case XC_LOCALE_COLOMBIA: + case XC_LOCALE_UNITED_STATES: + case XC_LOCALE_LATIN_AMERICA: + locales.push_back(eMCLang_laLAS); + locales.push_back(eMCLang_esMX); + break; + default://XC_LOCALE_SPAIN + break; + } + locales.push_back(eMCLang_esES); + break; + case XC_LANGUAGE_ITALIAN : + locales.push_back(eMCLang_itIT); + break; + case XC_LANGUAGE_KOREAN : + locales.push_back(eMCLang_koKR); + break; + case XC_LANGUAGE_TCHINESE : + switch(XGetLocale()) + { + case XC_LOCALE_HONG_KONG: + locales.push_back(eMCLang_zhHK); + locales.push_back(eMCLang_zhTW); + break; + case XC_LOCALE_TAIWAN: + locales.push_back(eMCLang_zhTW); + locales.push_back(eMCLang_zhHK); + default: + break; + } + locales.push_back(eMCLang_hant); + locales.push_back(eMCLang_zhCHT); + break; + case XC_LANGUAGE_PORTUGUESE : + if(XGetLocale()==XC_LOCALE_BRAZIL) + { + locales.push_back(eMCLang_ptBR); + } + locales.push_back(eMCLang_ptPT); + break; + case XC_LANGUAGE_POLISH : + locales.push_back(eMCLang_plPL); + break; + case XC_LANGUAGE_RUSSIAN : + locales.push_back(eMCLang_ruRU); + break; + case XC_LANGUAGE_SWEDISH : + locales.push_back(eMCLang_svSV); + locales.push_back(eMCLang_svSE); + break; + case XC_LANGUAGE_TURKISH : + locales.push_back(eMCLang_trTR); + break; + case XC_LANGUAGE_BNORWEGIAN : + locales.push_back(eMCLang_nbNO); + locales.push_back(eMCLang_noNO); + locales.push_back(eMCLang_nnNO); + break; + case XC_LANGUAGE_DUTCH : + switch(XGetLocale()) + { + case XC_LOCALE_BELGIUM: + locales.push_back(eMCLang_nlBE); + break; + default: + break; + } + locales.push_back(eMCLang_nlNL); + break; + case XC_LANGUAGE_SCHINESE : + switch(XGetLocale()) + { + case XC_LOCALE_SINGAPORE: + locales.push_back(eMCLang_zhSG); + break; + default: + break; + } + locales.push_back(eMCLang_hans); + locales.push_back(eMCLang_csCS); + locales.push_back(eMCLang_zhCN); + break; + +#if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ || defined _DURANGO + case XC_LANGUAGE_DANISH: + locales.push_back(eMCLang_daDA); + locales.push_back(eMCLang_daDK); + break; + + case XC_LANGUAGE_FINISH : + locales.push_back(eMCLang_fiFI); + break; + + case XC_LANGUAGE_CZECH : + locales.push_back(eMCLang_csCZ); + locales.push_back(eMCLang_enCZ); + break; + + case XC_LANGUAGE_SLOVAK : + locales.push_back(eMCLang_skSK); + locales.push_back(eMCLang_enSK); + break; + + case XC_LANGUAGE_GREEK : + locales.push_back(eMCLang_elEL); + locales.push_back(eMCLang_elGR); + locales.push_back(eMCLang_enGR); + locales.push_back(eMCLang_enGB); + break; +#endif + } +#endif + + locales.push_back(eMCLang_enUS); + locales.push_back(eMCLang_null); + + for (size_t i=0; i= L'0' && ch <= L'9'; +} + +static bool isDataPackPckName(const wstring &baseNameLower) +{ + const wstring suffix = L"data.pck"; + if(baseNameLower.size() <= suffix.size() + 1) + { + return false; + } + if(baseNameLower[0] != L'x') + { + return false; + } + if(baseNameLower.compare(baseNameLower.size() - suffix.size(), suffix.size(), suffix) != 0) + { + return false; + } + const size_t digitsStart = 1; + const size_t digitsEnd = baseNameLower.size() - suffix.size(); + if(digitsEnd <= digitsStart) + { + return false; + } + for(size_t i = digitsStart; i < digitsEnd; ++i) + { + if(!isDigitW(baseNameLower[i])) + { + return false; + } + } + return true; +} + +static bool hasPckFolderFallback(const wstring &path, wstring &folderPath) +{ + wstring lowerPath = toLower(path); + const wstring pckSuffix = L".pck"; + if(lowerPath.size() <= pckSuffix.size()) + { + return false; + } + if(lowerPath.compare(lowerPath.size() - pckSuffix.size(), pckSuffix.size(), pckSuffix) != 0) + { + return false; + } + + const size_t nameStart = lowerPath.find_last_of(L"/\\"); + const size_t baseOffset = (nameStart == wstring::npos) ? 0 : (nameStart + 1); + wstring baseNameLower = lowerPath.substr(baseOffset); + if(!isDataPackPckName(baseNameLower)) + { + return false; + } + + folderPath = path.substr(0, path.size() - pckSuffix.size()); + return true; +} + +static DLCManager::EDLCType getFolderFileType(const wstring &path) +{ + wstring lowerPath = toLower(path); + if(lowerPath == L"colours.col" || lowerPath.rfind(L"/colours.col") != wstring::npos) + { + return DLCManager::e_DLCType_ColourTable; + } + if(lowerPath.rfind(L"/languages.loc") != wstring::npos || lowerPath.rfind(L".loc") != wstring::npos) + { + return DLCManager::e_DLCType_LocalisationData; + } + if(lowerPath.rfind(L".xzp") != wstring::npos) + { + return DLCManager::e_DLCType_UIData; + } + if(lowerPath.rfind(L".grf") != wstring::npos) + { + return DLCManager::e_DLCType_GameRulesHeader; + } + return DLCManager::e_DLCType_Texture; +} const WCHAR *DLCManager::wchTypeNamesA[]= { @@ -329,13 +414,47 @@ bool DLCManager::readDLCDataFile(DWORD &dwFilesProcessed, const string &path, DL } else if (fromArchive) return false; + wstring finalPathW = wPath; #ifdef _WINDOWS64 string finalPath = StorageManager.GetMountedPath(path.c_str()); if(finalPath.size() == 0) finalPath = path; - HANDLE file = CreateFile(finalPath.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + finalPathW = convStringToWstring(finalPath); #elif defined(_DURANGO) wstring finalPath = StorageManager.GetMountedPath(wPath.c_str()); if(finalPath.size() == 0) finalPath = wPath; + finalPathW = finalPath; +#endif + + if(!fromArchive) + { + wstring folderPath; + if(hasPckFolderFallback(finalPathW, folderPath)) + { + wstring resolvedFolderPath = folderPath; +#ifdef _WINDOWS64 + const char *folderPathA = wstringtofilename(folderPath); + string mountedFolderPath = StorageManager.GetMountedPath(folderPathA); + if(mountedFolderPath.size() > 0) + { + resolvedFolderPath = convStringToWstring(mountedFolderPath); + } +#elif defined(_DURANGO) + wstring mountedFolderPath = StorageManager.GetMountedPath(folderPath.c_str()); + if(mountedFolderPath.size() > 0) + { + resolvedFolderPath = mountedFolderPath; + } +#endif + if(readDLCDataFolder(dwFilesProcessed, resolvedFolderPath, pack)) + { + return true; + } + } + } + +#ifdef _WINDOWS64 + HANDLE file = CreateFile(finalPath.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); +#elif defined(_DURANGO) HANDLE file = CreateFile(finalPath.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); #else HANDLE file = CreateFile(path.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); @@ -372,6 +491,81 @@ bool DLCManager::readDLCDataFile(DWORD &dwFilesProcessed, const string &path, DL return processDLCDataFile(dwFilesProcessed, pbData, bytesRead, pack); } +bool DLCManager::readDLCDataFolder(DWORD &dwFilesProcessed, const wstring &path, DLCPack *pack) +{ + File folder(path); + if(!folder.exists() || !folder.isDirectory()) + { + return false; + } + + FolderFile folderFile(path); + vector *fileList = folderFile.getFileList(); + if(fileList == nullptr || fileList->empty()) + { + delete fileList; + return false; + } + + struct FolderEntry + { + wstring rawPath; + wstring normalizedPath; + int size; + }; + vector entries; + entries.reserve(fileList->size()); + + unsigned int totalBytes = 0; + for(const auto &rawPath : *fileList) + { + wstring normalized = replaceAll(rawPath, L"\\", L"/"); + if(normalized.empty() || normalized == L"0") + { + continue; + } + int size = folderFile.getFileSize(rawPath); + if(size <= 0) + { + continue; + } + entries.push_back({ rawPath, normalized, size }); + totalBytes += static_cast(size); + } + delete fileList; + + if(entries.empty() || totalBytes == 0) + { + return false; + } + + PBYTE dataBuffer = new BYTE[totalBytes]; + pack->SetDataPointer(dataBuffer); + + unsigned int offset = 0; + for(const auto &entry : entries) + { + byteArray data = folderFile.getFile(entry.rawPath); + if(data.data == nullptr || data.length == 0) + { + continue; + } + + DLCManager::EDLCType type = getFolderFileType(entry.normalizedPath); + DLCFile *dlcFile = pack->addFile(type, entry.normalizedPath); + if(dlcFile != nullptr) + { + memcpy(dataBuffer + offset, data.data, data.length); + dlcFile->addData(dataBuffer + offset, data.length); + offset += data.length; + ++dwFilesProcessed; + } + delete [] data.data; + } + + return dwFilesProcessed > 0; +} + bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD dwLength, DLCPack *pack) { unordered_map parameterMapping; diff --git a/Minecraft.Client/Common/DLC/DLCManager.h b/Minecraft.Client/Common/DLC/DLCManager.h index a51160d7..8a60a3c7 100644 --- a/Minecraft.Client/Common/DLC/DLCManager.h +++ b/Minecraft.Client/Common/DLC/DLCManager.h @@ -94,6 +94,7 @@ public: bool readDLCDataFile(DWORD &dwFilesProcessed, const wstring &path, DLCPack *pack, bool fromArchive = false); bool readDLCDataFile(DWORD &dwFilesProcessed, const string &path, DLCPack *pack, bool fromArchive = false); + bool readDLCDataFolder(DWORD &dwFilesProcessed, const wstring &path, DLCPack *pack); DWORD retrievePackIDFromDLCDataFile(const string &path, DLCPack *pack); static unsigned short SwapInt16(unsigned short value) { diff --git a/Minecraft.Client/Common/DLC/DLCPack.cpp b/Minecraft.Client/Common/DLC/DLCPack.cpp index 5f3874d0..e3dfcd00 100644 --- a/Minecraft.Client/Common/DLC/DLCPack.cpp +++ b/Minecraft.Client/Common/DLC/DLCPack.cpp @@ -416,15 +416,28 @@ bool DLCPack::hasPurchasedFile(DLCManager::EDLCType type, const wstring &path) void DLCPack::UpdateLanguage() { // find the language file - DLCManager::e_DLCType_LocalisationData; - DLCFile *file = nullptr; - - if(m_files[DLCManager::e_DLCType_LocalisationData].size() > 0) + if (m_files[DLCManager::e_DLCType_LocalisationData].empty()) { - file = m_files[DLCManager::e_DLCType_LocalisationData][0]; - DLCLocalisationFile *localisationFile = static_cast(getFile(DLCManager::e_DLCType_LocalisationData, L"languages.loc")); - StringTable *strTable = localisationFile->getStringTable(); - strTable->ReloadStringTable(); + return; } -} \ No newline at end of file + DLCFile *file = getFile(DLCManager::e_DLCType_LocalisationData, L"languages.loc"); + if (!file) + { + file = m_files[DLCManager::e_DLCType_LocalisationData][0]; + } + + DLCLocalisationFile *localisationFile = static_cast(file); + if (!localisationFile) + { + return; + } + + StringTable *strTable = localisationFile->getStringTable(); + if (!strTable) + { + return; + } + + strTable->ReloadStringTable(); +} diff --git a/Minecraft.Client/Common/GameRules/AddEnchantmentRuleDefinition.cpp b/Minecraft.Client/Common/GameRules/AddEnchantmentRuleDefinition.cpp index 0157be0b..43a4b759 100644 --- a/Minecraft.Client/Common/GameRules/AddEnchantmentRuleDefinition.cpp +++ b/Minecraft.Client/Common/GameRules/AddEnchantmentRuleDefinition.cpp @@ -50,9 +50,9 @@ bool AddEnchantmentRuleDefinition::enchantItem(shared_ptr item) { // 4J-JEV: Ripped code from enchantmenthelpers // Maybe we want to add an addEnchantment method to EnchantmentHelpers - if (item->id == Item::enchantedBook_Id) + if (item->id == Item::enchanted_book_Id) { - Item::enchantedBook->addEnchantment( item, new EnchantmentInstance(m_enchantmentId, m_enchantmentLevel) ); + Item::enchanted_book->addEnchantment( item, new EnchantmentInstance(m_enchantmentId, m_enchantmentLevel) ); } else if (item->isEnchantable()) { diff --git a/Minecraft.Client/Common/GameRules/GameRuleDefinition.cpp b/Minecraft.Client/Common/GameRules/GameRuleDefinition.cpp index a0d3f1e8..acf5274c 100644 --- a/Minecraft.Client/Common/GameRules/GameRuleDefinition.cpp +++ b/Minecraft.Client/Common/GameRules/GameRuleDefinition.cpp @@ -59,6 +59,7 @@ void GameRuleDefinition::addAttribute(const wstring &attributeName, const wstrin { m_descriptionId = attributeValue; #ifndef _CONTENT_PACKAGE + if (m_descriptionId == L"IDS_COLLECTED_MUSIC_DISCS") m_descriptionId = L"You have found {*progress*} of {*goal*} Music Discs!"; wprintf(L"GameRuleDefinition: Adding parameter descriptionId=%ls\n",m_descriptionId.c_str()); #endif } @@ -74,6 +75,11 @@ void GameRuleDefinition::addAttribute(const wstring &attributeName, const wstrin m_4JDataValue = _fromString(attributeValue); app.DebugPrintf("GameRuleDefinition: Adding parameter m_4JDataValue=%d\n",m_4JDataValue); } + else if(attributeName.compare(L"goalType") == 0) + { + m_4JDataValue = _fromString(attributeValue); + app.DebugPrintf("GameRuleDefinition: Adding parameter goalType=%d\n",m_4JDataValue); + } else { #ifndef _CONTENT_PACKAGE diff --git a/Minecraft.Client/Common/GameRules/LevelGenerationOptions.h b/Minecraft.Client/Common/GameRules/LevelGenerationOptions.h index dee60c82..26f7b23b 100644 --- a/Minecraft.Client/Common/GameRules/LevelGenerationOptions.h +++ b/Minecraft.Client/Common/GameRules/LevelGenerationOptions.h @@ -13,6 +13,7 @@ class ConsoleSchematicFile; class LevelRuleset; class BiomeOverride; class StartFeature; +class DLCPack; class GrSource { @@ -135,6 +136,7 @@ public: void setBaseSavePath(const wstring &x); bool ready(); + DLCPack *getParentDLCPack() { return m_parentDLCPack; } void setBaseSaveData(PBYTE pbData, DWORD dwSize); PBYTE getBaseSaveData(DWORD &size); diff --git a/Minecraft.Client/Common/GameRules/XboxStructureActionPlaceSpawner.cpp b/Minecraft.Client/Common/GameRules/XboxStructureActionPlaceSpawner.cpp index 83e3d294..ce6ef69b 100644 --- a/Minecraft.Client/Common/GameRules/XboxStructureActionPlaceSpawner.cpp +++ b/Minecraft.Client/Common/GameRules/XboxStructureActionPlaceSpawner.cpp @@ -7,7 +7,7 @@ XboxStructureActionPlaceSpawner::XboxStructureActionPlaceSpawner() { - m_tile = Tile::mobSpawner_Id; + m_tile = Tile::mob_spawner_Id; m_entityId = L"Pig"; } diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Controls1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/Controls1080.swf index 9ec38f92..2f7a232a 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/Controls1080.swf and b/Minecraft.Client/Common/Media/MediaWindows64/Controls1080.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Controls720.swf b/Minecraft.Client/Common/Media/MediaWindows64/Controls720.swf index 61eb9c83..40cfe29d 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/Controls720.swf and b/Minecraft.Client/Common/Media/MediaWindows64/Controls720.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/ControlsSplit1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/ControlsSplit1080.swf index e7c1c971..33e81aad 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/ControlsSplit1080.swf and b/Minecraft.Client/Common/Media/MediaWindows64/ControlsSplit1080.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/ControlsSplit720.swf b/Minecraft.Client/Common/Media/MediaWindows64/ControlsSplit720.swf index 8f657ac9..4586cb05 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/ControlsSplit720.swf and b/Minecraft.Client/Common/Media/MediaWindows64/ControlsSplit720.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/CreateWorldMenu720.swf b/Minecraft.Client/Common/Media/MediaWindows64/CreateWorldMenu720.swf index b2d044d4..6a698bc3 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/CreateWorldMenu720.swf and b/Minecraft.Client/Common/Media/MediaWindows64/CreateWorldMenu720.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/HD/PS4HD.swf b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/HD/PS4HD.swf new file mode 100644 index 00000000..2d854158 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/HD/PS4HD.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/HD/xbox360HD.swf b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/HD/xbox360HD.swf new file mode 100644 index 00000000..c18d4ed6 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/HD/xbox360HD.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/HD/xboxOne.swf b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/HD/xboxOne.swf new file mode 100644 index 00000000..464cb346 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/HD/xboxOne.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/HD/xboxOneHD.swf b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/HD/xboxOneHD.swf new file mode 100644 index 00000000..464cb346 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/HD/xboxOneHD.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/PS3.swf b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/PS3.swf new file mode 100644 index 00000000..4316c234 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/PS3.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/PS4.swf b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/PS4.swf new file mode 100644 index 00000000..f7c64ef0 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/PS4.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/Panorama/Panorama_N.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/Panorama/Panorama_N.png new file mode 100644 index 00000000..8501cd40 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/Panorama/Panorama_N.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/Panorama/Panorama_S.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/Panorama/Panorama_S.png new file mode 100644 index 00000000..f15b4a43 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/Panorama/Panorama_S.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/WiiU.swf b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/WiiU.swf new file mode 100644 index 00000000..23d30190 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/WiiU.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/vita.swf b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/vita.swf new file mode 100644 index 00000000..29b08e74 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/vita.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/xbox360.swf b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/xbox360.swf new file mode 100644 index 00000000..9389645d Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/xbox360.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/xboxOne.swf b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/xboxOne.swf new file mode 100644 index 00000000..6bcdbb6e Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/ControlType/xboxOne.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1024.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1024.png new file mode 100644 index 00000000..46c290ab Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1024.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1025.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1025.png new file mode 100644 index 00000000..c4159a86 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1025.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1026.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1026.png new file mode 100644 index 00000000..183419de Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1026.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1029.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1029.png new file mode 100644 index 00000000..f6b698ee Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1029.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1030.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1030.png new file mode 100644 index 00000000..2ec62675 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1030.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1031.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1031.png new file mode 100644 index 00000000..51346e22 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1031.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1033.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1033.png new file mode 100644 index 00000000..d6059a68 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1033.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1034.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1034.png new file mode 100644 index 00000000..efb97029 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1034.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1268.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1268.png new file mode 100644 index 00000000..d4c15fc8 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1268.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1269.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1269.png new file mode 100644 index 00000000..3f7301bc Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/1269.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/512.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/512.png new file mode 100644 index 00000000..ec0686e9 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/512.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/513.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/513.png new file mode 100644 index 00000000..ef593683 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/513.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/514.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/514.png new file mode 100644 index 00000000..4911fc9c Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/514.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/515.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/515.png new file mode 100644 index 00000000..1ff56c3f Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/515.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/517.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/517.png new file mode 100644 index 00000000..d6059a68 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/517.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/518.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/518.png new file mode 100644 index 00000000..d637d4e0 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/518.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/519.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/519.png new file mode 100644 index 00000000..75681a65 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/519.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/520.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/520.png new file mode 100644 index 00000000..12aa908a Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/520.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/521.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/521.png new file mode 100644 index 00000000..feaea90d Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/521.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/522.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/522.png new file mode 100644 index 00000000..20fa24ea Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/522.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/524.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/524.png new file mode 100644 index 00000000..3a6ce073 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/524.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/525.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/525.png new file mode 100644 index 00000000..8978607e Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/525.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/527.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/527.png new file mode 100644 index 00000000..cb069af1 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/527.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/529.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/529.png new file mode 100644 index 00000000..536e54c9 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/529.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/530.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/530.png new file mode 100644 index 00000000..982554ec Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/530.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/532.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/532.png new file mode 100644 index 00000000..d60a740c Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/532.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/533.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/533.png new file mode 100644 index 00000000..1ea547b8 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/533.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/534.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/534.png new file mode 100644 index 00000000..c3fd7ddb Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/534.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/535.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/535.png new file mode 100644 index 00000000..c515f8ae Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/535.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/536.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/536.png new file mode 100644 index 00000000..3843b8a6 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/536.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/537.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/537.png new file mode 100644 index 00000000..1b81c21c Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/537.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/538.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/538.png new file mode 100644 index 00000000..2704d06a Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/538.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/539.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/539.png new file mode 100644 index 00000000..04cd0a7a Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/539.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/540.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/540.png new file mode 100644 index 00000000..985707dc Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/540.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/541.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/541.png new file mode 100644 index 00000000..67e943b4 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/541.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/542.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/542.png new file mode 100644 index 00000000..4619bab0 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/542.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/546.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/546.png new file mode 100644 index 00000000..5e1c46b5 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/546.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/547.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/547.png new file mode 100644 index 00000000..6ad023a7 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/547.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/548.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/548.png new file mode 100644 index 00000000..0e3856f8 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/548.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/550.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/550.png new file mode 100644 index 00000000..a39b51ea Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/550.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/default.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/default.png new file mode 100644 index 00000000..eb42dc0d Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/default.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/playStation.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/playStation.png new file mode 100644 index 00000000..abc950b9 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/playStation.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/wiiU.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/wiiU.png new file mode 100644 index 00000000..b91d0f75 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/wiiU.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/xbox360.png b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/xbox360.png new file mode 100644 index 00000000..8b1ef2c0 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/Graphics/PackGraphics/xbox360.png differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/LoadMenu720.swf b/Minecraft.Client/Common/Media/MediaWindows64/LoadMenu720.swf index 7a82499f..f70f90fc 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/LoadMenu720.swf and b/Minecraft.Client/Common/Media/MediaWindows64/LoadMenu720.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/MultilistMenu1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/MultilistMenu1080.swf new file mode 100644 index 00000000..1c8adadc Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/MultilistMenu1080.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/MultilistMenu720.swf b/Minecraft.Client/Common/Media/MediaWindows64/MultilistMenu720.swf new file mode 100644 index 00000000..df0f958c Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/MultilistMenu720.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/MultilistMenuSplit1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/MultilistMenuSplit1080.swf new file mode 100644 index 00000000..1c4b279e Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/MultilistMenuSplit1080.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/MultilistMenuSplit720.swf b/Minecraft.Client/Common/Media/MediaWindows64/MultilistMenuSplit720.swf new file mode 100644 index 00000000..748facf3 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/MultilistMenuSplit720.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Panorama1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/Panorama1080.swf deleted file mode 100644 index a73b2b85..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/Panorama1080.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Panorama480.swf b/Minecraft.Client/Common/Media/MediaWindows64/Panorama480.swf deleted file mode 100644 index 9cd162a2..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/Panorama480.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/Panorama720.swf b/Minecraft.Client/Common/Media/MediaWindows64/Panorama720.swf deleted file mode 100644 index 07cc2e36..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/Panorama720.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/PanoramaSplit1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/PanoramaSplit1080.swf deleted file mode 100644 index f0178099..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/PanoramaSplit1080.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/PanoramaSplit720.swf b/Minecraft.Client/Common/Media/MediaWindows64/PanoramaSplit720.swf deleted file mode 100644 index 459e7bc9..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/PanoramaSplit720.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/PanoramaVita.swf b/Minecraft.Client/Common/Media/MediaWindows64/PanoramaVita.swf deleted file mode 100644 index 281d0cf7..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/PanoramaVita.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenu1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenu1080.swf index cc3330ab..7e731522 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenu1080.swf and b/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenu1080.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenu480.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenu480.swf deleted file mode 100644 index aaa79aee..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenu480.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenu720.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenu720.swf deleted file mode 100644 index 45993245..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenu720.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenuSplit1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenuSplit1080.swf index 6115bf4f..99d2251b 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenuSplit1080.swf and b/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenuSplit1080.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenuSplit720.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenuSplit720.swf deleted file mode 100644 index 7dd3f025..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenuSplit720.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenuVita.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenuVita.swf deleted file mode 100644 index 86e7295c..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsAudioMenuVita.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenu1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenu1080.swf deleted file mode 100644 index 19f88ec2..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenu1080.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenu480.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenu480.swf deleted file mode 100644 index 1e05af61..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenu480.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenu720.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenu720.swf deleted file mode 100644 index 983e879e..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenu720.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenuSplit1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenuSplit1080.swf deleted file mode 100644 index 58770d0a..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenuSplit1080.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenuSplit720.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenuSplit720.swf deleted file mode 100644 index 2893aac0..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenuSplit720.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenuVita.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenuVita.swf deleted file mode 100644 index dcf91a67..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsControlMenuVita.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenu1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenu1080.swf index ffe2701a..39fc0dd4 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenu1080.swf and b/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenu1080.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenu480.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenu480.swf deleted file mode 100644 index f47956ae..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenu480.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenu720.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenu720.swf deleted file mode 100644 index 19db4f33..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenu720.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenuSplit1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenuSplit1080.swf index 5f134779..0b3713ae 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenuSplit1080.swf and b/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenuSplit1080.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenuSplit720.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenuSplit720.swf deleted file mode 100644 index 842d2123..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenuSplit720.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenuVita.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenuVita.swf deleted file mode 100644 index 5f345e76..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsGraphicsMenuVita.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenu1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenu1080.swf index 9e922acd..626b1d0c 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenu1080.swf and b/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenu1080.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenu480.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenu480.swf deleted file mode 100644 index 4f94774b..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenu480.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenu720.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenu720.swf deleted file mode 100644 index 38371275..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenu720.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenuSplit1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenuSplit1080.swf index 467b2e1f..35998343 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenuSplit1080.swf and b/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenuSplit1080.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenuSplit720.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenuSplit720.swf deleted file mode 100644 index 7c504168..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenuSplit720.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenuVita.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenuVita.swf deleted file mode 100644 index b8bd51b7..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsMenuVita.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenu1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenu1080.swf index ede96935..dfefaf46 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenu1080.swf and b/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenu1080.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenu480.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenu480.swf deleted file mode 100644 index d3d5b93e..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenu480.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenu720.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenu720.swf deleted file mode 100644 index ce8434bf..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenu720.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenuSplit1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenuSplit1080.swf index b435a238..cfceefcf 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenuSplit1080.swf and b/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenuSplit1080.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenuSplit720.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenuSplit720.swf deleted file mode 100644 index d178d4cb..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenuSplit720.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenuVita.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenuVita.swf deleted file mode 100644 index 562a0c22..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsOptionsMenuVita.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsUIMenu1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsUIMenu1080.swf new file mode 100644 index 00000000..78b8aa2c Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/SettingsUIMenu1080.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsUIMenu720.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsUIMenu720.swf deleted file mode 100644 index 7fd4cca9..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsUIMenu720.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsUIMenuSplit1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsUIMenuSplit1080.swf index 18128a0e..055f36e8 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsUIMenuSplit1080.swf and b/Minecraft.Client/Common/Media/MediaWindows64/SettingsUIMenuSplit1080.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsUIMenuSplit720.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsUIMenuSplit720.swf deleted file mode 100644 index 82c22145..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsUIMenuSplit720.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SettingsUIMenuVita.swf b/Minecraft.Client/Common/Media/MediaWindows64/SettingsUIMenuVita.swf deleted file mode 100644 index 76eaf79d..00000000 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SettingsUIMenuVita.swf and /dev/null differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenu1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenu1080.swf index 5eaf67fb..fc9abf52 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenu1080.swf and b/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenu1080.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenu480.swf b/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenu480.swf index 236bb593..b37ea799 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenu480.swf and b/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenu480.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenu720.swf b/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenu720.swf index 059ae199..a0abbde0 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenu720.swf and b/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenu720.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenuSplit1080.swf b/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenuSplit1080.swf index 03c532fe..75a911c4 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenuSplit1080.swf and b/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenuSplit1080.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenuSplit720.swf b/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenuSplit720.swf index a49f20e8..c227d66f 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenuSplit720.swf and b/Minecraft.Client/Common/Media/MediaWindows64/SkinSelectMenuSplit720.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/skinGraphicsLabelsLC.swf b/Minecraft.Client/Common/Media/MediaWindows64/skinGraphicsLabelsLC.swf new file mode 100644 index 00000000..5ed1670c Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/skinGraphicsLabelsLC.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/skinHDGraphics.swf b/Minecraft.Client/Common/Media/MediaWindows64/skinHDGraphics.swf index 8ef923d9..26a0fa92 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64/skinHDGraphics.swf and b/Minecraft.Client/Common/Media/MediaWindows64/skinHDGraphics.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/skinHDGraphicsDR.swf b/Minecraft.Client/Common/Media/MediaWindows64/skinHDGraphicsDR.swf new file mode 100644 index 00000000..6108d609 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/skinHDGraphicsDR.swf differ diff --git a/Minecraft.Client/Common/Network/GameNetworkManager.cpp b/Minecraft.Client/Common/Network/GameNetworkManager.cpp index 0e83c8b2..1a3a7bd7 100644 --- a/Minecraft.Client/Common/Network/GameNetworkManager.cpp +++ b/Minecraft.Client/Common/Network/GameNetworkManager.cpp @@ -988,6 +988,13 @@ int CGameNetworkManager::RunNetworkGameThreadProc( void* lpParameter ) int CGameNetworkManager::ServerThreadProc( void* lpParameter ) { int64_t seed = 0; + + Compression::UseDefaultThreadStorage(); + if (Compression::getCompression() == nullptr) + { + Compression::CreateNewThreadStorage(); + } + if (lpParameter != nullptr) { NetworkGameInitData *param = static_cast(lpParameter); @@ -1027,6 +1034,7 @@ int CGameNetworkManager::ServerThreadProc( void* lpParameter ) AABB::ReleaseThreadStorage(); Vec3::ReleaseThreadStorage(); IntCache::ReleaseThreadStorage(); + Compression::ReleaseThreadStorage(); Level::destroyLightingCache(); if(lpParameter != nullptr) delete lpParameter; diff --git a/Minecraft.Client/Common/Tutorial/ChoiceTask.cpp b/Minecraft.Client/Common/Tutorial/ChoiceTask.cpp index 8a45ee02..8e0b4bfa 100644 --- a/Minecraft.Client/Common/Tutorial/ChoiceTask.cpp +++ b/Minecraft.Client/Common/Tutorial/ChoiceTask.cpp @@ -40,6 +40,9 @@ bool ChoiceTask::isCompleted() return false; int xboxPad = pMinecraft->player->GetXboxPad(); + int tutorialPad = tutorial->getPad(); + bool hasValidPad = (tutorialPad >= 0 && tutorialPad < XUSER_MAX_COUNT); + bool menuDisplayed = hasValidPad && ui.GetMenuDisplayed(tutorialPad); if( m_bConfirmMappingComplete || m_bCancelMappingComplete ) { @@ -48,14 +51,10 @@ bool ChoiceTask::isCompleted() return true; } - if(ui.GetMenuDisplayed(tutorial->getPad())) - { - // If a menu is displayed, then we use the handleUIInput to complete the task - } - else + if(!menuDisplayed) { // If the player is under water then allow all keypresses so they can jump out - if (pMinecraft->localplayers[tutorial->getPad()]->isUnderLiquid(Material::water)) return false; + if (hasValidPad && pMinecraft->localplayers[tutorialPad] != nullptr && pMinecraft->localplayers[tutorialPad]->isUnderLiquid(Material::water)) return false; #ifdef _WINDOWS64 if (!m_bConfirmMappingComplete && (InputManager.GetValue(xboxPad, m_iConfirmMapping) > 0 @@ -85,8 +84,9 @@ bool ChoiceTask::isCompleted() sendTelemetry(); enableConstraints(false, true); } - return m_bConfirmMappingComplete || m_bCancelMappingComplete; } + + return m_bConfirmMappingComplete || m_bCancelMappingComplete; } eTutorial_CompletionAction ChoiceTask::getCompletionAction() diff --git a/Minecraft.Client/Common/Tutorial/FullTutorial.cpp b/Minecraft.Client/Common/Tutorial/FullTutorial.cpp index e3faa4d4..6ef13419 100644 --- a/Minecraft.Client/Common/Tutorial/FullTutorial.cpp +++ b/Minecraft.Client/Common/Tutorial/FullTutorial.cpp @@ -75,7 +75,7 @@ FullTutorial::FullTutorial(int iPad, bool isTrial /*= false*/) int mineMappings[] = {MINECRAFT_ACTION_ACTION}; addTask(e_Tutorial_State_Gameplay, new ControllerTask( this, IDS_TUTORIAL_TASK_MINE, false, true, mineMappings, 1) ); - addTask(e_Tutorial_State_Gameplay, new PickupTask( Tile::treeTrunk_Id, 4, -1, this, IDS_TUTORIAL_TASK_CHOP_WOOD ) ); + addTask(e_Tutorial_State_Gameplay, new PickupTask( Tile::log_Id, 4, -1, this, IDS_TUTORIAL_TASK_CHOP_WOOD ) ); int scrollMappings[] = {MINECRAFT_ACTION_LEFT_SCROLL,MINECRAFT_ACTION_RIGHT_SCROLL}; //int scrollMappings[] = {ACTION_MENU_LEFT_SCROLL,ACTION_MENU_RIGHT_SCROLL}; @@ -92,9 +92,9 @@ FullTutorial::FullTutorial(int iPad, bool isTrial /*= false*/) addTask(e_Tutorial_State_Gameplay, new InfoTask(this, IDS_TUTORIAL_TASK_FOOD_BAR_FEED, IDS_TUTORIAL_PROMPT_PRESS_A_TO_CONTINUE, true, ACTION_MENU_A) ); // While they should only eat the item we give them, includ the ability to complete this task with different items - int foodItems[] = {Item::mushroomStew_Id, Item::apple_Id, Item::bread_Id, Item::porkChop_raw_Id, Item::porkChop_cooked_Id, - Item::apple_gold_Id, Item::fish_raw_Id, Item::fish_cooked_Id, Item::cookie_Id, Item::beef_cooked_Id, - Item::beef_raw_Id, Item::chicken_cooked_Id, Item::chicken_raw_Id, Item::melon_Id, Item::rotten_flesh_Id}; + int foodItems[] = {Item::mushroom_stew_Id, Item::apple_Id, Item::bread_Id, Item::porkchop_Id, Item::cooked_porkchop_Id, + Item::golden_apple_Id, Item::fish_Id, Item::cooked_fish_Id, Item::cookie_Id, Item::cooked_beef_Id, + Item::beef_Id, Item::cooked_chicken_Id, Item::chicken_Id, Item::melon_block_Id, Item::rotten_flesh_Id}; addTask(e_Tutorial_State_Gameplay, new CompleteUsingItemTask(this, IDS_TUTORIAL_TASK_FOOD_BAR_EAT_STEAK, foodItems, 15, true) ); int crftMappings[] = {MINECRAFT_ACTION_CRAFTING}; @@ -103,13 +103,13 @@ FullTutorial::FullTutorial(int iPad, bool isTrial /*= false*/) addTask(e_Tutorial_State_Gameplay, new ProgressFlagTask( &m_progressFlags, FULL_TUTORIAL_PROGRESS_2_X_2_Crafting, ProgressFlagTask::e_Progress_Set_Flag, this ) ); addTask(e_Tutorial_State_Gameplay, new StateChangeTask( e_Tutorial_State_2x2Crafting_Menu, this) ); - addTask(e_Tutorial_State_Gameplay, new CraftTask( Tile::wood_Id, -1, 1, this, IDS_TUTORIAL_TASK_CREATE_PLANKS) ); - addTask(e_Tutorial_State_Gameplay, new CraftTask( Tile::workBench_Id, -1, 1, this, IDS_TUTORIAL_TASK_CREATE_CRAFTING_TABLE) ); + addTask(e_Tutorial_State_Gameplay, new CraftTask( Tile::planks_Id, -1, 1, this, IDS_TUTORIAL_TASK_CREATE_PLANKS) ); + addTask(e_Tutorial_State_Gameplay, new CraftTask( Tile::crafting_table_Id, -1, 1, this, IDS_TUTORIAL_TASK_CREATE_CRAFTING_TABLE) ); //int useMappings[] = {MINECRAFT_ACTION_USE}; //addTask(e_Tutorial_State_Gameplay, new ControllerTask( this, IDS_TUTORIAL_TASK_USE, false, false, useMappings, 1) ); addTask(e_Tutorial_State_Gameplay, new InfoTask(this, IDS_TUTORIAL_TASK_USE, IDS_TUTORIAL_PROMPT_PRESS_A_TO_CONTINUE, true, ACTION_MENU_A) ); - addTask(e_Tutorial_State_Gameplay, new UseItemTask( Tile::workBench_Id, this, IDS_TUTORIAL_TASK_PLACE_WORKBENCH, true ) ); + addTask(e_Tutorial_State_Gameplay, new UseItemTask( Tile::crafting_table_Id, this, IDS_TUTORIAL_TASK_PLACE_WORKBENCH, true ) ); addTask(e_Tutorial_State_Gameplay, new InfoTask(this, IDS_TUTORIAL_TASK_NIGHT_DANGER, IDS_TUTORIAL_PROMPT_PRESS_A_TO_CONTINUE, true, ACTION_MENU_A) ); addTask(e_Tutorial_State_Gameplay, new InfoTask(this, IDS_TUTORIAL_TASK_NEARBY_SHELTER, IDS_TUTORIAL_PROMPT_PRESS_A_TO_CONTINUE, true, ACTION_MENU_A) ); @@ -121,22 +121,22 @@ FullTutorial::FullTutorial(int iPad, bool isTrial /*= false*/) // START OF FULL TUTORIAL - addTask(e_Tutorial_State_Gameplay, new UseTileTask( Tile::workBench_Id, this, IDS_TUTORIAL_TASK_OPEN_WORKBENCH, false ) ); + addTask(e_Tutorial_State_Gameplay, new UseTileTask( Tile::crafting_table_Id, this, IDS_TUTORIAL_TASK_OPEN_WORKBENCH, false ) ); addTask(e_Tutorial_State_Gameplay, new ProgressFlagTask( &m_progressFlags, FULL_TUTORIAL_PROGRESS_3_X_3_Crafting, ProgressFlagTask::e_Progress_Set_Flag, this ) ); addTask(e_Tutorial_State_Gameplay, new StateChangeTask( e_Tutorial_State_3x3Crafting_Menu, this) ); addTask(e_Tutorial_State_Gameplay, new CraftTask( Item::stick->id, -1, 1, this, IDS_TUTORIAL_TASK_CREATE_STICKS) ); - int shovelItems[] = {Item::shovel_wood->id, Item::shovel_stone->id, Item::shovel_iron->id, Item::shovel_gold->id, Item::shovel_diamond->id}; + int shovelItems[] = {Item::wooden_shovel->id, Item::stone_shovel->id, Item::iron_shovel->id, Item::golden_shovel->id, Item::diamond_shovel->id}; int shovelAuxVals[] = {-1,-1,-1,-1,-1}; addTask(e_Tutorial_State_Gameplay, new CraftTask( shovelItems, shovelAuxVals, 5, 1, this, IDS_TUTORIAL_TASK_CREATE_WOODEN_SHOVEL) ); - int hatchetItems[] = {Item::hatchet_wood->id, Item::hatchet_stone->id, Item::hatchet_iron->id, Item::hatchet_gold->id, Item::hatchet_diamond->id}; + int hatchetItems[] = {Item::wooden_axe->id, Item::stone_axe->id, Item::iron_axe->id, Item::golden_axe->id, Item::diamond_axe->id}; int hatchetAuxVals[] = {-1,-1,-1,-1,-1}; addTask(e_Tutorial_State_Gameplay, new CraftTask( hatchetItems, hatchetAuxVals, 5, 1, this, IDS_TUTORIAL_TASK_CREATE_WOODEN_HATCHET) ); - int pickaxeItems[] = {Item::pickAxe_wood->id, Item::pickAxe_stone->id, Item::pickAxe_iron->id, Item::pickAxe_gold->id, Item::pickAxe_diamond->id}; + int pickaxeItems[] = {Item::wooden_pickaxe->id, Item::stone_pickaxe->id, Item::iron_pickaxe->id, Item::golden_pickaxe->id, Item::diamond_pickaxe->id}; int pickaxeAuxVals[] = {-1,-1,-1,-1,-1}; addTask(e_Tutorial_State_Gameplay, new CraftTask( pickaxeItems, pickaxeAuxVals, 5, 1, this, IDS_TUTORIAL_TASK_CREATE_WOODEN_PICKAXE) ); @@ -150,8 +150,8 @@ FullTutorial::FullTutorial(int iPad, bool isTrial /*= false*/) addTask(e_Tutorial_State_Gameplay, new StateChangeTask( e_Tutorial_State_Furnace_Menu, this) ); addTask(e_Tutorial_State_Gameplay, new CraftTask( Item::coal->id, -1, 1, this, IDS_TUTORIAL_TASK_CREATE_CHARCOAL) ); addTask(e_Tutorial_State_Gameplay, new CraftTask( Tile::glass_Id, -1, 1, this, IDS_TUTORIAL_TASK_CREATE_GLASS) ); - addTask(e_Tutorial_State_Gameplay, new CraftTask( Item::door_wood->id, -1, 1, this, IDS_TUTORIAL_TASK_CREATE_WOODEN_DOOR) ); - addTask(e_Tutorial_State_Gameplay, new UseItemTask(Item::door_wood->id, this, IDS_TUTORIAL_TASK_PLACE_DOOR) ); + addTask(e_Tutorial_State_Gameplay, new CraftTask( Item::wooden_door->id, -1, 1, this, IDS_TUTORIAL_TASK_CREATE_WOODEN_DOOR) ); + addTask(e_Tutorial_State_Gameplay, new UseItemTask(Item::wooden_door->id, this, IDS_TUTORIAL_TASK_PLACE_DOOR) ); addTask(e_Tutorial_State_Gameplay, new CraftTask( Tile::torch_Id, -1, 1, this, IDS_TUTORIAL_TASK_CREATE_TORCH) ); if(app.getGameRuleDefinitions() != nullptr) @@ -201,12 +201,12 @@ FullTutorial::FullTutorial(int iPad, bool isTrial /*= false*/) addTask(e_Tutorial_State_2x2Crafting_Menu, new FullTutorialActiveTask( this, e_Tutorial_Completion_Complete_State) ); - addTask(e_Tutorial_State_2x2Crafting_Menu, new CraftTask( Tile::wood_Id, -1, 1, this, IDS_TUTORIAL_TASK_CRAFT_CREATE_PLANKS) ); + addTask(e_Tutorial_State_2x2Crafting_Menu, new CraftTask( Tile::planks_Id, -1, 1, this, IDS_TUTORIAL_TASK_CRAFT_CREATE_PLANKS) ); ProcedureCompoundTask *workbenchCompound = new ProcedureCompoundTask( this ); workbenchCompound->AddTask( new XuiCraftingTask( this, IDS_TUTORIAL_TASK_CRAFT_SELECT_STRUCTURES, Recipy::eGroupType_Structure) ); - workbenchCompound->AddTask( new XuiCraftingTask( this, IDS_TUTORIAL_TASK_CRAFT_SELECT_CRAFTING_TABLE, Tile::workBench_Id) ); - workbenchCompound->AddTask( new CraftTask( Tile::workBench_Id, -1, 1, this, IDS_TUTORIAL_TASK_CREATE_CRAFTING_TABLE) ); + workbenchCompound->AddTask( new XuiCraftingTask( this, IDS_TUTORIAL_TASK_CRAFT_SELECT_CRAFTING_TABLE, Tile::crafting_table_Id) ); + workbenchCompound->AddTask( new CraftTask( Tile::crafting_table_Id, -1, 1, this, IDS_TUTORIAL_TASK_CREATE_CRAFTING_TABLE) ); addTask(e_Tutorial_State_2x2Crafting_Menu, workbenchCompound ); addTask(e_Tutorial_State_2x2Crafting_Menu, new InfoTask(this, IDS_TUTORIAL_TASK_CRAFT_EXIT_AND_PLACE_TABLE, -1, false, ACTION_MENU_B) ); @@ -219,7 +219,7 @@ FullTutorial::FullTutorial(int iPad, bool isTrial /*= false*/) ProcedureCompoundTask *shovelCompound = new ProcedureCompoundTask( this ); shovelCompound->AddTask( new XuiCraftingTask( this, IDS_TUTORIAL_TASK_CRAFT_SELECT_TOOLS, Recipy::eGroupType_Tool) ); - shovelCompound->AddTask( new XuiCraftingTask( this, IDS_TUTORIAL_TASK_CRAFT_SELECT_WOODEN_SHOVEL, Item::shovel_wood->id) ); + shovelCompound->AddTask( new XuiCraftingTask( this, IDS_TUTORIAL_TASK_CRAFT_SELECT_WOODEN_SHOVEL, Item::wooden_shovel->id) ); shovelCompound->AddTask( new CraftTask( shovelItems, shovelAuxVals, 5, 1, this, IDS_TUTORIAL_TASK_CREATE_WOODEN_SHOVEL) ); addTask(e_Tutorial_State_3x3Crafting_Menu, shovelCompound ); addTask(e_Tutorial_State_3x3Crafting_Menu, new CraftTask( hatchetItems, hatchetAuxVals, 5, 1, this, IDS_TUTORIAL_TASK_CREATE_WOODEN_HATCHET) ); @@ -234,7 +234,7 @@ FullTutorial::FullTutorial(int iPad, bool isTrial /*= false*/) addTask(e_Tutorial_State_3x3Crafting_Menu, new InfoTask(this, IDS_TUTORIAL_TASK_CRAFT_EXIT_AND_PLACE_FURNACE, -1, false, ACTION_MENU_B) ); // No need to block here, as it's fine if the player wants to do this out of order - addTask(e_Tutorial_State_3x3Crafting_Menu, new CraftTask( Item::door_wood->id, -1, 1, this, IDS_TUTORIAL_TASK_CREATE_WOODEN_DOOR) ); + addTask(e_Tutorial_State_3x3Crafting_Menu, new CraftTask( Item::wooden_door->id, -1, 1, this, IDS_TUTORIAL_TASK_CREATE_WOODEN_DOOR) ); addTask(e_Tutorial_State_3x3Crafting_Menu, new CraftTask( Tile::torch_Id, -1, 1, this, IDS_TUTORIAL_TASK_CREATE_TORCH) ); /* @@ -445,7 +445,7 @@ FullTutorial::FullTutorial(int iPad, bool isTrial /*= false*/) addTask(e_Tutorial_State_Brewing, new ChoiceTask(this, IDS_TUTORIAL_TASK_BREWING_OVERVIEW, IDS_TUTORIAL_PROMPT_BREWING_OVERVIEW, true, ACTION_MENU_A, ACTION_MENU_B, e_Tutorial_Completion_Complete_State_Gameplay_Constraints, eTelemetryTutorial_Brewing) ); ProcedureCompoundTask *fillWaterBottleTask = new ProcedureCompoundTask( this ); - fillWaterBottleTask->AddTask( new PickupTask( Item::glassBottle_Id, 1, -1, this, IDS_TUTORIAL_TASK_BREWING_GET_GLASS_BOTTLE ) ); + fillWaterBottleTask->AddTask( new PickupTask( Item::glass_bottle_Id, 1, -1, this, IDS_TUTORIAL_TASK_BREWING_GET_GLASS_BOTTLE ) ); fillWaterBottleTask->AddTask( new PickupTask( Item::potion_Id, 1, 0, this, IDS_TUTORIAL_TASK_BREWING_FILL_GLASS_BOTTLE ) ); addTask(e_Tutorial_State_Brewing, fillWaterBottleTask); diff --git a/Minecraft.Client/Common/Tutorial/InfoTask.cpp b/Minecraft.Client/Common/Tutorial/InfoTask.cpp index 1d148d60..c2279e9b 100644 --- a/Minecraft.Client/Common/Tutorial/InfoTask.cpp +++ b/Minecraft.Client/Common/Tutorial/InfoTask.cpp @@ -40,11 +40,13 @@ bool InfoTask::isCompleted() bool bAllComplete = true; Minecraft *pMinecraft = Minecraft::GetInstance(); + int tutorialPad = tutorial->getPad(); + bool hasValidPad = (tutorialPad >= 0 && tutorialPad < XUSER_MAX_COUNT); // If the player is under water then allow all keypresses so they can jump out - if( pMinecraft->localplayers[tutorial->getPad()]->isUnderLiquid(Material::water) ) return false; + if( hasValidPad && pMinecraft->localplayers[tutorialPad] != nullptr && pMinecraft->localplayers[tutorialPad]->isUnderLiquid(Material::water) ) return false; - if(ui.GetMenuDisplayed(tutorial->getPad())) + if(hasValidPad && ui.GetMenuDisplayed(tutorialPad)) { // If a menu is displayed, then we use the handleUIInput to complete the task bAllComplete = true; diff --git a/Minecraft.Client/Common/Tutorial/Tutorial.cpp b/Minecraft.Client/Common/Tutorial/Tutorial.cpp index ee6b7771..70ce40f6 100644 --- a/Minecraft.Client/Common/Tutorial/Tutorial.cpp +++ b/Minecraft.Client/Common/Tutorial/Tutorial.cpp @@ -405,19 +405,19 @@ Tutorial::Tutorial(int iPad, bool isFullTutorial /*= false*/) : m_iPad( iPad ) int stoneItems[] = {Tile::cobblestone_Id}; if(!isHintCompleted(e_Tutorial_Hint_Stone)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Stone, this, stoneItems, 1 ) ); - int plankItems[] = {Tile::wood_Id}; + int plankItems[] = {Tile::planks_Id}; if(!isHintCompleted(e_Tutorial_Hint_Planks)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Planks, this, plankItems, 1 ) ); int saplingItems[] = {Tile::sapling_Id}; if(!isHintCompleted(e_Tutorial_Hint_Sapling)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Sapling, this, saplingItems, 1 ) ); - int unbreakableItems[] = {Tile::unbreakable_Id}; + int unbreakableItems[] = {Tile::bedrock_Id}; if(!isHintCompleted(e_Tutorial_Hint_Unbreakable)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Unbreakable, this, unbreakableItems, 1 ) ); - int waterItems[] = {Tile::water_Id, Tile::calmWater_Id}; + int waterItems[] = {Tile::flowing_water_Id, Tile::water_Id}; if(!isHintCompleted(e_Tutorial_Hint_Water)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Water, this, waterItems, 2 ) ); - int lavaItems[] = {Tile::lava_Id, Tile::calmLava_Id}; + int lavaItems[] = {Tile::flowing_lava_Id, Tile::lava_Id}; if(!isHintCompleted(e_Tutorial_Hint_Lava)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Lava, this, lavaItems, 2 ) ); int sandItems[] = {Tile::sand_Id}; @@ -426,16 +426,16 @@ Tutorial::Tutorial(int iPad, bool isFullTutorial /*= false*/) : m_iPad( iPad ) int gravelItems[] = {Tile::gravel_Id}; if(!isHintCompleted(e_Tutorial_Hint_Gravel)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Gravel, this, gravelItems, 1 ) ); - int goldOreItems[] = {Tile::goldOre_Id}; + int goldOreItems[] = {Tile::gold_ore_Id}; if(!isHintCompleted(e_Tutorial_Hint_Gold_Ore)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Gold_Ore, this, goldOreItems, 1 ) ); - int ironOreItems[] = {Tile::ironOre_Id}; + int ironOreItems[] = {Tile::iron_ore_Id}; if(!isHintCompleted(e_Tutorial_Hint_Iron_Ore)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Iron_Ore, this, ironOreItems, 1 ) ); - int coalOreItems[] = {Tile::coalOre_Id}; + int coalOreItems[] = {Tile::coal_ore_Id}; if(!isHintCompleted(e_Tutorial_Hint_Coal_Ore)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Coal_Ore, this, coalOreItems, 1 ) ); - int treeTrunkItems[] = {Tile::treeTrunk_Id}; + int treeTrunkItems[] = {Tile::log_Id}; if(!isHintCompleted(e_Tutorial_Hint_Tree_Trunk)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Tree_Trunk, this, treeTrunkItems, 1 ) ); int leavesItems[] = {Tile::leaves_Id}; @@ -444,16 +444,16 @@ Tutorial::Tutorial(int iPad, bool isFullTutorial /*= false*/) : m_iPad( iPad ) int glassItems[] = {Tile::glass_Id}; if(!isHintCompleted(e_Tutorial_Hint_Glass)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Glass, this, glassItems, 1 ) ); - int lapisOreItems[] = {Tile::lapisOre_Id}; + int lapisOreItems[] = {Tile::lapis_ore_Id}; if(!isHintCompleted(e_Tutorial_Hint_Lapis_Ore)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Lapis_Ore, this, lapisOreItems, 1 ) ); - int lapisBlockItems[] = {Tile::lapisBlock_Id}; + int lapisBlockItems[] = {Tile::lapis_block_Id}; if(!isHintCompleted(e_Tutorial_Hint_Lapis_Block)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Lapis_Block, this, lapisBlockItems, 1 ) ); int dispenserItems[] = {Tile::dispenser_Id}; if(!isHintCompleted(e_Tutorial_Hint_Dispenser)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Dispenser, this, dispenserItems, 1 ) ); - int sandstoneItems[] = {Tile::sandStone_Id}; + int sandstoneItems[] = {Tile::sandstone_Id}; if(!isHintCompleted(e_Tutorial_Hint_Sandstone)) { addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Sandstone, this, sandstoneItems, 1, -1, SandStoneTile::TYPE_DEFAULT ) ); @@ -464,10 +464,10 @@ Tutorial::Tutorial(int iPad, bool isFullTutorial /*= false*/) : m_iPad( iPad ) int noteBlockItems[] = {Tile::noteblock_Id}; if(!isHintCompleted(e_Tutorial_Hint_Note_Block)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Note_Block, this, noteBlockItems, 1 ) ); - int poweredRailItems[] = {Tile::goldenRail_Id}; + int poweredRailItems[] = {Tile::golden_rail_Id}; if(!isHintCompleted(e_Tutorial_Hint_Powered_Rail)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Powered_Rail, this, poweredRailItems, 1 ) ); - int detectorRailItems[] = {Tile::detectorRail_Id}; + int detectorRailItems[] = {Tile::detector_rail_Id}; if(!isHintCompleted(e_Tutorial_Hint_Detector_Rail)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Detector_Rail, this, detectorRailItems, 1 ) ); int tallGrassItems[] = {Tile::tallgrass_Id}; @@ -481,19 +481,19 @@ Tutorial::Tutorial(int iPad, bool isFullTutorial /*= false*/) : m_iPad( iPad ) int woolItems[] = {Tile::wool_Id}; if(!isHintCompleted(e_Tutorial_Hint_Wool)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Wool, this, woolItems, 1 ) ); - int flowerItems[] = {Tile::flower_Id, Tile::rose_Id}; + int flowerItems[] = {Tile::yellow_flower_Id, Tile::red_flower_Id}; if(!isHintCompleted(e_Tutorial_Hint_Flower)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Flower, this, flowerItems, 2 ) ); int mushroomItems[] = {Tile::mushroom_brown_Id, Tile::mushroom_red_Id}; if(!isHintCompleted(e_Tutorial_Hint_Mushroom)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Mushroom, this, mushroomItems, 2 ) ); - int goldBlockItems[] = {Tile::goldBlock_Id}; + int goldBlockItems[] = {Tile::gold_block_Id}; if(!isHintCompleted(e_Tutorial_Hint_Gold_Block)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Gold_Block, this, goldBlockItems, 1 ) ); - int ironBlockItems[] = {Tile::ironBlock_Id}; + int ironBlockItems[] = {Tile::iron_block_Id}; if(!isHintCompleted(e_Tutorial_Hint_Iron_Block)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Iron_Block, this, ironBlockItems, 1 ) ); - int stoneSlabItems[] = {Tile::stoneSlabHalf_Id, Tile::stoneSlab_Id}; + int stoneSlabItems[] = {Tile::stone_slab_Id, Tile::double_stone_slab_Id}; if(!isHintCompleted(e_Tutorial_Hint_Stone_Slab)) { addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Stone_Slab, this, stoneSlabItems, 2, -1, StoneSlabTile::STONE_SLAB ) ); @@ -506,14 +506,14 @@ Tutorial::Tutorial(int iPad, bool isFullTutorial /*= false*/) : m_iPad( iPad ) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Stone_Slab, this, stoneSlabItems, 2, -1, StoneSlabTile::QUARTZ_SLAB ) ); } - int woodSlabItems[] = {Tile::woodSlabHalf_Id, Tile::woodSlab_Id}; + int woodSlabItems[] = {Tile::wooden_slab_Id, Tile::double_wooden_slab_Id}; if(!isHintCompleted(e_Tutorial_Hint_Stone_Slab)) { addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Stone_Slab, this, woodSlabItems, 2, -1, TreeTile::BIRCH_TRUNK ) ); addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Stone_Slab, this, woodSlabItems, 2, -1, TreeTile::DARK_TRUNK ) ); } - int redBrickItems[] = {Tile::redBrick_Id}; + int redBrickItems[] = {Tile::brick_block_Id}; if(!isHintCompleted(e_Tutorial_Hint_Red_Brick)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Red_Brick, this, redBrickItems, 1 ) ); int tntItems[] = {Tile::tnt_Id}; @@ -522,7 +522,7 @@ Tutorial::Tutorial(int iPad, bool isFullTutorial /*= false*/) : m_iPad( iPad ) int bookshelfItems[] = {Tile::bookshelf_Id}; if(!isHintCompleted(e_Tutorial_Hint_Bookshelf)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Bookshelf, this, bookshelfItems, 1 ) ); - int mossStoneItems[] = {Tile::mossyCobblestone_Id}; + int mossStoneItems[] = {Tile::mossy_cobblestone_Id}; if(!isHintCompleted(e_Tutorial_Hint_Moss_Stone)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Moss_Stone, this, mossStoneItems, 1 ) ); int obsidianItems[] = {Tile::obsidian_Id}; @@ -531,22 +531,22 @@ Tutorial::Tutorial(int iPad, bool isFullTutorial /*= false*/) : m_iPad( iPad ) int torchItems[] = {Tile::torch_Id}; if(!isHintCompleted(e_Tutorial_Hint_Torch)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Torch, this, torchItems, 1 ) ); - int mobSpawnerItems[] = {Tile::mobSpawner_Id}; + int mobSpawnerItems[] = {Tile::mob_spawner_Id}; if(!isHintCompleted(e_Tutorial_Hint_MobSpawner)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_MobSpawner, this, mobSpawnerItems, 1 ) ); int chestItems[] = {Tile::chest_Id}; if(!isHintCompleted(e_Tutorial_Hint_Chest)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Chest, this, chestItems, 1 ) ); - int redstoneItems[] = {Tile::redStoneDust_Id}; - if(!isHintCompleted(e_Tutorial_Hint_Redstone)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Redstone, this, redstoneItems, 1, Item::redStone_Id ) ); + int redstoneItems[] = {Tile::redstone_wire_Id}; + if(!isHintCompleted(e_Tutorial_Hint_Redstone)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Redstone, this, redstoneItems, 1, Item::redstone_Id ) ); - int diamondOreItems[] = {Tile::diamondOre_Id}; + int diamondOreItems[] = {Tile::diamond_ore_Id}; if(!isHintCompleted(e_Tutorial_Hint_Diamond_Ore)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Diamond_Ore, this, diamondOreItems, 1 ) ); - int diamondBlockItems[] = {Tile::diamondBlock_Id}; + int diamondBlockItems[] = {Tile::diamond_block_Id}; if(!isHintCompleted(e_Tutorial_Hint_Diamond_Block)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Diamond_Block, this, diamondBlockItems, 1 ) ); - int craftingTableItems[] = {Tile::workBench_Id}; + int craftingTableItems[] = {Tile::crafting_table_Id}; if(!isHintCompleted(e_Tutorial_Hint_Crafting_Table)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Crafting_Table, this, craftingTableItems, 1 ) ); int cropsItems[] = {Tile::wheat_Id}; @@ -555,19 +555,19 @@ Tutorial::Tutorial(int iPad, bool isFullTutorial /*= false*/) : m_iPad( iPad ) int farmlandItems[] = {Tile::farmland_Id}; if(!isHintCompleted(e_Tutorial_Hint_Farmland)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Farmland, this, farmlandItems, 1 ) ); - int furnaceItems[] = {Tile::furnace_Id, Tile::furnace_lit_Id}; + int furnaceItems[] = {Tile::furnace_Id, Tile::lit_furnace_Id}; if(!isHintCompleted(e_Tutorial_Hint_Furnace)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Furnace, this, furnaceItems, 2 ) ); - int signItems[] = {Tile::sign_Id, Tile::wallSign_Id}; - if(!isHintCompleted(e_Tutorial_Hint_Sign)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Sign, this, signItems, 2, Item::sign_Id ) ); + int signItems[] = {Tile::standing_sign_Id, Tile::wall_standing_sign_Id}; + if(!isHintCompleted(e_Tutorial_Hint_Sign)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Sign, this, signItems, 2, Item::standing_sign_Id ) ); - int doorWoodItems[] = {Tile::door_wood_Id}; - if(!isHintCompleted(e_Tutorial_Hint_Door_Wood)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Door_Wood, this, doorWoodItems, 1, Item::door_wood->id ) ); + int doorWoodItems[] = {Tile::wooden_door_Id}; + if(!isHintCompleted(e_Tutorial_Hint_Door_Wood)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Door_Wood, this, doorWoodItems, 1, Item::wooden_door->id ) ); int ladderItems[] = {Tile::ladder_Id}; if(!isHintCompleted(e_Tutorial_Hint_Ladder)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Ladder, this, ladderItems, 1 ) ); - int stairsStoneItems[] = {Tile::stairs_stone_Id,Tile::stairs_bricks_Id,Tile::stairs_stoneBrick_Id,Tile::stairs_wood_Id,Tile::stairs_sprucewood_Id,Tile::stairs_birchwood_Id,Tile::stairs_netherBricks_Id,Tile::stairs_sandstone_Id,Tile::stairs_quartz_Id}; + int stairsStoneItems[] = {Tile::stone_stairs_Id,Tile::brick_stairs_Id,Tile::stone_brick_stairs_Id,Tile::oak_stairs_Id,Tile::spruce_stairs_Id,Tile::birch_stairs_Id,Tile::nether_brick_stairs_Id,Tile::sandstone_stairs_Id,Tile::quartz_stairs_Id}; if(!isHintCompleted(e_Tutorial_Hint_Stairs_Stone)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Stairs_Stone, this, stairsStoneItems, 9 ) ); int railItems[] = {Tile::rail_Id}; @@ -576,19 +576,19 @@ Tutorial::Tutorial(int iPad, bool isFullTutorial /*= false*/) : m_iPad( iPad ) int leverItems[] = {Tile::lever_Id}; if(!isHintCompleted(e_Tutorial_Hint_Lever)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Lever, this, leverItems, 1 ) ); - int pressurePlateItems[] = {Tile::pressurePlate_stone_Id, Tile::pressurePlate_wood_Id}; + int pressurePlateItems[] = {Tile::stone_pressure_plate_Id, Tile::wooden_pressure_plate_Id}; if(!isHintCompleted(e_Tutorial_Hint_PressurePlate)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_PressurePlate, this, pressurePlateItems, 2 ) ); - int doorIronItems[] = {Tile::door_iron_Id}; - if(!isHintCompleted(e_Tutorial_Hint_Door_Iron)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Door_Iron, this, doorIronItems, 1, Item::door_iron->id ) ); + int doorIronItems[] = {Tile::iron_door_Id}; + if(!isHintCompleted(e_Tutorial_Hint_Door_Iron)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Door_Iron, this, doorIronItems, 1, Item::iron_door->id ) ); - int redstoneOreItems[] = {Tile::redStoneOre_Id, Tile::redStoneOre_lit_Id}; + int redstoneOreItems[] = {Tile::redstone_ore_Id, Tile::lit_redstone_ore_Id}; if(!isHintCompleted(e_Tutorial_Hint_Redstone_Ore)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Redstone_Ore, this, redstoneOreItems, 2 ) ); - int redstoneTorchItems[] = {Tile::redstoneTorch_off_Id, Tile::redstoneTorch_on_Id}; + int redstoneTorchItems[] = {Tile::unlit_redstone_torch_Id, Tile::redstone_torch_Id}; if(!isHintCompleted(e_Tutorial_Hint_Redstone_Torch)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Redstone_Torch, this, redstoneTorchItems, 2 ) ); - int buttonItems[] = {Tile::button_stone_Id, Tile::button_wood_Id}; + int buttonItems[] = {Tile::stone_button_Id, Tile::wooden_button_Id}; if(!isHintCompleted(e_Tutorial_Hint_Button)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Button, this, buttonItems, 2 ) ); int snowItems[] = {Tile::snow_Id}; @@ -612,134 +612,134 @@ Tutorial::Tutorial(int iPad, bool isFullTutorial /*= false*/) : m_iPad( iPad ) int pumpkinItems[] = {Tile::pumpkin_Id}; if(!isHintCompleted(e_Tutorial_Hint_Pumpkin)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Pumpkin, this, pumpkinItems, 1, -1, -1, 0 ) ); - int hellRockItems[] = {Tile::netherRack_Id}; + int hellRockItems[] = {Tile::netherrack_Id}; if(!isHintCompleted(e_Tutorial_Hint_Hell_Rock)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Hell_Rock, this, hellRockItems, 1 ) ); - int hellSandItems[] = {Tile::soulsand_Id}; + int hellSandItems[] = {Tile::soul_sand_Id}; if(!isHintCompleted(e_Tutorial_Hint_Hell_Sand)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Hell_Sand, this, hellSandItems, 1 ) ); int glowstoneItems[] = {Tile::glowstone_Id}; if(!isHintCompleted(e_Tutorial_Hint_Glowstone)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Glowstone, this, glowstoneItems, 1 ) ); - int portalItems[] = {Tile::portalTile_Id}; + int portalItems[] = {Tile::portal_Id}; if(!isHintCompleted(e_Tutorial_Hint_Portal)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Portal, this, portalItems, 1 ) ); - int pumpkinLitItems[] = {Tile::litPumpkin_Id}; + int pumpkinLitItems[] = {Tile::lit_pumpkin_Id}; if(!isHintCompleted(e_Tutorial_Hint_Pumpkin_Lit)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Pumpkin_Lit, this, pumpkinLitItems, 1, -1, -1, 0 ) ); int cakeItems[] = {Tile::cake_Id}; if(!isHintCompleted(e_Tutorial_Hint_Cake)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Cake, this, cakeItems, 1 ) ); - int redstoneRepeaterItems[] = {Tile::diode_on_Id, Tile::diode_off_Id}; + int redstoneRepeaterItems[] = {Tile::powered_repeater_Id, Tile::unpowered_repeater_Id}; if(!isHintCompleted(e_Tutorial_Hint_Redstone_Repeater)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Redstone_Repeater, this, redstoneRepeaterItems, 2, Item::repeater_Id ) ); int trapdoorItems[] = {Tile::trapdoor_Id}; if(!isHintCompleted(e_Tutorial_Hint_Trapdoor)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Trapdoor, this, trapdoorItems, 1 ) ); - int pistonItems[] = {Tile::pistonBase_Id}; + int pistonItems[] = {Tile::piston_Id}; if(!isHintCompleted(e_Tutorial_Hint_Piston)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Piston, this, pistonItems, 1 ) ); - int stickyPistonItems[] = {Tile::pistonStickyBase_Id}; + int stickyPistonItems[] = {Tile::sticky_piston_Id}; if(!isHintCompleted(e_Tutorial_Hint_Sticky_Piston)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Sticky_Piston, this, stickyPistonItems, 1 ) ); - int monsterStoneEggItems[] = {Tile::monsterStoneEgg_Id}; - if(!isHintCompleted(e_Tutorial_Hint_Monster_Stone_Egg)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Monster_Stone_Egg, this, monsterStoneEggItems, 1 ) ); + int monster_eggItems[] = {Tile::monster_egg_Id}; + if(!isHintCompleted(e_Tutorial_Hint_Monster_Stone_Egg)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Monster_Stone_Egg, this, monster_eggItems, 1 ) ); - int stoneBrickSmoothItems[] = {Tile::stoneBrick_Id}; + int stoneBrickSmoothItems[] = {Tile::stonebrick_Id}; if(!isHintCompleted(e_Tutorial_Hint_Stone_Brick_Smooth)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Stone_Brick_Smooth, this, stoneBrickSmoothItems, 1 ) ); - int hugeMushroomItems[] = {Tile::hugeMushroom_brown_Id,Tile::hugeMushroom_red_Id}; + int hugeMushroomItems[] = {Tile::brown_mushroom_block_Id,Tile::red_mushroom_block_Id}; if(!isHintCompleted(e_Tutorial_Hint_Huge_Mushroom)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Huge_Mushroom, this, hugeMushroomItems, 2 ) ); - int ironFenceItems[] = {Tile::ironFence_Id}; - if(!isHintCompleted(e_Tutorial_Hint_Iron_Fence)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Iron_Fence, this, ironFenceItems, 1 ) ); + int iron_barsItems[] = {Tile::iron_bars_Id}; + if(!isHintCompleted(e_Tutorial_Hint_Iron_Fence)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Iron_Fence, this, iron_barsItems, 1 ) ); - int thisGlassItems[] = {Tile::thinGlass_Id}; + int thisGlassItems[] = {Tile::glass_pane_Id}; if(!isHintCompleted(e_Tutorial_Hint_Thin_Glass)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Thin_Glass, this, thisGlassItems, 1 ) ); - int melonItems[] = {Tile::melon_Id}; + int melonItems[] = {Tile::melon_block_Id}; if(!isHintCompleted(e_Tutorial_Hint_Melon)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Melon, this, melonItems, 1 ) ); int vineItems[] = {Tile::vine_Id}; if(!isHintCompleted(e_Tutorial_Hint_Vine)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Vine, this, vineItems, 1 ) ); - int fenceGateItems[] = {Tile::fenceGate_Id}; + int fenceGateItems[] = {Tile::fence_gate_Id}; if(!isHintCompleted(e_Tutorial_Hint_Fence_Gate)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Fence_Gate, this, fenceGateItems, 1 ) ); - int mycelItems[] = {Tile::mycel_Id}; + int mycelItems[] = {Tile::mycelium_Id}; if(!isHintCompleted(e_Tutorial_Hint_Mycel)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Mycel, this, mycelItems, 1 ) ); - int waterLilyItems[] = {Tile::waterLily_Id}; + int waterLilyItems[] = {Tile::waterlily_Id}; if(!isHintCompleted(e_Tutorial_Hint_Water_Lily)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Water_Lily, this, waterLilyItems, 1 ) ); - int netherBrickItems[] = {Tile::netherBrick_Id}; + int netherBrickItems[] = {Tile::nether_brick_Id}; if(!isHintCompleted(e_Tutorial_Hint_Nether_Brick)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Nether_Brick, this, netherBrickItems, 1 ) ); - int netherFenceItems[] = {Tile::netherFence_Id}; + int netherFenceItems[] = {Tile::nether_brick_fence_Id}; if(!isHintCompleted(e_Tutorial_Hint_Nether_Fence)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Nether_Fence, this, netherFenceItems, 1 ) ); - int netherStalkItems[] = {Tile::netherStalk_Id}; + int netherStalkItems[] = {Tile::nether_wart_Id}; if(!isHintCompleted(e_Tutorial_Hint_Nether_Stalk)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Nether_Stalk, this, netherStalkItems, 1 ) ); - int enchantTableItems[] = {Tile::enchantTable_Id}; + int enchantTableItems[] = {Tile::enchanting_table_Id}; if(!isHintCompleted(e_Tutorial_Hint_Enchant_Table)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Enchant_Table, this, enchantTableItems, 1 ) ); - int brewingStandItems[] = {Tile::brewingStand_Id}; - if(!isHintCompleted(e_Tutorial_Hint_Brewing_Stand)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Brewing_Stand, this, brewingStandItems, 1, Item::brewingStand_Id ) ); + int brewingStandItems[] = {Tile::brewing_stand_Id}; + if(!isHintCompleted(e_Tutorial_Hint_Brewing_Stand)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Brewing_Stand, this, brewingStandItems, 1, Item::brewing_stand_Id ) ); int cauldronItems[] = {Tile::cauldron_Id}; if(!isHintCompleted(e_Tutorial_Hint_Cauldron)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Cauldron, this, cauldronItems, 1, Item::cauldron_Id ) ); - int endPortalItems[] = {Tile::endPortalTile_Id}; + int endPortalItems[] = {Tile::end_portal_Id}; if(!isHintCompleted(e_Tutorial_Hint_End_Portal)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_End_Portal, this, endPortalItems, 1, -2 ) ); - int endPortalFrameItems[] = {Tile::endPortalFrameTile_Id}; + int endPortalFrameItems[] = {Tile::end_portal_frame_Id}; if(!isHintCompleted(e_Tutorial_Hint_End_Portal_Frame)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_End_Portal_Frame, this, endPortalFrameItems, 1 ) ); - int whiteStoneItems[] = {Tile::endStone_Id}; + int whiteStoneItems[] = {Tile::end_stone_Id}; if(!isHintCompleted(e_Tutorial_Hint_White_Stone)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_White_Stone, this, whiteStoneItems, 1 ) ); - int dragonEggItems[] = {Tile::dragonEgg_Id}; + int dragonEggItems[] = {Tile::dragon_egg_Id}; if(!isHintCompleted(e_Tutorial_Hint_Dragon_Egg)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Dragon_Egg, this, dragonEggItems, 1 ) ); - int redstoneLampItems[] = {Tile::redstoneLight_Id, Tile::redstoneLight_lit_Id}; + int redstoneLampItems[] = {Tile::redstone_lamp_Id, Tile::lit_redstone_lamp_Id}; if(!isHintCompleted(e_Tutorial_Hint_RedstoneLamp)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_RedstoneLamp, this, redstoneLampItems, 2 ) ); int cocoaItems[] = {Tile::cocoa_Id}; - if(!isHintCompleted(e_Tutorial_Hint_Cocoa)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Cocoa, this, cocoaItems, 1, Item::dye_powder_Id, -1, DyePowderItem::BROWN) ); + if(!isHintCompleted(e_Tutorial_Hint_Cocoa)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Cocoa, this, cocoaItems, 1, Item::dye_Id, -1, DyePowderItem::BROWN) ); - int emeraldOreItems[] = {Tile::emeraldOre_Id}; + int emeraldOreItems[] = {Tile::emerald_ore_Id}; if(!isHintCompleted(e_Tutorial_Hint_EmeraldOre)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_EmeraldOre, this, emeraldOreItems, 1 ) ); - int emeraldBlockItems[] = {Tile::emeraldBlock_Id}; + int emeraldBlockItems[] = {Tile::emerald_block_Id}; if(!isHintCompleted(e_Tutorial_Hint_EmeraldBlock)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_EmeraldBlock, this, emeraldBlockItems, 1 ) ); - int enderChestItems[] = {Tile::enderChest_Id}; + int enderChestItems[] = {Tile::ender_chest_Id}; if(!isHintCompleted(e_Tutorial_Hint_EnderChest)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_EnderChest, this, enderChestItems, 1 ) ); - int tripwireSourceItems[] = {Tile::tripWireSource_Id}; + int tripwireSourceItems[] = {Tile::tripwire_hook_Id}; if(!isHintCompleted(e_Tutorial_Hint_TripwireSource)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_TripwireSource, this, tripwireSourceItems, 1 ) ); - int tripwireItems[] = {Tile::tripWire_Id}; + int tripwireItems[] = {Tile::tripwire_Id}; if(!isHintCompleted(e_Tutorial_Hint_Tripwire)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Tripwire, this, tripwireItems, 1, Item::string_Id ) ); - int cobblestoneWallItems[] = {Tile::cobbleWall_Id}; + int cobblestoneWallItems[] = {Tile::cobblestone_wall_Id}; if(!isHintCompleted(e_Tutorial_Hint_CobblestoneWall)) { addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_CobblestoneWall, this, cobblestoneWallItems, 1, -1, WallTile::TYPE_NORMAL ) ); addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_CobblestoneWall, this, cobblestoneWallItems, 1, -1, WallTile::TYPE_MOSSY ) ); } - int flowerpotItems[] = {Tile::flowerPot_Id}; - if(!isHintCompleted(e_Tutorial_Hint_Flowerpot)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Flowerpot, this, flowerpotItems, 1, Item::flowerPot_Id ) ); + int flowerpotItems[] = {Tile::flower_pot_Id}; + if(!isHintCompleted(e_Tutorial_Hint_Flowerpot)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Flowerpot, this, flowerpotItems, 1, Item::flower_pot_Id ) ); int anvilItems[] = {Tile::anvil_Id}; if(!isHintCompleted(e_Tutorial_Hint_Anvil)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Anvil, this, anvilItems, 1 ) ); - int quartzOreItems[] = {Tile::netherQuartz_Id}; + int quartzOreItems[] = {Tile::quartz_ore_Id}; if(!isHintCompleted(e_Tutorial_Hint_QuartzOre)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_QuartzOre, this, quartzOreItems, 1 ) ); - int quartzBlockItems[] = {Tile::quartzBlock_Id}; + int quartzBlockItems[] = {Tile::quartz_block_Id}; if(!isHintCompleted(e_Tutorial_Hint_QuartzBlock)) { addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_QuartzBlock, this, quartzBlockItems, 1, -1, QuartzBlockTile::TYPE_DEFAULT ) ); @@ -749,7 +749,7 @@ Tutorial::Tutorial(int iPad, bool isFullTutorial /*= false*/) : m_iPad( iPad ) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_QuartzBlock, this, quartzBlockItems, 1, -1, QuartzBlockTile::TYPE_LINES_Z ) ); } - int carpetItems[] = {Tile::woolCarpet_Id}; + int carpetItems[] = {Tile::carpet_Id}; if(!isHintCompleted(e_Tutorial_Hint_WoolCarpet)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_WoolCarpet, this, carpetItems, 1 ) ); int potatoItems[] = {Tile::potatoes_Id}; @@ -758,19 +758,19 @@ Tutorial::Tutorial(int iPad, bool isFullTutorial /*= false*/) : m_iPad( iPad ) int carrotItems[] = {Tile::carrots_Id}; if(!isHintCompleted(e_Tutorial_Hint_Carrot)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Carrot, this, carrotItems, 1, -1, -1, 7 ) ); - int commandBlockItems[] = {Tile::commandBlock_Id}; + int commandBlockItems[] = {Tile::command_block_Id}; if(!isHintCompleted(e_Tutorial_Hint_CommandBlock)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_CommandBlock, this, commandBlockItems, 1 ) ); int beaconItems[] = {Tile::beacon_Id}; if(!isHintCompleted(e_Tutorial_Hint_Beacon)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Beacon, this, beaconItems, 1 ) ); - int activatorRailItems[] = {Tile::activatorRail_Id}; + int activatorRailItems[] = {Tile::activator_rail_Id}; if(!isHintCompleted(e_Tutorial_Hint_Activator_Rail)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Activator_Rail, this, activatorRailItems, 1 ) ); - int redstoneBlockItems[] = {Tile::redstoneBlock_Id}; + int redstoneBlockItems[] = {Tile::redstone_block_Id}; if(!isHintCompleted(e_Tutorial_Hint_RedstoneBlock)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_RedstoneBlock, this, redstoneBlockItems, 1 ) ); - int daylightDetectorItems[] = {Tile::daylightDetector_Id}; + int daylightDetectorItems[] = {Tile::daylight_detector_Id}; if(!isHintCompleted(e_Tutorial_Hint_DaylightDetector)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_DaylightDetector, this, daylightDetectorItems, 1 ) ); int dropperItems[] = {Tile::dropper_Id}; @@ -779,22 +779,22 @@ Tutorial::Tutorial(int iPad, bool isFullTutorial /*= false*/) : m_iPad( iPad ) int hopperItems[] = {Tile::hopper_Id}; if(!isHintCompleted(e_Tutorial_Hint_Hopper)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Hopper, this, hopperItems, 1 ) ); - int comparatorItems[] = {Tile::comparator_off_Id, Tile::comparator_on_Id}; + int comparatorItems[] = {Tile::unpowered_comparator_Id, Tile::powered_comparator_Id}; if(!isHintCompleted(e_Tutorial_Hint_Comparator)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_Comparator, this, comparatorItems, 2, Item::comparator_Id ) ); int trappedChestItems[] = {Tile::chest_trap_Id}; if(!isHintCompleted(e_Tutorial_Hint_ChestTrap)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_ChestTrap, this, trappedChestItems, 1 ) ); - int hayBlockItems[] = {Tile::hayBlock_Id}; + int hayBlockItems[] = {Tile::hay_block_Id}; if(!isHintCompleted(e_Tutorial_Hint_HayBlock)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_HayBlock, this, hayBlockItems, 1 ) ); - int clayHardenedItems[] = {Tile::clayHardened_Id}; + int clayHardenedItems[] = {Tile::hardened_clay_Id}; if(!isHintCompleted(e_Tutorial_Hint_ClayHardened)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_ClayHardened, this, clayHardenedItems, 1 ) ); - int clayHardenedColoredItems[] = {Tile::clayHardened_colored_Id}; + int clayHardenedColoredItems[] = {Tile::stained_hardened_clay_Id}; if(!isHintCompleted(e_Tutorial_Hint_ClayHardenedColored)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_ClayHardenedColored, this, clayHardenedColoredItems, 1 ) ); - int coalBlockItems[] = {Tile::coalBlock_Id}; + int coalBlockItems[] = {Tile::coal_block_Id}; if(!isHintCompleted(e_Tutorial_Hint_CoalBlock)) addHint(e_Tutorial_State_Gameplay, new LookAtTileHint(e_Tutorial_Hint_CoalBlock, this, coalBlockItems, 1 ) ); /* @@ -833,13 +833,13 @@ Tutorial::Tutorial(int iPad, bool isFullTutorial /*= false*/) : m_iPad( iPad ) /* * ITEM HINTS */ - int shovelItems[] = {Item::shovel_wood->id, Item::shovel_stone->id, Item::shovel_iron->id, Item::shovel_gold->id, Item::shovel_diamond->id}; + int shovelItems[] = {Item::wooden_shovel->id, Item::stone_shovel->id, Item::iron_shovel->id, Item::golden_shovel->id, Item::diamond_shovel->id}; if(!isHintCompleted(e_Tutorial_Hint_Item_Shovel)) addHint(e_Tutorial_State_Gameplay, new DiggerItemHint(e_Tutorial_Hint_Item_Shovel, this, IDS_TUTORIAL_HINT_DIGGER_ITEM_SHOVEL, shovelItems, 5) ); - int hatchetItems[] = {Item::hatchet_wood->id, Item::hatchet_stone->id, Item::hatchet_iron->id, Item::hatchet_gold->id, Item::hatchet_diamond->id}; + int hatchetItems[] = {Item::wooden_axe->id, Item::stone_axe->id, Item::iron_axe->id, Item::golden_axe->id, Item::diamond_axe->id}; if(!isHintCompleted(e_Tutorial_Hint_Item_Hatchet)) addHint(e_Tutorial_State_Gameplay, new DiggerItemHint(e_Tutorial_Hint_Item_Hatchet, this, IDS_TUTORIAL_HINT_DIGGER_ITEM_HATCHET, hatchetItems, 5 ) ); - int pickaxeItems[] = {Item::pickAxe_wood->id, Item::pickAxe_stone->id, Item::pickAxe_iron->id, Item::pickAxe_gold->id, Item::pickAxe_diamond->id}; + int pickaxeItems[] = {Item::wooden_pickaxe->id, Item::stone_pickaxe->id, Item::iron_pickaxe->id, Item::golden_pickaxe->id, Item::diamond_pickaxe->id}; if(!isHintCompleted(e_Tutorial_Hint_Item_Pickaxe)) addHint(e_Tutorial_State_Gameplay, new DiggerItemHint(e_Tutorial_Hint_Item_Pickaxe, this, IDS_TUTORIAL_HINT_DIGGER_ITEM_PICKAXE, pickaxeItems, 5 ) ); /* @@ -1993,7 +1993,7 @@ void Tutorial::onSelectedItemChanged(shared_ptr item) { switch(item->id) { - case Item::fishingRod_Id: + case Item::fishing_rod_Id: changeTutorialState(e_Tutorial_State_Fishing); break; default: diff --git a/Minecraft.Client/Common/Tutorial/TutorialHint.cpp b/Minecraft.Client/Common/Tutorial/TutorialHint.cpp index 9f207a3e..86a09b15 100644 --- a/Minecraft.Client/Common/Tutorial/TutorialHint.cpp +++ b/Minecraft.Client/Common/Tutorial/TutorialHint.cpp @@ -118,10 +118,12 @@ bool TutorialHint::onLookAtEntity(eINSTANCEOF type) int TutorialHint::tick() { int returnVal = -1; + int tutorialPad = m_tutorial->getPad(); + bool hasValidPad = (tutorialPad >= 0 && tutorialPad < XUSER_MAX_COUNT); switch(m_type) { case e_Hint_SwimUp: - if( Minecraft::GetInstance()->localplayers[m_tutorial->getPad()]->isUnderLiquid(Material::water) ) returnVal = m_descriptionId; + if( hasValidPad && Minecraft::GetInstance()->localplayers[tutorialPad] != nullptr && Minecraft::GetInstance()->localplayers[tutorialPad]->isUnderLiquid(Material::water) ) returnVal = m_descriptionId; break; } return returnVal; diff --git a/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp b/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp index a61edb05..18ed185f 100644 --- a/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp +++ b/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp @@ -1242,37 +1242,37 @@ void IUIScene_AbstractContainerMenu::onMouseTick() switch(iId) { case Item::bow_Id: - case Item::sword_wood_Id: - case Item::sword_stone_Id: - case Item::sword_iron_Id: - case Item::sword_diamond_Id: + case Item::wooden_sword_Id: + case Item::stone_sword_Id: + case Item::iron_sword_Id: + case Item::diamond_sword_Id: buttonY=eToolTipQuickMoveWeapon; break; - case Item::helmet_leather_Id: - case Item::chestplate_leather_Id: - case Item::leggings_leather_Id: - case Item::boots_leather_Id: + case Item::leather_helmet_Id: + case Item::leather_chestplate_Id: + case Item::leather_leggings_Id: + case Item::leather_boots_Id: - case Item::helmet_chain_Id: - case Item::chestplate_chain_Id: - case Item::leggings_chain_Id: - case Item::boots_chain_Id: + case Item::chainmail_helmet_Id: + case Item::chainmail_chestplate_Id: + case Item::chainmail_leggings_Id: + case Item::chainmail_boots_Id: - case Item::helmet_iron_Id: - case Item::chestplate_iron_Id: - case Item::leggings_iron_Id: - case Item::boots_iron_Id: + case Item::iron_helmet_Id: + case Item::iron_chestplate_Id: + case Item::iron_leggings_Id: + case Item::iron_boots_Id: - case Item::helmet_diamond_Id: - case Item::chestplate_diamond_Id: - case Item::leggings_diamond_Id: - case Item::boots_diamond_Id: + case Item::diamond_helmet_Id: + case Item::diamond_chestplate_Id: + case Item::diamond_leggings_Id: + case Item::diamond_boots_Id: - case Item::helmet_gold_Id: - case Item::chestplate_gold_Id: - case Item::leggings_gold_Id: - case Item::boots_gold_Id: + case Item::golden_helmet_Id: + case Item::golden_chestplate_Id: + case Item::golden_leggings_Id: + case Item::golden_boots_Id: case Item::elytra_Id: diff --git a/Minecraft.Client/Common/UI/IUIScene_CraftingMenu.cpp b/Minecraft.Client/Common/UI/IUIScene_CraftingMenu.cpp index 76ed5596..02e7c0fe 100644 --- a/Minecraft.Client/Common/UI/IUIScene_CraftingMenu.cpp +++ b/Minecraft.Client/Common/UI/IUIScene_CraftingMenu.cpp @@ -269,7 +269,7 @@ bool IUIScene_CraftingMenu::handleKeyDown(int iPad, int iAction, bool bRepeat) //pMinecraft->soundEngine->playUI( L"random.pop", 1.0f, 1.0f); ui.PlayUISFX(eSFX_Craft); - if(pTempItemInst->id != Item::fireworksCharge_Id && pTempItemInst->id != Item::fireworks_Id) + if(pTempItemInst->id != Item::firework_charge_Id && pTempItemInst->id != Item::fireworks_Id) { // and remove those resources from your inventory for(int i=0;iid ) { - case Tile::workBench_Id: m_pPlayer->awardStat(GenericStats::buildWorkbench(), GenericStats::param_buildWorkbench()); break; - case Item::pickAxe_wood_Id: m_pPlayer->awardStat(GenericStats::buildPickaxe(), GenericStats::param_buildPickaxe()); break; + case Tile::crafting_table_Id: m_pPlayer->awardStat(GenericStats::buildWorkbench(), GenericStats::param_buildWorkbench()); break; + case Item::wooden_pickaxe_Id: m_pPlayer->awardStat(GenericStats::buildPickaxe(), GenericStats::param_buildPickaxe()); break; case Tile::furnace_Id: m_pPlayer->awardStat(GenericStats::buildFurnace(), GenericStats::param_buildFurnace()); break; - //case Item::hoe_wood_Id: m_pPlayer->awardStat(GenericStats::buildHoe(), GenericStats::param_buildHoe()); break; + //case Item::wooden_hoe_Id: m_pPlayer->awardStat(GenericStats::buildHoe(), GenericStats::param_buildHoe()); break; case Item::bread_Id: m_pPlayer->awardStat(GenericStats::makeBread(), GenericStats::param_makeBread()); break; case Item::cake_Id: m_pPlayer->awardStat(GenericStats::bakeCake(), GenericStats::param_bakeCake()); break; - case Item::pickAxe_stone_Id: m_pPlayer->awardStat(GenericStats::buildBetterPickaxe(), GenericStats::param_buildBetterPickaxe()); break; - //case Item::sword_wood_Id: m_pPlayer->awardStat(GenericStats::buildSword(), GenericStats::param_buildSword()); break; + case Item::stone_pickaxe_Id: m_pPlayer->awardStat(GenericStats::buildBetterPickaxe(), GenericStats::param_buildBetterPickaxe()); break; + //case Item::wooden_sword_Id: m_pPlayer->awardStat(GenericStats::buildSword(), GenericStats::param_buildSword()); break; case Tile::dispenser_Id: m_pPlayer->awardStat(GenericStats::dispenseWithThis(), GenericStats::param_dispenseWithThis()); break; - case Tile::enchantTable_Id: m_pPlayer->awardStat(GenericStats::enchantments(), GenericStats::param_enchantments()); break; + case Tile::enchanting_table_Id: m_pPlayer->awardStat(GenericStats::enchantments(), GenericStats::param_enchantments()); break; case Tile::bookshelf_Id: m_pPlayer->awardStat(GenericStats::bookcase(), GenericStats::param_bookcase()); break; } switch (pTempItemInst->getItem()->getBaseItemType()) { @@ -1092,7 +1092,7 @@ void IUIScene_CraftingMenu::DisplayIngredients() { idescID=IDS_ANY_WOOL; } - else if((pTempItemInst->id==Item::fireworksCharge_Id) && (id==Item::dye_powder_Id)) + else if((pTempItemInst->id==Item::firework_charge_Id) && (id==Item::dye_Id)) { idescID=IDS_ITEM_DYE_POWDER; iAuxVal = 1; @@ -1162,7 +1162,7 @@ void IUIScene_CraftingMenu::DisplayIngredients() { iAuxVal = 0xFF; } - else if( pTempItemInst->id==Item::fireworksCharge_Id && id == Item::dye_powder_Id) + else if( pTempItemInst->id==Item::firework_charge_Id && id == Item::dye_Id) { iAuxVal = 1; } diff --git a/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp b/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp index 128df572..ac1dbdfc 100644 --- a/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp +++ b/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp @@ -85,9 +85,9 @@ void IUIScene_CreativeMenu::staticCtor() ITEM_AUX(Tile::dirt_Id, 0) ITEM(Tile::cobblestone_Id) ITEM(Tile::sand_Id) - ITEM(Tile::sandStone_Id) - ITEM_AUX(Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE) - ITEM_AUX(Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS) + ITEM(Tile::sandstone_Id) + ITEM_AUX(Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE) + ITEM_AUX(Tile::sandstone_Id, SandStoneTile::TYPE_HEIROGLYPHS) ITEM_AUX(Tile::sand_Id, SandTile::RED_SAND) ITEM(Tile::red_sandstone_Id) ITEM_AUX(Tile::red_sandstone_Id, RedSandStoneTile::TYPE_SMOOTHSIDE) @@ -98,150 +98,151 @@ void IUIScene_CreativeMenu::staticCtor() ITEM_AUX(Tile::stone_Id, StoneTile::POLISHED_ANDESITE) ITEM_AUX(Tile::stone_Id, StoneTile::DIORITE) ITEM_AUX(Tile::stone_Id, StoneTile::POLISHED_DIORITE) - ITEM(Tile::coalBlock_Id) - ITEM(Tile::goldBlock_Id) - ITEM(Tile::ironBlock_Id) - ITEM(Tile::lapisBlock_Id) - ITEM(Tile::diamondBlock_Id) - ITEM(Tile::emeraldBlock_Id) - ITEM_AUX(Tile::quartzBlock_Id,QuartzBlockTile::TYPE_DEFAULT) - ITEM(Tile::coalOre_Id) - ITEM(Tile::lapisOre_Id) - ITEM(Tile::diamondOre_Id) - ITEM(Tile::redStoneOre_Id) - ITEM(Tile::ironOre_Id) - ITEM(Tile::goldOre_Id) - ITEM(Tile::emeraldOre_Id) - ITEM(Tile::netherQuartz_Id) - ITEM(Tile::unbreakable_Id) - ITEM_AUX(Tile::wood_Id,0) - ITEM_AUX(Tile::wood_Id,TreeTile::SPRUCE_TRUNK) - ITEM_AUX(Tile::wood_Id,TreeTile::BIRCH_TRUNK) - ITEM_AUX(Tile::wood_Id,TreeTile::JUNGLE_TRUNK) - ITEM_AUX(Tile::wood_Id, TreeTile::ACACIA_TRUNK) - ITEM_AUX(Tile::wood_Id, TreeTile::DARK_TRUNK) - ITEM_AUX(Tile::treeTrunk_Id, 0) - ITEM_AUX(Tile::treeTrunk_Id, TreeTile::SPRUCE_TRUNK) - ITEM_AUX(Tile::treeTrunk_Id, TreeTile::BIRCH_TRUNK) - ITEM_AUX(Tile::treeTrunk_Id, TreeTile::JUNGLE_TRUNK) - ITEM_AUX(Tile::tree2Trunk_Id, TreeTile2::ACACIA_TRUNK) - ITEM_AUX(Tile::tree2Trunk_Id, TreeTile2::DARK_TRUNK) + ITEM(Tile::coal_block_Id) + ITEM(Tile::gold_block_Id) + ITEM(Tile::iron_block_Id) + ITEM(Tile::lapis_block_Id) + ITEM(Tile::diamond_block_Id) + ITEM(Tile::emerald_block_Id) + ITEM_AUX(Tile::quartz_block_Id,QuartzBlockTile::TYPE_DEFAULT) + ITEM(Tile::coal_ore_Id) + ITEM(Tile::lapis_ore_Id) + ITEM(Tile::diamond_ore_Id) + ITEM(Tile::redstone_ore_Id) + ITEM(Tile::iron_ore_Id) + ITEM(Tile::gold_ore_Id) + ITEM(Tile::emerald_ore_Id) + ITEM(Tile::quartz_ore_Id) + ITEM(Tile::bedrock_Id) + ITEM_AUX(Tile::planks_Id,0) + ITEM_AUX(Tile::planks_Id,TreeTile::SPRUCE_TRUNK) + ITEM_AUX(Tile::planks_Id,TreeTile::BIRCH_TRUNK) + ITEM_AUX(Tile::planks_Id,TreeTile::JUNGLE_TRUNK) + ITEM_AUX(Tile::planks_Id, TreeTile::ACACIA_TRUNK) + ITEM_AUX(Tile::planks_Id, TreeTile::DARK_TRUNK) + ITEM_AUX(Tile::log_Id, 0) + ITEM_AUX(Tile::log_Id, TreeTile::SPRUCE_TRUNK) + ITEM_AUX(Tile::log_Id, TreeTile::BIRCH_TRUNK) + ITEM_AUX(Tile::log_Id, TreeTile::JUNGLE_TRUNK) + ITEM_AUX(Tile::log2_Id, TreeTile2::ACACIA_TRUNK) + ITEM_AUX(Tile::log2_Id, TreeTile2::DARK_TRUNK) ITEM(Tile::gravel_Id) - ITEM(Tile::redBrick_Id) - ITEM(Tile::mossyCobblestone_Id) + ITEM(Tile::brick_block_Id) + ITEM(Tile::mossy_cobblestone_Id) ITEM(Tile::obsidian_Id) ITEM(Tile::clay) ITEM(Tile::ice_Id) - ITEM(Tile::packedIce_Id) + ITEM(Tile::packed_ice_Id) ITEM(Tile::snow_Id) - ITEM(Tile::netherRack_Id) - ITEM(Tile::soulsand_Id) + ITEM(Tile::netherrack_Id) + ITEM(Tile::soul_sand_Id) ITEM(Tile::glowstone_Id) - ITEM(Tile::seaLantern_Id) + ITEM(Tile::sea_lantern_Id) ITEM_AUX(Tile::prismarine_Id, PrismarineTile::TYPE_DEFAULT) ITEM_AUX(Tile::prismarine_Id, PrismarineTile::TYPE_BRICKS) ITEM_AUX(Tile::prismarine_Id, PrismarineTile::TYPE_DARK) + ITEM(Tile::slime_Id) ITEM(Tile::fence_Id) // TU25 - ITEM(Tile::spruceFence_Id) - ITEM(Tile::birchFence_Id) - ITEM(Tile::jungleFence_Id) - ITEM(Tile::acaciaFence_Id) - ITEM(Tile::darkFence_Id) + ITEM(Tile::spruce_fence_Id) + ITEM(Tile::birch_fence_Id) + ITEM(Tile::jungle_fence_Id) + ITEM(Tile::acacia_fence_Id) + ITEM(Tile::dark_oak_fence_Id) - ITEM(Tile::netherFence_Id) - ITEM(Tile::ironFence_Id) - ITEM_AUX(Tile::cobbleWall_Id, WallTile::TYPE_NORMAL) - ITEM_AUX(Tile::cobbleWall_Id, WallTile::TYPE_MOSSY) - ITEM_AUX(Tile::stoneBrick_Id,SmoothStoneBrickTile::TYPE_DEFAULT) - ITEM_AUX(Tile::stoneBrick_Id,SmoothStoneBrickTile::TYPE_MOSSY) - ITEM_AUX(Tile::stoneBrick_Id,SmoothStoneBrickTile::TYPE_CRACKED) - ITEM_AUX(Tile::stoneBrick_Id,SmoothStoneBrickTile::TYPE_DETAIL) - ITEM_AUX(Tile::monsterStoneEgg_Id,StoneMonsterTile::HOST_ROCK) - ITEM_AUX(Tile::monsterStoneEgg_Id,StoneMonsterTile::HOST_COBBLE) - ITEM_AUX(Tile::monsterStoneEgg_Id,StoneMonsterTile::HOST_STONEBRICK) - ITEM(Tile::mycel_Id) + ITEM(Tile::nether_brick_fence_Id) + ITEM(Tile::iron_bars_Id) + ITEM_AUX(Tile::cobblestone_wall_Id, WallTile::TYPE_NORMAL) + ITEM_AUX(Tile::cobblestone_wall_Id, WallTile::TYPE_MOSSY) + ITEM_AUX(Tile::stonebrick_Id,SmoothStoneBrickTile::TYPE_DEFAULT) + ITEM_AUX(Tile::stonebrick_Id,SmoothStoneBrickTile::TYPE_MOSSY) + ITEM_AUX(Tile::stonebrick_Id,SmoothStoneBrickTile::TYPE_CRACKED) + ITEM_AUX(Tile::stonebrick_Id,SmoothStoneBrickTile::TYPE_DETAIL) + ITEM_AUX(Tile::monster_egg_Id,StoneMonsterTile::HOST_ROCK) + ITEM_AUX(Tile::monster_egg_Id,StoneMonsterTile::HOST_COBBLE) + ITEM_AUX(Tile::monster_egg_Id,StoneMonsterTile::HOST_STONEBRICK) + ITEM(Tile::mycelium_Id) ITEM_AUX(Tile::dirt_Id, DirtTile::COARSE_DIRT) ITEM_AUX(Tile::dirt_Id, DirtTile::PODZOL) - ITEM(Tile::netherBrick_Id) - ITEM(Tile::endStone_Id) - ITEM_AUX(Tile::quartzBlock_Id,QuartzBlockTile::TYPE_CHISELED) - ITEM_AUX(Tile::quartzBlock_Id,QuartzBlockTile::TYPE_LINES_Y) + ITEM(Tile::nether_brick_Id) + ITEM(Tile::end_stone_Id) + ITEM_AUX(Tile::quartz_block_Id,QuartzBlockTile::TYPE_CHISELED) + ITEM_AUX(Tile::quartz_block_Id,QuartzBlockTile::TYPE_LINES_Y) ITEM(Tile::trapdoor_Id) ITEM(Tile::iron_trapdoor_Id) - ITEM(Tile::fenceGate_Id) + ITEM(Tile::fence_gate_Id) // TU25 - ITEM(Tile::spruceGate_Id) - ITEM(Tile::birchGate_Id) - ITEM(Tile::jungleGate_Id) - ITEM(Tile::acaciaGate_Id) - ITEM(Tile::darkGate_Id) + ITEM(Tile::spruce_fence_gate_Id) + ITEM(Tile::birch_fence_gate_Id) + ITEM(Tile::jungle_fence_gate_Id) + ITEM(Tile::acacia_fence_gate_Id) + ITEM(Tile::dark_oak_fence_gate_Id) - ITEM(Item::door_wood_Id) - ITEM(Item::door_iron_Id) + ITEM(Item::wooden_door_Id) + ITEM(Item::iron_door_Id) // TU25 - ITEM(Item::door_spruce_Id) - ITEM(Item::door_birch_Id) - ITEM(Item::door_jungle_Id) - ITEM(Item::door_acacia_Id) - ITEM(Item::door_dark_Id) + ITEM(Item::spruce_door_Id) + ITEM(Item::birch_door_Id) + ITEM(Item::jungle_door_Id) + ITEM(Item::acacia_door_Id) + ITEM(Item::dark_oak_door_Id) - ITEM_AUX(Tile::stoneSlabHalf_Id,StoneSlabTile::STONE_SLAB) - ITEM_AUX(Tile::stoneSlabHalf_Id,StoneSlabTile::SAND_SLAB) + ITEM_AUX(Tile::stone_slab_Id,StoneSlabTile::STONE_SLAB) + ITEM_AUX(Tile::stone_slab_Id,StoneSlabTile::SAND_SLAB) // AP - changed oak slab to be wood because it wouldn't burn -// ITEM_AUX(Tile::stoneSlabHalf_Id,StoneSlabTile::WOOD_SLAB) - ITEM_AUX(Tile::woodSlabHalf_Id,0) - ITEM_AUX(Tile::woodSlabHalf_Id, TreeTile::SPRUCE_TRUNK) - ITEM_AUX(Tile::woodSlabHalf_Id,TreeTile::BIRCH_TRUNK) - ITEM_AUX(Tile::woodSlabHalf_Id,TreeTile::JUNGLE_TRUNK) +// ITEM_AUX(Tile::stone_slab_Id,StoneSlabTile::WOOD_SLAB) + ITEM_AUX(Tile::wooden_slab_Id,0) + ITEM_AUX(Tile::wooden_slab_Id, TreeTile::SPRUCE_TRUNK) + ITEM_AUX(Tile::wooden_slab_Id,TreeTile::BIRCH_TRUNK) + ITEM_AUX(Tile::wooden_slab_Id,TreeTile::JUNGLE_TRUNK) // TU25 -- added acacia and dark oak - ITEM_AUX(Tile::woodSlabHalf_Id, TreeTile::ACACIA_TRUNK) - ITEM_AUX(Tile::woodSlabHalf_Id, TreeTile::DARK_TRUNK) + ITEM_AUX(Tile::wooden_slab_Id, TreeTile::ACACIA_TRUNK) + ITEM_AUX(Tile::wooden_slab_Id, TreeTile::DARK_TRUNK) - ITEM_AUX(Tile::stoneSlabHalf_Id,StoneSlabTile::COBBLESTONE_SLAB) - ITEM_AUX(Tile::stoneSlabHalf_Id,StoneSlabTile::BRICK_SLAB) - ITEM_AUX(Tile::stoneSlabHalf_Id,StoneSlabTile::SMOOTHBRICK_SLAB) - ITEM_AUX(Tile::stoneSlabHalf_Id,StoneSlabTile::NETHERBRICK_SLAB) - ITEM_AUX(Tile::stoneSlabHalf_Id,StoneSlabTile::QUARTZ_SLAB) + ITEM_AUX(Tile::stone_slab_Id,StoneSlabTile::COBBLESTONE_SLAB) + ITEM_AUX(Tile::stone_slab_Id,StoneSlabTile::BRICK_SLAB) + ITEM_AUX(Tile::stone_slab_Id,StoneSlabTile::SMOOTHBRICK_SLAB) + ITEM_AUX(Tile::stone_slab_Id,StoneSlabTile::NETHERBRICK_SLAB) + ITEM_AUX(Tile::stone_slab_Id,StoneSlabTile::QUARTZ_SLAB) ITEM_AUX(Tile::stone_slab2_Id ,StoneSlabTile2::RED_SANDSTONE_SLAB) - ITEM(Tile::stairs_wood_Id) - ITEM(Tile::stairs_birchwood_Id) - ITEM(Tile::stairs_sprucewood_Id) - ITEM(Tile::stairs_junglewood_Id) - ITEM(Tile::stairs_acaciawood_Id) - ITEM(Tile::stairs_darkwood_Id) - ITEM(Tile::stairs_stone_Id) - ITEM(Tile::stairs_bricks_Id) - ITEM(Tile::stairs_stoneBrick_Id) - ITEM(Tile::stairs_netherBricks_Id) - ITEM(Tile::stairs_sandstone_Id) + ITEM(Tile::oak_stairs_Id) + ITEM(Tile::birch_stairs_Id) + ITEM(Tile::spruce_stairs_Id) + ITEM(Tile::jungle_stairs_Id) + ITEM(Tile::acacia_stairs_Id) + ITEM(Tile::dark_oak_stairs_Id) + ITEM(Tile::stone_stairs_Id) + ITEM(Tile::brick_stairs_Id) + ITEM(Tile::stone_brick_stairs_Id) + ITEM(Tile::nether_brick_stairs_Id) + ITEM(Tile::sandstone_stairs_Id) ITEM(Tile::stairs_red_sandstone) - ITEM(Tile::stairs_quartz_Id) + ITEM(Tile::quartz_stairs_Id) - ITEM(Tile::clayHardened_Id) - ITEM_AUX(Tile::clayHardened_colored_Id,14) // Red - ITEM_AUX(Tile::clayHardened_colored_Id,1) // Orange - ITEM_AUX(Tile::clayHardened_colored_Id,4) // Yellow - ITEM_AUX(Tile::clayHardened_colored_Id,5) // Lime - ITEM_AUX(Tile::clayHardened_colored_Id,3) // Light Blue - ITEM_AUX(Tile::clayHardened_colored_Id,9) // Cyan - ITEM_AUX(Tile::clayHardened_colored_Id,11) // Blue - ITEM_AUX(Tile::clayHardened_colored_Id,10) // Purple - ITEM_AUX(Tile::clayHardened_colored_Id,2) // Magenta - ITEM_AUX(Tile::clayHardened_colored_Id,6) // Pink - ITEM_AUX(Tile::clayHardened_colored_Id,0) // White - ITEM_AUX(Tile::clayHardened_colored_Id,8) // Light Gray - ITEM_AUX(Tile::clayHardened_colored_Id,7) // Gray - ITEM_AUX(Tile::clayHardened_colored_Id,15) // Black - ITEM_AUX(Tile::clayHardened_colored_Id,13) // Green - ITEM_AUX(Tile::clayHardened_colored_Id,12) // Brown + ITEM(Tile::hardened_clay_Id) + ITEM_AUX(Tile::stained_hardened_clay_Id,14) // Red + ITEM_AUX(Tile::stained_hardened_clay_Id,1) // Orange + ITEM_AUX(Tile::stained_hardened_clay_Id,4) // Yellow + ITEM_AUX(Tile::stained_hardened_clay_Id,5) // Lime + ITEM_AUX(Tile::stained_hardened_clay_Id,3) // Light Blue + ITEM_AUX(Tile::stained_hardened_clay_Id,9) // Cyan + ITEM_AUX(Tile::stained_hardened_clay_Id,11) // Blue + ITEM_AUX(Tile::stained_hardened_clay_Id,10) // Purple + ITEM_AUX(Tile::stained_hardened_clay_Id,2) // Magenta + ITEM_AUX(Tile::stained_hardened_clay_Id,6) // Pink + ITEM_AUX(Tile::stained_hardened_clay_Id,0) // White + ITEM_AUX(Tile::stained_hardened_clay_Id,8) // Light Gray + ITEM_AUX(Tile::stained_hardened_clay_Id,7) // Gray + ITEM_AUX(Tile::stained_hardened_clay_Id,15) // Black + ITEM_AUX(Tile::stained_hardened_clay_Id,13) // Green + ITEM_AUX(Tile::stained_hardened_clay_Id,12) // Brown // Decoration DEF(eCreativeInventory_Decoration) @@ -252,9 +253,9 @@ void IUIScene_CreativeMenu::staticCtor() ITEM_AUX(Item::skull_Id,SkullTileEntity::TYPE_CREEPER) ITEM_AUX(Tile::sponge_Id, 0) // dry sponge ITEM_AUX(Tile::sponge_Id, 1) // wet sponge - ITEM(Tile::melon_Id) + ITEM(Tile::melon_block_Id) ITEM(Tile::pumpkin_Id) - ITEM(Tile::litPumpkin_Id) + ITEM(Tile::lit_pumpkin_Id) ITEM_AUX(Tile::sapling_Id, Sapling::TYPE_DEFAULT) ITEM_AUX(Tile::sapling_Id, Sapling::TYPE_EVERGREEN) ITEM_AUX(Tile::sapling_Id, Sapling::TYPE_BIRCH) @@ -268,42 +269,42 @@ void IUIScene_CreativeMenu::staticCtor() ITEM_AUX(Tile::leaves2_Id, LeafTile2::ACACIA_LEAF) ITEM_AUX(Tile::leaves2_Id, LeafTile2::DARK_OAK_LEAF) ITEM(Tile::vine) - ITEM(Tile::waterLily_Id) + ITEM(Tile::waterlily_Id) ITEM(Tile::torch_Id) ITEM_AUX(Tile::tallgrass_Id, TallGrass::DEAD_SHRUB) ITEM_AUX(Tile::tallgrass_Id, TallGrass::TALL_GRASS) ITEM_AUX(Tile::tallgrass_Id, TallGrass::FERN) - ITEM(Tile::deadBush_Id) - ITEM(Tile::flower_Id) - ITEM(Tile::rose_Id) - ITEM_AUX(Tile::rose_Id, Rose::BLUE_ORCHID) - ITEM_AUX(Tile::rose_Id, Rose::ALLIUM) - ITEM_AUX(Tile::rose_Id, Rose::AZURE_BLUET) - ITEM_AUX(Tile::rose_Id, Rose::RED_TULIP) - ITEM_AUX(Tile::rose_Id, Rose::ORANGE_TULIP) - ITEM_AUX(Tile::rose_Id, Rose::WHITE_TULIP) - ITEM_AUX(Tile::rose_Id, Rose::PINK_TULIP) - ITEM_AUX(Tile::rose_Id, Rose::OXEYE_DAISY) - // SUNFLOWER LOCATION - ITEM_AUX(Tile::tallgrass2_Id, TallGrass2::LILAC) - ITEM_AUX(Tile::tallgrass2_Id, TallGrass2::TALL_GRASS) - ITEM_AUX(Tile::tallgrass2_Id, TallGrass2::LARGE_FERN) - ITEM_AUX(Tile::tallgrass2_Id, TallGrass2::ROSE_BUSH) - ITEM_AUX(Tile::tallgrass2_Id, TallGrass2::PEONY) + ITEM(Tile::deadbush_Id) + ITEM(Tile::yellow_flower_Id) + ITEM(Tile::red_flower_Id) + ITEM_AUX(Tile::red_flower_Id, Rose::BLUE_ORCHID) + ITEM_AUX(Tile::red_flower_Id, Rose::ALLIUM) + ITEM_AUX(Tile::red_flower_Id, Rose::AZURE_BLUET) + ITEM_AUX(Tile::red_flower_Id, Rose::RED_TULIP) + ITEM_AUX(Tile::red_flower_Id, Rose::ORANGE_TULIP) + ITEM_AUX(Tile::red_flower_Id, Rose::WHITE_TULIP) + ITEM_AUX(Tile::red_flower_Id, Rose::PINK_TULIP) + ITEM_AUX(Tile::red_flower_Id, Rose::OXEYE_DAISY) + ITEM(Tile::double_plant_Id) + ITEM_AUX(Tile::double_plant_Id, TallGrass2::LILAC) + ITEM_AUX(Tile::double_plant_Id, TallGrass2::TALL_GRASS) + ITEM_AUX(Tile::double_plant_Id, TallGrass2::LARGE_FERN) + ITEM_AUX(Tile::double_plant_Id, TallGrass2::ROSE_BUSH) + ITEM_AUX(Tile::double_plant_Id, TallGrass2::PEONY) ITEM(Tile::mushroom_brown_Id) ITEM(Tile::mushroom_red_Id) ITEM(Tile::cactus_Id) - ITEM(Tile::topSnow_Id) + ITEM(Tile::snow_layer_Id) // 4J-PB - Already got sugar cane in Materials ITEM_11(Tile::reeds_Id) ITEM(Tile::web_Id) - ITEM(Tile::thinGlass_Id) + ITEM(Tile::glass_pane_Id) ITEM(Tile::glass_Id) ITEM(Item::painting_Id) - ITEM(Item::itemFrame_Id) - ITEM(Item::sign_Id) + ITEM(Item::item_frame_Id) + ITEM(Item::standing_sign_Id) ITEM(Tile::bookshelf_Id) - ITEM(Item::flowerPot_Id) - ITEM(Tile::hayBlock_Id) + ITEM(Item::flower_pot_Id) + ITEM(Tile::hay_block_Id) ITEM_AUX(Tile::wool_Id,14) // Red ITEM_AUX(Tile::wool_Id,1) // Orange ITEM_AUX(Tile::wool_Id,4) // Yellow @@ -321,22 +322,22 @@ void IUIScene_CreativeMenu::staticCtor() ITEM_AUX(Tile::wool_Id,13) // Green ITEM_AUX(Tile::wool_Id,12) // Brown - ITEM_AUX(Tile::woolCarpet_Id,14) // Red - ITEM_AUX(Tile::woolCarpet_Id,1) // Orange - ITEM_AUX(Tile::woolCarpet_Id,4) // Yellow - ITEM_AUX(Tile::woolCarpet_Id,5) // Lime - ITEM_AUX(Tile::woolCarpet_Id,3) // Light Blue - ITEM_AUX(Tile::woolCarpet_Id,9) // Cyan - ITEM_AUX(Tile::woolCarpet_Id,11) // Blue - ITEM_AUX(Tile::woolCarpet_Id,10) // Purple - ITEM_AUX(Tile::woolCarpet_Id,2) // Magenta - ITEM_AUX(Tile::woolCarpet_Id,6) // Pink - ITEM_AUX(Tile::woolCarpet_Id,0) // White - ITEM_AUX(Tile::woolCarpet_Id,8) // Light Gray - ITEM_AUX(Tile::woolCarpet_Id,7) // Gray - ITEM_AUX(Tile::woolCarpet_Id,15) // Black - ITEM_AUX(Tile::woolCarpet_Id,13) // Green - ITEM_AUX(Tile::woolCarpet_Id,12) // Brown + ITEM_AUX(Tile::carpet_Id,14) // Red + ITEM_AUX(Tile::carpet_Id,1) // Orange + ITEM_AUX(Tile::carpet_Id,4) // Yellow + ITEM_AUX(Tile::carpet_Id,5) // Lime + ITEM_AUX(Tile::carpet_Id,3) // Light Blue + ITEM_AUX(Tile::carpet_Id,9) // Cyan + ITEM_AUX(Tile::carpet_Id,11) // Blue + ITEM_AUX(Tile::carpet_Id,10) // Purple + ITEM_AUX(Tile::carpet_Id,2) // Magenta + ITEM_AUX(Tile::carpet_Id,6) // Pink + ITEM_AUX(Tile::carpet_Id,0) // White + ITEM_AUX(Tile::carpet_Id,8) // Light Gray + ITEM_AUX(Tile::carpet_Id,7) // Gray + ITEM_AUX(Tile::carpet_Id,15) // Black + ITEM_AUX(Tile::carpet_Id,13) // Green + ITEM_AUX(Tile::carpet_Id,12) // Brown ITEM_AUX(Tile::stained_glass_Id,14) // Red ITEM_AUX(Tile::stained_glass_Id,1) // Orange @@ -398,40 +399,40 @@ void IUIScene_CreativeMenu::staticCtor() DEF(eCreativeInventory_Redstone) ITEM(Tile::dispenser_Id) ITEM(Tile::noteblock_Id) - ITEM(Tile::pistonBase_Id) - ITEM(Tile::pistonStickyBase_Id) + ITEM(Tile::piston_Id) + ITEM(Tile::sticky_piston_Id) ITEM(Tile::tnt_Id) ITEM(Tile::lever_Id) - ITEM(Tile::button_stone_Id) - ITEM(Tile::button_wood_Id) - ITEM(Tile::pressurePlate_stone_Id) - ITEM(Tile::pressurePlate_wood_Id) - ITEM(Item::redStone_Id) - ITEM(Tile::redstoneBlock_Id) - ITEM(Tile::redstoneTorch_on_Id) + ITEM(Tile::stone_button_Id) + ITEM(Tile::wooden_button_Id) + ITEM(Tile::stone_pressure_plate_Id) + ITEM(Tile::wooden_pressure_plate_Id) + ITEM(Item::redstone_Id) + ITEM(Tile::redstone_block_Id) + ITEM(Tile::redstone_torch_Id) ITEM(Item::repeater_Id) - ITEM(Tile::redstoneLight_Id) - ITEM(Tile::tripWireSource_Id) - ITEM(Tile::daylightDetector_Id) + ITEM(Tile::redstone_lamp_Id) + ITEM(Tile::tripwire_hook_Id) + ITEM(Tile::daylight_detector_Id) ITEM(Tile::dropper_Id) ITEM(Tile::hopper_Id) ITEM(Item::comparator_Id) ITEM(Tile::chest_trap_Id) - ITEM(Tile::weightedPlate_heavy_Id) - ITEM(Tile::weightedPlate_light_Id) + ITEM(Tile::heavy_weighted_pressure_plate_Id) + ITEM(Tile::light_weighted_pressure_plate_Id) // Transport DEF(eCreativeInventory_Transport) ITEM(Tile::rail_Id) - ITEM(Tile::goldenRail_Id) - ITEM(Tile::detectorRail_Id) - ITEM(Tile::activatorRail_Id) + ITEM(Tile::golden_rail_Id) + ITEM(Tile::detector_rail_Id) + ITEM(Tile::activator_rail_Id) ITEM(Tile::ladder_Id) ITEM(Item::minecart_Id) - ITEM(Item::minecart_chest_Id) - ITEM(Item::minecart_furnace_Id) - ITEM(Item::minecart_hopper_Id) - ITEM(Item::minecart_tnt_Id) + ITEM(Item::chest_minecart_Id) + ITEM(Item::furnace_minecart_Id) + ITEM(Item::hopper_minecart_Id) + ITEM(Item::tnt_minecart_Id) ITEM(Item::saddle_Id) ITEM(Item::boat_Id) ITEM(Item::elytra_Id) @@ -439,76 +440,76 @@ void IUIScene_CreativeMenu::staticCtor() // Miscellaneous DEF(eCreativeInventory_Misc) ITEM(Tile::chest_Id) - ITEM(Tile::enderChest_Id) - ITEM(Tile::workBench_Id) + ITEM(Tile::ender_chest_Id) + ITEM(Tile::crafting_table_Id) ITEM(Tile::furnace_Id) - ITEM(Item::brewingStand_Id) - ITEM(Tile::enchantTable_Id) + ITEM(Item::brewing_stand_Id) + ITEM(Tile::enchanting_table_Id) ITEM(Tile::beacon_Id) - ITEM(Tile::endPortalFrameTile_Id) + ITEM(Tile::end_portal_frame_Id) ITEM(Tile::jukebox_Id) ITEM(Tile::anvil_Id); ITEM(Item::bed_Id) - ITEM(Item::bucket_empty_Id) - ITEM(Item::bucket_lava_Id) - ITEM(Item::bucket_water_Id) - ITEM(Item::bucket_milk_Id) + ITEM(Item::bucket_Id) + ITEM(Item::lava_bucket_Id) + ITEM(Item::water_bucket_Id) + ITEM(Item::milk_bucket_Id) ITEM(Item::cauldron_Id) - ITEM(Item::snowBall_Id) + ITEM(Item::snowball_Id) ITEM(Item::paper_Id) ITEM(Item::book_Id) //TU25 - ITEM(Item::writingBook_Id) + ITEM(Item::writable_book_Id) - ITEM(Item::enderPearl_Id) - ITEM(Item::eyeOfEnder_Id) - ITEM(Item::nameTag_Id) - ITEM(Item::netherStar_Id) - ITEM_AUX(Item::spawnEgg_Id, 50); // Creeper - ITEM_AUX(Item::spawnEgg_Id, 51); // Skeleton - ITEM_AUX(Item::spawnEgg_Id, 52); // Spider - ITEM_AUX(Item::spawnEgg_Id, 54); // Zombie - ITEM_AUX(Item::spawnEgg_Id, 55); // Slime - ITEM_AUX(Item::spawnEgg_Id, 56); // Ghast - ITEM_AUX(Item::spawnEgg_Id, 57); // Zombie Pigman - ITEM_AUX(Item::spawnEgg_Id, 58); // Enderman - ITEM_AUX(Item::spawnEgg_Id, 59); // Cave Spider - ITEM_AUX(Item::spawnEgg_Id, 60); // Silverfish - ITEM_AUX(Item::spawnEgg_Id, 61); // Blaze - ITEM_AUX(Item::spawnEgg_Id, 62); // Magma Cube - ITEM_AUX(Item::spawnEgg_Id, 65); // Bat - ITEM_AUX(Item::spawnEgg_Id, 66); // Witch + ITEM(Item::ender_pearl_Id) + ITEM(Item::eye_of_ender_Id) + ITEM(Item::name_tag_Id) + ITEM(Item::nether_star_Id) + ITEM_AUX(Item::spawn_egg_Id, 50); // Creeper + ITEM_AUX(Item::spawn_egg_Id, 51); // Skeleton + ITEM_AUX(Item::spawn_egg_Id, 52); // Spider + ITEM_AUX(Item::spawn_egg_Id, 54); // Zombie + ITEM_AUX(Item::spawn_egg_Id, 55); // Slime + ITEM_AUX(Item::spawn_egg_Id, 56); // Ghast + ITEM_AUX(Item::spawn_egg_Id, 57); // Zombie Pigman + ITEM_AUX(Item::spawn_egg_Id, 58); // Enderman + ITEM_AUX(Item::spawn_egg_Id, 59); // Cave Spider + ITEM_AUX(Item::spawn_egg_Id, 60); // Silverfish + ITEM_AUX(Item::spawn_egg_Id, 61); // Blaze + ITEM_AUX(Item::spawn_egg_Id, 62); // Magma Cube + ITEM_AUX(Item::spawn_egg_Id, 65); // Bat + ITEM_AUX(Item::spawn_egg_Id, 66); // Witch - ITEM_AUX(Item::spawnEgg_Id, 67); // Endermite - ITEM_AUX(Item::spawnEgg_Id, 68); // Guardian - ITEM_AUX(Item::spawnEgg_Id, 4); // Elder Guardian - ITEM_AUX(Item::spawnEgg_Id, 90); // Pig - ITEM_AUX(Item::spawnEgg_Id, 91); // Sheep - ITEM_AUX(Item::spawnEgg_Id, 92); // Cow - ITEM_AUX(Item::spawnEgg_Id, 93); // Chicken - ITEM_AUX(Item::spawnEgg_Id, 94); // Squid - ITEM_AUX(Item::spawnEgg_Id, 95); // Wolf - ITEM_AUX(Item::spawnEgg_Id, 96); // Mooshroom - ITEM_AUX(Item::spawnEgg_Id, 98); // Ozelot - ITEM_AUX(Item::spawnEgg_Id, 100); // Horse + ITEM_AUX(Item::spawn_egg_Id, 67); // Endermite + ITEM_AUX(Item::spawn_egg_Id, 68); // Guardian + ITEM_AUX(Item::spawn_egg_Id, 4); // Elder Guardian + ITEM_AUX(Item::spawn_egg_Id, 90); // Pig + ITEM_AUX(Item::spawn_egg_Id, 91); // Sheep + ITEM_AUX(Item::spawn_egg_Id, 92); // Cow + ITEM_AUX(Item::spawn_egg_Id, 93); // Chicken + ITEM_AUX(Item::spawn_egg_Id, 94); // Squid + ITEM_AUX(Item::spawn_egg_Id, 95); // Wolf + ITEM_AUX(Item::spawn_egg_Id, 96); // Mooshroom + ITEM_AUX(Item::spawn_egg_Id, 98); // Ozelot + ITEM_AUX(Item::spawn_egg_Id, 100); // Horse - ITEM_AUX(Item::spawnEgg_Id, 100 | ((EntityHorse::TYPE_DONKEY + 1) << 12) ); // Donkey - ITEM_AUX(Item::spawnEgg_Id, 100 | ((EntityHorse::TYPE_MULE + 1) << 12)); // Mule - ITEM_AUX(Item::spawnEgg_Id, 120); // Villager - ITEM_AUX(Item::spawnEgg_Id, 101); // Rabbit Brown - ITEM(Item::record_01_Id) - ITEM(Item::record_02_Id) - ITEM(Item::record_03_Id) - ITEM(Item::record_04_Id) - ITEM(Item::record_05_Id) - ITEM(Item::record_06_Id) - ITEM(Item::record_07_Id) - ITEM(Item::record_08_Id) - ITEM(Item::record_09_Id) - ITEM(Item::record_10_Id) + ITEM_AUX(Item::spawn_egg_Id, 100 | ((EntityHorse::TYPE_DONKEY + 1) << 12) ); // Donkey + ITEM_AUX(Item::spawn_egg_Id, 100 | ((EntityHorse::TYPE_MULE + 1) << 12)); // Mule + ITEM_AUX(Item::spawn_egg_Id, 120); // Villager + ITEM_AUX(Item::spawn_egg_Id, 101); // Rabbit Brown + ITEM(Item::record_13_Id) + ITEM(Item::record_cat_Id) + ITEM(Item::record_blocks_Id) + ITEM(Item::record_chirp_Id) + ITEM(Item::record_far_Id) + ITEM(Item::record_mall_Id) + ITEM(Item::record_mellohi_Id) + ITEM(Item::record_stal_Id) + ITEM(Item::record_strad_Id) + ITEM(Item::record_ward_Id) ITEM(Item::record_11_Id) - ITEM(Item::record_12_Id) + ITEM(Item::record_wait_Id) BuildFirework(list, FireworksItem::TYPE_SMALL, DyePowderItem::LIGHT_BLUE, 1, true, false); BuildFirework(list, FireworksItem::TYPE_CREEPER, DyePowderItem::GREEN, 2, false, false); @@ -520,119 +521,119 @@ void IUIScene_CreativeMenu::staticCtor() DEF(eCreativeInventory_ArtToolsMisc) if(app.DebugSettingsOn()) { - ITEM_AUX(Item::spawnEgg_Id, 100 | ((EntityHorse::TYPE_SKELETON + 1) << 12)); // Skeleton - ITEM_AUX(Item::spawnEgg_Id, 100 | ((EntityHorse::TYPE_UNDEAD + 1) << 12)); // Zombie - ITEM_AUX(Item::spawnEgg_Id, 98 | ((Ocelot::TYPE_BLACK + 1) << 12)); - ITEM_AUX(Item::spawnEgg_Id, 98 | ((Ocelot::TYPE_RED + 1) << 12)); - ITEM_AUX(Item::spawnEgg_Id, 98 | ((Ocelot::TYPE_SIAMESE + 1) << 12)); - ITEM_AUX(Item::spawnEgg_Id, 52 | (2 << 12)); // Spider-Jockey - ITEM_AUX(Item::spawnEgg_Id, 63); // Enderdragon + ITEM_AUX(Item::spawn_egg_Id, 100 | ((EntityHorse::TYPE_SKELETON + 1) << 12)); // Skeleton + ITEM_AUX(Item::spawn_egg_Id, 100 | ((EntityHorse::TYPE_UNDEAD + 1) << 12)); // Zombie + ITEM_AUX(Item::spawn_egg_Id, 98 | ((Ocelot::TYPE_BLACK + 1) << 12)); + ITEM_AUX(Item::spawn_egg_Id, 98 | ((Ocelot::TYPE_RED + 1) << 12)); + ITEM_AUX(Item::spawn_egg_Id, 98 | ((Ocelot::TYPE_SIAMESE + 1) << 12)); + ITEM_AUX(Item::spawn_egg_Id, 52 | (2 << 12)); // Spider-Jockey + ITEM_AUX(Item::spawn_egg_Id, 63); // Enderdragon } // Food DEF(eCreativeInventory_Food) ITEM(Item::apple_Id) - ITEM(Item::apple_gold_Id) - ITEM_AUX(Item::apple_gold_Id,1) // Enchanted - ITEM(Item::melon_Id) - ITEM(Item::mushroomStew_Id) - ITEM(Item::rabbitStew_Id) + ITEM(Item::golden_apple_Id) + ITEM_AUX(Item::golden_apple_Id,1) // Enchanted + ITEM(Item::melon_block_Id) + ITEM(Item::mushroom_stew_Id) + ITEM(Item::rabbit_stew_Id) ITEM(Item::bread_Id) ITEM(Item::cake_Id) ITEM(Item::cookie_Id) - ITEM(Item::fish_cooked_Id) - ITEM(Item::fish_raw_Id) + ITEM(Item::cooked_fish_Id) + ITEM(Item::fish_Id) - ITEM_AUX(Item::fish_cooked_Id, 1) - ITEM_AUX(Item::fish_raw_Id, 1) - ITEM_AUX(Item::fish_raw_Id, 2) - ITEM_AUX(Item::fish_raw_Id, 3) + ITEM_AUX(Item::cooked_fish_Id, 1) + ITEM_AUX(Item::fish_Id, 1) + ITEM_AUX(Item::fish_Id, 2) + ITEM_AUX(Item::fish_Id, 3) - ITEM(Item::porkChop_cooked_Id) - ITEM(Item::porkChop_raw_Id) - ITEM(Item::beef_cooked_Id) - ITEM(Item::beef_raw_Id) - ITEM(Item::chicken_raw_Id) - ITEM(Item::chicken_cooked_Id) - ITEM(Item::mutton_raw_Id) - ITEM(Item::mutton_cooked_Id) - ITEM(Item::rabbit_raw_Id) - ITEM(Item::rabbit_cooked_Id) + ITEM(Item::cooked_porkchop_Id) + ITEM(Item::porkchop_Id) + ITEM(Item::cooked_beef_Id) + ITEM(Item::beef_Id) + ITEM(Item::chicken_Id) + ITEM(Item::cooked_chicken_Id) + ITEM(Item::mutton_Id) + ITEM(Item::cooked_mutton_Id) + ITEM(Item::rabbit_Id) + ITEM(Item::cooked_rabbit_Id) ITEM(Item::rotten_flesh_Id) - ITEM(Item::spiderEye_Id) + ITEM(Item::spider_eye_Id) ITEM(Item::potato_Id) - ITEM(Item::potatoBaked_Id) - ITEM(Item::potatoPoisonous_Id) - ITEM(Item::carrots_Id) - ITEM(Item::carrotGolden_Id) - ITEM(Item::pumpkinPie_Id) + ITEM(Item::baked_potato_Id) + ITEM(Item::poisonous_potato_Id) + ITEM(Item::carrot_Id) + ITEM(Item::golden_carrot_Id) + ITEM(Item::pumpkin_pie_Id) // Tools, Armour and Weapons (Complete) DEF(eCreativeInventory_ToolsArmourWeapons) ITEM(Item::compass_Id) - ITEM(Item::helmet_leather_Id) - ITEM(Item::chestplate_leather_Id) - ITEM(Item::leggings_leather_Id) - ITEM(Item::boots_leather_Id) - ITEM(Item::sword_wood_Id) - ITEM(Item::shovel_wood_Id) - ITEM(Item::pickAxe_wood_Id) - ITEM(Item::hatchet_wood_Id) - ITEM(Item::hoe_wood_Id) + ITEM(Item::leather_helmet_Id) + ITEM(Item::leather_chestplate_Id) + ITEM(Item::leather_leggings_Id) + ITEM(Item::leather_boots_Id) + ITEM(Item::wooden_sword_Id) + ITEM(Item::wooden_shovel_Id) + ITEM(Item::wooden_pickaxe_Id) + ITEM(Item::wooden_axe_Id) + ITEM(Item::wooden_hoe_Id) - ITEM(Item::emptyMap_Id) - ITEM(Item::helmet_chain_Id) - ITEM(Item::chestplate_chain_Id) - ITEM(Item::leggings_chain_Id) - ITEM(Item::boots_chain_Id) - ITEM(Item::sword_stone_Id) - ITEM(Item::shovel_stone_Id) - ITEM(Item::pickAxe_stone_Id) - ITEM(Item::hatchet_stone_Id) - ITEM(Item::hoe_stone_Id) + ITEM(Item::map_Id) + ITEM(Item::chainmail_helmet_Id) + ITEM(Item::chainmail_chestplate_Id) + ITEM(Item::chainmail_leggings_Id) + ITEM(Item::chainmail_boots_Id) + ITEM(Item::stone_sword_Id) + ITEM(Item::stone_shovel_Id) + ITEM(Item::stone_pickaxe_Id) + ITEM(Item::stone_axe_Id) + ITEM(Item::stone_hoe_Id) ITEM(Item::bow_Id) - ITEM(Item::helmet_iron_Id) - ITEM(Item::chestplate_iron_Id) - ITEM(Item::leggings_iron_Id) - ITEM(Item::boots_iron_Id) - ITEM(Item::sword_iron_Id) - ITEM(Item::shovel_iron_Id) - ITEM(Item::pickAxe_iron_Id) - ITEM(Item::hatchet_iron_Id) - ITEM(Item::hoe_iron_Id) + ITEM(Item::iron_helmet_Id) + ITEM(Item::iron_chestplate_Id) + ITEM(Item::iron_leggings_Id) + ITEM(Item::iron_boots_Id) + ITEM(Item::iron_sword_Id) + ITEM(Item::iron_shovel_Id) + ITEM(Item::iron_pickaxe_Id) + ITEM(Item::iron_axe_Id) + ITEM(Item::iron_hoe_Id) ITEM(Item::arrow_Id) - ITEM(Item::helmet_gold_Id) - ITEM(Item::chestplate_gold_Id) - ITEM(Item::leggings_gold_Id) - ITEM(Item::boots_gold_Id) - ITEM(Item::sword_gold_Id) - ITEM(Item::shovel_gold_Id) - ITEM(Item::pickAxe_gold_Id) - ITEM(Item::hatchet_gold_Id) - ITEM(Item::hoe_gold_Id) + ITEM(Item::golden_helmet_Id) + ITEM(Item::golden_chestplate_Id) + ITEM(Item::golden_leggings_Id) + ITEM(Item::golden_boots_Id) + ITEM(Item::golden_sword_Id) + ITEM(Item::golden_shovel_Id) + ITEM(Item::golden_pickaxe_Id) + ITEM(Item::golden_axe_Id) + ITEM(Item::golden_hoe_Id) - ITEM(Item::flintAndSteel_Id) - ITEM(Item::helmet_diamond_Id) - ITEM(Item::chestplate_diamond_Id) - ITEM(Item::leggings_diamond_Id) - ITEM(Item::boots_diamond_Id) - ITEM(Item::sword_diamond_Id) - ITEM(Item::shovel_diamond_Id) - ITEM(Item::pickAxe_diamond_Id) - ITEM(Item::hatchet_diamond_Id) - ITEM(Item::hoe_diamond_Id) + ITEM(Item::flint_and_steel_Id) + ITEM(Item::diamond_helmet_Id) + ITEM(Item::diamond_chestplate_Id) + ITEM(Item::diamond_leggings_Id) + ITEM(Item::diamond_boots_Id) + ITEM(Item::diamond_sword_Id) + ITEM(Item::diamond_shovel_Id) + ITEM(Item::diamond_pickaxe_Id) + ITEM(Item::diamond_axe_Id) + ITEM(Item::diamond_hoe_Id) - ITEM(Item::fireball_Id) + ITEM(Item::fire_charge_Id) ITEM(Item::clock_Id) ITEM(Item::shears_Id) - ITEM(Item::fishingRod_Id) - ITEM(Item::carrotOnAStick_Id) + ITEM(Item::fishing_rod_Id) + ITEM(Item::carrot_on_a_stick_Id) ITEM(Item::lead_Id) - ITEM(Item::horseArmorDiamond_Id) - ITEM(Item::horseArmorGold_Id) - ITEM(Item::horseArmorMetal_Id) + ITEM(Item::diamond_horse_armor_Id) + ITEM(Item::golden_horse_armor_Id) + ITEM(Item::iron_horse_armor_Id) ITEM(Item::armor_stand_Id) @@ -642,13 +643,13 @@ void IUIScene_CreativeMenu::staticCtor() { Enchantment *enchantment = Enchantment::enchantments[i]; if (enchantment == nullptr || enchantment->category == nullptr) continue; - list->push_back(Item::enchantedBook->createForEnchantment(new EnchantmentInstance(enchantment, enchantment->getMaxLevel()))); + list->push_back(Item::enchanted_book->createForEnchantment(new EnchantmentInstance(enchantment, enchantment->getMaxLevel()))); } #ifndef _CONTENT_PACKAGE if(app.DebugSettingsOn()) { - shared_ptr debugSword = std::make_shared(Item::sword_diamond_Id, 1, 0); + shared_ptr debugSword = std::make_shared(Item::diamond_sword_Id, 1, 0); debugSword->enchant( Enchantment::damageBonus, 50 ); debugSword->setHoverName(L"Sword of Debug"); list->push_back(debugSword); @@ -661,11 +662,11 @@ void IUIScene_CreativeMenu::staticCtor() ITEM_AUX(Item::coal_Id,1) ITEM(Item::diamond_Id) ITEM(Item::emerald_Id) - ITEM(Item::ironIngot_Id) - ITEM(Item::goldIngot_Id) - ITEM(Item::netherQuartz_Id) + ITEM(Item::iron_ingot_Id) + ITEM(Item::gold_ingot_Id) + ITEM(Item::quartz_Id) ITEM(Item::brick_Id) - ITEM(Item::netherbrick_Id) + ITEM(Item::nether_brick_Id) ITEM(Item::stick_Id) ITEM(Item::bowl_Id) ITEM(Item::bone_Id) @@ -676,49 +677,49 @@ void IUIScene_CreativeMenu::staticCtor() ITEM(Item::rabbit_hide_Id) ITEM(Item::gunpowder_Id) ITEM(Item::clay_Id) - ITEM(Item::yellowDust_Id) - ITEM(Item::prismarine_cystal_Id) + ITEM(Item::glowstone_dust_Id) + ITEM(Item::prismarine_crystals_Id) ITEM(Item::prismarine_shard_Id) - ITEM(Item::seeds_wheat_Id) - ITEM(Item::seeds_melon_Id) - ITEM(Item::seeds_pumpkin_Id) + ITEM(Item::wheat_seeds_Id) + ITEM(Item::melon_seeds_Id) + ITEM(Item::pumpkin_seeds_Id) ITEM(Item::wheat_Id) ITEM(Item::reeds_Id) ITEM(Item::egg_Id) ITEM(Item::sugar_Id) - ITEM(Item::slimeBall_Id) - ITEM(Item::blazeRod_Id) - ITEM(Item::goldNugget_Id) + ITEM(Item::slime_ball_Id) + ITEM(Item::blaze_rod_Id) + ITEM(Item::gold_nugget_Id) ITEM(Item::netherwart_seeds_Id) - ITEM_AUX(Item::dye_powder_Id,1) // Red - ITEM_AUX(Item::dye_powder_Id,14) // Orange - ITEM_AUX(Item::dye_powder_Id,11) // Yellow - ITEM_AUX(Item::dye_powder_Id,10) // Lime - ITEM_AUX(Item::dye_powder_Id,12) // Light Blue - ITEM_AUX(Item::dye_powder_Id,6) // Cyan - ITEM_AUX(Item::dye_powder_Id,4) // Blue - ITEM_AUX(Item::dye_powder_Id,5) // Purple - ITEM_AUX(Item::dye_powder_Id,13) // Magenta - ITEM_AUX(Item::dye_powder_Id,9) // Pink - ITEM_AUX(Item::dye_powder_Id,15) // Bone Meal - ITEM_AUX(Item::dye_powder_Id,7) // Light gray - ITEM_AUX(Item::dye_powder_Id,8) // Gray - ITEM_AUX(Item::dye_powder_Id,0) // black (ink sac) - ITEM_AUX(Item::dye_powder_Id,2) // Green - ITEM_AUX(Item::dye_powder_Id,3) // Brown + ITEM_AUX(Item::dye_Id,1) // Red + ITEM_AUX(Item::dye_Id,14) // Orange + ITEM_AUX(Item::dye_Id,11) // Yellow + ITEM_AUX(Item::dye_Id,10) // Lime + ITEM_AUX(Item::dye_Id,12) // Light Blue + ITEM_AUX(Item::dye_Id,6) // Cyan + ITEM_AUX(Item::dye_Id,4) // Blue + ITEM_AUX(Item::dye_Id,5) // Purple + ITEM_AUX(Item::dye_Id,13) // Magenta + ITEM_AUX(Item::dye_Id,9) // Pink + ITEM_AUX(Item::dye_Id,15) // Bone Meal + ITEM_AUX(Item::dye_Id,7) // Light gray + ITEM_AUX(Item::dye_Id,8) // Gray + ITEM_AUX(Item::dye_Id,0) // black (ink sac) + ITEM_AUX(Item::dye_Id,2) // Green + ITEM_AUX(Item::dye_Id,3) // Brown // Brewing (TODO) DEF(eCreativeInventory_Brewing) - ITEM(Item::expBottle_Id) + ITEM(Item::experience_bottle_Id) // 4J Stu - Anything else added here also needs to be added to the key handler below - ITEM(Item::ghastTear_Id) - ITEM(Item::fermentedSpiderEye_Id) - ITEM(Item::blazePowder_Id) - ITEM(Item::magmaCream_Id) - ITEM(Item::speckledMelon_Id) - ITEM(Item::rabbits_foot_Id) - ITEM(Item::glassBottle_Id) + ITEM(Item::ghast_tear_Id) + ITEM(Item::fermented_spider_eye_Id) + ITEM(Item::blaze_powder_Id) + ITEM(Item::magma_cream_Id) + ITEM(Item::speckled_melon_block_Id) + ITEM(Item::rabbit_foot_Id) + ITEM(Item::glass_bottle_Id) ITEM_AUX(Item::potion_Id,0) // Water bottle //ITEM_AUX(Item::potion_Id,MACRO_MAKEPOTION_AUXVAL(0, 0, MASK_TYPE_AWKWARD)) // Awkward Potion diff --git a/Minecraft.Client/Common/UI/IUIScene_TradingMenu.cpp b/Minecraft.Client/Common/UI/IUIScene_TradingMenu.cpp index 7eda5803..82e8afa9 100644 --- a/Minecraft.Client/Common/UI/IUIScene_TradingMenu.cpp +++ b/Minecraft.Client/Common/UI/IUIScene_TradingMenu.cpp @@ -76,10 +76,11 @@ bool IUIScene_TradingMenu::handleKeyDown(int iPad, int iAction, bool bRepeat) // Do we have the ingredients? shared_ptr buyAItem = activeRecipe->getBuyAItem(); shared_ptr buyBItem = activeRecipe->getBuyBItem(); + shared_ptr sellItem = activeRecipe->getSellItem(); shared_ptr player = Minecraft::GetInstance()->localplayers[getPad()]; int buyAMatches = player->inventory->countMatches(buyAItem); int buyBMatches = player->inventory->countMatches(buyBItem); - if( (buyAItem != nullptr && buyAMatches >= buyAItem->count) && (buyBItem == nullptr || buyBMatches >= buyBItem->count) ) + if( sellItem != nullptr && (buyAItem != nullptr && buyAMatches >= buyAItem->count) && (buyBItem == nullptr || buyBMatches >= buyBItem->count) ) { // 4J-JEV: Fix for PS4 #7111: [PATCH 1.12] Trading Librarian villagers for multiple �Enchanted Books� will cause the title to crash. int actualShopItem = m_activeOffers.at(selectedShopItem).second; @@ -91,7 +92,7 @@ bool IUIScene_TradingMenu::handleKeyDown(int iPad, int iAction, bool bRepeat) player->inventory->removeResources(buyBItem); // Add the item we have purchased - shared_ptr result = activeRecipe->getSellItem()->copy(); + shared_ptr result = sellItem->copy(); if(!player->inventory->add( result ) ) { player->drop(result); @@ -238,6 +239,7 @@ void IUIScene_TradingMenu::updateDisplay() if( selectedShopItem < m_activeOffers.size() ) { MerchantRecipe *activeRecipe = m_activeOffers.at(selectedShopItem).first; + shared_ptr sellItem = activeRecipe ? activeRecipe->getSellItem() : nullptr; wstring wsTemp; @@ -245,11 +247,11 @@ void IUIScene_TradingMenu::updateDisplay() wsTemp = app.GetString(IDS_VILLAGER_OFFERS_ITEM); wsTemp = replaceAll(wsTemp,L"{*VILLAGER_TYPE*}",m_merchant->getDisplayName()); size_t iPos=wsTemp.find(L"%s"); - wsTemp.replace(iPos,2,activeRecipe->getSellItem()->getHoverName()); + wsTemp.replace(iPos,2,sellItem != nullptr ? sellItem->getHoverName() : L""); setTitle(wsTemp.c_str()); - vector *offerDescription = GetItemDescription(activeRecipe->getSellItem()); + vector *offerDescription = GetItemDescription(sellItem); setOfferDescription(offerDescription); shared_ptr buyAItem = activeRecipe->getBuyAItem(); @@ -270,8 +272,8 @@ void IUIScene_TradingMenu::updateDisplay() int buyAMatches = player->inventory->countMatches(buyAItem); if(buyAMatches > 0) { - setRequest1RedBox(buyAMatches < buyAItem->count); - canMake = buyAMatches > buyAItem->count; + setRequest1RedBox(buyAItem == nullptr || buyAMatches < buyAItem->count); + canMake = buyAItem != nullptr && buyAMatches > buyAItem->count; } else { @@ -282,8 +284,8 @@ void IUIScene_TradingMenu::updateDisplay() int buyBMatches = player->inventory->countMatches(buyBItem); if(buyBMatches > 0) { - setRequest2RedBox(buyBMatches < buyBItem->count); - canMake = canMake && buyBMatches > buyBItem->count; + setRequest2RedBox(buyBItem == nullptr || buyBMatches < buyBItem->count); + canMake = canMake && buyBItem != nullptr && buyBMatches > buyBItem->count; } else { @@ -369,6 +371,11 @@ void IUIScene_TradingMenu::setTradeItem(int index, shared_ptr item vector *IUIScene_TradingMenu::GetItemDescription(shared_ptr item) { + if (item == nullptr) + { + return new vector(); + } + bool advanced = false; if (const Minecraft* pMinecraft = Minecraft::GetInstance()) { diff --git a/Minecraft.Client/Common/UI/UI.h b/Minecraft.Client/Common/UI/UI.h index a737f10b..fdd8d0b5 100644 --- a/Minecraft.Client/Common/UI/UI.h +++ b/Minecraft.Client/Common/UI/UI.h @@ -83,7 +83,6 @@ #include "UIScene_SettingsMenu.h" #include "UIScene_SettingsOptionsMenu.h" #include "UIScene_SettingsAudioMenu.h" -#include "UIScene_SettingsControlMenu.h" #include "UIScene_SettingsGraphicsMenu.h" #include "UIScene_SettingsUIMenu.h" #include "UIScene_SkinSelectMenu.h" diff --git a/Minecraft.Client/Common/UI/UIComponent_Panorama.cpp b/Minecraft.Client/Common/UI/UIComponent_Panorama.cpp index 6700887a..4dffa43d 100644 --- a/Minecraft.Client/Common/UI/UIComponent_Panorama.cpp +++ b/Minecraft.Client/Common/UI/UIComponent_Panorama.cpp @@ -5,45 +5,237 @@ #include "MultiPlayerLevel.h" #include "../../../Minecraft.World/net.minecraft.world.level.dimension.h" #include "../../../Minecraft.World/net.minecraft.world.level.storage.h" +#include "Tesselator.h" +#include "Textures.h" +#include "BufferedImage.h" +#include "../GameRules/LevelGenerationOptions.h" +#include +#include +#include + +static const wchar_t *PANORAMA_TEXTURE_RELPATH = L"Graphics/ControlType/Panorama/"; + +static wstring GetPanoramaTexturePath() +{ + const wchar_t *envOverride = _wgetenv(L"PANORAMA_TEXTURE_PATH"); + if(envOverride && envOverride[0] != L'\0') + { + wstring path(envOverride); + if(!path.empty() && path.back() != L'/' && path.back() != L'\\') + path += L'/'; + return path; + } + + if(app.getLevelGenerationOptions() != nullptr) + { + LevelGenerationOptions *levelGen = app.getLevelGenerationOptions(); + DLCPack *parentPack = levelGen->getParentDLCPack(); + if(parentPack != nullptr) + { + wstring packName = parentPack->getName(); + if(!packName.empty()) + { + wchar_t buf[MAX_PATH]; + if(_wgetcwd(buf, MAX_PATH)) + { + wstring path(buf); + path += L"\\Windows64Media\\DLC\\"; + path += packName; + path += L"\\Data\\ControlType\\Panorama\\"; + wstring sampleDay = path + L"Panorama_S.png"; + wstring sampleNight = path + L"Panorama_N.png"; + if(GetFileAttributesW(sampleDay.c_str()) != INVALID_FILE_ATTRIBUTES || + GetFileAttributesW(sampleNight.c_str()) != INVALID_FILE_ATTRIBUTES) + { + return path; + } + } + } + } + } + + const char *mountedPanoramaRoots[] = + { + "TPACK:Data/ControlType/Panorama/", + "WPACK:Data/ControlType/Panorama/", + }; + + for(const char *mountedRoot : mountedPanoramaRoots) + { + wstring mountedPath = convStringToWstring(StorageManager.GetMountedPath(mountedRoot)); + if(mountedPath.empty()) continue; + + wstring sampleDay = mountedPath + L"Panorama_S.png"; + wstring sampleNight = mountedPath + L"Panorama_N.png"; + if(GetFileAttributesW(sampleDay.c_str()) != INVALID_FILE_ATTRIBUTES || + GetFileAttributesW(sampleNight.c_str()) != INVALID_FILE_ATTRIBUTES) + { + if(!mountedPath.empty() && mountedPath.back() != L'/' && mountedPath.back() != L'\\') + mountedPath += L'/'; + return mountedPath; + } + } + + wchar_t buf[MAX_PATH]; + if(_wgetcwd(buf, MAX_PATH)) + { + wstring path(buf); + path += L"\\Common\\Media\\MediaWindows64\\Graphics\\ControlType\\Panorama\\"; + return path; + } + + // fallback + return PANORAMA_TEXTURE_RELPATH; +} + +// opengl time :v +static int LoadPanoramaQuadTexture(const wstring &fileName, int &outWidth, int &outHeight) +{ + wstring filePath = GetPanoramaTexturePath() + fileName; + const char *nativePath = wstringtofilename(filePath); + std::ifstream stream(nativePath, std::ios::binary); + if(!stream) + { + printf("Failed to open panorama quad texture %ls\n", filePath.c_str()); + return -1; + } + + stream.seekg(0, std::ios::end); + std::streamoff size = stream.tellg(); + if(size <= 0) + { + printf("Empty panorama quad texture %ls\n", filePath.c_str()); + return -1; + } + stream.seekg(0, std::ios::beg); + + BYTE *data = new BYTE[static_cast(size)]; + if(!stream.read(reinterpret_cast(data), size)) + { + delete [] data; + printf("Failed to read panorama quad texture %ls\n", filePath.c_str()); + return -1; + } + + BufferedImage image(data, static_cast(size)); + delete [] data; + + if(image.getData() == nullptr) + { + printf("Failed to decode panorama quad texture %ls\n", filePath.c_str()); + return -1; + } + + // gaussian blur + const float sigma = 0.5f; + const int width = image.getWidth(); + const int height = image.getHeight(); + + const int radius = static_cast(ceilf(3.0f * sigma)); + const int ksize = radius * 2 + 1; + vector kernel(ksize); + float sum = 0.0f; + for(int i = -radius; i <= radius; ++i) + { + float v = expf(-(i*i) / (2.0f * sigma * sigma)); + kernel[i + radius] = v; + sum += v; + } + for(int i = 0; i < ksize; ++i) kernel[i] /= sum; + + float *tmpA = new float[width * height]; + float *tmpR = new float[width * height]; + float *tmpG = new float[width * height]; + float *tmpB = new float[width * height]; + + int *sourcePixels = image.getData(); + + for(int y = 0; y < height; ++y) + { + for(int x = 0; x < width; ++x) + { + float a = 0, r = 0, g = 0, b = 0; + for(int k = -radius; k <= radius; ++k) + { + // horizontal wrap + int sx = x + k; + while(sx < 0) sx += width; + while(sx >= width) sx -= width; + int p = sourcePixels[sx + y * width]; + float w = kernel[k + radius]; + a += w * static_cast((p >> 24) & 0xff); + r += w * static_cast((p >> 16) & 0xff); + g += w * static_cast((p >> 8) & 0xff); + b += w * static_cast(p & 0xff); + } + int idx = x + y * width; + tmpA[idx] = a; + tmpR[idx] = r; + tmpG[idx] = g; + tmpB[idx] = b; + } + } + + // vertical clamp + BufferedImage blurredImage(width, height, BufferedImage::TYPE_INT_ARGB); + int *targetPixels = blurredImage.getData(); + for(int y = 0; y < height; ++y) + { + for(int x = 0; x < width; ++x) + { + float a = 0, r = 0, g = 0, b = 0; + for(int k = -radius; k <= radius; ++k) + { + int sy = y + k; + if(sy < 0) sy = 0; + if(sy >= height) sy = height - 1; + int idx = x + sy * width; + float w = kernel[k + radius]; + a += w * tmpA[idx]; + r += w * tmpR[idx]; + g += w * tmpG[idx]; + b += w * tmpB[idx]; + } + int ia = static_cast(a + 0.5f); + int ir = static_cast(r + 0.5f); + int ig = static_cast(g + 0.5f); + int ib = static_cast(b + 0.5f); + if(ia < 0) ia = 0; if(ia > 255) ia = 255; + if(ir < 0) ir = 0; if(ir > 255) ir = 255; + if(ig < 0) ig = 0; if(ig > 255) ig = 255; + if(ib < 0) ib = 0; if(ib > 255) ib = 255; + targetPixels[x + y * width] = (ia << 24) | (ir << 16) | (ig << 8) | ib; + } + } + + delete [] tmpA; + delete [] tmpR; + delete [] tmpG; + delete [] tmpB; + + outWidth = image.getWidth(); + outHeight = image.getHeight(); + + int id = Minecraft::GetInstance()->textures->getTexture(&blurredImage, C4JRender::TEXTURE_FORMAT_RxGyBzAw, false); + printf("Loaded panorama background quad '%ls' -> texture id %d\n", filePath.c_str(), id); + return id; +} UIComponent_Panorama::UIComponent_Panorama(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer) { - // Setup all the Iggy references we need for this scene - initialiseMovie(); - m_bShowingDay = true; - - while(!m_hasTickedOnce) tick(); + tick(); } wstring UIComponent_Panorama::getMoviePath() -{ - switch( m_parentLayer->getViewport() ) - { - case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: - case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: - case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT: - case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT: - case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT: - case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT: - case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT: - case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT: - m_bSplitscreen = true; - return L"PanoramaSplit"; - break; - case C4JRender::VIEWPORT_TYPE_FULLSCREEN: - default: - m_bSplitscreen = false; - return L"Panorama"; - break; - } +{ + return L""; } void UIComponent_Panorama::tick() { - if(!hasMovie()) return; - Minecraft *pMinecraft = Minecraft::GetInstance(); + bool isDay = true; EnterCriticalSection(&pMinecraft->m_setLevelCS); if(pMinecraft->level!=nullptr) { @@ -52,24 +244,122 @@ void UIComponent_Panorama::tick() if(pMinecraft->level->dimension->id==0) { i64TimeOfDay = pMinecraft->level->getLevelData()->getGameTime() % 24000; + isDay = (i64TimeOfDay <= 14000); } - if(i64TimeOfDay>14000) - { - setPanorama(false); - } - else - { - setPanorama(true); - } + setPanorama(isDay); } else { setPanorama(true); } + + // fix: tick rate affected by user framerate + const DWORD nowMs = GetTickCount(); + if(m_lastScrollTickMs != 0) + { + const DWORD kMaxElapsedMs = 250; + const float kScrollPerMs = 0.0001f / 16.6667f; + DWORD elapsedMs = nowMs - m_lastScrollTickMs; + + if(elapsedMs > kMaxElapsedMs) elapsedMs = kMaxElapsedMs; + m_panoramaScroll += kScrollPerMs * static_cast(elapsedMs); + } + m_lastScrollTickMs = nowMs; + LeaveCriticalSection(&pMinecraft->m_setLevelCS); - UIScene::tick(); + m_hasTickedOnce = true; +} + +void UIComponent_Panorama::EnsurePanoramaTexturesLoaded() +{ + wstring currentRoot = GetPanoramaTexturePath(); + if(m_bPanoramaTexturesLoaded && currentRoot == m_panoramaTextureRoot) return; + + if(m_texPanoramaDay >= 0) + { + Minecraft::GetInstance()->textures->releaseTexture(m_texPanoramaDay); + m_texPanoramaDay = -1; + } + if(m_texPanoramaNight >= 0) + { + Minecraft::GetInstance()->textures->releaseTexture(m_texPanoramaNight); + m_texPanoramaNight = -1; + } + + m_panoramaTextureRoot = currentRoot; + m_bPanoramaTexturesLoaded = false; + int dayWidth = 0; + int dayHeight = 0; + m_texPanoramaDay = LoadPanoramaQuadTexture(L"Panorama_S.png", dayWidth, dayHeight); + int nightWidth = 0; + int nightHeight = 0; + m_texPanoramaNight = LoadPanoramaQuadTexture(L"Panorama_N.png", nightWidth, nightHeight); + if(dayWidth > 0 && dayHeight > 0) + { + m_panoramaAspect = static_cast(dayWidth) / static_cast(dayHeight); + } + else if(nightWidth > 0 && nightHeight > 0) + { + m_panoramaAspect = static_cast(nightWidth) / static_cast(nightHeight); + } + m_bPanoramaTexturesLoaded = (m_texPanoramaDay >= 0 || m_texPanoramaNight >= 0); +} + +void UIComponent_Panorama::DrawPanoramaBackgroundQuad(S32 width, S32 height) +{ + EnsurePanoramaTexturesLoaded(); + + int texId = m_bShowingDay ? m_texPanoramaDay : m_texPanoramaNight; + if(texId < 0) return; // failed + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, width, height, 0, -1, 1); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + + Minecraft::GetInstance()->textures->bind(texId); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + float sourceWidth = static_cast(height) * m_panoramaAspect; + float scroll = m_panoramaScroll - floorf(m_panoramaScroll); + float scrollPx = scroll * sourceWidth; + float startX = -scrollPx; + float startY = 0.0f; + const float overscanY = (static_cast(height) * 0.03f > 8.0f) ? (static_cast(height) * 0.03f) : 8.0f; + const float drawTop = -overscanY; + const float drawBottom = static_cast(height) + overscanY; + + Tesselator *t = Tesselator::getInstance(); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + t->begin(); + for(float x = startX - sourceWidth; x < static_cast(width) + sourceWidth; x += sourceWidth) + { + float left = x; + float right = x + sourceWidth; + t->vertexUV(left, drawBottom, 0.0f, 0.0f, 1.0f); + t->vertexUV(right, drawBottom, 0.0f, 1.0f, 1.0f); + t->vertexUV(right, drawTop, 0.0f, 1.0f, 0.0f); + t->vertexUV(left, drawTop, 0.0f, 0.0f, 0.0f); + } + t->end(); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glDisable(GL_BLEND); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); } void UIComponent_Panorama::render(S32 width, S32 height, C4JRender::eViewportType viewport) @@ -78,7 +368,7 @@ void UIComponent_Panorama::render(S32 width, S32 height, C4JRender::eViewportTyp (viewport == C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM) || (viewport == C4JRender::VIEWPORT_TYPE_SPLIT_LEFT) || (viewport == C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT); - if(m_bSplitscreen && specialViewport) + if(specialViewport) { S32 xPos = 0; S32 yPos = 0; @@ -108,32 +398,17 @@ void UIComponent_Panorama::render(S32 width, S32 height, C4JRender::eViewportTyp tileYStart = static_cast(ui.getScreenHeight() / 2); } - F32 scaleW = static_cast(tileXStart + tileWidth) / static_cast(m_movieWidth); - F32 scaleH = static_cast(tileYStart + tileHeight) / static_cast(m_movieHeight); - F32 scale = (scaleW > scaleH) ? scaleW : scaleH; - if(scale < 1.0f) scale = 1.0f; - - IggyPlayerSetDisplaySize( getMovie(), static_cast(m_movieWidth * scale), static_cast(m_movieHeight * scale) ); - - IggyPlayerDrawTilesStart ( getMovie() ); - m_renderWidth = tileWidth; m_renderHeight = tileHeight; - IggyPlayerDrawTile ( getMovie() , - tileXStart , - tileYStart , - tileXStart + tileWidth , - tileYStart + tileHeight , - 0 ); - IggyPlayerDrawTilesEnd ( getMovie() ); + + DrawPanoramaBackgroundQuad(tileWidth, tileHeight); } else { - if(m_bIsReloading) return; - if(!m_hasTickedOnce || !getMovie()) return; ui.setupRenderPosition(0, 0); - IggyPlayerSetDisplaySize( getMovie(), static_cast(ui.getScreenWidth()), static_cast(ui.getScreenHeight()) ); - IggyPlayerDraw( getMovie() ); + m_renderWidth = static_cast(ui.getScreenWidth()); + m_renderHeight = static_cast(ui.getScreenHeight()); + DrawPanoramaBackgroundQuad(static_cast(ui.getScreenWidth()), static_cast(ui.getScreenHeight())); } } @@ -142,12 +417,5 @@ void UIComponent_Panorama::setPanorama(bool isDay) if(isDay != m_bShowingDay) { m_bShowingDay = isDay; - - IggyDataValue result; - IggyDataValue value[1]; - value[0].type = IGGY_DATATYPE_boolean; - value[0].boolval = isDay; - - IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcShowPanoramaDay , 1 , value ); } -} +} \ No newline at end of file diff --git a/Minecraft.Client/Common/UI/UIComponent_Panorama.h b/Minecraft.Client/Common/UI/UIComponent_Panorama.h index 99dc115c..3572c36a 100644 --- a/Minecraft.Client/Common/UI/UIComponent_Panorama.h +++ b/Minecraft.Client/Common/UI/UIComponent_Panorama.h @@ -5,14 +5,16 @@ class UIComponent_Panorama : public UIScene { private: - bool m_bSplitscreen; bool m_bShowingDay; - -protected: - IggyName m_funcShowPanoramaDay; - UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) - UI_MAP_NAME(m_funcShowPanoramaDay, L"ShowPanoramaDay"); - UI_END_MAP_ELEMENTS_AND_NAMES() + void EnsurePanoramaTexturesLoaded(); + void DrawPanoramaBackgroundQuad(S32 width, S32 height); + int m_texPanoramaDay = -1; + int m_texPanoramaNight = -1; + bool m_bPanoramaTexturesLoaded = false; + wstring m_panoramaTextureRoot; + float m_panoramaAspect = 1.0f; + DWORD m_lastScrollTickMs = 0; + float m_panoramaScroll = 0.0f; public: UIComponent_Panorama(int iPad, void *initData, UILayer *parentLayer); @@ -23,6 +25,8 @@ protected: public: virtual EUIScene getSceneType() { return eUIComponent_Panorama;} + virtual bool isPanoramaOverrideScene() { return true; } + virtual bool isPanoramaDayOverride() { return m_bShowingDay; } // Returns true if this scene handles input virtual bool stealsFocus() { return false; } diff --git a/Minecraft.Client/Common/UI/UIComponent_Tooltips.cpp b/Minecraft.Client/Common/UI/UIComponent_Tooltips.cpp index 4f60de5f..18852873 100644 --- a/Minecraft.Client/Common/UI/UIComponent_Tooltips.cpp +++ b/Minecraft.Client/Common/UI/UIComponent_Tooltips.cpp @@ -5,6 +5,10 @@ UIComponent_Tooltips::UIComponent_Tooltips(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer) { + m_lastResizeAwareScreenW = -1.0; + m_lastResizeAwareScreenH = -1.0; + m_lastResizeAwareNudgeActive = false; + for(int i=0;i 720.0f) || (screenW > 1280.0f); + const bool menuContext = ui.GetMenuDisplayed(m_iPad); + if(getSceneResolution() == eSceneResolution_720 && largerThan720Window && menuContext) + { + const F64 widthScale = screenW / 1920.0f; + const F64 heightScale = screenH / 1080.0f; + const F64 nudgeScale = (widthScale > heightScale) ? widthScale : heightScale; + const F64 nudgeX = 31.0 * nudgeScale; + const F64 nudgeY = 16.5 * nudgeScale; + const F64 spacingNudgeX = 20.0 * nudgeScale; + safeLeft = (safeLeft > nudgeX) ? (safeLeft - nudgeX) : 0.0; + safeBottom = (safeBottom > nudgeY) ? (safeBottom - nudgeY) : 0.0; + // remind me to work on the 'margin' nudge + // they dont seem very effective at the moment + safeRight += spacingNudgeX; + } + } +#endif + break; } setSafeZone(safeTop, safeBottom, safeLeft, safeRight); @@ -141,6 +169,37 @@ void UIComponent_Tooltips::tick() { UIScene::tick(); +#ifdef _WINDOWS64 + if(!m_bSplitscreen && !ui.IsReloadingSkin()) + { + const F64 screenW = ui.getScreenWidth(); + const F64 screenH = ui.getScreenHeight(); + const bool largerThan720Window = (screenH > 720.0f) || (screenW > 1280.0f); + const bool nudgeActive = (getSceneResolution() == eSceneResolution_720) && largerThan720Window && ui.GetMenuDisplayed(m_iPad); + + F64 dW = screenW - m_lastResizeAwareScreenW; + if(dW < 0.0) dW = -dW; + F64 dH = screenH - m_lastResizeAwareScreenH; + if(dH < 0.0) dH = -dH; + + const F64 baseW = (m_lastResizeAwareScreenW > 1.0) ? m_lastResizeAwareScreenW : 1.0; + const F64 baseH = (m_lastResizeAwareScreenH > 1.0) ? m_lastResizeAwareScreenH : 1.0; + const bool significantResize = + (m_lastResizeAwareScreenW < 0.0) || (m_lastResizeAwareScreenH < 0.0) || + (dW >= 20.0) || (dH >= 20.0) || + ((dW / baseW) >= 0.01) || ((dH / baseH) >= 0.01); + + if(significantResize || (nudgeActive != m_lastResizeAwareNudgeActive)) + { + updateSafeZone(); + _Relayout(); + m_lastResizeAwareScreenW = screenW; + m_lastResizeAwareScreenH = screenH; + m_lastResizeAwareNudgeActive = nudgeActive; + } + } +#endif + // set the opacity of the tooltip items unsigned char ucAlpha=app.GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_InterfaceOpacity); float fVal; @@ -368,6 +427,10 @@ void UIComponent_Tooltips::_Relayout() IggyDataValue result; IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcUpdateLayout, 0 , nullptr ); +#ifdef _WINDOWS64 + doHorizontalResizeCheck(); +#endif + #ifdef __PSVITA__ // rebuild touchboxes ui.TouchBoxRebuild(this); diff --git a/Minecraft.Client/Common/UI/UIComponent_Tooltips.h b/Minecraft.Client/Common/UI/UIComponent_Tooltips.h index f8db9439..db5e769b 100644 --- a/Minecraft.Client/Common/UI/UIComponent_Tooltips.h +++ b/Minecraft.Client/Common/UI/UIComponent_Tooltips.h @@ -7,6 +7,12 @@ class UIComponent_Tooltips : public UIScene private: bool m_bSplitscreen; +#ifdef _WINDOWS64 + F64 m_lastResizeAwareScreenW; + F64 m_lastResizeAwareScreenH; + bool m_lastResizeAwareNudgeActive; +#endif + protected: typedef struct _TooltipValues { diff --git a/Minecraft.Client/Common/UI/UIComponent_TutorialPopup.cpp b/Minecraft.Client/Common/UI/UIComponent_TutorialPopup.cpp index 40fcad55..826b2238 100644 --- a/Minecraft.Client/Common/UI/UIComponent_TutorialPopup.cpp +++ b/Minecraft.Client/Common/UI/UIComponent_TutorialPopup.cpp @@ -251,7 +251,7 @@ wstring UIComponent_TutorialPopup::_SetIcon(int icon, int iAuxVal, bool isFoil, // remove any icon text else if(temp.find(L"{*CraftingTableIcon*}")!=wstring::npos) { - m_iconItem = std::make_shared(Tile::workBench_Id, 1, 0); + m_iconItem = std::make_shared(Tile::crafting_table_Id, 1, 0); } else if(temp.find(L"{*SticksIcon*}")!=wstring::npos) { @@ -259,19 +259,19 @@ wstring UIComponent_TutorialPopup::_SetIcon(int icon, int iAuxVal, bool isFoil, } else if(temp.find(L"{*PlanksIcon*}")!=wstring::npos) { - m_iconItem = std::make_shared(Tile::wood_Id, 1, 0); + m_iconItem = std::make_shared(Tile::planks_Id, 1, 0); } else if(temp.find(L"{*WoodenShovelIcon*}")!=wstring::npos) { - m_iconItem = std::make_shared(Item::shovel_wood_Id, 1, 0); + m_iconItem = std::make_shared(Item::wooden_shovel_Id, 1, 0); } else if(temp.find(L"{*WoodenHatchetIcon*}")!=wstring::npos) { - m_iconItem = std::make_shared(Item::hatchet_wood_Id, 1, 0); + m_iconItem = std::make_shared(Item::wooden_axe_Id, 1, 0); } else if(temp.find(L"{*WoodenPickaxeIcon*}")!=wstring::npos) { - m_iconItem = std::make_shared(Item::pickAxe_wood_Id, 1, 0); + m_iconItem = std::make_shared(Item::wooden_pickaxe_Id, 1, 0); } else if(temp.find(L"{*FurnaceIcon*}")!=wstring::npos) { @@ -279,7 +279,7 @@ wstring UIComponent_TutorialPopup::_SetIcon(int icon, int iAuxVal, bool isFoil, } else if(temp.find(L"{*WoodenDoorIcon*}")!=wstring::npos) { - m_iconItem = std::make_shared(Item::door_wood, 1, 0); + m_iconItem = std::make_shared(Item::wooden_door, 1, 0); } else if(temp.find(L"{*TorchIcon*}")!=wstring::npos) { @@ -291,11 +291,11 @@ wstring UIComponent_TutorialPopup::_SetIcon(int icon, int iAuxVal, bool isFoil, } else if(temp.find(L"{*FishingRodIcon*}")!=wstring::npos) { - m_iconItem = std::make_shared(Item::fishingRod_Id, 1, 0); + m_iconItem = std::make_shared(Item::fishing_rod_Id, 1, 0); } else if(temp.find(L"{*FishIcon*}")!=wstring::npos) { - m_iconItem = std::make_shared(Item::fish_raw_Id, 1, 0); + m_iconItem = std::make_shared(Item::fish_Id, 1, 0); } else if(temp.find(L"{*MinecartIcon*}")!=wstring::npos) { @@ -307,7 +307,7 @@ wstring UIComponent_TutorialPopup::_SetIcon(int icon, int iAuxVal, bool isFoil, } else if(temp.find(L"{*PoweredRailIcon*}")!=wstring::npos) { - m_iconItem = std::make_shared(Tile::goldenRail_Id, 1, 0); + m_iconItem = std::make_shared(Tile::golden_rail_Id, 1, 0); } else if(temp.find(L"{*StructuresIcon*}")!=wstring::npos) { diff --git a/Minecraft.Client/Common/UI/UIControl_MultiList.cpp b/Minecraft.Client/Common/UI/UIControl_MultiList.cpp new file mode 100644 index 00000000..62004d78 --- /dev/null +++ b/Minecraft.Client/Common/UI/UIControl_MultiList.cpp @@ -0,0 +1,363 @@ +#include "stdafx.h" +#include "UI.h" +#include "UIControl_MultiList.h" + +// Multilist By aRockefeler Or aRockefort + +UIControl_MultiList::UIControl_MultiList() +{ + m_itemCount = 0; + m_iCurrentSelection = 0; +} + +bool UIControl_MultiList::setupControl(UIScene *scene, IggyValuePath *parent, const string &controlName) +{ + UIControl::setControlType(UIControl::eButtonList); // reuses eButtonList, same as original + bool success = UIControl_Base::setupControl(scene, parent, controlName); + + m_funcSetPossibleLabels = registerFastName(L"SetPossibleLabels"); + m_funcAddNewItem_Label = registerFastName(L"addNewItem_Label"); + m_funcAddNewItem_Button = registerFastName(L"addNewItem_Button"); + m_funcAddNewItem_MenuButton = registerFastName(L"addNewItem_MenuButton"); + m_funcAddNewItem_CheckBox = registerFastName(L"addNewItem_CheckBox"); + m_funcAddNewItem_Slider = registerFastName(L"addNewItem_Slider"); + m_funcAddNewItem_TextInput = registerFastName(L"addNewItem_TextInput"); + m_funcSetCheckBox = registerFastName(L"SetCheckBox"); + m_funcGetCheckBox = registerFastName(L"GetCheckBox"); + m_funcSetSliderValue = registerFastName(L"SetSliderValue"); + m_funcGetSliderValue = registerFastName(L"GetSliderValue"); + m_funcSetItemLabel = registerFastName(L"SetItemLabel"); + // these use the same pattern as UIControl_ButtonList + m_funcHighlightItem = registerFastName(L"HighlightItem"); + m_funcEnableItem = registerFastName(L"EnableItem"); + m_funcCheckElementExists = registerFastName(L"CheckElementExists"); + m_funcSetTouchFocus = registerFastName(L"SetTouchFocus"); + m_removeAllItemsFunc = registerFastName(L"removeAllItems"); + + return success; +} + +void UIControl_MultiList::init(int id) +{ + IggyDataValue result; + IggyDataValue value[1]; + value[0].type = IGGY_DATATYPE_number; + value[0].number = (F64)id; + IggyResult out = IggyPlayerCallMethodRS( + m_parentScene->getMovie(), + &result, + getIggyValuePath(), + m_initFunc, + 1, + value); +} + +// the internal element array +// Items are stored in insertion order so +// we walk m_itemIds to find the 0-based position of the given id +int UIControl_MultiList::getListIndex(int id) const +{ + for (size_t i = 0; i < m_itemIds.size(); ++i) + { + if (m_itemIds[i] == id) + return (int)i; + } + return -1; +} + +// returns the item id stored at the given position in m_itemIds or -1 if out of range +int UIControl_MultiList::getIdFromIndex(int index) const +{ + if (index >= 0 && index < (int)m_itemIds.size()) + return m_itemIds[index]; + return -1; +} + +void UIControl_MultiList::AddNewLabel(const wstring &label) +{ + IggyDataValue result; + IggyDataValue value[1]; + + IggyStringUTF16 stringVal; + stringVal.string = (IggyUTF16*)label.c_str(); + stringVal.length = label.length(); + value[0].type = IGGY_DATATYPE_string_UTF16; + value[0].string16 = stringVal; + + IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, + getIggyValuePath(), m_funcAddNewItem_Label, 1, value); + + m_itemIds.push_back(-1); + ++m_itemCount; +} + +void UIControl_MultiList::AddNewButton(const wstring &label, int id) +{ + IggyDataValue result; + IggyDataValue value[2]; + + IggyStringUTF16 stringVal; + stringVal.string = (IggyUTF16*)label.c_str(); + stringVal.length = label.length(); + value[0].type = IGGY_DATATYPE_string_UTF16; + value[0].string16 = stringVal; + + value[1].type = IGGY_DATATYPE_number; + value[1].number = (double)id; + + IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, + getIggyValuePath(), m_funcAddNewItem_Button, 2, value); + + m_itemIds.push_back(id); + ++m_itemCount; +} + +void UIControl_MultiList::AddNewMenuButton(const wstring &label, int id) +{ + AddNewButton(label, id); +} + +void UIControl_MultiList::AddNewCheckbox(const wstring &label, int id, bool checked) +{ + IggyDataValue result; + IggyDataValue value[3]; + + IggyStringUTF16 stringVal; + stringVal.string = (IggyUTF16*)label.c_str(); + stringVal.length = label.length(); + value[0].type = IGGY_DATATYPE_string_UTF16; + value[0].string16 = stringVal; + + value[1].type = IGGY_DATATYPE_number; + value[1].number = (double)id; + + value[2].type = IGGY_DATATYPE_boolean; + value[2].boolval = checked ? 1 : 0; + + IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, + getIggyValuePath(), m_funcAddNewItem_CheckBox, 3, value); + + m_itemIds.push_back(id); + ++m_itemCount; +} + +void UIControl_MultiList::AddNewSlider(const wstring &label, int id, int minVal, int maxVal, int step, int initialVal) +{ + app.DebugPrintf("[MULTILIST] AddNewSlider: label=%ls id=%d min=%d max=%d step=%d init=%d\n", + label.c_str(), id, minVal, maxVal, step, initialVal); + IggyDataValue result; + IggyDataValue value[5]; + + IggyStringUTF16 stringVal; + stringVal.string = (IggyUTF16*)label.c_str(); + stringVal.length = label.length(); + value[0].type = IGGY_DATATYPE_string_UTF16; + value[0].string16 = stringVal; + + value[1].type = IGGY_DATATYPE_number; + value[1].number = (double)id; + + value[2].type = IGGY_DATATYPE_number; + value[2].number = (double)minVal; + + value[3].type = IGGY_DATATYPE_number; + value[3].number = (double)maxVal; + + value[4].type = IGGY_DATATYPE_number; + value[4].number = (double)initialVal; + + IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, + getIggyValuePath(), m_funcAddNewItem_Slider, 5, value); + + m_itemIds.push_back(id); + ++m_itemCount; +} + +void UIControl_MultiList::AddNewTextInput(const wstring &label, int id) +{ + IggyDataValue result; + IggyDataValue value[2]; + + IggyStringUTF16 stringVal; + stringVal.string = (IggyUTF16*)label.c_str(); + stringVal.length = label.length(); + value[0].type = IGGY_DATATYPE_string_UTF16; + value[0].string16 = stringVal; + + value[1].type = IGGY_DATATYPE_number; + value[1].number = (double)id; + + IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, + getIggyValuePath(), m_funcAddNewItem_TextInput, 2, value); + + m_itemIds.push_back(id); + ++m_itemCount; +} + +bool UIControl_MultiList::GetCheckboxValue(int id) +{ + IggyDataValue result; + IggyDataValue value[1]; + + value[0].type = IGGY_DATATYPE_number; + value[0].number = (double)getListIndex(id); + + IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, + getIggyValuePath(), m_funcGetCheckBox, 1, value); + + if (result.type == IGGY_DATATYPE_boolean) + return result.boolval != 0; + if (result.type == IGGY_DATATYPE_number) + return (int)result.number == 1; + return false; +} + +void UIControl_MultiList::SetCheckboxValue(int id, bool checked, bool bImmediate) +{ + + IggyDataValue result; + IggyDataValue value[2]; + + value[0].type = IGGY_DATATYPE_number; + value[0].number = (double)getListIndex(id); + + value[1].type = IGGY_DATATYPE_boolean; + value[1].boolval = checked ? 1 : 0; + + IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, + getIggyValuePath(), m_funcSetCheckBox, 2, value); +} + +int UIControl_MultiList::GetSliderValue(int id) +{ + IggyDataValue result; + IggyDataValue value[1]; + + value[0].type = IGGY_DATATYPE_number; + value[0].number = (double)getListIndex(id); + + IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, + getIggyValuePath(), m_funcGetSliderValue, 1, value); + + if (result.type == IGGY_DATATYPE_number) + return (int)result.number; + return 0; +} + + +void UIControl_MultiList::SetSliderValue(int id, int value, bool bImmediate) +{ + IggyDataValue result; + IggyDataValue args[2]; + + args[0].type = IGGY_DATATYPE_number; + args[0].number = (double)getListIndex(id); + + args[1].type = IGGY_DATATYPE_number; + args[1].number = (double)value; + + IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, + getIggyValuePath(), m_funcSetSliderValue, 2, args); +} + +void UIControl_MultiList::SetSliderLabel(int id, const wstring &label, bool bImmediate) +{ + IggyDataValue result; + IggyDataValue args[2]; + + args[0].type = IGGY_DATATYPE_number; + args[0].number = (double)getListIndex(id); + + IggyStringUTF16 stringVal; + stringVal.string = (IggyUTF16*)label.c_str(); + stringVal.length = label.length(); + args[1].type = IGGY_DATATYPE_string_UTF16; + args[1].string16 = stringVal; + + IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, + getIggyValuePath(), m_funcSetItemLabel, 2, args); +} + +void UIControl_MultiList::HighlightItem(int id, bool animate) +{ + IggyDataValue result; + IggyDataValue value[2]; + + value[0].type = IGGY_DATATYPE_number; + value[0].number = (double)getListIndex(id); + + value[1].type = IGGY_DATATYPE_boolean; + value[1].boolval = animate ? 1 : 0; + + IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, + getIggyValuePath(), m_funcHighlightItem, 2, value); + + m_iCurrentSelection = id; +} + +void UIControl_MultiList::EnableItem(int id, bool bEnable, bool bImmediate) +{ + if (!bImmediate) + return; // deferred mode not implemented + + int listIndex = getListIndex(id); + if (listIndex < 0) + return; + + IggyDataValue result; + IggyDataValue value[2]; + + value[0].type = IGGY_DATATYPE_number; + value[0].number = (double)listIndex; + + value[1].type = IGGY_DATATYPE_boolean; + value[1].boolval = bEnable ? 1 : 0; + + IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, + getIggyValuePath(), m_funcEnableItem, 2, value); +} + +void UIControl_MultiList::clearList() +{ + IggyDataValue result; + IggyResult out = IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, + getIggyValuePath(), m_removeAllItemsFunc, 0, nullptr); + + m_itemIds.clear(); + m_itemCount = 0; + m_iCurrentSelection = 0; +} + +bool UIControl_MultiList::CheckElementExists(int id) +{ + IggyDataValue result; + IggyDataValue value[1]; + + value[0].type = IGGY_DATATYPE_number; + value[0].number = (double)id; + + IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, + getIggyValuePath(), m_funcCheckElementExists, 1, value); + + if (result.type == IGGY_DATATYPE_boolean) + return result.boolval != 0; + if (result.type == IGGY_DATATYPE_number) + return (int)result.number != 0; + return false; +} + +void UIControl_MultiList::SetTouchFocus(S32 iX, S32 iY, bool bRepeat) +{ + IggyDataValue result; + IggyDataValue value[3]; + + value[0].type = IGGY_DATATYPE_number; + value[0].number = iX; + value[1].type = IGGY_DATATYPE_number; + value[1].number = iY; + value[2].type = IGGY_DATATYPE_boolean; + value[2].boolval = bRepeat; + + IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, + getIggyValuePath(), m_funcSetTouchFocus, 3, value); +} diff --git a/Minecraft.Client/Common/UI/UIControl_MultiList.h b/Minecraft.Client/Common/UI/UIControl_MultiList.h new file mode 100644 index 00000000..96408ee0 --- /dev/null +++ b/Minecraft.Client/Common/UI/UIControl_MultiList.h @@ -0,0 +1,64 @@ +#pragma once + +#include "UIControl_Base.h" +#include + + +class UIControl_MultiList : public UIControl_Base +{ +protected: + // iggy fast names for flash-side methods + IggyName m_funcSetPossibleLabels; + IggyName m_funcAddNewItem_Label; + IggyName m_funcAddNewItem_Button; + IggyName m_funcAddNewItem_MenuButton; + IggyName m_funcAddNewItem_CheckBox; + IggyName m_funcAddNewItem_Slider; + IggyName m_funcAddNewItem_TextInput; + IggyName m_funcSetCheckBox; + IggyName m_funcGetCheckBox; + IggyName m_funcSetSliderValue; + IggyName m_funcGetSliderValue; + IggyName m_funcSetItemLabel; + IggyName m_funcHighlightItem; + IggyName m_funcEnableItem; + IggyName m_funcCheckElementExists; + IggyName m_funcSetTouchFocus; + IggyName m_removeAllItemsFunc; + + // stores caller-defined ids in insertion order (label = -1) + // iggy uses positional index; getListIndex() converts id to index. + std::vector m_itemIds; + int m_itemCount; + int m_iCurrentSelection; + +public: + UIControl_MultiList(); + + virtual bool setupControl(UIScene *scene, IggyValuePath *parent, const string &controlName); + + void init(int id); + void AddNewLabel(const wstring &label); + void AddNewButton(const wstring &label, int id); + void AddNewMenuButton(const wstring &label, int id); + void AddNewCheckbox(const wstring &label, int id, bool checked); + void AddNewSlider(const wstring &label, int id, int minVal, int maxVal, int step, int initialVal); + void AddNewTextInput(const wstring &label, int id); + bool GetCheckboxValue(int id); + void SetCheckboxValue(int id, bool checked, bool bImmediate = true); + int GetSliderValue(int id); + void SetSliderValue(int id, int value, bool bImmediate = true); + void SetSliderLabel(int id, const wstring &label, bool bImmediate = true); + void HighlightItem(int id, bool animate = false); + void EnableItem(int id, bool bEnable, bool bImmediate = true); + void clearList(); + bool CheckElementExists(int id); + int getCurrentSelection() const { return m_iCurrentSelection; } + void updateChildFocus(int iChild) { m_iCurrentSelection = iChild; } + int getIdFromIndex(int index) const; + int getItemCount() const { return m_itemCount; } + void SetTouchFocus(S32 iX, S32 iY, bool bRepeat); + +private: + int getListIndex(int id) const; +}; diff --git a/Minecraft.Client/Common/UI/UIControl_PlayerSkinPreview.cpp b/Minecraft.Client/Common/UI/UIControl_PlayerSkinPreview.cpp index 653b98cd..631ee84b 100644 --- a/Minecraft.Client/Common/UI/UIControl_PlayerSkinPreview.cpp +++ b/Minecraft.Client/Common/UI/UIControl_PlayerSkinPreview.cpp @@ -120,7 +120,7 @@ void UIControl_PlayerSkinPreview::tick() ++m_framesAnimatingRotation; m_yRot = m_fOriginalRotation + m_framesAnimatingRotation * ( (m_fTargetRotation - m_fOriginalRotation) / CHANGING_SKIN_FRAMES ); - //if(m_framesAnimatingRotation == CHANGING_SKIN_FRAMES) m_bAnimatingToFacing = false; + if(m_framesAnimatingRotation == CHANGING_SKIN_FRAMES) m_bAnimatingToFacing = false; } else { diff --git a/Minecraft.Client/Common/UI/UIControl_PlayerSkinPreview.h b/Minecraft.Client/Common/UI/UIControl_PlayerSkinPreview.h index 91430ab9..4533716f 100644 --- a/Minecraft.Client/Common/UI/UIControl_PlayerSkinPreview.h +++ b/Minecraft.Client/Common/UI/UIControl_PlayerSkinPreview.h @@ -12,7 +12,7 @@ private: static const int LOOK_LEFT_EXTENT = 45; static const int LOOK_RIGHT_EXTENT = -45; - static const int CHANGING_SKIN_FRAMES = 15; + static const int CHANGING_SKIN_FRAMES = 8; enum ESkinPreviewAnimations { @@ -77,6 +77,7 @@ public: void DecrementXRotation() { m_xRot = (m_xRot-2); if(m_xRot < -22) m_xRot = -22; } void SetAutoRotate(bool autoRotate) { m_bAutoRotate = autoRotate; } void SetFacing(ESkinPreviewFacing facing, bool bAnimate = false); + bool IsAnimatingToFacing() const { return m_bAnimatingToFacing; } void CycleNextAnimation(); void CyclePreviousAnimation(); diff --git a/Minecraft.Client/Common/UI/UIController.cpp b/Minecraft.Client/Common/UI/UIController.cpp index 04976b5b..765ce602 100644 --- a/Minecraft.Client/Common/UI/UIController.cpp +++ b/Minecraft.Client/Common/UI/UIController.cpp @@ -187,6 +187,61 @@ static void RADLINK DeallocateFunction ( void * alloc_callback_user_data , void LeaveCriticalSection(&controller->m_Allocatorlock); } +#ifdef _WINDOWS64 +static wstring GetControlTypeSkinPath(int controlType, bool hd) +{ + const wchar_t *skinName = L"windows"; // default to windows if control type is unknown + + switch(controlType) + { + case 0: + skinName = L"windows"; + break; + case 1: + skinName = L"xboxOne"; + break; + case 2: + skinName = L"xbox360"; + break; + case -1: + skinName = L"vita"; // not implemented yet + break; + case 3: + skinName = L"PS3"; + break; + case 4: + skinName = L"PS4"; + break; + case 5: + skinName = L"WiiU"; + break; + case -2: + skinName = L"Switch"; // not implemented yet + break; + default: + break; + } + + if(skinName == L"windows") { + if (hd) + { + return L"skinHDWin.swf"; + } + + return L"skinWin.swf"; + } + else + { + if(hd) + { + return wstring(L"Graphics\\ControlType\\HD\\") + skinName + L"HD.swf"; + } + + return wstring(L"Graphics\\ControlType\\") + skinName + L".swf"; + } +} +#endif + UIController::UIController() { m_uiDebugConsole = nullptr; @@ -200,6 +255,14 @@ UIController::UIController() m_moj11 = nullptr; m_unicodeBitmapFont = nullptr; +#ifdef _WINDOWS64 + m_savedPlatformSkinHD = IGGY_INVALID_LIBRARY; + m_savedPlatformSkin = IGGY_INVALID_LIBRARY; + m_panoramaPlatformSkinHD = IGGY_INVALID_LIBRARY; + m_panoramaPlatformSkin = IGGY_INVALID_LIBRARY; + m_platformSkinOverrideDepth = 0; +#endif + // 4J-JEV: It's important that these remain the same, unless updateCurrentLanguage is going to be called. m_eCurrentFont = m_eTargetFont = eFont_NotLoaded; @@ -583,10 +646,26 @@ void UIController::loadSkins() m_iggyLibraries[eLibrary_Default] = loadSkin(L"skin.swf", L"skin.swf"); #elif defined _WINDOWS64 - // HD platform skin — required by skinHD*.swf (1080p scene SWFs) - m_iggyLibraries[eLibrary_Platform] = loadSkin(L"skinHDWin.swf", L"platformskinHD.swf"); - // Non-HD platform skin — required by skin*.swf (720p/480p scene SWFs) - m_iggyLibraries[eLibraryFallback_Platform] = loadSkin(L"skinWin.swf", L"platformskin.swf"); + // emulate control type skins + const int controlType = app.GetGameSettings(ProfileManager.GetPrimaryPad(), eGameSetting_ControlType); + wstring platformSkinHD = GetControlTypeSkinPath(controlType, true); + wstring platformSkin = GetControlTypeSkinPath(controlType, false); + + m_iggyLibraries[eLibrary_Platform] = loadSkin(platformSkinHD, L"platformskinHD.swf"); + if(m_iggyLibraries[eLibrary_Platform] == IGGY_INVALID_LIBRARY) + { + m_iggyLibraries[eLibrary_Platform] = loadSkin(platformSkin, L"platformskinHD.swf"); + } + + m_iggyLibraries[eLibraryFallback_Platform] = loadSkin(platformSkin, L"platformskin.swf"); + if(m_iggyLibraries[eLibraryFallback_Platform] == IGGY_INVALID_LIBRARY) + { + m_iggyLibraries[eLibraryFallback_Platform] = loadSkin(L"Graphics\\ControlType\\windows.swf", L"platformskin.swf"); + } + if(m_iggyLibraries[eLibrary_Platform] == IGGY_INVALID_LIBRARY) + { + m_iggyLibraries[eLibrary_Platform] = loadSkin(L"Graphics\\ControlType\\HD\\windowsHD.swf", L"platformskin.swf"); + } // Non-HD skin set (720p/480p scenes import these) m_iggyLibraries[eLibraryFallback_GraphicsDefault] = loadSkin(L"skinGraphics.swf", L"skinGraphics.swf"); @@ -707,6 +786,14 @@ void UIController::ReloadSkin() m_iggyLibraries[i] = IGGY_INVALID_LIBRARY; } +#ifdef _WINDOWS64 + m_savedPlatformSkinHD = IGGY_INVALID_LIBRARY; + m_savedPlatformSkin = IGGY_INVALID_LIBRARY; + m_panoramaPlatformSkinHD = IGGY_INVALID_LIBRARY; + m_panoramaPlatformSkin = IGGY_INVALID_LIBRARY; + m_platformSkinOverrideDepth = 0; +#endif + #ifdef _WINDOWS64 // 4J Stu - Don't load on a thread on windows. I haven't investigated this in detail, so a quick fix reloadSkinThreadProc(this); @@ -738,6 +825,70 @@ void UIController::StartReloadSkinThread() if(m_reloadSkinThread) m_reloadSkinThread->Run(); } +#ifdef _WINDOWS64 +void UIController::PushDefaultPlatformSkinForPanorama() +{ + if(m_platformSkinOverrideDepth++ > 0) + { + return; + } + + m_savedPlatformSkinHD = m_iggyLibraries[eLibrary_Platform]; + m_savedPlatformSkin = m_iggyLibraries[eLibraryFallback_Platform]; + m_panoramaPlatformSkinHD = IGGY_INVALID_LIBRARY; + m_panoramaPlatformSkin = IGGY_INVALID_LIBRARY; + + const wstring defaultHd = L"Graphics\\ControlType\\HD\\windowsHD.swf"; + const wstring defaultSd = L"Graphics\\ControlType\\windows.swf"; + + IggyLibrary hdLib = loadSkin(defaultHd, L"platformskinHD.swf"); + if(hdLib != IGGY_INVALID_LIBRARY) + { + m_panoramaPlatformSkinHD = hdLib; + m_iggyLibraries[eLibrary_Platform] = hdLib; + } + + IggyLibrary sdLib = loadSkin(defaultSd, L"platformskin.swf"); + if(sdLib != IGGY_INVALID_LIBRARY) + { + m_panoramaPlatformSkin = sdLib; + m_iggyLibraries[eLibraryFallback_Platform] = sdLib; + } +} + +void UIController::PopDefaultPlatformSkinForPanorama() +{ + if(m_platformSkinOverrideDepth == 0) + { + return; + } + if(--m_platformSkinOverrideDepth > 0) + { + return; + } + + if(m_panoramaPlatformSkinHD != IGGY_INVALID_LIBRARY) + { + IggyLibraryDestroy(m_panoramaPlatformSkinHD); + m_panoramaPlatformSkinHD = IGGY_INVALID_LIBRARY; + } + if(m_panoramaPlatformSkin != IGGY_INVALID_LIBRARY) + { + IggyLibraryDestroy(m_panoramaPlatformSkin); + m_panoramaPlatformSkin = IGGY_INVALID_LIBRARY; + } + + if(m_savedPlatformSkinHD != IGGY_INVALID_LIBRARY) + { + m_iggyLibraries[eLibrary_Platform] = m_savedPlatformSkinHD; + } + if(m_savedPlatformSkin != IGGY_INVALID_LIBRARY) + { + m_iggyLibraries[eLibraryFallback_Platform] = m_savedPlatformSkin; + } +} +#endif + int UIController::reloadSkinThreadProc(void* lpParam) { EnterCriticalSection(&ms_reloadSkinCS); // MGH - added to prevent crash loading Iggy movies while the skins were being reloaded @@ -950,6 +1101,9 @@ void UIController::tickInput() panelOffsetY = pMainPanel->getYPos(); } + bool leftPressed = g_KBMInput.IsMouseButtonPressed(KeyboardMouseInput::MOUSE_LEFT); + bool leftDown = leftPressed || g_KBMInput.IsMouseButtonDown(KeyboardMouseInput::MOUSE_LEFT); + // Mouse hover — hit test against C++ control bounds. // Simple controls use SetFocusToElement; list controls // use their own SetTouchFocus for Flash-side hit testing. @@ -999,16 +1153,34 @@ void UIController::tickInput() { // ButtonList manages focus internally via Flash — // pass mouse coords so it can highlight the right item. - S32 adjustedMouseY = static_cast(sceneMouseY); - if (pScene->getSceneType() == eUIScene_LoadCreateJoinMenu) + S32 adjustedMouseY = static_cast(sceneMouseY); + if (pScene->getSceneType() == eUIScene_LoadCreateJoinMenu) + { + const S32 visibleRows = 7; + const S32 rowHeight = (visibleRows > 0) ? (ch / visibleRows) : 0; + if (rowHeight > 0) + adjustedMouseY -= rowHeight; + } + UIControl_MultiList *pMulti = dynamic_cast(ctrl); + if (pMulti) { - const S32 visibleRows = 7; - const S32 rowHeight = (visibleRows > 0) ? (ch / visibleRows) : 0; - if (rowHeight > 0) - adjustedMouseY -= rowHeight; + S32 adjustedY = static_cast(sceneMouseY); + if (pScene->getSceneType() == eUIScene_LoadMenu) + { + const S32 visibleRows = 7; + const S32 rowHeight = (visibleRows > 0) ? (ch / visibleRows) : 0; + if (rowHeight > 0) + adjustedY -= (rowHeight * 2); + } + + S32 localX = static_cast(sceneMouseX) - cx; + pMulti->SetTouchFocus(localX, adjustedY, leftDown); } + else + { static_cast(ctrl)->SetTouchFocus( - static_cast(sceneMouseX), adjustedMouseY, false); + static_cast(sceneMouseX), adjustedMouseY, leftDown); + } hitControlId = -1; hitArea = INT_MAX; hitCtrl = NULL; @@ -1079,9 +1251,6 @@ void UIController::tickInput() } } - bool leftPressed = g_KBMInput.IsMouseButtonPressed(KeyboardMouseInput::MOUSE_LEFT); - bool leftDown = leftPressed || g_KBMInput.IsMouseButtonDown(KeyboardMouseInput::MOUSE_LEFT); - if (m_mouseDraggingSliderScene != eUIScene_COUNT && m_mouseDraggingSliderScene != pScene->getSceneType()) { m_mouseDraggingSliderScene = eUIScene_COUNT; @@ -1157,8 +1326,8 @@ void UIController::tickInput() break; } } + } } - } if (leftDown && m_mouseDraggingSliderScene == pScene->getSceneType() && m_mouseDraggingSliderId >= 0) { @@ -2018,10 +2187,10 @@ void UIController::unregisterSubstitutionTexture(const wstring &textureName, boo bool UIController::NavigateToScene(int iPad, EUIScene scene, void *initData, EUILayer layer, EUIGroup group) { static bool bSeenUpdateTextThisSession = false; - #if 0 // Disable since we don't use this + #if 1 // Disable since we don't use this // If you're navigating to the multigamejoinload, and the player hasn't seen the updates message yet, display it now // display this message the first 3 times - if((scene==eUIScene_LoadOrJoinMenu) && (bSeenUpdateTextThisSession==false) && ( app.GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_DisplayUpdateMessage)!=0)) + if((scene==eUIScene_LoadCreateJoinMenu) && (bSeenUpdateTextThisSession==false) && ( app.GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_DisplayUpdateMessage)!=0)) { scene=eUIScene_NewUpdateMessage; bSeenUpdateTextThisSession=true; @@ -2672,6 +2841,11 @@ void UIController::DisplayGamertag(unsigned int iPad, bool show) void UIController::SetSelectedItem(unsigned int iPad, const wstring &name) { + // control type settings are already disabled whilst in-game + // this just serves as an additional check just incase the removal of the option doesnt work for some reason + if(IsReloadingSkin()) + return; + EUIGroup group; if( app.GetGameStarted() ) @@ -2685,7 +2859,12 @@ void UIController::SetSelectedItem(unsigned int iPad, const wstring &name) group = eUIGroup_Fullscreen; } bool handled = false; - if(m_groups[static_cast(group)]->getHUD()) m_groups[static_cast(group)]->getHUD()->SetSelectedLabel(name); + + auto pHUD = m_groups[static_cast(group)]->getHUD(); + if(pHUD && pHUD->hasMovie()) + { + pHUD->SetSelectedLabel(name); + } } void UIController::UpdateSelectedItemPos(unsigned int iPad) diff --git a/Minecraft.Client/Common/UI/UIController.h b/Minecraft.Client/Common/UI/UIController.h index 27c5c61d..63ab9475 100644 --- a/Minecraft.Client/Common/UI/UIController.h +++ b/Minecraft.Client/Common/UI/UIController.h @@ -187,6 +187,14 @@ private: int m_accumulatedTicks; uint64_t m_lastUiSfx; // Tracks time (ms) of last UI sound effect +#ifdef _WINDOWS64 + IggyLibrary m_savedPlatformSkinHD; + IggyLibrary m_savedPlatformSkin; + IggyLibrary m_panoramaPlatformSkinHD; + IggyLibrary m_panoramaPlatformSkin; + int m_platformSkinOverrideDepth; +#endif + D3D11_RECT m_customRenderingClearRect; unordered_map m_registeredCallbackScenes; // A collection of scenes and unique id's that are used in async callbacks so we can safely handle when they get destroyed @@ -253,6 +261,11 @@ public: virtual bool IsExpectingOrReloadingSkin(); virtual void CleanUpSkinReload(); +#ifdef _WINDOWS64 + void PushDefaultPlatformSkinForPanorama(); + void PopDefaultPlatformSkinForPanorama(); +#endif + private: static int reloadSkinThreadProc(void* lpParam); diff --git a/Minecraft.Client/Common/UI/UIEnums.h b/Minecraft.Client/Common/UI/UIEnums.h index e9973348..bcf382c5 100644 --- a/Minecraft.Client/Common/UI/UIEnums.h +++ b/Minecraft.Client/Common/UI/UIEnums.h @@ -60,7 +60,6 @@ enum EUIScene eUIScene_ControlsMenu, eUIScene_SettingsOptionsMenu, eUIScene_SettingsAudioMenu, - eUIScene_SettingsControlMenu, eUIScene_SettingsGraphicsMenu, eUIScene_SettingsUIMenu, eUIScene_SettingsMenu, diff --git a/Minecraft.Client/Common/UI/UILayer.cpp b/Minecraft.Client/Common/UI/UILayer.cpp index 9c6f1335..2c10f87c 100644 --- a/Minecraft.Client/Common/UI/UILayer.cpp +++ b/Minecraft.Client/Common/UI/UILayer.cpp @@ -288,9 +288,6 @@ bool UILayer::NavigateToScene(int iPad, EUIScene scene, void *initData) case eUIScene_SettingsAudioMenu: newScene = new UIScene_SettingsAudioMenu(iPad, initData, this); break; - case eUIScene_SettingsControlMenu: - newScene = new UIScene_SettingsControlMenu(iPad, initData, this); - break; case eUIScene_SettingsGraphicsMenu: newScene = new UIScene_SettingsGraphicsMenu(iPad, initData, this); break; diff --git a/Minecraft.Client/Common/UI/UIScene.cpp b/Minecraft.Client/Common/UI/UIScene.cpp index e696b1ab..2b94ab02 100644 --- a/Minecraft.Client/Common/UI/UIScene.cpp +++ b/Minecraft.Client/Common/UI/UIScene.cpp @@ -1,1472 +1,1541 @@ -#include "stdafx.h" -#include "UI.h" -#include "UIScene.h" -#include "UISplitScreenHelpers.h" - -#include "../../Lighting.h" -#include "../../LocalPlayer.h" -#include "../../ItemRenderer.h" -#include "../../../Minecraft.World/net.minecraft.world.item.h" -#include "UIScene_BookAndQuillMenu.h" - -UIScene::UIScene(int iPad, UILayer *parentLayer) -{ - m_parentLayer = parentLayer; - m_iPad = iPad; - swf = nullptr; - m_pItemRenderer = nullptr; - - bHasFocus = false; - m_hasTickedOnce = false; - m_bFocussedOnce = false; - m_bVisible = true; - m_bCanHandleInput = false; - m_bIsReloading = false; - - m_iFocusControl = -1; - m_iFocusChild = 0; - m_lastOpacity = 1.0f; - m_bUpdateOpacity = false; - - m_backScene = nullptr; - - m_cacheSlotRenders = false; - m_needsCacheRendered = true; - m_expectedCachedSlotCount = 0; - m_callbackUniqueId = 0; -} - -UIScene::~UIScene() -{ - /* Destroy the Iggy player. */ - IggyPlayerDestroy( swf ); - - for(auto & it : m_registeredTextures) - { - ui.unregisterSubstitutionTexture( it.first, it.second ); - } - - if(m_callbackUniqueId != 0) - { - ui.UnregisterCallbackId(m_callbackUniqueId); - } - - if(m_pItemRenderer != nullptr) delete m_pItemRenderer; -} - -void UIScene::destroyMovie() -{ - /* Destroy the Iggy player. */ - IggyPlayerDestroy( swf ); - swf = nullptr; - - // Clear out the controls collection (doesn't delete the controls, and they get re-setup later) - m_controls.clear(); - - // Clear out all the fast names for the current movie - m_fastNames.clear(); -} - -void UIScene::reloadMovie(bool force) -{ - if(!force && (stealsFocus() && (getSceneType() != eUIScene_FullscreenProgress && !bHasFocus))) return; - - m_bIsReloading = true; - if(swf) - { - /* Destroy the Iggy player. */ - IggyPlayerDestroy( swf ); - - // Clear out the controls collection (doesn't delete the controls, and they get re-setup later) - m_controls.clear(); - - // Clear out all the fast names for the current movie - m_fastNames.clear(); - } - - // Reload everything - initialiseMovie(); - - handlePreReload(); - - // Reload controls - for(auto & it : m_controls) - { - it->ReInit(); - } - - updateComponents(); - handleReload(); - - IggyDataValue result; - IggyDataValue value[1]; - - value[0].type = IGGY_DATATYPE_number; - value[0].number = m_iFocusControl; - - IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetFocus , 1 , value ); - - m_needsCacheRendered = true; - m_bIsReloading = false; -} - -bool UIScene::needsReloaded() -{ - return !swf && (!stealsFocus() || bHasFocus); -} - -bool UIScene::hasMovie() -{ - return swf != nullptr; -} - -F64 UIScene::getSafeZoneHalfHeight() -{ - float height = ui.getScreenHeight(); - - float safeHeight = 0.0f; - -#ifndef __PSVITA__ - if( !RenderManager.IsHiDef() && RenderManager.IsWidescreen() ) - { - // 90% safezone - safeHeight = height * (0.15f / 2); - } - else - { - // 90% safezone - safeHeight = height * (0.1f / 2); - } -#endif - return safeHeight; -} - -F64 UIScene::getSafeZoneHalfWidth() -{ - float width = ui.getScreenWidth(); - - float safeWidth = 0.0f; -#ifndef __PSVITA__ - if( !RenderManager.IsHiDef() && RenderManager.IsWidescreen() ) - { - // 85% safezone - safeWidth = width * (0.15f / 2); - } - else - { - // 90% safezone - safeWidth = width * (0.1f / 2); - } -#endif - return safeWidth; -} - -void UIScene::updateSafeZone() -{ - // Distance from edge - F64 safeTop = 0.0; - F64 safeBottom = 0.0; - F64 safeLeft = 0.0; - F64 safeRight = 0.0; - - switch( m_parentLayer->getViewport() ) - { - case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: - safeTop = getSafeZoneHalfHeight(); - safeLeft = getSafeZoneHalfWidth(); - - break; - case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: - // safeTop mirrors SPLIT_TOP for visual symmetry. safeBottom omitted. - safeTop = getSafeZoneHalfHeight(); - safeLeft = getSafeZoneHalfWidth(); - - break; - case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT: - safeTop = getSafeZoneHalfHeight(); - safeLeft = getSafeZoneHalfWidth(); - break; - case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT: - safeTop = getSafeZoneHalfHeight(); - - break; - case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT: - safeTop = getSafeZoneHalfHeight(); - safeLeft = getSafeZoneHalfWidth(); - break; - case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT: - safeTop = getSafeZoneHalfHeight(); - - break; - case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT: - safeTop = getSafeZoneHalfHeight(); - safeLeft = getSafeZoneHalfWidth(); - break; - case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT: - safeTop = getSafeZoneHalfHeight(); - - break; - case C4JRender::VIEWPORT_TYPE_FULLSCREEN: - default: - safeTop = getSafeZoneHalfHeight(); - safeBottom = getSafeZoneHalfHeight(); - safeLeft = getSafeZoneHalfWidth(); - - break; - } - setSafeZone(safeTop, safeBottom, safeLeft, safeRight); -} - -void UIScene::setSafeZone(S32 safeTop, S32 safeBottom, S32 safeLeft, S32 safeRight) -{ - IggyDataValue result; - IggyDataValue value[4]; - - value[0].type = IGGY_DATATYPE_number; - value[0].number = safeTop; - value[1].type = IGGY_DATATYPE_number; - value[1].number = safeBottom; - value[2].type = IGGY_DATATYPE_number; - value[2].number = safeLeft; - value[3].type = IGGY_DATATYPE_number; - value[3].number = safeRight; - IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetSafeZone , 4 , value ); -} - -void UIScene::initialiseMovie() -{ - loadMovie(); - mapElementsAndNames(); - - updateSafeZone(); - - m_bUpdateOpacity = true; -} - -#if defined(__PSVITA__) || defined(_WINDOWS64) -void UIScene::SetFocusToElement(int iID) -{ - IggyDataValue result; - IggyDataValue value[1]; - - value[0].type = IGGY_DATATYPE_number; - value[0].number = iID; - - IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetFocus , 1 , value ); - - // also trigger handle focus change (just in case if anything else in relation needs updating!) - _handleFocusChange(iID, 0); -} -#endif - -bool UIScene::mapElementsAndNames() -{ - m_rootPath = IggyPlayerRootPath( swf ); - - m_funcRemoveObject = registerFastName( L"RemoveObject" ); - m_funcSlideLeft = registerFastName( L"SlideLeft" ); - m_funcSlideRight = registerFastName( L"SlideRight" ); - m_funcSetSafeZone = registerFastName( L"SetSafeZone" ); - m_funcSetAlpha = registerFastName( L"SetAlpha" ); - m_funcSetFocus = registerFastName( L"SetFocus" ); - m_funcHorizontalResizeCheck = registerFastName( L"DoHorizontalResizeCheck"); - return true; -} - -extern CRITICAL_SECTION s_loadSkinCS; -void UIScene::loadMovie() -{ - EnterCriticalSection(&UIController::ms_reloadSkinCS); // MGH - added to prevent crash loading Iggy movies while the skins were being reloaded - wstring moviePath = getMoviePath(); - -#ifdef __PS3__ - if(RenderManager.IsWidescreen()) - { - moviePath.append(L"720.swf"); - m_loadedResolution = eSceneResolution_720; - } - else - { - moviePath.append(L"480.swf"); - m_loadedResolution = eSceneResolution_480; - } -#elif defined __PSVITA__ - moviePath.append(L"Vita.swf"); - m_loadedResolution = eSceneResolution_Vita; -#elif defined _WINDOWS64 - if(ui.getScreenHeight() > 720.0f) - { - moviePath.append(L"1080.swf"); - m_loadedResolution = eSceneResolution_1080; - } - else - { - moviePath.append(L"720.swf"); - m_loadedResolution = eSceneResolution_720; - } -#else - moviePath.append(L"1080.swf"); - m_loadedResolution = eSceneResolution_1080; -#endif - - if(!app.hasArchiveFile(moviePath)) - { - app.DebugPrintf("WARNING: Could not find iggy movie %ls, trying other resolutions\n", moviePath.c_str()); - - // Try 720 first, then 1080 as final fallback - moviePath = getMoviePath(); - moviePath.append(L"720.swf"); - m_loadedResolution = eSceneResolution_720; - - if(!app.hasArchiveFile(moviePath)) - { - moviePath = getMoviePath(); - moviePath.append(L"1080.swf"); - m_loadedResolution = eSceneResolution_1080; - - if(!app.hasArchiveFile(moviePath)) - { - app.DebugPrintf("ERROR: Could not find any iggy movie for %ls!\n", moviePath.c_str()); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - app.FatalLoadError(); - } - } - } - - byteArray baFile = ui.getMovieData(moviePath.c_str()); - int64_t beforeLoad = ui.iggyAllocCount; - swf = IggyPlayerCreateFromMemory ( baFile.data , baFile.length, nullptr); - int64_t afterLoad = ui.iggyAllocCount; - - if(!swf) - { - app.DebugPrintf("ERROR: Failed to load iggy scene!\n"); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - app.FatalLoadError(); - } - - // Read movie dimensions from the SWF header (available immediately after - // CreateFromMemory, no init tick needed). - IggyProperties *properties = IggyPlayerProperties ( swf ); - if(!properties) - { - app.DebugPrintf("ERROR: IggyPlayerProperties returned null for scene '%ls'\n", moviePath.c_str()); -#ifndef _CONTENT_PACKAGE - __debugbreak(); -#endif - app.FatalLoadError(); - } - m_movieHeight = properties->movie_height_in_pixels; - m_movieWidth = properties->movie_width_in_pixels; - m_renderWidth = m_movieWidth; - m_renderHeight = m_movieHeight; - - // Set display size BEFORE the init tick to match what render() will use. - // InitializeAndTickRS runs ActionScript that creates text fields. If the - // display size here differs from what render() passes to SetDisplaySize, - // Iggy can cache glyph rasterizations at one scale during init and then - // reuse them at a different scale during draw, producing mixed glyph sizes. -#ifdef _WINDOWS64 - { - S32 fitW, fitH, fitOffX, fitOffY; - Fit16x9(ui.getScreenWidth(), ui.getScreenHeight(), fitW, fitH, fitOffX, fitOffY); - IggyPlayerSetDisplaySize( swf, fitW, fitH ); - } -#else - IggyPlayerSetDisplaySize( swf, m_movieWidth, m_movieHeight ); -#endif - - IggyPlayerInitializeAndTickRS ( swf ); - int64_t afterTick = ui.iggyAllocCount; - -#ifdef _WINDOWS64 - // Flush Iggy's internal font caches so all glyphs get rasterized fresh - // at the current display scale on the first Draw. Without this, stale - // cache entries from a previous scene (loaded at a different display size) - // cause mixed glyph sizes. ResizeD3D already calls this, which is why - // fonts look correct after a resize but break when a scene reloads - // without one. - IggyFlushInstalledFonts(); -#endif - - app.DebugPrintf( app.USER_SR, "Loaded iggy movie %ls\n", moviePath.c_str() ); - - IggyPlayerSetUserdata(swf,this); - -//#ifdef _DEBUG -#if 0 - IggyMemoryUseInfo memoryInfo; - rrbool res; - int iteration = 0; - int64_t totalStatic = 0; - int64_t totalDynamic = 0; - while(res = IggyDebugGetMemoryUseInfo ( swf , - nullptr , - 0 , - 0 , - iteration , - &memoryInfo )) - { - totalStatic += memoryInfo.static_allocation_bytes; - totalDynamic += memoryInfo.dynamic_allocation_bytes; - app.DebugPrintf(app.USER_SR, "%ls - %.*s static: %d ( %d ) dynamic: %d ( %d )\n", moviePath.c_str(), memoryInfo.subcategory_stringlen, memoryInfo.subcategory, - memoryInfo.static_allocation_bytes, memoryInfo.static_allocation_count, memoryInfo.dynamic_allocation_bytes, memoryInfo.dynamic_allocation_count); - ++iteration; - //if(memoryInfo.static_allocation_bytes > 0) getDebugMemoryUseRecursive(moviePath, memoryInfo); - - } - - app.DebugPrintf(app.USER_SR, "%ls - Total: %d, Expected: %d, Diff: %d\n", moviePath.c_str(), totalStatic + totalDynamic, afterTick - beforeLoad, (afterTick - beforeLoad) - (totalStatic + totalDynamic)); - -#endif - LeaveCriticalSection(&UIController::ms_reloadSkinCS); - -} - -void UIScene::getDebugMemoryUseRecursive(const wstring &moviePath, IggyMemoryUseInfo &memoryInfo) -{ - rrbool res; - IggyMemoryUseInfo internalMemoryInfo; - int internalIteration = 0; - while (res = IggyDebugGetMemoryUseInfo(swf, - 0, - memoryInfo.subcategory, - memoryInfo.subcategory_stringlen, - internalIteration, - &internalMemoryInfo)) - { - app.DebugPrintf(app.USER_SR, "%ls - %.*s static: %d ( %d ) dynamic: %d ( %d )\n", moviePath.c_str(), internalMemoryInfo.subcategory_stringlen, internalMemoryInfo.subcategory, - internalMemoryInfo.static_allocation_bytes, internalMemoryInfo.static_allocation_count, internalMemoryInfo.dynamic_allocation_bytes, internalMemoryInfo.dynamic_allocation_count); - ++internalIteration; - if (internalMemoryInfo.subcategory_stringlen > memoryInfo.subcategory_stringlen) - getDebugMemoryUseRecursive(moviePath, internalMemoryInfo); - } -} - -void UIScene::PrintTotalMemoryUsage(int64_t &totalStatic, int64_t &totalDynamic) -{ - if(!swf) return; - - IggyMemoryUseInfo memoryInfo; - rrbool res; - int iteration = 0; - int64_t sceneStatic = 0; - int64_t sceneDynamic = 0; - while(res = IggyDebugGetMemoryUseInfo ( swf , - 0 , - "" , - 0 , - iteration , - &memoryInfo )) - { - sceneStatic += memoryInfo.static_allocation_bytes; - sceneDynamic += memoryInfo.dynamic_allocation_bytes; - totalStatic += memoryInfo.static_allocation_bytes; - totalDynamic += memoryInfo.dynamic_allocation_bytes; - ++iteration; - - } - - app.DebugPrintf(app.USER_SR, " \\- Scene static: %d , Scene dynamic: %d , Total: %d - %ls\n", sceneStatic, sceneDynamic, sceneStatic + sceneDynamic, getMoviePath().c_str()); -} - -void UIScene::tick() -{ - if(m_bIsReloading) return; - if(m_hasTickedOnce) m_bCanHandleInput = true; - while(IggyPlayerReadyToTick( swf )) - { - tickTimers(); - for(auto & it : m_controls) - { - it->tick(); - } - IggyPlayerTickRS( swf ); - m_hasTickedOnce = true; - } - -#ifdef _WINDOWS64 - { - vector inputs; - getDirectEditInputs(inputs); - for (size_t i = 0; i < inputs.size(); i++) - { - UIControl_TextInput::EDirectEditResult result = inputs[i]->tickDirectEdit(); - if (result != UIControl_TextInput::eDirectEdit_Continue) - onDirectEditFinished(inputs[i], result); - } - //Attempt at matching input code for textinputs for labels - vector labels; - getDirectEditLabels(labels); - for (size_t i = 0; i < labels.size(); i++) - { - //app.DebugPrintf(("label; " + std::to_string(i) + "\n").c_str()); - UIControl_Label::EDirectEditResult result1 = labels[i]->tickDirectEdit(); - //app.DebugPrintf(("result; " + std::to_string(result1) + "\n").c_str()); - if (result1 != UIControl_Label::eDirectEdit_Continue) - onDirectEditLabelFinished(labels[i], result1); - } - } -#endif -} - -UIControl* UIScene::GetMainPanel() -{ - return nullptr; -} - -#ifdef _WINDOWS64 -bool UIScene::isDirectEditBlocking() -{ - vector inputs; - getDirectEditInputs(inputs); - for (size_t i = 0; i < inputs.size(); i++) - { - if (inputs[i]->isDirectEditing() || inputs[i]->getDirectEditCooldown() > 0) - return true; - } - return false; -} - -bool UIScene::handleMouseClick(F32 x, F32 y) -{ - S32 panelOffsetX = 0, panelOffsetY = 0; - UIControl *pMainPanel = GetMainPanel(); - if (pMainPanel) - { - pMainPanel->UpdateControl(); - panelOffsetX = pMainPanel->getXPos(); - panelOffsetY = pMainPanel->getYPos(); - } - - // Click-outside-to-deselect: confirm any active direct edit if - // the click landed outside the editing text input. - { - vector deInputs; - getDirectEditInputs(deInputs); - for (size_t i = 0; i < deInputs.size(); i++) - { - if (!deInputs[i]->isDirectEditing()) - continue; - deInputs[i]->UpdateControl(); - S32 cx = deInputs[i]->getXPos() + panelOffsetX; - S32 cy = deInputs[i]->getYPos() + panelOffsetY; - S32 cw = deInputs[i]->getWidth(); - S32 ch = deInputs[i]->getHeight(); - if (!(cw > 0 && ch > 0 && x >= cx && x <= cx + cw && y >= cy && y <= cy + ch)) - { - deInputs[i]->confirmDirectEdit(); - onDirectEditFinished(deInputs[i], UIControl_TextInput::eDirectEdit_Confirmed); - } - } - } - - vector *controls = GetControls(); - if (!controls) return false; - - // Hit-test controls and pick the smallest-area match to handle - // overlapping Flash bounds correctly without sacrificing precision. - int bestId = -1; - S32 bestArea = INT_MAX; - UIControl *bestCtrl = NULL; - - for (size_t i = 0; i < controls->size(); ++i) - { - UIControl *ctrl = (*controls)[i]; - if (!ctrl || ctrl->getHidden() || !ctrl->getVisible() || ctrl->getId() < 0) - continue; - - UIControl::eUIControlType type = ctrl->getControlType(); - if (type != UIControl::eButton && type != UIControl::eTextInput && - type != UIControl::eCheckBox && type != UIControl::eBook && type != UIControl::ePageFlip) - continue; - - if (pMainPanel && ctrl->getParentPanel() != pMainPanel) - continue; - - ctrl->UpdateControl(); - S32 cx = ctrl->getXPos() + panelOffsetX; - S32 cy = ctrl->getYPos() + panelOffsetY; - S32 cw = ctrl->getWidth(); - S32 ch = ctrl->getHeight(); - if (cw <= 0 || ch <= 0) - continue; - - if (x >= cx && x <= cx + cw && y >= cy && y <= cy + ch) - { - S32 area = cw * ch; - if (area < bestArea) - { - bestArea = area; - bestId = ctrl->getId(); - bestCtrl = ctrl; - } - } - } - - if (bestId >= 0 && bestCtrl) - { - if (bestCtrl->getControlType() == UIControl::eCheckBox) - { - UIControl_CheckBox *cb = static_cast(bestCtrl); - if (cb->IsEnabled()) - { - bool newState = !cb->IsChecked(); - cb->setChecked(newState); - handleCheckboxToggled((F64)bestId, newState); - } - } - else - { - handlePress((F64)bestId, 0); - } - return true; - } - return false; -} -#endif - -void UIScene::addTimer(int id, int ms) -{ - int currentTime = System::currentTimeMillis(); - - TimerInfo info; - info.running = true; - info.duration = ms; - info.targetTime = currentTime + ms; - m_timers[id] = info; -} - -void UIScene::killTimer(int id) -{ - auto it = m_timers.find(id); - if(it != m_timers.end()) - { - it->second.running = false; - } -} - -void UIScene::tickTimers() -{ - int currentTime = System::currentTimeMillis(); - for (auto it = m_timers.begin(); it != m_timers.end();) - { - if(!it->second.running) - { - it = m_timers.erase(it); - } - else - { - if(currentTime > it->second.targetTime) - { - handleTimerComplete(it->first); - - // Auto-restart - it->second.targetTime = it->second.duration + currentTime; - } - ++it; - } - } -} - -IggyName UIScene::registerFastName(const wstring &name) -{ - IggyName var; - auto it = m_fastNames.find(name); - if(it != m_fastNames.end()) - { - var = it->second; - } - else - { - var = IggyPlayerCreateFastName ( getMovie() , (IggyUTF16 *)name.c_str() , -1 ); - m_fastNames[name] = var; - } - return var; -} - -void UIScene::removeControl( UIControl_Base *control, bool centreScene) -{ - IggyDataValue result; - IggyDataValue value[2]; - - string name = control->getControlName(); - IggyStringUTF8 stringVal; - stringVal.string = (char*)name.c_str(); - stringVal.length = name.length(); - value[0].type = IGGY_DATATYPE_string_UTF8; - value[0].string8 = stringVal; - - value[1].type = IGGY_DATATYPE_boolean; - value[1].boolval = centreScene; - IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcRemoveObject , 2 , value ); - -#ifdef __PSVITA__ - // update the button positions since they may have changed - UpdateSceneControls(); - - // remove it from the touchboxes - ui.TouchBoxRebuild(control->getParentScene()); -#endif - - // mark the button as removed so hover/touch hit-tests skip it - control->setHidden(true); - -} - -void UIScene::slideLeft() -{ - IggyDataValue result; - IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSlideLeft , 0 , nullptr ); -} - -void UIScene::slideRight() -{ - IggyDataValue result; - IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSlideRight , 0 , nullptr ); -} - -void UIScene::doHorizontalResizeCheck() -{ - IggyDataValue result; - IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcHorizontalResizeCheck , 0 , nullptr ); -} - -void UIScene::render(S32 width, S32 height, C4JRender::eViewportType viewport) -{ - if(m_bIsReloading) return; - if(!m_hasTickedOnce || !swf) return; - - if(viewport != C4JRender::VIEWPORT_TYPE_FULLSCREEN) - { - F32 originX, originY, viewW, viewH; - GetViewportRect(ui.getScreenWidth(), ui.getScreenHeight(), viewport, originX, originY, viewW, viewH); - S32 fitW, fitH, offsetX, offsetY; - Fit16x9(viewW, viewH, fitW, fitH, offsetX, offsetY); - ui.setupRenderPosition(static_cast(originX) + offsetX, static_cast(originY) + offsetY); - IggyPlayerSetDisplaySize( swf, fitW, fitH ); - IggyPlayerDraw( swf ); - } - else - { - ui.setupRenderPosition(viewport); - IggyPlayerSetDisplaySize( swf, width, height ); - IggyPlayerDraw( swf ); - } -} - -void UIScene::setOpacity(float percent) -{ - if(percent != m_lastOpacity || (m_bUpdateOpacity && getMovie())) - { - m_lastOpacity = percent; - - // 4J-TomK once a scene has been freshly loaded or re-loaded we force update opacity via initialiseMovie - if(m_bUpdateOpacity) - m_bUpdateOpacity = false; - - IggyDataValue result; - IggyDataValue value[1]; - value[0].type = IGGY_DATATYPE_number; - value[0].number = percent; - - IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetAlpha , 1 , value ); - } -} - -void UIScene::setVisible(bool visible) -{ - m_bVisible = visible; -} - -void UIScene::customDraw(IggyCustomDrawCallbackRegion *region) -{ - //app.DebugPrintf("Handling custom draw for scene with no override!\n"); -} - -void UIScene::customDrawSlotControl(IggyCustomDrawCallbackRegion *region, int iPad, shared_ptr item, float fAlpha, bool isFoil, bool bDecorations) -{ - if (item!= nullptr) - { - if(m_cacheSlotRenders) - { - if( (m_cachedSlotDraw.size() + 1) == m_expectedCachedSlotCount) - { - //Make sure that pMinecraft->player is the correct player so that player specific rendering - // eg clock and compass, are rendered correctly - Minecraft *pMinecraft=Minecraft::GetInstance(); - shared_ptr oldPlayer = pMinecraft->player; - if( iPad >= 0 && iPad < XUSER_MAX_COUNT ) pMinecraft->player = pMinecraft->localplayers[iPad]; - - // Setup GDraw, normal game render states and matrices - //CustomDrawData *customDrawRegion = ui.setupCustomDraw(this,region); - PIXBeginNamedEvent(0,"Starting Iggy custom draw\n"); - CustomDrawData *customDrawRegion = ui.calculateCustomDraw(region); - ui.beginIggyCustomDraw4J(region, customDrawRegion); - ui.setupCustomDrawGameState(); - - int list = m_parentLayer->m_parentGroup->getCommandBufferList(); - - bool useCommandBuffers = false; -#ifdef _XBOX_ONE - useCommandBuffers = true; - - // 4J Stu - Temporary until we fix the glint animation which needs updated if we are just replaying a command buffer - m_needsCacheRendered = true; -#endif - - if(!useCommandBuffers || m_needsCacheRendered) - { -#if (!defined __PS3__) && (!defined __PSVITA__) - if(useCommandBuffers) RenderManager.CBuffStart(list, true); -#endif - PIXBeginNamedEvent(0,"Draw uncached"); - ui.setupCustomDrawMatrices(this, customDrawRegion); - _customDrawSlotControl(customDrawRegion, iPad, item, fAlpha, isFoil, bDecorations, useCommandBuffers); - delete customDrawRegion; - PIXEndNamedEvent(); - - PIXBeginNamedEvent(0,"Draw all cache"); - // Draw all the cached slots - for(auto& drawData : m_cachedSlotDraw) - { - ui.setupCustomDrawMatrices(this, drawData->customDrawRegion); - _customDrawSlotControl(drawData->customDrawRegion, iPad, drawData->item, drawData->fAlpha, drawData->isFoil, drawData->bDecorations, useCommandBuffers); - delete drawData->customDrawRegion; - delete drawData; - } - PIXEndNamedEvent(); -#ifndef __PS3__ - if(useCommandBuffers) RenderManager.CBuffEnd(); -#endif - } - m_cachedSlotDraw.clear(); - -#ifndef __PS3__ - if(useCommandBuffers) RenderManager.CBuffCall(list); -#endif - - // Finish GDraw and anything else that needs to be finalised - ui.endCustomDraw(region); - - pMinecraft->player = oldPlayer; - } - else - { - PIXBeginNamedEvent(0,"Caching region"); - CachedSlotDrawData *drawData = new CachedSlotDrawData(); - drawData->item = item; - drawData->fAlpha = fAlpha; - drawData->isFoil = isFoil; - drawData->bDecorations = bDecorations; - drawData->customDrawRegion = ui.calculateCustomDraw(region); - - m_cachedSlotDraw.push_back(drawData); - PIXEndNamedEvent(); - } - } - else - { - // Setup GDraw, normal game render states and matrices - CustomDrawData *customDrawRegion = ui.setupCustomDraw(this,region); - - Minecraft *pMinecraft=Minecraft::GetInstance(); - - //Make sure that pMinecraft->player is the correct player so that player specific rendering - // eg clock and compass, are rendered correctly - shared_ptr oldPlayer = pMinecraft->player; - if( iPad >= 0 && iPad < XUSER_MAX_COUNT ) pMinecraft->player = pMinecraft->localplayers[iPad]; - - _customDrawSlotControl(customDrawRegion, iPad, item, fAlpha, isFoil, bDecorations, false); - delete customDrawRegion; - pMinecraft->player = oldPlayer; - - // Finish GDraw and anything else that needs to be finalised - ui.endCustomDraw(region); - } - } -} - -void UIScene::_customDrawSlotControl(CustomDrawData *region, int iPad, shared_ptr item, float fAlpha, bool isFoil, bool bDecorations, bool usingCommandBuffer) -{ - Minecraft *pMinecraft=Minecraft::GetInstance(); - - float bwidth,bheight; - bwidth = region->x1 - region->x0; - bheight = region->y1 - region->y0; - - float x = region->x0; - float y = region->y0; - - // Base scale on height of this control, compared to height of what the item renderer normally renders (16 pixels high). Potentially - // we might want separate x & y scales here - - float scaleX = bwidth / 16.0f; - float scaleY = bheight / 16.0f; - - glEnable(GL_RESCALE_NORMAL); - glPushMatrix(); - glRotatef(120, 1, 0, 0); - Lighting::turnOn(); - glPopMatrix(); - - float pop = item->popTime; - if (pop > 0) - { - glPushMatrix(); - float squeeze = 1 + pop / static_cast(Inventory::POP_TIME_DURATION); - float sx = x; - float sy = y; - float sxoffs = 8 * scaleX; - float syoffs = 12 * scaleY; - glTranslatef((float)(sx + sxoffs), (float)(sy + syoffs), 0); - glScalef(1 / squeeze, (squeeze + 1) / 2, 1); - glTranslatef((float)-(sx + sxoffs), (float)-(sy + syoffs), 0); - } - - PIXBeginNamedEvent(0,"Render and decorate"); - if(m_pItemRenderer == nullptr) m_pItemRenderer = new ItemRenderer(); - RenderManager.StateSetBlendEnable(true); - RenderManager.StateSetBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - RenderManager.StateSetBlendFactor(0xffffffff); - m_pItemRenderer->renderAndDecorateItem(pMinecraft->font, pMinecraft->textures, item, x, y,scaleX,scaleY,fAlpha,isFoil,false, !usingCommandBuffer); - PIXEndNamedEvent(); - - if (pop > 0) - { - glPopMatrix(); - } - - if(bDecorations) - { - if((scaleX!=1.0f) ||(scaleY!=1.0f)) - { - glPushMatrix(); - glScalef(scaleX, scaleY, 1.0f); - int iX= static_cast(0.5f + ((float)x) / scaleX); - int iY= static_cast(0.5f + ((float)y) / scaleY); - - m_pItemRenderer->renderGuiItemDecorations(pMinecraft->font, pMinecraft->textures, item, iX, iY, fAlpha); - glPopMatrix(); - } - else - { - m_pItemRenderer->renderGuiItemDecorations(pMinecraft->font, pMinecraft->textures, item, static_cast(x), static_cast(y), fAlpha); - } - } - - Lighting::turnOff(); - glDisable(GL_RESCALE_NORMAL); -} - -// 4J Stu - Not threadsafe -//void UIScene::navigateForward(int iPad, EUIScene scene, void *initData) -//{ -// if(m_parentLayer == nullptr) -// { -// app.DebugPrintf("A scene is trying to navigate forwards, but it's parent layer is nullptr!\n"); -// } -// else -// { -// m_parentLayer->NavigateToScene(iPad,scene,initData); -// } -//} - -void UIScene::navigateBack() -{ - //CD - Added for audio - ui.PlayUISFX(eSFX_Back); - - ui.NavigateBack(m_iPad); - - if(m_parentLayer == nullptr) - { - } - else - { -// m_parentLayer->removeScene(this); - -#ifdef _DURANGO - if (ui.GetTopScene(0)) - InputManager.SetEnabledGtcButtons( ui.GetTopScene(0)->getDefaultGtcButtons() ); -#endif - } - -} - -void UIScene::gainFocus() -{ - if( !bHasFocus && stealsFocus() ) - { - // 4J Stu - Don't do this - /* - IggyEvent event; - IggyMakeEventFocusGained( &event , 0); - - IggyEventResult result; - IggyPlayerDispatchEventRS( getMovie() , &event , &result ); - - app.DebugPrintf("Sent gain focus event to scene\n"); - */ - bHasFocus = true; - if(needsReloaded()) - { - reloadMovie(); - } - - updateTooltips(); - updateComponents(); - - if(!m_bFocussedOnce) - { - IggyDataValue result; - IggyDataValue value[1]; - - value[0].type = IGGY_DATATYPE_number; - value[0].number = -1; - - IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetFocus , 1 , value ); - } - - handleGainFocus(m_bFocussedOnce); - if(bHasFocus) m_bFocussedOnce = true; - } - else if(bHasFocus && stealsFocus()) - { - updateTooltips(); - } -} - -void UIScene::loseFocus() -{ - if(bHasFocus) - { - // 4J Stu - Don't do this - /* - IggyEvent event; - IggyMakeEventFocusLost( &event ); - IggyEventResult result; - IggyPlayerDispatchEventRS ( getMovie() , &event , &result ); - */ - - app.DebugPrintf("Sent lose focus event to scene\n"); - bHasFocus = false; - handleLoseFocus(); - } -} - -void UIScene::handleGainFocus(bool navBack) -{ -#ifdef _DURANGO - InputManager.SetEnabledGtcButtons( this->getDefaultGtcButtons() ); -#endif -} - -void UIScene::updateTooltips() -{ - if(!ui.IsReloadingSkin()) - ui.SetTooltips(m_iPad, -1); -} - -void UIScene::sendInputToMovie(int key, bool repeat, bool pressed, bool released) -{ - if(!swf) return; - - int iggyKeyCode = convertGameActionToIggyKeycode(key); - - if(iggyKeyCode < 0) - { - app.DebugPrintf("UI WARNING: Ignoring input as game action does not translate to an Iggy keycode\n"); - return; - } - -#ifdef _WINDOWS64 - // If a navigation key is pressed with no focused element, focus the first - // available one so arrow keys work even when the mouse is over empty space. - if(pressed && (iggyKeyCode == IGGY_KEYCODE_UP || iggyKeyCode == IGGY_KEYCODE_DOWN || - iggyKeyCode == IGGY_KEYCODE_LEFT || iggyKeyCode == IGGY_KEYCODE_RIGHT)) - { - IggyFocusHandle currentFocus = IGGY_FOCUS_NULL; - IggyFocusableObject focusables[64]; - S32 numFocusables = 0; - IggyPlayerGetFocusableObjects(swf, ¤tFocus, focusables, 64, &numFocusables); - if(currentFocus == IGGY_FOCUS_NULL && numFocusables > 0) - { - IggyPlayerSetFocusRS(swf, focusables[0].object, 0); - return; - } - } -#endif - - IggyEvent keyEvent; - // 4J Stu - Keyloc is always standard as we don't care about shift/alt - IggyMakeEventKey( &keyEvent, pressed?IGGY_KEYEVENT_Down:IGGY_KEYEVENT_Up, static_cast(iggyKeyCode), IGGY_KEYLOC_Standard ); - - IggyEventResult result; - IggyPlayerDispatchEventRS ( swf , &keyEvent , &result ); -} - -int UIScene::convertGameActionToIggyKeycode(int action) -{ - // TODO: This action to key mapping should probably use the control mapping - int keycode = -1; - switch(action) - { -#ifdef __ORBIS__ - case ACTION_MENU_TOUCHPAD_PRESS: -#endif - case ACTION_MENU_A: - keycode = IGGY_KEYCODE_ENTER; - break; - case ACTION_MENU_B: - keycode = IGGY_KEYCODE_ESCAPE; - break; - case ACTION_MENU_X: - keycode = IGGY_KEYCODE_F1; - break; - case ACTION_MENU_Y: - keycode = IGGY_KEYCODE_F2; - break; - case ACTION_MENU_OK: - keycode = IGGY_KEYCODE_ENTER; - break; - case ACTION_MENU_CANCEL: - keycode = IGGY_KEYCODE_ESCAPE; - break; - case ACTION_MENU_UP: - keycode = IGGY_KEYCODE_UP; - break; - case ACTION_MENU_DOWN: - keycode = IGGY_KEYCODE_DOWN; - break; - case ACTION_MENU_RIGHT: - keycode = IGGY_KEYCODE_RIGHT; - break; - case ACTION_MENU_LEFT: - keycode = IGGY_KEYCODE_LEFT; - break; - case ACTION_MENU_PAGEUP: - keycode = IGGY_KEYCODE_PAGE_UP; - break; - case ACTION_MENU_PAGEDOWN: -#ifdef __PSVITA__ - if (!InputManager.IsVitaTV()) - { - keycode = IGGY_KEYCODE_F6; - } - else -#endif - { - keycode = IGGY_KEYCODE_PAGE_DOWN; - } - break; - case ACTION_MENU_RIGHT_SCROLL: - keycode = IGGY_KEYCODE_F3; - break; - case ACTION_MENU_LEFT_SCROLL: - keycode = IGGY_KEYCODE_F4; - break; - case ACTION_MENU_STICK_PRESS: - break; - case ACTION_MENU_OTHER_STICK_PRESS: - keycode = IGGY_KEYCODE_F5; - break; - case ACTION_MENU_OTHER_STICK_UP: - keycode = IGGY_KEYCODE_F11; - break; - case ACTION_MENU_OTHER_STICK_DOWN: - keycode = IGGY_KEYCODE_F12; - break; - case ACTION_MENU_OTHER_STICK_LEFT: - break; - case ACTION_MENU_OTHER_STICK_RIGHT: - break; - }; - - return keycode; -} - -bool UIScene::allowRepeat(int key) -{ - // 4J-PB - ignore repeats of action ABXY buttons - // fix for PS3 213 - [MAIN MENU] Holding down buttons will continue to activate every prompt. - switch(key) - { - case ACTION_MENU_OK: - case ACTION_MENU_CANCEL: - case ACTION_MENU_A: - case ACTION_MENU_B: - case ACTION_MENU_X: - case ACTION_MENU_Y: - return false; - } - return true; -} - -void UIScene::externalCallback(IggyExternalFunctionCallUTF16 * call) -{ - if(wcscmp((wchar_t *)call->function_name.string,L"handlePress")==0) - { - if(call->num_arguments != 2) - { - app.DebugPrintf("Callback for handlePress did not have the correct number of arguments\n"); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - return; - } - if(call->arguments[0].type != IGGY_DATATYPE_number || call->arguments[1].type != IGGY_DATATYPE_number) - { - app.DebugPrintf("Arguments for handlePress were not of the correct type\n"); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - return; - } - handlePress(call->arguments[0].number, call->arguments[1].number); - } - else if(wcscmp((wchar_t *)call->function_name.string,L"handleFocusChange")==0) - { - if(call->num_arguments != 2) - { - app.DebugPrintf("Callback for handleFocusChange did not have the correct number of arguments\n"); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - return; - } - if(call->arguments[0].type != IGGY_DATATYPE_number || call->arguments[1].type != IGGY_DATATYPE_number) - { - app.DebugPrintf("Arguments for handleFocusChange were not of the correct type\n"); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - return; - } - _handleFocusChange(call->arguments[0].number, call->arguments[1].number); - } - else if(wcscmp((wchar_t *)call->function_name.string,L"handleInitFocus")==0) - { - if(call->num_arguments != 2) - { - app.DebugPrintf("Callback for handleInitFocus did not have the correct number of arguments\n"); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - return; - } - if(call->arguments[0].type != IGGY_DATATYPE_number || call->arguments[1].type != IGGY_DATATYPE_number) - { - app.DebugPrintf("Arguments for handleInitFocus were not of the correct type\n"); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - return; - } - _handleInitFocus(call->arguments[0].number, call->arguments[1].number); - } - else if(wcscmp((wchar_t *)call->function_name.string,L"handleCheckboxToggled")==0) - { - if(call->num_arguments != 2) - { - app.DebugPrintf("Callback for handleCheckboxToggled did not have the correct number of arguments\n"); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - return; - } - if(call->arguments[0].type != IGGY_DATATYPE_number || call->arguments[1].type != IGGY_DATATYPE_boolean) - { - app.DebugPrintf("Arguments for handleCheckboxToggled were not of the correct type\n"); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - return; - } - handleCheckboxToggled(call->arguments[0].number, call->arguments[1].boolval); - } - else if(wcscmp((wchar_t *)call->function_name.string,L"handleSliderMove")==0) - { - if(call->num_arguments != 2) - { - app.DebugPrintf("Callback for handleSliderMove did not have the correct number of arguments\n"); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - return; - } - if(call->arguments[0].type != IGGY_DATATYPE_number || call->arguments[1].type != IGGY_DATATYPE_number) - { - app.DebugPrintf("Arguments for handleSliderMove were not of the correct type\n"); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - return; - } - handleSliderMove(call->arguments[0].number, call->arguments[1].number); - } - else if(wcscmp((wchar_t *)call->function_name.string,L"handleAnimationEnd")==0) - { - if(call->num_arguments != 0) - { - app.DebugPrintf("Callback for handleAnimationEnd did not have the correct number of arguments\n"); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - return; - } - handleAnimationEnd(); - } - else if(wcscmp((wchar_t *)call->function_name.string,L"handleSelectionChanged")==0) - { - if(call->num_arguments != 1) - { - app.DebugPrintf("Callback for handleSelectionChanged did not have the correct number of arguments\n"); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - return; - } - if(call->arguments[0].type != IGGY_DATATYPE_number) - { - app.DebugPrintf("Arguments for handleSelectionChanged were not of the correct type\n"); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - return; - } - handleSelectionChanged(call->arguments[0].number); - } - else if(wcscmp((wchar_t *)call->function_name.string,L"handleRequestMoreData")==0) - { - if(call->num_arguments == 0) - { - handleRequestMoreData(0,false); - } - else - { - if(call->num_arguments != 2) - { - app.DebugPrintf("Callback for handleRequestMoreData did not have the correct number of arguments\n"); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - return; - } - if(call->arguments[0].type != IGGY_DATATYPE_number || call->arguments[1].type != IGGY_DATATYPE_boolean) - { - app.DebugPrintf("Arguments for handleRequestMoreData were not of the correct type\n"); -#ifndef _CONTENT_PACKAGE - DEBUG_BREAK(); -#endif - return; - } - handleRequestMoreData(call->arguments[0].number, call->arguments[1].boolval); - } - } - else if(wcscmp((wchar_t *)call->function_name.string,L"handleTouchBoxRebuild")==0) - { - handleTouchBoxRebuild(); - } - else - { - app.DebugPrintf("Unhandled callback: %s\n", call->function_name.string); - } -} - -void UIScene::registerSubstitutionTexture(const wstring &textureName, PBYTE pbData, DWORD dwLength, bool deleteData) -{ - m_registeredTextures[textureName] = deleteData;; - ui.registerSubstitutionTexture(textureName, pbData, dwLength); -} - -bool UIScene::hasRegisteredSubstitutionTexture(const wstring &textureName) -{ - auto it = m_registeredTextures.find(textureName); - - return it != m_registeredTextures.end(); -} - -void UIScene::_handleFocusChange(F64 controlId, F64 childId) -{ - int newControl = static_cast(controlId); - int newChild = static_cast(childId); - if (newControl != m_iFocusControl || newChild != m_iFocusChild) - { - m_iFocusControl = newControl; - m_iFocusChild = newChild; - - handleFocusChange(controlId, childId); - ui.PlayUISFX(eSFX_Focus); - } -} - -void UIScene::_handleInitFocus(F64 controlId, F64 childId) -{ - m_iFocusControl = static_cast(controlId); - m_iFocusChild = static_cast(childId); - - //handleInitFocus(controlId, childId); - handleFocusChange(controlId, childId); -} - -bool UIScene::controlHasFocus(int iControlId) -{ - return m_iFocusControl == iControlId; -} - -bool UIScene::controlHasFocus(UIControl_Base *control) -{ - return controlHasFocus( control->getId() ); -} - -int UIScene::getControlChildFocus() -{ - return m_iFocusChild; -} - -int UIScene::getControlFocus() -{ - return m_iFocusControl; -} - -void UIScene::setBackScene(UIScene *scene) -{ - m_backScene = scene; -} - -UIScene *UIScene::getBackScene() -{ - return m_backScene; -} -#ifdef __PSVITA__ -void UIScene::UpdateSceneControls() -{ - for ( UIControl *control : *GetControls() ) - { - control->UpdateControl(); - } -} -#endif - -void UIScene::HandleMessage(EUIMessage message, void *data) -{ -} - -size_t UIScene::GetCallbackUniqueId() -{ - if( m_callbackUniqueId == 0) - { - m_callbackUniqueId = ui.RegisterForCallbackId(this); - } - return m_callbackUniqueId; -} - -bool UIScene::isReadyToDelete() -{ - return true; -} +#include "stdafx.h" +#include "UI.h" +#include "UIScene.h" +#include "UISplitScreenHelpers.h" + +#include "../../Lighting.h" +#include "../../LocalPlayer.h" +#include "../../ItemRenderer.h" +#include "../../../Minecraft.World/net.minecraft.world.item.h" +#include "UIScene_BookAndQuillMenu.h" + +UIScene::UIScene(int iPad, UILayer *parentLayer) +{ + m_parentLayer = parentLayer; + m_iPad = iPad; + swf = nullptr; + m_pItemRenderer = nullptr; + + bHasFocus = false; + m_hasTickedOnce = false; + m_bFocussedOnce = false; + m_bPanoramaUsesDefaultPlatformSkin = false; + m_bVisible = true; + m_bCanHandleInput = false; + m_bIsReloading = false; + + m_iFocusControl = -1; + m_iFocusChild = 0; + m_lastOpacity = 1.0f; + m_bUpdateOpacity = false; + + m_backScene = nullptr; + + m_cacheSlotRenders = false; + m_needsCacheRendered = true; + m_expectedCachedSlotCount = 0; + m_callbackUniqueId = 0; +} + +UIScene::~UIScene() +{ + if(m_bPanoramaUsesDefaultPlatformSkin) + { + ui.PopDefaultPlatformSkinForPanorama(); + m_bPanoramaUsesDefaultPlatformSkin = false; + } + + /* Destroy the Iggy player. */ + IggyPlayerDestroy( swf ); + + for(auto & it : m_registeredTextures) + { + ui.unregisterSubstitutionTexture( it.first, it.second ); + } + + if(m_callbackUniqueId != 0) + { + ui.UnregisterCallbackId(m_callbackUniqueId); + } + + if(m_pItemRenderer != nullptr) delete m_pItemRenderer; +} + +void UIScene::destroyMovie() +{ + if(m_bPanoramaUsesDefaultPlatformSkin) + { + ui.PopDefaultPlatformSkinForPanorama(); + m_bPanoramaUsesDefaultPlatformSkin = false; + } + + /* Destroy the Iggy player. */ + IggyPlayerDestroy( swf ); + swf = nullptr; + + // Clear out the controls collection (doesn't delete the controls, and they get re-setup later) + m_controls.clear(); + + // Clear out all the fast names for the current movie + m_fastNames.clear(); +} + +void UIScene::reloadMovie(bool force) +{ + if(!force && (stealsFocus() && (getSceneType() != eUIScene_FullscreenProgress && !bHasFocus))) return; + + m_bIsReloading = true; + if(swf) + { + if(m_bPanoramaUsesDefaultPlatformSkin) + { + ui.PopDefaultPlatformSkinForPanorama(); + m_bPanoramaUsesDefaultPlatformSkin = false; + } + + /* Destroy the Iggy player. */ + IggyPlayerDestroy( swf ); + + // Clear out the controls collection (doesn't delete the controls, and they get re-setup later) + m_controls.clear(); + + // Clear out all the fast names for the current movie + m_fastNames.clear(); + } + + // Reload everything + initialiseMovie(); + + handlePreReload(); + + // Reload controls + for(auto & it : m_controls) + { + it->ReInit(); + } + + updateComponents(); + handleReload(); + + IggyDataValue result; + IggyDataValue value[1]; + + value[0].type = IGGY_DATATYPE_number; + value[0].number = m_iFocusControl; + + if(swf && m_funcSetFocus) + { + IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetFocus , 1 , value ); + } + + m_needsCacheRendered = true; + m_bIsReloading = false; +} + +bool UIScene::needsReloaded() +{ + return !swf && (!stealsFocus() || bHasFocus); +} + +bool UIScene::hasMovie() +{ + return swf != nullptr; +} + +F64 UIScene::getSafeZoneHalfHeight() +{ + float height = ui.getScreenHeight(); + + float safeHeight = 0.0f; + +#ifndef __PSVITA__ + if( !RenderManager.IsHiDef() && RenderManager.IsWidescreen() ) + { + // 90% safezone + safeHeight = height * (0.15f / 2); + } + else + { + // 90% safezone + safeHeight = height * (0.1f / 2); + } +#endif + return safeHeight; +} + +F64 UIScene::getSafeZoneHalfWidth() +{ + float width = ui.getScreenWidth(); + + float safeWidth = 0.0f; +#ifndef __PSVITA__ + if( !RenderManager.IsHiDef() && RenderManager.IsWidescreen() ) + { + // 85% safezone + safeWidth = width * (0.15f / 2); + } + else + { + // 90% safezone + safeWidth = width * (0.1f / 2); + } +#endif + return safeWidth; +} + +void UIScene::updateSafeZone() +{ + // Distance from edge + F64 safeTop = 0.0; + F64 safeBottom = 0.0; + F64 safeLeft = 0.0; + F64 safeRight = 0.0; + + switch( m_parentLayer->getViewport() ) + { + case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: + safeTop = getSafeZoneHalfHeight(); + safeLeft = getSafeZoneHalfWidth(); + + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: + // safeTop mirrors SPLIT_TOP for visual symmetry. safeBottom omitted. + safeTop = getSafeZoneHalfHeight(); + safeLeft = getSafeZoneHalfWidth(); + + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT: + safeTop = getSafeZoneHalfHeight(); + safeLeft = getSafeZoneHalfWidth(); + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT: + safeTop = getSafeZoneHalfHeight(); + + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT: + safeTop = getSafeZoneHalfHeight(); + safeLeft = getSafeZoneHalfWidth(); + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT: + safeTop = getSafeZoneHalfHeight(); + + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT: + safeTop = getSafeZoneHalfHeight(); + safeLeft = getSafeZoneHalfWidth(); + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT: + safeTop = getSafeZoneHalfHeight(); + + break; + case C4JRender::VIEWPORT_TYPE_FULLSCREEN: + default: + safeTop = getSafeZoneHalfHeight(); + safeBottom = getSafeZoneHalfHeight(); + safeLeft = getSafeZoneHalfWidth(); + + break; + } + setSafeZone(safeTop, safeBottom, safeLeft, safeRight); +} + +void UIScene::setSafeZone(S32 safeTop, S32 safeBottom, S32 safeLeft, S32 safeRight) +{ + if(!swf) return; + + IggyDataValue result; + IggyDataValue value[4]; + + value[0].type = IGGY_DATATYPE_number; + value[0].number = safeTop; + value[1].type = IGGY_DATATYPE_number; + value[1].number = safeBottom; + value[2].type = IGGY_DATATYPE_number; + value[2].number = safeLeft; + value[3].type = IGGY_DATATYPE_number; + value[3].number = safeRight; + IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetSafeZone , 4 , value ); +} + +void UIScene::initialiseMovie() +{ + wstring moviePath = getMoviePath(); + if(!moviePath.empty()) + { + loadMovie(); + mapElementsAndNames(); + } + + updateSafeZone(); + + m_bUpdateOpacity = true; +} + +#if defined(__PSVITA__) || defined(_WINDOWS64) +void UIScene::SetFocusToElement(int iID) +{ + IggyDataValue result; + IggyDataValue value[1]; + + value[0].type = IGGY_DATATYPE_number; + value[0].number = iID; + + IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetFocus , 1 , value ); + + // also trigger handle focus change (just in case if anything else in relation needs updating!) + _handleFocusChange(iID, 0); +} +#endif + +bool UIScene::mapElementsAndNames() +{ + m_rootPath = IggyPlayerRootPath( swf ); + + m_funcRemoveObject = registerFastName( L"RemoveObject" ); + m_funcSlideLeft = registerFastName( L"SlideLeft" ); + m_funcSlideRight = registerFastName( L"SlideRight" ); + m_funcSetSafeZone = registerFastName( L"SetSafeZone" ); + m_funcSetAlpha = registerFastName( L"SetAlpha" ); + m_funcSetFocus = registerFastName( L"SetFocus" ); + m_funcHorizontalResizeCheck = registerFastName( L"DoHorizontalResizeCheck"); + return true; +} + +extern CRITICAL_SECTION s_loadSkinCS; +void UIScene::loadMovie() +{ + EnterCriticalSection(&UIController::ms_reloadSkinCS); // MGH - added to prevent crash loading Iggy movies while the skins were being reloaded + wstring moviePath = getMoviePath(); + +#ifdef _WINDOWS64 + const bool isPanoramaMovie = (moviePath == L"Panorama" || moviePath == L"PanoramaSplit"); + if(isPanoramaMovie) + { + ui.PushDefaultPlatformSkinForPanorama(); + m_bPanoramaUsesDefaultPlatformSkin = true; + } +#endif + +#ifdef __PS3__ + if(RenderManager.IsWidescreen()) + { + moviePath.append(L"720.swf"); + m_loadedResolution = eSceneResolution_720; + } + else + { + moviePath.append(L"480.swf"); + m_loadedResolution = eSceneResolution_480; + } +#elif defined __PSVITA__ + moviePath.append(L"Vita.swf"); + m_loadedResolution = eSceneResolution_Vita; +#elif defined _WINDOWS64 + int primaryPad = ProfileManager.GetPrimaryPad(); + if(primaryPad < 0 || primaryPad >= XUSER_MAX_COUNT) + primaryPad = 0; + const int controlType = app.GetGameSettings(primaryPad, eGameSetting_ControlType); + const bool force720ForControlType = (controlType == 3 || controlType == 5); + // tutorial popups + HUD elements have inaccuracies + crashes that we need to fix here + const bool isTutorialPopupMovie = (moviePath.find(L"TutorialPopup") == 0); + const bool isHUDMovie = (moviePath.find(L"HUD") == 0); + const bool use1080 = (ui.getScreenHeight() > 720.0f) && (!force720ForControlType || isTutorialPopupMovie); + if(use1080) + { + moviePath.append(L"1080.swf"); + m_loadedResolution = eSceneResolution_1080; + } + else + { + moviePath.append(L"720.swf"); + m_loadedResolution = eSceneResolution_720; + } +#else + moviePath.append(L"1080.swf"); + m_loadedResolution = eSceneResolution_1080; +#endif + + if(!app.hasArchiveFile(moviePath)) + { + app.DebugPrintf("WARNING: Could not find iggy movie %ls, trying other resolutions\n", moviePath.c_str()); + + // Try 720 first, then 1080 as final fallback + moviePath = getMoviePath(); + moviePath.append(L"720.swf"); + m_loadedResolution = eSceneResolution_720; + + if(!app.hasArchiveFile(moviePath)) + { + moviePath = getMoviePath(); + moviePath.append(L"1080.swf"); + m_loadedResolution = eSceneResolution_1080; + + if(!app.hasArchiveFile(moviePath)) + { + app.DebugPrintf("ERROR: Could not find any iggy movie for %ls!\n", moviePath.c_str()); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + app.FatalLoadError(); + } + } + } + + byteArray baFile = ui.getMovieData(moviePath.c_str()); + int64_t beforeLoad = ui.iggyAllocCount; + swf = IggyPlayerCreateFromMemory ( baFile.data , baFile.length, nullptr); + int64_t afterLoad = ui.iggyAllocCount; + + if(!swf) + { + app.DebugPrintf("ERROR: Failed to load iggy scene!\n"); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + app.FatalLoadError(); + } + + // Read movie dimensions from the SWF header (available immediately after + // CreateFromMemory, no init tick needed). + IggyProperties *properties = IggyPlayerProperties ( swf ); + if(!properties) + { + app.DebugPrintf("ERROR: IggyPlayerProperties returned null for scene '%ls'\n", moviePath.c_str()); +#ifndef _CONTENT_PACKAGE + __debugbreak(); +#endif + app.FatalLoadError(); + } + m_movieHeight = properties->movie_height_in_pixels; + m_movieWidth = properties->movie_width_in_pixels; + m_renderWidth = m_movieWidth; + m_renderHeight = m_movieHeight; + + // Set display size BEFORE the init tick to match what render() will use. + // InitializeAndTickRS runs ActionScript that creates text fields. If the + // display size here differs from what render() passes to SetDisplaySize, + // Iggy can cache glyph rasterizations at one scale during init and then + // reuse them at a different scale during draw, producing mixed glyph sizes. +#ifdef _WINDOWS64 + { + S32 fitW, fitH, fitOffX, fitOffY; + Fit16x9(ui.getScreenWidth(), ui.getScreenHeight(), fitW, fitH, fitOffX, fitOffY); + IggyPlayerSetDisplaySize( swf, fitW, fitH ); + } +#else + IggyPlayerSetDisplaySize( swf, m_movieWidth, m_movieHeight ); +#endif + + IggyPlayerInitializeAndTickRS ( swf ); + int64_t afterTick = ui.iggyAllocCount; + +#ifdef _WINDOWS64 + // Flush Iggy's internal font caches so all glyphs get rasterized fresh + // at the current display scale on the first Draw. Without this, stale + // cache entries from a previous scene (loaded at a different display size) + // cause mixed glyph sizes. ResizeD3D already calls this, which is why + // fonts look correct after a resize but break when a scene reloads + // without one. + IggyFlushInstalledFonts(); +#endif + + app.DebugPrintf( app.USER_SR, "Loaded iggy movie %ls\n", moviePath.c_str() ); + + IggyPlayerSetUserdata(swf,this); + +//#ifdef _DEBUG +#if 0 + IggyMemoryUseInfo memoryInfo; + rrbool res; + int iteration = 0; + int64_t totalStatic = 0; + int64_t totalDynamic = 0; + while(res = IggyDebugGetMemoryUseInfo ( swf , + nullptr , + 0 , + 0 , + iteration , + &memoryInfo )) + { + totalStatic += memoryInfo.static_allocation_bytes; + totalDynamic += memoryInfo.dynamic_allocation_bytes; + app.DebugPrintf(app.USER_SR, "%ls - %.*s static: %d ( %d ) dynamic: %d ( %d )\n", moviePath.c_str(), memoryInfo.subcategory_stringlen, memoryInfo.subcategory, + memoryInfo.static_allocation_bytes, memoryInfo.static_allocation_count, memoryInfo.dynamic_allocation_bytes, memoryInfo.dynamic_allocation_count); + ++iteration; + //if(memoryInfo.static_allocation_bytes > 0) getDebugMemoryUseRecursive(moviePath, memoryInfo); + + } + + app.DebugPrintf(app.USER_SR, "%ls - Total: %d, Expected: %d, Diff: %d\n", moviePath.c_str(), totalStatic + totalDynamic, afterTick - beforeLoad, (afterTick - beforeLoad) - (totalStatic + totalDynamic)); + +#endif + LeaveCriticalSection(&UIController::ms_reloadSkinCS); + +} + +void UIScene::getDebugMemoryUseRecursive(const wstring &moviePath, IggyMemoryUseInfo &memoryInfo) +{ + rrbool res; + IggyMemoryUseInfo internalMemoryInfo; + int internalIteration = 0; + while (res = IggyDebugGetMemoryUseInfo(swf, + 0, + memoryInfo.subcategory, + memoryInfo.subcategory_stringlen, + internalIteration, + &internalMemoryInfo)) + { + app.DebugPrintf(app.USER_SR, "%ls - %.*s static: %d ( %d ) dynamic: %d ( %d )\n", moviePath.c_str(), internalMemoryInfo.subcategory_stringlen, internalMemoryInfo.subcategory, + internalMemoryInfo.static_allocation_bytes, internalMemoryInfo.static_allocation_count, internalMemoryInfo.dynamic_allocation_bytes, internalMemoryInfo.dynamic_allocation_count); + ++internalIteration; + if (internalMemoryInfo.subcategory_stringlen > memoryInfo.subcategory_stringlen) + getDebugMemoryUseRecursive(moviePath, internalMemoryInfo); + } +} + +void UIScene::PrintTotalMemoryUsage(int64_t &totalStatic, int64_t &totalDynamic) +{ + if(!swf) return; + + IggyMemoryUseInfo memoryInfo; + rrbool res; + int iteration = 0; + int64_t sceneStatic = 0; + int64_t sceneDynamic = 0; + while(res = IggyDebugGetMemoryUseInfo ( swf , + 0 , + "" , + 0 , + iteration , + &memoryInfo )) + { + sceneStatic += memoryInfo.static_allocation_bytes; + sceneDynamic += memoryInfo.dynamic_allocation_bytes; + totalStatic += memoryInfo.static_allocation_bytes; + totalDynamic += memoryInfo.dynamic_allocation_bytes; + ++iteration; + + } + + app.DebugPrintf(app.USER_SR, " \\- Scene static: %d , Scene dynamic: %d , Total: %d - %ls\n", sceneStatic, sceneDynamic, sceneStatic + sceneDynamic, getMoviePath().c_str()); +} + +void UIScene::tick() +{ + if(m_bIsReloading) return; + if(m_hasTickedOnce) m_bCanHandleInput = true; + while(IggyPlayerReadyToTick( swf )) + { + tickTimers(); + for(auto & it : m_controls) + { + it->tick(); + } + IggyPlayerTickRS( swf ); + m_hasTickedOnce = true; + } + +#ifdef _WINDOWS64 + { + vector inputs; + getDirectEditInputs(inputs); + for (size_t i = 0; i < inputs.size(); i++) + { + UIControl_TextInput::EDirectEditResult result = inputs[i]->tickDirectEdit(); + if (result != UIControl_TextInput::eDirectEdit_Continue) + onDirectEditFinished(inputs[i], result); + } + //Attempt at matching input code for textinputs for labels + vector labels; + getDirectEditLabels(labels); + for (size_t i = 0; i < labels.size(); i++) + { + //app.DebugPrintf(("label; " + std::to_string(i) + "\n").c_str()); + UIControl_Label::EDirectEditResult result1 = labels[i]->tickDirectEdit(); + //app.DebugPrintf(("result; " + std::to_string(result1) + "\n").c_str()); + if (result1 != UIControl_Label::eDirectEdit_Continue) + onDirectEditLabelFinished(labels[i], result1); + } + } +#endif +} + +UIControl* UIScene::GetMainPanel() +{ + return nullptr; +} + +#ifdef _WINDOWS64 +bool UIScene::isDirectEditBlocking() +{ + vector inputs; + getDirectEditInputs(inputs); + for (size_t i = 0; i < inputs.size(); i++) + { + if (inputs[i]->isDirectEditing() || inputs[i]->getDirectEditCooldown() > 0) + return true; + } + return false; +} + +bool UIScene::handleMouseClick(F32 x, F32 y) +{ + S32 panelOffsetX = 0, panelOffsetY = 0; + UIControl *pMainPanel = GetMainPanel(); + if (pMainPanel) + { + pMainPanel->UpdateControl(); + panelOffsetX = pMainPanel->getXPos(); + panelOffsetY = pMainPanel->getYPos(); + } + + // Click-outside-to-deselect: confirm any active direct edit if + // the click landed outside the editing text input. + { + vector deInputs; + getDirectEditInputs(deInputs); + for (size_t i = 0; i < deInputs.size(); i++) + { + if (!deInputs[i]->isDirectEditing()) + continue; + deInputs[i]->UpdateControl(); + S32 cx = deInputs[i]->getXPos() + panelOffsetX; + S32 cy = deInputs[i]->getYPos() + panelOffsetY; + S32 cw = deInputs[i]->getWidth(); + S32 ch = deInputs[i]->getHeight(); + if (!(cw > 0 && ch > 0 && x >= cx && x <= cx + cw && y >= cy && y <= cy + ch)) + { + deInputs[i]->confirmDirectEdit(); + onDirectEditFinished(deInputs[i], UIControl_TextInput::eDirectEdit_Confirmed); + } + } + } + + vector *controls = GetControls(); + if (!controls) return false; + + // Hit-test controls and pick the smallest-area match to handle + // overlapping Flash bounds correctly without sacrificing precision. + int bestId = -1; + S32 bestArea = INT_MAX; + UIControl *bestCtrl = NULL; + + for (size_t i = 0; i < controls->size(); ++i) + { + UIControl *ctrl = (*controls)[i]; + if (!ctrl || ctrl->getHidden() || !ctrl->getVisible() || ctrl->getId() < 0) + continue; + + UIControl::eUIControlType type = ctrl->getControlType(); + if (type != UIControl::eButton && type != UIControl::eTextInput && + type != UIControl::eCheckBox && type != UIControl::eBook && type != UIControl::ePageFlip) + continue; + + if (pMainPanel && ctrl->getParentPanel() != pMainPanel) + continue; + + ctrl->UpdateControl(); + S32 cx = ctrl->getXPos() + panelOffsetX; + S32 cy = ctrl->getYPos() + panelOffsetY; + S32 cw = ctrl->getWidth(); + S32 ch = ctrl->getHeight(); + if (cw <= 0 || ch <= 0) + continue; + + if (x >= cx && x <= cx + cw && y >= cy && y <= cy + ch) + { + S32 area = cw * ch; + if (area < bestArea) + { + bestArea = area; + bestId = ctrl->getId(); + bestCtrl = ctrl; + } + } + } + + if (bestId >= 0 && bestCtrl) + { + if (bestCtrl->getControlType() == UIControl::eCheckBox) + { + UIControl_CheckBox *cb = static_cast(bestCtrl); + if (cb->IsEnabled()) + { + bool newState = !cb->IsChecked(); + cb->setChecked(newState); + handleCheckboxToggled((F64)bestId, newState); + } + } + else + { + handlePress((F64)bestId, 0); + } + return true; + } + return false; +} +#endif + +void UIScene::addTimer(int id, int ms) +{ + int currentTime = System::currentTimeMillis(); + + TimerInfo info; + info.running = true; + info.duration = ms; + info.targetTime = currentTime + ms; + m_timers[id] = info; +} + +void UIScene::killTimer(int id) +{ + auto it = m_timers.find(id); + if(it != m_timers.end()) + { + it->second.running = false; + } +} + +void UIScene::tickTimers() +{ + int currentTime = System::currentTimeMillis(); + for (auto it = m_timers.begin(); it != m_timers.end();) + { + if(!it->second.running) + { + it = m_timers.erase(it); + } + else + { + if(currentTime > it->second.targetTime) + { + handleTimerComplete(it->first); + + // Auto-restart + it->second.targetTime = it->second.duration + currentTime; + } + ++it; + } + } +} + +IggyName UIScene::registerFastName(const wstring &name) +{ + IggyName var; + auto it = m_fastNames.find(name); + if(it != m_fastNames.end()) + { + var = it->second; + } + else + { + var = IggyPlayerCreateFastName ( getMovie() , (IggyUTF16 *)name.c_str() , -1 ); + m_fastNames[name] = var; + } + return var; +} + +void UIScene::removeControl( UIControl_Base *control, bool centreScene) +{ + IggyDataValue result; + IggyDataValue value[2]; + + string name = control->getControlName(); + IggyStringUTF8 stringVal; + stringVal.string = (char*)name.c_str(); + stringVal.length = name.length(); + value[0].type = IGGY_DATATYPE_string_UTF8; + value[0].string8 = stringVal; + + value[1].type = IGGY_DATATYPE_boolean; + value[1].boolval = centreScene; + IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcRemoveObject , 2 , value ); + +#ifdef __PSVITA__ + // update the button positions since they may have changed + UpdateSceneControls(); + + // remove it from the touchboxes + ui.TouchBoxRebuild(control->getParentScene()); +#endif + + // mark the button as removed so hover/touch hit-tests skip it + control->setHidden(true); + +} + +void UIScene::slideLeft() +{ + IggyDataValue result; + IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSlideLeft , 0 , nullptr ); +} + +void UIScene::slideRight() +{ + IggyDataValue result; + IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSlideRight , 0 , nullptr ); +} + +void UIScene::doHorizontalResizeCheck() +{ + IggyDataValue result; + IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcHorizontalResizeCheck , 0 , nullptr ); +} + +void UIScene::render(S32 width, S32 height, C4JRender::eViewportType viewport) +{ + if(m_bIsReloading) return; + if(!m_hasTickedOnce || !swf) return; + + if(viewport != C4JRender::VIEWPORT_TYPE_FULLSCREEN) + { + F32 originX, originY, viewW, viewH; + GetViewportRect(ui.getScreenWidth(), ui.getScreenHeight(), viewport, originX, originY, viewW, viewH); + S32 fitW, fitH, offsetX, offsetY; + Fit16x9(viewW, viewH, fitW, fitH, offsetX, offsetY); + ui.setupRenderPosition(static_cast(originX) + offsetX, static_cast(originY) + offsetY); + IggyPlayerSetDisplaySize( swf, fitW, fitH ); + IggyPlayerDraw( swf ); + } + else + { + ui.setupRenderPosition(viewport); + IggyPlayerSetDisplaySize( swf, width, height ); + IggyPlayerDraw( swf ); + } +} + +void UIScene::setOpacity(float percent) +{ + if(percent != m_lastOpacity || (m_bUpdateOpacity && getMovie())) + { + m_lastOpacity = percent; + + // 4J-TomK once a scene has been freshly loaded or re-loaded we force update opacity via initialiseMovie + if(m_bUpdateOpacity) + m_bUpdateOpacity = false; + + IggyDataValue result; + IggyDataValue value[1]; + value[0].type = IGGY_DATATYPE_number; + value[0].number = percent; + + IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetAlpha , 1 , value ); + } +} + +void UIScene::setVisible(bool visible) +{ + m_bVisible = visible; +} + +void UIScene::customDraw(IggyCustomDrawCallbackRegion *region) +{ + //app.DebugPrintf("Handling custom draw for scene with no override!\n"); +} + +void UIScene::customDrawSlotControl(IggyCustomDrawCallbackRegion *region, int iPad, shared_ptr item, float fAlpha, bool isFoil, bool bDecorations) +{ + if (item!= nullptr) + { + bool useCommandBuffers = false; +#ifdef _XBOX_ONE + useCommandBuffers = true; + + m_needsCacheRendered = true; +#endif + + bool shouldCacheSlotRender = m_cacheSlotRenders && (m_needsCacheRendered || useCommandBuffers); + if(shouldCacheSlotRender) + { + if( (m_cachedSlotDraw.size() + 1) == m_expectedCachedSlotCount) + { + //Make sure that pMinecraft->player is the correct player so that player specific rendering + // eg clock and compass, are rendered correctly + Minecraft *pMinecraft=Minecraft::GetInstance(); + shared_ptr oldPlayer = pMinecraft->player; + if( iPad >= 0 && iPad < XUSER_MAX_COUNT ) pMinecraft->player = pMinecraft->localplayers[iPad]; + + // Setup GDraw, normal game render states and matrices + //CustomDrawData *customDrawRegion = ui.setupCustomDraw(this,region); + PIXBeginNamedEvent(0,"Starting Iggy custom draw\n"); + CustomDrawData *customDrawRegion = ui.calculateCustomDraw(region); + ui.beginIggyCustomDraw4J(region, customDrawRegion); + ui.setupCustomDrawGameState(); + + int list = m_parentLayer->m_parentGroup->getCommandBufferList(); + + if(!useCommandBuffers || m_needsCacheRendered) + { +#if (!defined __PS3__) && (!defined __PSVITA__) + if(useCommandBuffers) RenderManager.CBuffStart(list, true); +#endif + PIXBeginNamedEvent(0,"Draw uncached"); + ui.setupCustomDrawMatrices(this, customDrawRegion); + _customDrawSlotControl(customDrawRegion, iPad, item, fAlpha, isFoil, bDecorations, useCommandBuffers); + delete customDrawRegion; + PIXEndNamedEvent(); + + PIXBeginNamedEvent(0,"Draw all cache"); + // Draw all the cached slots + for(auto& drawData : m_cachedSlotDraw) + { + ui.setupCustomDrawMatrices(this, drawData->customDrawRegion); + _customDrawSlotControl(drawData->customDrawRegion, iPad, drawData->item, drawData->fAlpha, drawData->isFoil, drawData->bDecorations, useCommandBuffers); + delete drawData->customDrawRegion; + delete drawData; + } + PIXEndNamedEvent(); +#ifndef __PS3__ + if(useCommandBuffers) RenderManager.CBuffEnd(); +#endif + } + m_cachedSlotDraw.clear(); + +#ifndef __PS3__ + if(useCommandBuffers) RenderManager.CBuffCall(list); +#endif + + // Finish GDraw and anything else that needs to be finalised + ui.endCustomDraw(region); + + pMinecraft->player = oldPlayer; + } + else + { + PIXBeginNamedEvent(0,"Caching region"); + CachedSlotDrawData *drawData = new CachedSlotDrawData(); + drawData->item = item; + drawData->fAlpha = fAlpha; + drawData->isFoil = isFoil; + drawData->bDecorations = bDecorations; + drawData->customDrawRegion = ui.calculateCustomDraw(region); + + m_cachedSlotDraw.push_back(drawData); + PIXEndNamedEvent(); + } + } + else + { + // Setup GDraw, normal game render states and matrices + CustomDrawData *customDrawRegion = ui.setupCustomDraw(this,region); + + Minecraft *pMinecraft=Minecraft::GetInstance(); + + //Make sure that pMinecraft->player is the correct player so that player specific rendering + // eg clock and compass, are rendered correctly + shared_ptr oldPlayer = pMinecraft->player; + if( iPad >= 0 && iPad < XUSER_MAX_COUNT ) pMinecraft->player = pMinecraft->localplayers[iPad]; + + _customDrawSlotControl(customDrawRegion, iPad, item, fAlpha, isFoil, bDecorations, false); + delete customDrawRegion; + pMinecraft->player = oldPlayer; + + // Finish GDraw and anything else that needs to be finalised + ui.endCustomDraw(region); + } + } +} + +void UIScene::_customDrawSlotControl(CustomDrawData *region, int iPad, shared_ptr item, float fAlpha, bool isFoil, bool bDecorations, bool usingCommandBuffer) +{ + Minecraft *pMinecraft=Minecraft::GetInstance(); + + float bwidth,bheight; + bwidth = region->x1 - region->x0; + bheight = region->y1 - region->y0; + + float x = region->x0; + float y = region->y0; + + // Base scale on height of this control, compared to height of what the item renderer normally renders (16 pixels high). Potentially + // we might want separate x & y scales here + + float scaleX = bwidth / 16.0f; + float scaleY = bheight / 16.0f; + + glEnable(GL_RESCALE_NORMAL); + glPushMatrix(); + glRotatef(120, 1, 0, 0); + Lighting::turnOn(); + glPopMatrix(); + + float pop = item->popTime; + if (pop > 0) + { + glPushMatrix(); + float squeeze = 1 + pop / static_cast(Inventory::POP_TIME_DURATION); + float sx = x; + float sy = y; + float sxoffs = 8 * scaleX; + float syoffs = 12 * scaleY; + glTranslatef((float)(sx + sxoffs), (float)(sy + syoffs), 0); + glScalef(1 / squeeze, (squeeze + 1) / 2, 1); + glTranslatef((float)-(sx + sxoffs), (float)-(sy + syoffs), 0); + } + + PIXBeginNamedEvent(0,"Render and decorate"); + if(m_pItemRenderer == nullptr) m_pItemRenderer = new ItemRenderer(); + RenderManager.StateSetBlendEnable(true); + RenderManager.StateSetBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + RenderManager.StateSetBlendFactor(0xffffffff); + m_pItemRenderer->renderAndDecorateItem(pMinecraft->font, pMinecraft->textures, item, x, y,scaleX,scaleY,fAlpha,isFoil,false, !usingCommandBuffer); + PIXEndNamedEvent(); + + if (pop > 0) + { + glPopMatrix(); + } + + if(bDecorations) + { + if((scaleX!=1.0f) ||(scaleY!=1.0f)) + { + glPushMatrix(); + glScalef(scaleX, scaleY, 1.0f); + int iX= static_cast(0.5f + ((float)x) / scaleX); + int iY= static_cast(0.5f + ((float)y) / scaleY); + + m_pItemRenderer->renderGuiItemDecorations(pMinecraft->font, pMinecraft->textures, item, iX, iY, fAlpha); + glPopMatrix(); + } + else + { + m_pItemRenderer->renderGuiItemDecorations(pMinecraft->font, pMinecraft->textures, item, static_cast(x), static_cast(y), fAlpha); + } + } + + Lighting::turnOff(); + glDisable(GL_RESCALE_NORMAL); +} + +// 4J Stu - Not threadsafe +//void UIScene::navigateForward(int iPad, EUIScene scene, void *initData) +//{ +// if(m_parentLayer == nullptr) +// { +// app.DebugPrintf("A scene is trying to navigate forwards, but it's parent layer is nullptr!\n"); +// } +// else +// { +// m_parentLayer->NavigateToScene(iPad,scene,initData); +// } +//} + +void UIScene::navigateBack() +{ + //CD - Added for audio + ui.PlayUISFX(eSFX_Back); + + ui.NavigateBack(m_iPad); + + if(m_parentLayer == nullptr) + { + } + else + { +// m_parentLayer->removeScene(this); + +#ifdef _DURANGO + if (ui.GetTopScene(0)) + InputManager.SetEnabledGtcButtons( ui.GetTopScene(0)->getDefaultGtcButtons() ); +#endif + } + +} + +void UIScene::gainFocus() +{ + if( !bHasFocus && stealsFocus() ) + { + // 4J Stu - Don't do this + /* + IggyEvent event; + IggyMakeEventFocusGained( &event , 0); + + IggyEventResult result; + IggyPlayerDispatchEventRS( getMovie() , &event , &result ); + + app.DebugPrintf("Sent gain focus event to scene\n"); + */ + bHasFocus = true; + if(needsReloaded()) + { + reloadMovie(); + } + + updateTooltips(); + updateComponents(); + + if(!m_bFocussedOnce) + { + IggyDataValue result; + IggyDataValue value[1]; + + value[0].type = IGGY_DATATYPE_number; + value[0].number = -1; + + IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetFocus , 1 , value ); + } + + handleGainFocus(m_bFocussedOnce); + if(bHasFocus) m_bFocussedOnce = true; + } + else if(bHasFocus && stealsFocus()) + { + updateTooltips(); + } +} + +void UIScene::loseFocus() +{ + if(bHasFocus) + { + // 4J Stu - Don't do this + /* + IggyEvent event; + IggyMakeEventFocusLost( &event ); + IggyEventResult result; + IggyPlayerDispatchEventRS ( getMovie() , &event , &result ); + */ + + app.DebugPrintf("Sent lose focus event to scene\n"); + bHasFocus = false; + handleLoseFocus(); + } +} + +void UIScene::handleGainFocus(bool navBack) +{ +#ifdef _DURANGO + InputManager.SetEnabledGtcButtons( this->getDefaultGtcButtons() ); +#endif +} + +void UIScene::updateTooltips() +{ + if(!ui.IsReloadingSkin()) + ui.SetTooltips(m_iPad, -1); +} + +void UIScene::sendInputToMovie(int key, bool repeat, bool pressed, bool released) +{ + if(!swf) return; + + int iggyKeyCode = convertGameActionToIggyKeycode(key); + + if(iggyKeyCode < 0) + { + app.DebugPrintf("UI WARNING: Ignoring input as game action does not translate to an Iggy keycode\n"); + return; + } + +#ifdef _WINDOWS64 + // If a navigation key is pressed with no focused element, focus the first + // available one so arrow keys work even when the mouse is over empty space. + if(pressed && (iggyKeyCode == IGGY_KEYCODE_UP || iggyKeyCode == IGGY_KEYCODE_DOWN || + iggyKeyCode == IGGY_KEYCODE_LEFT || iggyKeyCode == IGGY_KEYCODE_RIGHT)) + { + IggyFocusHandle currentFocus = IGGY_FOCUS_NULL; + IggyFocusableObject focusables[64]; + S32 numFocusables = 0; + IggyPlayerGetFocusableObjects(swf, ¤tFocus, focusables, 64, &numFocusables); + if(currentFocus == IGGY_FOCUS_NULL && numFocusables > 0) + { + IggyPlayerSetFocusRS(swf, focusables[0].object, 0); + return; + } + } +#endif + + IggyEvent keyEvent; + // 4J Stu - Keyloc is always standard as we don't care about shift/alt + IggyMakeEventKey( &keyEvent, pressed?IGGY_KEYEVENT_Down:IGGY_KEYEVENT_Up, static_cast(iggyKeyCode), IGGY_KEYLOC_Standard ); + + IggyEventResult result; + IggyPlayerDispatchEventRS ( swf , &keyEvent , &result ); +} + +int UIScene::convertGameActionToIggyKeycode(int action) +{ + // TODO: This action to key mapping should probably use the control mapping + int keycode = -1; + switch(action) + { +#ifdef __ORBIS__ + case ACTION_MENU_TOUCHPAD_PRESS: +#endif + case ACTION_MENU_A: + keycode = IGGY_KEYCODE_ENTER; + break; + case ACTION_MENU_B: + keycode = IGGY_KEYCODE_ESCAPE; + break; + case ACTION_MENU_X: + keycode = IGGY_KEYCODE_F1; + break; + case ACTION_MENU_Y: + keycode = IGGY_KEYCODE_F2; + break; + case ACTION_MENU_OK: + keycode = IGGY_KEYCODE_ENTER; + break; + case ACTION_MENU_CANCEL: + keycode = IGGY_KEYCODE_ESCAPE; + break; + case ACTION_MENU_UP: + keycode = IGGY_KEYCODE_UP; + break; + case ACTION_MENU_DOWN: + keycode = IGGY_KEYCODE_DOWN; + break; + case ACTION_MENU_RIGHT: + keycode = IGGY_KEYCODE_RIGHT; + break; + case ACTION_MENU_LEFT: + keycode = IGGY_KEYCODE_LEFT; + break; + case ACTION_MENU_PAGEUP: + keycode = IGGY_KEYCODE_PAGE_UP; + break; + case ACTION_MENU_PAGEDOWN: +#ifdef __PSVITA__ + if (!InputManager.IsVitaTV()) + { + keycode = IGGY_KEYCODE_F6; + } + else +#endif + { + keycode = IGGY_KEYCODE_PAGE_DOWN; + } + break; + case ACTION_MENU_RIGHT_SCROLL: + keycode = IGGY_KEYCODE_F3; + break; + case ACTION_MENU_LEFT_SCROLL: + keycode = IGGY_KEYCODE_F4; + break; + case ACTION_MENU_STICK_PRESS: + break; + case ACTION_MENU_OTHER_STICK_PRESS: + keycode = IGGY_KEYCODE_F5; + break; + case ACTION_MENU_OTHER_STICK_UP: + keycode = IGGY_KEYCODE_F11; + break; + case ACTION_MENU_OTHER_STICK_DOWN: + keycode = IGGY_KEYCODE_F12; + break; + case ACTION_MENU_OTHER_STICK_LEFT: + break; + case ACTION_MENU_OTHER_STICK_RIGHT: + break; + }; + + return keycode; +} + +bool UIScene::allowRepeat(int key) +{ + // 4J-PB - ignore repeats of action ABXY buttons + // fix for PS3 213 - [MAIN MENU] Holding down buttons will continue to activate every prompt. + switch(key) + { + case ACTION_MENU_OK: + case ACTION_MENU_CANCEL: + case ACTION_MENU_A: + case ACTION_MENU_B: + case ACTION_MENU_X: + case ACTION_MENU_Y: + return false; + } + return true; +} + +void UIScene::externalCallback(IggyExternalFunctionCallUTF16 * call) +{ + if(wcscmp((wchar_t *)call->function_name.string,L"handlePress")==0) + { + if(call->num_arguments != 2) + { + app.DebugPrintf("Callback for handlePress did not have the correct number of arguments\n"); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + if(call->arguments[0].type != IGGY_DATATYPE_number || call->arguments[1].type != IGGY_DATATYPE_number) + { + app.DebugPrintf("Arguments for handlePress were not of the correct type\n"); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + handlePress(call->arguments[0].number, call->arguments[1].number); + } + else if(wcscmp((wchar_t *)call->function_name.string,L"handleFocusChange")==0) + { + if(call->num_arguments != 2) + { + app.DebugPrintf("Callback for handleFocusChange did not have the correct number of arguments\n"); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + if(call->arguments[0].type != IGGY_DATATYPE_number || call->arguments[1].type != IGGY_DATATYPE_number) + { + app.DebugPrintf("Arguments for handleFocusChange were not of the correct type\n"); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + _handleFocusChange(call->arguments[0].number, call->arguments[1].number); + } + else if(wcscmp((wchar_t *)call->function_name.string,L"handleInitFocus")==0) + { + if(call->num_arguments != 2) + { + app.DebugPrintf("Callback for handleInitFocus did not have the correct number of arguments\n"); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + if(call->arguments[0].type != IGGY_DATATYPE_number || call->arguments[1].type != IGGY_DATATYPE_number) + { + app.DebugPrintf("Arguments for handleInitFocus were not of the correct type\n"); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + _handleInitFocus(call->arguments[0].number, call->arguments[1].number); + } + else if(wcscmp((wchar_t *)call->function_name.string,L"handleCheckboxToggled")==0) + { + if(call->num_arguments < 2 || call->num_arguments > 3) + { + app.DebugPrintf("Callback for handleCheckboxToggled did not have the correct number of arguments (%d)\n", call->num_arguments); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + if(call->arguments[0].type != IGGY_DATATYPE_number) + { + app.DebugPrintf("Arguments for handleCheckboxToggled were not of the correct type\n"); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + int selArg = (call->num_arguments == 3) ? 2 : 1; + if(call->arguments[selArg].type != IGGY_DATATYPE_boolean && call->arguments[selArg].type != IGGY_DATATYPE_number) + { + app.DebugPrintf("Arguments for handleCheckboxToggled were not of the correct type\n"); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + bool selected = (call->arguments[selArg].type == IGGY_DATATYPE_boolean) + ? call->arguments[selArg].boolval + : (call->arguments[selArg].number != 0); + handleCheckboxToggled(call->arguments[0].number, selected); + } + else if(wcscmp((wchar_t *)call->function_name.string,L"handleSliderMove")==0) + { + if(call->num_arguments < 2 || call->num_arguments > 3) + { + app.DebugPrintf("Callback for handleSliderMove did not have the correct number of arguments (%d)\n", call->num_arguments); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + if(call->arguments[0].type != IGGY_DATATYPE_number) + { + app.DebugPrintf("Arguments for handleSliderMove were not of the correct type\n"); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + int idArg = 0; + int valArg = (call->num_arguments == 3) ? 2 : 1; + if(call->num_arguments == 3) idArg = 1; + if(call->arguments[valArg].type != IGGY_DATATYPE_number) + { + app.DebugPrintf("Arguments for handleSliderMove were not of the correct type\n"); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + handleSliderMove(call->arguments[idArg].number, call->arguments[valArg].number); + } + else if(wcscmp((wchar_t *)call->function_name.string,L"handleAnimationEnd")==0) + { + if(call->num_arguments != 0) + { + app.DebugPrintf("Callback for handleAnimationEnd did not have the correct number of arguments\n"); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + handleAnimationEnd(); + } + else if(wcscmp((wchar_t *)call->function_name.string,L"handleSelectionChanged")==0) + { + if(call->num_arguments != 1) + { + app.DebugPrintf("Callback for handleSelectionChanged did not have the correct number of arguments\n"); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + if(call->arguments[0].type != IGGY_DATATYPE_number) + { + app.DebugPrintf("Arguments for handleSelectionChanged were not of the correct type\n"); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + handleSelectionChanged(call->arguments[0].number); + } + else if(wcscmp((wchar_t *)call->function_name.string,L"handleRequestMoreData")==0) + { + if(call->num_arguments == 0) + { + handleRequestMoreData(0,false); + } + else + { + if(call->num_arguments != 2) + { + app.DebugPrintf("Callback for handleRequestMoreData did not have the correct number of arguments\n"); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + if(call->arguments[0].type != IGGY_DATATYPE_number || call->arguments[1].type != IGGY_DATATYPE_boolean) + { + app.DebugPrintf("Arguments for handleRequestMoreData were not of the correct type\n"); +#ifndef _CONTENT_PACKAGE + DEBUG_BREAK(); +#endif + return; + } + handleRequestMoreData(call->arguments[0].number, call->arguments[1].boolval); + } + } + else if(wcscmp((wchar_t *)call->function_name.string,L"handleTouchBoxRebuild")==0) + { + handleTouchBoxRebuild(); + } + else + { + app.DebugPrintf("Unhandled callback: %s\n", call->function_name.string); + } +} + +void UIScene::registerSubstitutionTexture(const wstring &textureName, PBYTE pbData, DWORD dwLength, bool deleteData) +{ + m_registeredTextures[textureName] = deleteData;; + ui.registerSubstitutionTexture(textureName, pbData, dwLength); +} + +bool UIScene::hasRegisteredSubstitutionTexture(const wstring &textureName) +{ + auto it = m_registeredTextures.find(textureName); + + return it != m_registeredTextures.end(); +} + +void UIScene::_handleFocusChange(F64 controlId, F64 childId) +{ + int newControl = static_cast(controlId); + int newChild = static_cast(childId); + if (newControl != m_iFocusControl || newChild != m_iFocusChild) + { + m_iFocusControl = newControl; + m_iFocusChild = newChild; + + handleFocusChange(controlId, childId); + ui.PlayUISFX(eSFX_Focus); + } +} + +void UIScene::_handleInitFocus(F64 controlId, F64 childId) +{ + m_iFocusControl = static_cast(controlId); + m_iFocusChild = static_cast(childId); + + //handleInitFocus(controlId, childId); + handleFocusChange(controlId, childId); +} + +bool UIScene::controlHasFocus(int iControlId) +{ + return m_iFocusControl == iControlId; +} + +bool UIScene::controlHasFocus(UIControl_Base *control) +{ + return controlHasFocus( control->getId() ); +} + +int UIScene::getControlChildFocus() +{ + return m_iFocusChild; +} + +int UIScene::getControlFocus() +{ + return m_iFocusControl; +} + +void UIScene::setBackScene(UIScene *scene) +{ + m_backScene = scene; +} + +UIScene *UIScene::getBackScene() +{ + return m_backScene; +} +#ifdef __PSVITA__ +void UIScene::UpdateSceneControls() +{ + for ( UIControl *control : *GetControls() ) + { + control->UpdateControl(); + } +} +#endif + +void UIScene::HandleMessage(EUIMessage message, void *data) +{ +} + +size_t UIScene::GetCallbackUniqueId() +{ + if( m_callbackUniqueId == 0) + { + m_callbackUniqueId = ui.RegisterForCallbackId(this); + } + return m_callbackUniqueId; +} + +bool UIScene::isReadyToDelete() +{ + return true; +} diff --git a/Minecraft.Client/Common/UI/UIScene.h b/Minecraft.Client/Common/UI/UIScene.h index e232e48d..59502a5b 100644 --- a/Minecraft.Client/Common/UI/UIScene.h +++ b/Minecraft.Client/Common/UI/UIScene.h @@ -89,6 +89,7 @@ protected: bool m_bIsReloading; bool m_bFocussedOnce; + bool m_bPanoramaUsesDefaultPlatformSkin; int m_movieWidth, m_movieHeight; int m_renderWidth, m_renderHeight; diff --git a/Minecraft.Client/Common/UI/UIScene_BeaconMenu.cpp b/Minecraft.Client/Common/UI/UIScene_BeaconMenu.cpp index ee8f6ade..1f905670 100644 --- a/Minecraft.Client/Common/UI/UIScene_BeaconMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_BeaconMenu.cpp @@ -342,10 +342,10 @@ void UIScene_BeaconMenu::customDraw(IggyCustomDrawCallbackRegion *region) item = std::make_shared(Item::diamond); break; case 2: - item = std::make_shared(Item::goldIngot); + item = std::make_shared(Item::gold_ingot); break; case 3: - item = std::make_shared(Item::ironIngot); + item = std::make_shared(Item::iron_ingot); break; default: assert(false); diff --git a/Minecraft.Client/Common/UI/UIScene_ControlsMenu.cpp b/Minecraft.Client/Common/UI/UIScene_ControlsMenu.cpp index dc747a63..0beff3d2 100644 --- a/Minecraft.Client/Common/UI/UIScene_ControlsMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_ControlsMenu.cpp @@ -13,7 +13,9 @@ UIScene_ControlsMenu::UIScene_ControlsMenu(int iPad, void *initData, UILayer *pa IggyDataValue value[1]; value[0].type = IGGY_DATATYPE_number; #if defined(_XBOX) || defined(_WIN64) - value[0].number = static_cast(0); + int controlType = app.GetGameSettings(m_iPad, eGameSetting_ControlType); + static const int platformMap[] = {0, 1, 0, 2, 3, 5}; + value[0].number = static_cast(platformMap[controlType]); #elif defined(_DURANGO) value[0].number = (F64)1; #elif defined(__PS3__) @@ -55,6 +57,16 @@ UIScene_ControlsMenu::UIScene_ControlsMenu(int iPad, void *initData, UILayer *pa m_checkboxInvert.init(app.GetString(IDS_INVERT_LOOK), eControl_InvertLook, app.GetGameSettings(m_iPad,eGameSetting_ControlInvertLook)); m_checkboxSouthpaw.init(app.GetString(IDS_SOUTHPAW), eControl_Southpaw, app.GetGameSettings(m_iPad,eGameSetting_ControlSouthPaw)); + m_checkboxSafeCam.init(app.GetString(IDS_SAFE_SPRINT), eControl_SafeCam, app.GetGameSettings(m_iPad,eGameSetting_SafeCam)); + m_checkboxAbswap.init(app.GetString(IDS_SWAP), eControl_ABSwap, app.GetGameSettings(m_iPad,eGameSetting_Swap)); + + { + IggyDataValue result; + IggyDataValue value[1]; + value[0].type = IGGY_DATATYPE_boolean; + value[0].boolval = 0; + IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcSetABSwapCheckBox, 1, value); + } m_iSchemeTextA[0]=IDS_CONTROLS_SCHEME0; m_iSchemeTextA[1]=IDS_CONTROLS_SCHEME1; @@ -96,11 +108,7 @@ UIScene_ControlsMenu::UIScene_ControlsMenu(int iPad, void *initData, UILayer *pa if (InputManager.IsVitaTV()) m_iCurrentNavigatedControlsLayout = 1; #endif - for(unsigned int i = 0; i < e_PadCOUNT; ++i) - { - m_labelsPad[i].init(L""); - m_controlLines[i].setVisible(false); - } + m_parentLayer->showComponent(m_iPad, eUIComponent_Logo, false); m_bLayoutChanged = false; @@ -189,6 +197,14 @@ void UIScene_ControlsMenu::handleCheckboxToggled(F64 controlId, bool selected) app.SetGameSettings(m_iPad,eGameSetting_ControlSouthPaw,(unsigned char)( selected ) ); PositionAllText(m_iPad); break; + case eControl_SafeCam: + app.SetGameSettings(m_iPad,eGameSetting_SafeCam,(unsigned char)( selected ) ); + m_bLayoutChanged = true; + break; + case eControl_ABSwap: + app.SetGameSettings(m_iPad,eGameSetting_Swap,(unsigned char)( selected ) ); + m_bLayoutChanged = true; + break; }; } @@ -230,11 +246,8 @@ void UIScene_ControlsMenu::handleFocusChange(F64 controlId, F64 childId) void UIScene_ControlsMenu::PositionAllText(int iPad) { - for(unsigned int i = 0; i < e_PadCOUNT; ++i) - { - m_labelsPad[i].setLabel(L""); - m_controlLines[i].setVisible(false); - } + IggyDataValue result; + IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcClearAllKeyLines, 0, 0); if(m_bCreativeMode) { @@ -331,6 +344,20 @@ void UIScene_ControlsMenu::PositionTextDirect(int iPad,int iTextID, int iControl { LPCWSTR text = app.GetString(iTextID); - m_labelsPad[iControlDetailsIndex].setLabel(text); - m_controlLines[iControlDetailsIndex].setVisible(bShow); + IggyDataValue result; + IggyDataValue value[3]; + + value[0].type = IGGY_DATATYPE_number; + value[0].number = static_cast(iControlDetailsIndex); + + IggyStringUTF16 stringVal; + stringVal.string = (IggyUTF16*)text; + stringVal.length = (int)wcslen(text); + value[1].type = IGGY_DATATYPE_string_UTF16; + value[1].string16 = stringVal; + + value[2].type = IGGY_DATATYPE_boolean; + value[2].boolval = bShow ? 1 : 0; + + IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcSetLineAndText, 3, value); } \ No newline at end of file diff --git a/Minecraft.Client/Common/UI/UIScene_ControlsMenu.h b/Minecraft.Client/Common/UI/UIScene_ControlsMenu.h index 538207fe..3f917d06 100644 --- a/Minecraft.Client/Common/UI/UIScene_ControlsMenu.h +++ b/Minecraft.Client/Common/UI/UIScene_ControlsMenu.h @@ -13,6 +13,8 @@ private: eControl_Button2, eControl_InvertLook, eControl_Southpaw, + eControl_SafeCam, + eControl_ABSwap, }; enum EPadButtons @@ -47,11 +49,11 @@ private: UIControl_Label m_labelCurrentLayout; UIControl_Label m_labelVersion; - UIControl_Label m_labelsPad[e_PadCOUNT]; - UIControl m_controlLines[e_PadCOUNT]; UIControl_Button m_buttonLayouts[3]; - UIControl_CheckBox m_checkboxInvert, m_checkboxSouthpaw; + UIControl_CheckBox m_checkboxInvert, m_checkboxSouthpaw, m_checkboxSafeCam, m_checkboxAbswap; IggyName m_funcSetPlatform, m_funcSetControllerLayout; + IggyName m_funcSetLineAndText, m_funcClearAllKeyLines; + IggyName m_funcSetABSwapCheckBox, m_funcRemoveSafeSprint; UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) #ifndef __PSVITA__ @@ -67,51 +69,17 @@ private: } #endif - UI_MAP_ELEMENT( m_labelsPad[e_PadBack], "LabelBack") - UI_MAP_ELEMENT( m_labelsPad[e_PadLT], "LabelLT") - UI_MAP_ELEMENT( m_labelsPad[e_PadLB], "LabelLB") - UI_MAP_ELEMENT( m_labelsPad[e_PadDPadLeft], "LabelDPadLeft") - UI_MAP_ELEMENT( m_labelsPad[e_PadDPadRight], "LabelDPadRight") - UI_MAP_ELEMENT( m_labelsPad[e_PadDPadUp], "LabelDPadUp") - UI_MAP_ELEMENT( m_labelsPad[e_PadDPadDown], "LabelDPadDown") - UI_MAP_ELEMENT( m_labelsPad[e_PadLS_1], "LabelLS_1") - UI_MAP_ELEMENT( m_labelsPad[e_PadLS_2], "LabelLS_2") - UI_MAP_ELEMENT( m_labelsPad[e_PadStart], "LabelStart") - UI_MAP_ELEMENT( m_labelsPad[e_PadRT], "LabelRT") - UI_MAP_ELEMENT( m_labelsPad[e_PadRB], "LabelRB") - UI_MAP_ELEMENT( m_labelsPad[e_PadY], "LabelY") - UI_MAP_ELEMENT( m_labelsPad[e_PadB], "LabelB") - UI_MAP_ELEMENT( m_labelsPad[e_PadA], "LabelA") - UI_MAP_ELEMENT( m_labelsPad[e_PadX], "LabelX") - UI_MAP_ELEMENT( m_labelsPad[e_PadRS_1], "LabelRS_1") - UI_MAP_ELEMENT( m_labelsPad[e_PadRS_2], "LabelRS_2") - UI_MAP_ELEMENT( m_labelsPad[e_PadTouch], "LabelTouch") - - UI_MAP_ELEMENT( m_controlLines[e_PadBack], "LineBack") - UI_MAP_ELEMENT( m_controlLines[e_PadLT], "LineLT") - UI_MAP_ELEMENT( m_controlLines[e_PadLB], "LineLB") - UI_MAP_ELEMENT( m_controlLines[e_PadDPadLeft], "LineDpadLeft") - UI_MAP_ELEMENT( m_controlLines[e_PadDPadRight], "LineDpadRight") - UI_MAP_ELEMENT( m_controlLines[e_PadDPadUp], "LineDpadUp") - UI_MAP_ELEMENT( m_controlLines[e_PadDPadDown], "LineDpadDown") - UI_MAP_ELEMENT( m_controlLines[e_PadLS_1], "LineL3") - UI_MAP_ELEMENT( m_controlLines[e_PadLS_2], "LineLeftStick") - UI_MAP_ELEMENT( m_controlLines[e_PadStart], "LineStart") - UI_MAP_ELEMENT( m_controlLines[e_PadRT], "LineRT") - UI_MAP_ELEMENT( m_controlLines[e_PadRB], "LineRB") - UI_MAP_ELEMENT( m_controlLines[e_PadY], "LineY") - UI_MAP_ELEMENT( m_controlLines[e_PadB], "LineB") - UI_MAP_ELEMENT( m_controlLines[e_PadA], "LineA") - UI_MAP_ELEMENT( m_controlLines[e_PadX], "LineX") - UI_MAP_ELEMENT( m_controlLines[e_PadRS_1], "LineR3") - UI_MAP_ELEMENT( m_controlLines[e_PadRS_2], "LineRightStick") - UI_MAP_ELEMENT( m_controlLines[e_PadTouch], "LineTouch") - UI_MAP_ELEMENT( m_checkboxInvert, "InvertLook") UI_MAP_ELEMENT( m_checkboxSouthpaw, "SouthPaw") + UI_MAP_ELEMENT( m_checkboxSafeCam, "SafeCam") + UI_MAP_ELEMENT( m_checkboxAbswap, "ABSwap") UI_MAP_NAME( m_funcSetPlatform, L"SetPlatform") UI_MAP_NAME( m_funcSetControllerLayout, L"SetControllerLayout") + UI_MAP_NAME( m_funcSetLineAndText, L"SetLineAndText") + UI_MAP_NAME( m_funcClearAllKeyLines, L"ClearAllKeyLines") + UI_MAP_NAME( m_funcSetABSwapCheckBox, L"SetABSwapCheckBox") + UI_MAP_NAME( m_funcRemoveSafeSprint, L"RemoveSafeSprint") UI_MAP_ELEMENT( m_labelVersion, "Version") UI_END_MAP_ELEMENTS_AND_NAMES() public: diff --git a/Minecraft.Client/Common/UI/UIScene_HelpAndOptionsMenu.cpp b/Minecraft.Client/Common/UI/UIScene_HelpAndOptionsMenu.cpp index d876de53..b0b7e055 100644 --- a/Minecraft.Client/Common/UI/UIScene_HelpAndOptionsMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_HelpAndOptionsMenu.cpp @@ -135,6 +135,7 @@ void UIScene_HelpAndOptionsMenu::handleReload() { // We should show the reinstall menu app.DebugPrintf("Reinstall Menu required...\n"); + removeControl( &m_buttons[BUTTON_HAO_REINSTALL], false); } else { diff --git a/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp b/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp index d38d42fc..92ab7e58 100644 --- a/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp @@ -131,6 +131,7 @@ void UIScene_JoinMenu::updateTooltips() void UIScene_JoinMenu::tick() { + if (this == nullptr) return; if (!m_friendInfoRequestIssued) { ui.NavigateToScene(m_iPad, eUIScene_Timer); diff --git a/Minecraft.Client/Common/UI/UIScene_LanguageSelector.cpp b/Minecraft.Client/Common/UI/UIScene_LanguageSelector.cpp index c2a30d3c..c7c2816a 100644 --- a/Minecraft.Client/Common/UI/UIScene_LanguageSelector.cpp +++ b/Minecraft.Client/Common/UI/UIScene_LanguageSelector.cpp @@ -37,6 +37,7 @@ UIScene_LanguageSelector::UIScene_LanguageSelector(int iPad, void *initData, UIL // Setup all the Iggy references we need for this scene initialiseMovie(); + m_bNeedsLanguageReload = false; m_buttonListHowTo.init(eControl_Buttons); for(unsigned int i = 0; i < eLanguageSelector_MAX; ++i) @@ -51,6 +52,18 @@ wstring UIScene_LanguageSelector::getMoviePath() else return L"LanguagesMenu"; } +void UIScene_LanguageSelector::tick() +{ + UIScene::tick(); + + if(m_bNeedsLanguageReload) + { + m_bNeedsLanguageReload = false; + app.loadStringTable(); + reloadMovie(); + } +} + void UIScene_LanguageSelector::updateTooltips() { ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK); @@ -125,5 +138,6 @@ void UIScene_LanguageSelector::handlePress(F64 controlId, F64 childId) app.SetMinecraftLocale(m_iPad, newLocale); app.CheckGameSettingsChanged(true, m_iPad); + m_bNeedsLanguageReload = true; } } \ No newline at end of file diff --git a/Minecraft.Client/Common/UI/UIScene_LanguageSelector.h b/Minecraft.Client/Common/UI/UIScene_LanguageSelector.h index b5c3d4c6..6e54206b 100644 --- a/Minecraft.Client/Common/UI/UIScene_LanguageSelector.h +++ b/Minecraft.Client/Common/UI/UIScene_LanguageSelector.h @@ -83,6 +83,7 @@ private: static const unsigned int m_uiHTPButtonNameA[eLanguageSelector_MAX]; UIControl_DynamicButtonList m_buttonListHowTo; + bool m_bNeedsLanguageReload; UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) UI_MAP_ELEMENT( m_buttonListHowTo, "HowToList") UI_END_MAP_ELEMENTS_AND_NAMES() @@ -92,6 +93,7 @@ public: virtual EUIScene getSceneType() { return eUIScene_LanguageSelector; } + virtual void tick(); virtual void updateTooltips(); virtual void updateComponents(); diff --git a/Minecraft.Client/Common/UI/UIScene_LeaderboardsMenu.cpp b/Minecraft.Client/Common/UI/UIScene_LeaderboardsMenu.cpp index 57f11f45..7272ecfd 100644 --- a/Minecraft.Client/Common/UI/UIScene_LeaderboardsMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_LeaderboardsMenu.cpp @@ -13,7 +13,7 @@ const int UIScene_LeaderboardsMenu::TitleIcons[UIScene_LeaderboardsMenu::NUM_LEA { {UIControl_LeaderboardList::e_ICON_TYPE_WALKED, UIControl_LeaderboardList::e_ICON_TYPE_FALLEN, Item::minecart_Id, Item::boat_Id, -1}, {Tile::dirt_Id, Tile::cobblestone_Id, Tile::sand_Id, Tile::stone_Id, Tile::gravel_Id, Tile::clay_Id, Tile::obsidian_Id}, - {Item::egg_Id, Item::wheat_Id, Tile::mushroom_brown_Id, Tile::reeds_Id, Item::bucket_milk_Id, Tile::pumpkin_Id, -1}, + {Item::egg_Id, Item::wheat_Id, Tile::mushroom_brown_Id, Tile::reeds_Id, Item::milk_bucket_Id, Tile::pumpkin_Id, -1}, {UIControl_LeaderboardList::e_ICON_TYPE_ZOMBIE, UIControl_LeaderboardList::e_ICON_TYPE_SKELETON, UIControl_LeaderboardList::e_ICON_TYPE_CREEPER, UIControl_LeaderboardList::e_ICON_TYPE_SPIDER, UIControl_LeaderboardList::e_ICON_TYPE_SPIDERJOKEY, UIControl_LeaderboardList::e_ICON_TYPE_ZOMBIEPIGMAN, UIControl_LeaderboardList::e_ICON_TYPE_SLIME}, }; const UIScene_LeaderboardsMenu::LeaderboardDescriptor UIScene_LeaderboardsMenu::LEADERBOARD_DESCRIPTORS[UIScene_LeaderboardsMenu::NUM_LEADERBOARDS][4] = { diff --git a/Minecraft.Client/Common/UI/UIScene_LoadCreateJoinMenu.cpp b/Minecraft.Client/Common/UI/UIScene_LoadCreateJoinMenu.cpp index 3ab3ba99..1f1d59fe 100644 --- a/Minecraft.Client/Common/UI/UIScene_LoadCreateJoinMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_LoadCreateJoinMenu.cpp @@ -765,7 +765,7 @@ UIScene_LoadCreateJoinMenu::UIScene_LoadCreateJoinMenu(int iPad, void *initData, m_controlSavesTimer.setVisible( true ); - m_controlNewGameTimer.setVisible( true ); + m_controlNewGameTimer.setVisible( false ); m_controlJoinTimer.setVisible( false ); @@ -2256,23 +2256,7 @@ void UIScene_LoadCreateJoinMenu::tick() - HANDLE hFile = CreateFileW(filePath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, nullptr); - - DWORD fileSize = 0; - - - - if (hFile != INVALID_HANDLE_VALUE) { - - fileSize = GetFileSize(hFile, nullptr); - - if (fileSize < 12 || fileSize == INVALID_FILE_SIZE) fileSize = 0; - - CloseHandle(hFile); - - } - - m_spaceIndicatorSaves.addSave(fileSize); + m_spaceIndicatorSaves.addSave(m_pSaveDetails->SaveInfoA[origIdx].metaData.dataSize); #elif defined(__ORBIS__) @@ -3143,11 +3127,12 @@ void UIScene_LoadCreateJoinMenu::handleInput(int iPad, int key, bool repeat, boo if(StorageManager.EnoughSpaceForAMinSaveGame() && !StorageManager.GetSaveDisabled()) { - UINT uiIDA[3]; + UINT uiIDA[4]; uiIDA[0]=IDS_CONFIRM_CANCEL; uiIDA[1]=IDS_TITLE_RENAMESAVE; uiIDA[2]=IDS_TOOLTIPS_DELETESAVE; - ui.RequestAlertMessage(IDS_TOOLTIPS_SAVEOPTIONS, IDS_TEXT_SAVEOPTIONS, uiIDA, 3, iPad,&UIScene_LoadCreateJoinMenu::SaveOptionsDialogReturned,this); + uiIDA[3]=IDS_COPYSAVE; + ui.RequestAlertMessage(IDS_TOOLTIPS_SAVEOPTIONS, IDS_TEXT_SAVEOPTIONS, uiIDA, 4, iPad,&UIScene_LoadCreateJoinMenu::SaveOptionsDialogReturned,this); } else { @@ -5830,30 +5815,6 @@ int UIScene_LoadCreateJoinMenu::SaveOptionsDialogReturned(void *pParam,int iPad, -#ifdef SONY_REMOTE_STORAGE_UPLOAD - - case C4JStorage::EMessage_ResultFourthOption: // upload to cloud - - { - - UINT uiIDA[2]; - - uiIDA[0]=IDS_CONFIRM_OK; - - uiIDA[1]=IDS_CONFIRM_CANCEL; - - - - ui.RequestAlertMessage(IDS_TOOLTIPS_SAVETRANSFER_UPLOAD, IDS_SAVE_TRANSFER_TEXT, uiIDA, 2, iPad,&UIScene_LoadCreateJoinMenu::SaveTransferDialogReturned,pClass); - - } - - break; - -#endif // SONY_REMOTE_STORAGE_UPLOAD - -#if defined _XBOX_ONE || defined __ORBIS__ - case C4JStorage::EMessage_ResultFourthOption: // copy save { @@ -5872,7 +5833,6 @@ int UIScene_LoadCreateJoinMenu::SaveOptionsDialogReturned(void *pParam,int iPad, break; -#endif @@ -8696,7 +8656,7 @@ void UIScene_LoadCreateJoinMenu::HandleDLCLicenseChange() -#if defined _XBOX_ONE || defined __ORBIS__ +#if defined _XBOX_ONE || defined __ORBIS__ || defined(_WINDOWS64) int UIScene_LoadCreateJoinMenu::CopySaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) @@ -8880,54 +8840,10 @@ int UIScene_LoadCreateJoinMenu::CopySaveDataReturned(LPVOID lpParam, bool succes { -#ifdef __ORBIS__ - - UINT uiIDA[1]; - - // you cancelled the save on exit after choosing exit and save? You go back to the Exit choices then. - - uiIDA[0]=IDS_OK; - - - - if( stat == C4JStorage::ESaveGame_CopyCompleteFailLocalStorage ) - - { - - ui.LeaveCallbackIdCriticalSection(); - - ui.RequestErrorMessage(IDS_COPYSAVE_FAILED_TITLE, IDS_COPYSAVE_FAILED_LOCAL, uiIDA, 1, ProfileManager.GetPrimaryPad(), CopySaveErrorDialogFinishedCallback, lpParam); - - } - - else if( stat == C4JStorage::ESaveGame_CopyCompleteFailQuota ) - - { - - ui.LeaveCallbackIdCriticalSection(); - - ui.RequestErrorMessage(IDS_COPYSAVE_FAILED_TITLE, IDS_COPYSAVE_FAILED_QUOTA, uiIDA, 1, ProfileManager.GetPrimaryPad(), CopySaveErrorDialogFinishedCallback, lpParam); - - } - - else - - { - - pClass->m_bCopying = false; - - ui.LeaveCallbackIdCriticalSection(); - - } - -#else - pClass->m_bCopying = false; ui.LeaveCallbackIdCriticalSection(); -#endif - } } diff --git a/Minecraft.Client/Common/UI/UIScene_LoadCreateJoinMenu.h b/Minecraft.Client/Common/UI/UIScene_LoadCreateJoinMenu.h index 721c298a..54a8199f 100644 --- a/Minecraft.Client/Common/UI/UIScene_LoadCreateJoinMenu.h +++ b/Minecraft.Client/Common/UI/UIScene_LoadCreateJoinMenu.h @@ -398,7 +398,7 @@ private: static int CrossSaveUploadFinishedCallback(void *pParam,int iPad,C4JStorage::EMessageResult result); #endif -#if defined _XBOX_ONE || defined __ORBIS__ +#if defined _XBOX_ONE || defined __ORBIS__ || defined(_WINDOWS64) static int CopySaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result); static int CopySaveThreadProc( LPVOID lpParameter ); static int CopySaveDataReturned( LPVOID lpParameter, bool success, C4JStorage::ESaveGameState state ); diff --git a/Minecraft.Client/Common/UI/UIScene_MainMenu.cpp b/Minecraft.Client/Common/UI/UIScene_MainMenu.cpp index c62dcf46..c0f8b8a1 100644 --- a/Minecraft.Client/Common/UI/UIScene_MainMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_MainMenu.cpp @@ -1,2174 +1,2200 @@ -#include "stdafx.h" -#include "../../../Minecraft.World/Mth.h" -#include "../../../Minecraft.World/StringHelpers.h" -#include "../../../Minecraft.World/Random.h" -#include "../../User.h" -#include "../../MinecraftServer.h" -#include "UI.h" -#include "UIScene_MainMenu.h" -#ifdef __ORBIS__ -#include -#endif - -Random *UIScene_MainMenu::random = new Random(); - -EUIScene UIScene_MainMenu::eNavigateWhenReady = static_cast(-1); - -UIScene_MainMenu::UIScene_MainMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer) -{ -#ifdef __ORBIS - //m_ePatchCheckState=ePatchCheck_Idle; - m_bRunGameChosen=false; - m_bErrorDialogRunning=false; -#endif - - - // Setup all the Iggy references we need for this scene - initialiseMovie(); - - parentLayer->addComponent(iPad,eUIComponent_Panorama); - parentLayer->addComponent(iPad,eUIComponent_Logo); - - m_eAction=eAction_None; - m_bIgnorePress=false; - - - m_buttons[static_cast(eControl_PlayGame)].init(IDS_PLAY_GAME,eControl_PlayGame); - m_buttons[(int)eControl_MiniGames].init(L"Mini Games",eControl_MiniGames); - -#ifdef _XBOX_ONE - if(!ProfileManager.IsFullVersion()) m_buttons[(int)eControl_PlayGame].setLabel(IDS_PLAY_TRIAL_GAME); - app.SetReachedMainMenu(); -#endif - - m_buttons[static_cast(eControl_Leaderboards)].init(IDS_LEADERBOARDS,eControl_Leaderboards); - m_buttons[static_cast(eControl_Achievements)].init( (UIString)IDS_ACHIEVEMENTS,eControl_Achievements); - m_buttons[static_cast(eControl_HelpAndOptions)].init(IDS_HELP_AND_OPTIONS,eControl_HelpAndOptions); - if(ProfileManager.IsFullVersion()) - { - m_bTrialVersion=false; - m_buttons[static_cast(eControl_UnlockOrDLC)].init(IDS_DOWNLOADABLECONTENT,eControl_UnlockOrDLC); - } - else - { - m_bTrialVersion=true; - m_buttons[static_cast(eControl_UnlockOrDLC)].init(IDS_UNLOCK_FULL_GAME,eControl_UnlockOrDLC); - } - -#ifndef _DURANGO - m_buttons[static_cast(eControl_Exit)].init(app.GetString(IDS_EXIT_GAME),eControl_Exit); -#else - m_buttons[(int)eControl_XboxHelp].init(IDS_XBOX_HELP_APP, eControl_XboxHelp); -#endif - -#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) - // Not allowed to exit from a PS3 game from the game - have to use the PS button - removeControl( &m_buttons[(int)eControl_Exit], false ); - // We don't have a way to display trophies/achievements, so remove the button - removeControl( &m_buttons[(int)eControl_Achievements], false ); - m_bLaunchFullVersionPurchase=false; -#endif -#ifdef _DURANGO - // Allowed to not have achievements in the menu - removeControl( &m_buttons[(int)eControl_Achievements], false ); - // Not allowed to exit from a Xbox One game from the game - have to use the Home button - //removeControl( &m_buttons[(int)eControl_Exit], false ); - m_bWaitingForDLCInfo=false; -#endif - - doHorizontalResizeCheck(); - - m_splash = L""; - - wstring filename = L"splashes.txt"; - if( app.hasArchiveFile(filename) ) - { - byteArray splashesArray = app.getArchiveFile(filename); - ByteArrayInputStream bais(splashesArray); - InputStreamReader isr( &bais ); - BufferedReader br( &isr ); - - wstring line = L""; - while ( !(line = br.readLine()).empty() ) - { - line = trimString( line ); - if (line.length() > 0) - { - m_splashes.push_back(line); - } - } - - br.close(); - } - - m_bIgnorePress=false; - m_bLoadTrialOnNetworkManagerReady = false; - - // 4J Stu - Clear out any loaded game rules - app.setLevelGenerationOptions(nullptr); - - // 4J Stu - Reset the leaving game flag so that we correctly handle signouts while in the menus - g_NetworkManager.ResetLeavingGame(); - -#if TO_BE_IMPLEMENTED - // Fix for #45154 - Frontend: DLC: Content can only be downloaded from the frontend if you have not joined/exited multiplayer - XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); -#endif -} - -UIScene_MainMenu::~UIScene_MainMenu() -{ - m_parentLayer->removeComponent(eUIComponent_Panorama); - m_parentLayer->removeComponent(eUIComponent_Logo); -} - -void UIScene_MainMenu::updateTooltips() -{ - int iX = -1; - int iA = -1; - if(!m_bIgnorePress) - { - iA = IDS_TOOLTIPS_SELECT; - -#ifdef _XBOX_ONE - iX = IDS_TOOLTIPS_CHOOSE_USER; -#elif defined __PSVITA__ - if(ProfileManager.IsFullVersion()) - { - iX = IDS_TOOLTIP_CHANGE_NETWORK_MODE; - } -#endif - } - ui.SetTooltips( DEFAULT_XUI_MENU_USER, iA, -1, iX); -} - -void UIScene_MainMenu::updateComponents() -{ - m_parentLayer->showComponent(m_iPad,eUIComponent_Panorama,true); - m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,true); -} - -void UIScene_MainMenu::handleGainFocus(bool navBack) -{ - UIScene::handleGainFocus(navBack); - ui.ShowPlayerDisplayname(false); - m_bIgnorePress=false; - - if (eNavigateWhenReady >= 0) - { - return; - } - - // 4J-JEV: This needs to come before SetLockedProfile(-1) as it wipes the XbLive contexts. - if (!navBack) - { - for (int iPad = 0; iPad < MAX_LOCAL_PLAYERS; iPad++) - { - // For returning to menus after exiting a game. - if (ProfileManager.IsSignedIn(iPad) ) - { - ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); - } - } - } - ProfileManager.SetLockedProfile(-1); - - m_bIgnorePress = false; - updateTooltips(); - -#ifdef _DURANGO - ProfileManager.ClearGameUsers(); -#endif - - if(navBack && ProfileManager.IsFullVersion()) - { - // Replace the Unlock Full Game with Downloadable Content - m_buttons[static_cast(eControl_UnlockOrDLC)].setLabel(IDS_DOWNLOADABLECONTENT); - } - -#if TO_BE_IMPLEMENTED - // Fix for #45154 - Frontend: DLC: Content can only be downloaded from the frontend if you have not joined/exited multiplayer - XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); - m_Timer.SetShow(FALSE); -#endif - m_controlTimer.setVisible( false ); - - // 4J-PB - remove the "hobo humping" message legal say we can't have, and the 1080p one for Vita -#ifdef __PSVITA__ - int splashIndex = eSplashRandomStart + 2 + random->nextInt( (int)m_splashes.size() - (eSplashRandomStart + 2) ); -#else - int splashIndex = eSplashRandomStart + 1 + random->nextInt( static_cast(m_splashes.size()) - (eSplashRandomStart + 1) ); -#endif - - // Override splash text on certain dates - SYSTEMTIME LocalSysTime; - GetLocalTime( &LocalSysTime ); - if (LocalSysTime.wMonth == 11 && LocalSysTime.wDay == 9) - { - splashIndex = eSplashHappyBirthdayEx; - } - else if (LocalSysTime.wMonth == 6 && LocalSysTime.wDay == 1) - { - splashIndex = eSplashHappyBirthdayNotch; - } - else if (LocalSysTime.wMonth == 12 && LocalSysTime.wDay == 24) // the Java game shows this on Christmas Eve, so we will too - { - splashIndex = eSplashMerryXmas; - } - else if (LocalSysTime.wMonth == 1 && LocalSysTime.wDay == 1) - { - splashIndex = eSplashHappyNewYear; - } - //splashIndex = 47; // Very short string - //splashIndex = 194; // Very long string - //splashIndex = 295; // Coloured - //splashIndex = 296; // Noise - m_splash = m_splashes.at( splashIndex ); -} - -wstring UIScene_MainMenu::getMoviePath() -{ - return L"MainMenu"; -} - -void UIScene_MainMenu::handleReload() -{ -#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) - // Not allowed to exit from a PS3 game from the game - have to use the PS button - removeControl( &m_buttons[(int)eControl_Exit], false ); - // We don't have a way to display trophies/achievements, so remove the button - removeControl( &m_buttons[(int)eControl_Achievements], false ); -#endif -#ifdef _DURANGO - // Allowed to not have achievements in the menu - removeControl( &m_buttons[(int)eControl_Achievements], false ); -#endif -} - -void UIScene_MainMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled) -{ - //app.DebugPrintf("UIScene_DebugOverlay handling input for pad %d, key %d, down- %s, pressed- %s, released- %s\n", iPad, key, down?"TRUE":"FALSE", pressed?"TRUE":"FALSE", released?"TRUE":"FALSE"); - - if ( m_bIgnorePress || (eNavigateWhenReady >= 0) ) return; - -#if defined (__ORBIS__) || defined (__PSVITA__) - // ignore all players except player 0 - it's their profile that is currently being used - if(iPad!=0) return; -#endif - - ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released); - - switch(key) - { - case ACTION_MENU_OK: -#ifdef __ORBIS__ - case ACTION_MENU_TOUCHPAD_PRESS: -#endif - if(pressed) - { - ProfileManager.SetPrimaryPad(iPad); - ProfileManager.SetLockedProfile(-1); - sendInputToMovie(key, repeat, pressed, released); - } - break; -#ifdef _XBOX_ONE - case ACTION_MENU_X: - if(pressed) - { - m_bIgnorePress = true; - ProfileManager.RequestSignInUI(false, false, false, false, false, ChooseUser_SignInReturned, this, iPad); - } - break; -#endif -#ifdef __PSVITA__ - case ACTION_MENU_X: - if(pressed && ProfileManager.IsFullVersion()) - { - UINT uiIDA[2]; - uiIDA[0]=IDS__NETWORK_PSN; - uiIDA[1]=IDS_NETWORK_ADHOC; - ui.RequestErrorMessage(IDS_SELECT_NETWORK_MODE_TITLE, IDS_SELECT_NETWORK_MODE_TEXT, uiIDA, 2, XUSER_INDEX_ANY, &UIScene_MainMenu::SelectNetworkModeReturned,this); - } - break; -#endif - - case ACTION_MENU_UP: - case ACTION_MENU_DOWN: - sendInputToMovie(key, repeat, pressed, released); - break; - } -} - -void UIScene_MainMenu::handlePress(F64 controlId, F64 childId) -{ - int primaryPad = ProfileManager.GetPrimaryPad(); - -#ifdef _XBOX_ONE - int (*signInReturnedFunc) (LPVOID,const bool, const int iPad, const int iController) = nullptr; -#else - int (*signInReturnedFunc) (LPVOID,const bool, const int iPad) = nullptr; -#endif - - switch(static_cast(controlId)) - { - case eControl_PlayGame: -#ifdef __ORBIS__ - { - m_bIgnorePress=true; - - //CD - Added for audio - ui.PlayUISFX(eSFX_Press); - - ProfileManager.RefreshChatAndContentRestrictions(RefreshChatAndContentRestrictionsReturned_PlayGame, this); - } -#else - m_eAction=eAction_RunGame; - //CD - Added for audio - ui.PlayUISFX(eSFX_Press); - - signInReturnedFunc = &UIScene_MainMenu::CreateLoad_SignInReturned; -#endif - break; - case eControl_MiniGames: - #ifdef __ORBIS__ - { - m_bIgnorePress=true; - - //CD - Added for audio - ui.PlayUISFX(eSFX_Press); - - ProfileManager.RefreshChatAndContentRestrictions(RefreshChatAndContentRestrictionsReturned_PlayGame, this); - } -#else - m_eAction=eAction_RunGame; - //CD - Added for audio - ui.PlayUISFX(eSFX_Press); - - signInReturnedFunc = &UIScene_MainMenu::CreateLoad_SignInReturned; -#endif - break; - case eControl_Leaderboards: - //CD - Added for audio - ui.PlayUISFX(eSFX_Press); -#ifdef __ORBIS__ - ProfileManager.RefreshChatAndContentRestrictions(RefreshChatAndContentRestrictionsReturned_Leaderboards, this); -#else - m_eAction=eAction_RunLeaderboards; - signInReturnedFunc = &UIScene_MainMenu::Leaderboards_SignInReturned; -#endif - break; - case eControl_Achievements: - //CD - Added for audio - ui.PlayUISFX(eSFX_Press); - - m_eAction=eAction_RunAchievements; - signInReturnedFunc = &UIScene_MainMenu::Achievements_SignInReturned; - break; - case eControl_HelpAndOptions: - //CD - Added for audio - ui.PlayUISFX(eSFX_Press); - - m_eAction=eAction_RunHelpAndOptions; - signInReturnedFunc = &UIScene_MainMenu::HelpAndOptions_SignInReturned; - break; - case eControl_UnlockOrDLC: - //CD - Added for audio - ui.PlayUISFX(eSFX_Press); - - m_eAction=eAction_RunUnlockOrDLC; - signInReturnedFunc = &UIScene_MainMenu::UnlockFullGame_SignInReturned; - break; - case eControl_Exit: - //CD - Added for audio - ui.PlayUISFX(eSFX_Press); - - if( ProfileManager.IsFullVersion() ) - { - UINT uiIDA[2]; - uiIDA[0]=IDS_CANCEL; - uiIDA[1]=IDS_OK; - ui.RequestErrorMessage(IDS_WINDOWS_EXIT, IDS_WARNING_ARCADE_TEXT, uiIDA, 2, XUSER_INDEX_ANY,&UIScene_MainMenu::ExitGameReturned,this); - } - else - { -#ifdef _XBOX -#ifdef _XBOX_ONE - ui.ShowPlayerDisplayname(true); -#endif - ui.NavigateToScene(primaryPad,eUIScene_TrialExitUpsell); -#endif - } - break; - -#ifdef _DURANGO - case eControl_XboxHelp: - ui.PlayUISFX(eSFX_Press); - - m_eAction=eAction_RunXboxHelp; - signInReturnedFunc = &UIScene_MainMenu::XboxHelp_SignInReturned; - break; -#endif - - default: DEBUG_BREAK(); - } - - bool confirmUser = false; - - // Note: if no sign in returned func, assume this isn't required - if (signInReturnedFunc != nullptr) - { - if(ProfileManager.IsSignedIn(primaryPad)) - { - if (confirmUser) - { - ProfileManager.RequestSignInUI(false, false, true, false, true, signInReturnedFunc, this, primaryPad); - } - else - { - RunAction(primaryPad); - } - } - else - { - // Ask user to sign in - UINT uiIDA[2]; - uiIDA[0]=IDS_CONFIRM_OK; - uiIDA[1]=IDS_CONFIRM_CANCEL; - ui.RequestErrorMessage(IDS_MUST_SIGN_IN_TITLE, IDS_MUST_SIGN_IN_TEXT, uiIDA, 2, primaryPad, &UIScene_MainMenu::MustSignInReturned, this); - } - } -} - -// Run current action -void UIScene_MainMenu::RunAction(int iPad) -{ - switch(m_eAction) - { - case eAction_RunGame: - RunPlayGame(iPad); - break; - case eAction_RunLeaderboards: - RunLeaderboards(iPad); - break; - case eAction_RunAchievements: - RunAchievements(iPad); - break; - case eAction_RunHelpAndOptions: - RunHelpAndOptions(iPad); - break; - case eAction_RunUnlockOrDLC: - RunUnlockOrDLC(iPad); - break; -#ifdef _DURANGO - case eAction_RunXboxHelp: - // 4J: Launch the dummy xbox help application. - WXS::User^ user = ProfileManager.GetUser(ProfileManager.GetPrimaryPad()); - Windows::Xbox::ApplicationModel::Help::Show(user); - break; -#endif - } -} - -void UIScene_MainMenu::customDraw(IggyCustomDrawCallbackRegion *region) -{ - if(wcscmp((wchar_t *)region->name,L"Splash")==0) - { - PIXBeginNamedEvent(0,"Custom draw splash"); - customDrawSplash(region); - PIXEndNamedEvent(); - } -} - -void UIScene_MainMenu::customDrawSplash(IggyCustomDrawCallbackRegion *region) -{ - Minecraft *pMinecraft = Minecraft::GetInstance(); - - // 4J Stu - Move this to the ctor when the main menu is not the first scene we navigate to - ScreenSizeCalculator ssc(pMinecraft->options, pMinecraft->width_phys, pMinecraft->height_phys); - m_fScreenWidth=static_cast(pMinecraft->width_phys); - m_fRawWidth=static_cast(ssc.rawWidth); - m_fScreenHeight=static_cast(pMinecraft->height_phys); - m_fRawHeight=static_cast(ssc.rawHeight); - - - // Setup GDraw, normal game render states and matrices - CustomDrawData *customDrawRegion = ui.setupCustomDraw(this,region); - delete customDrawRegion; - - - Font *font = pMinecraft->font; - - // build and render with the game call - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - - glPushMatrix(); - - float width = region->x1 - region->x0; - float height = region->y1 - region->y0; - float xo = width/2; - float yo = height; - - glTranslatef(xo, yo, 0); - - glRotatef(-17, 0, 0, 1); - float sss = 1.8f - Mth::abs(Mth::sin(System::currentTimeMillis() % 1000 / 1000.0f * PI * 2) * 0.1f); - sss*=(m_fScreenWidth/m_fRawWidth); - - sss = sss * 100 / (font->width(m_splash) + 8 * 4); - glScalef(sss, sss, sss); - //drawCenteredString(font, splash, 0, -8, 0xffff00); - font->drawShadow(m_splash, 0 - (font->width(m_splash)) / 2, -8, 0xffff00); - glPopMatrix(); - - glDisable(GL_RESCALE_NORMAL); - - glEnable(GL_DEPTH_TEST); - - - // Finish GDraw and anything else that needs to be finalised - ui.endCustomDraw(region); -} - -int UIScene_MainMenu::MustSignInReturned(void *pParam, int iPad, C4JStorage::EMessageResult result) -{ - UIScene_MainMenu* pClass = static_cast(pParam); - - if(result==C4JStorage::EMessage_ResultAccept) - { - // we need to specify local game here to display local and LIVE profiles in the list - switch(pClass->m_eAction) - { - case eAction_RunGame: ProfileManager.RequestSignInUI(false, true, false, false, true, &UIScene_MainMenu::CreateLoad_SignInReturned, pClass, iPad ); break; - case eAction_RunHelpAndOptions: ProfileManager.RequestSignInUI(false, false, true, false, true, &UIScene_MainMenu::HelpAndOptions_SignInReturned, pClass, iPad ); break; - case eAction_RunLeaderboards: ProfileManager.RequestSignInUI(false, false, true, false, true, &UIScene_MainMenu::Leaderboards_SignInReturned, pClass, iPad ); break; - case eAction_RunAchievements: ProfileManager.RequestSignInUI(false, false, true, false, true, &UIScene_MainMenu::Achievements_SignInReturned, pClass, iPad ); break; - case eAction_RunUnlockOrDLC: ProfileManager.RequestSignInUI(false, false, true, false, true, &UIScene_MainMenu::UnlockFullGame_SignInReturned, pClass, iPad ); break; -#ifdef _DURANGO - case eAction_RunXboxHelp: ProfileManager.RequestSignInUI(false, false, true, false, true, &UIScene_MainMenu::XboxHelp_SignInReturned, pClass, iPad ); break; -#endif - } - } - else - { - pClass->m_bIgnorePress=false; - // unlock the profile - ProfileManager.SetLockedProfile(-1); - for(int i=0;im_eAction) - { - case eAction_RunLeaderboardsPSN: - SQRNetworkManager_PS3::AttemptPSNSignIn(&UIScene_MainMenu::Leaderboards_SignInReturned, pClass); - break; - case eAction_RunGamePSN: - SQRNetworkManager_PS3::AttemptPSNSignIn(&UIScene_MainMenu::CreateLoad_SignInReturned, pClass); - break; - case eAction_RunUnlockOrDLCPSN: - SQRNetworkManager_PS3::AttemptPSNSignIn(&UIScene_MainMenu::UnlockFullGame_SignInReturned, pClass); - break; - } -#elif defined __PSVITA__ - switch(pClass->m_eAction) - { - case eAction_RunLeaderboardsPSN: - //CD - Must force Ad-Hoc off if they want leaderboard PSN sign-in - //Save settings change - app.SetGameSettings(0, eGameSetting_PSVita_NetworkModeAdhoc, 0); - //Force off - CGameNetworkManager::setAdhocMode(false); - //Now Sign-in - SQRNetworkManager_Vita::AttemptPSNSignIn(&UIScene_MainMenu::Leaderboards_SignInReturned, pClass); - break; - case eAction_RunGamePSN: - if(CGameNetworkManager::usingAdhocMode()) - { - SQRNetworkManager_AdHoc_Vita::AttemptAdhocSignIn(&UIScene_MainMenu::CreateLoad_SignInReturned, pClass); - } - else - { - SQRNetworkManager_Vita::AttemptPSNSignIn(&UIScene_MainMenu::CreateLoad_SignInReturned, pClass); - - } - break; - case eAction_RunUnlockOrDLCPSN: - //CD - Must force Ad-Hoc off if they want commerce PSN sign-in - //Save settings change - app.SetGameSettings(0, eGameSetting_PSVita_NetworkModeAdhoc, 0); - //Force off - CGameNetworkManager::setAdhocMode(false); - //Now Sign-in - SQRNetworkManager_Vita::AttemptPSNSignIn(&UIScene_MainMenu::UnlockFullGame_SignInReturned, pClass); - break; - } -#else - switch(pClass->m_eAction) - { - case eAction_RunLeaderboardsPSN: - SQRNetworkManager_Orbis::AttemptPSNSignIn(&UIScene_MainMenu::Leaderboards_SignInReturned, pClass, true, iPad); - break; - case eAction_RunGamePSN: - SQRNetworkManager_Orbis::AttemptPSNSignIn(&UIScene_MainMenu::CreateLoad_SignInReturned, pClass, true, iPad); - break; - case eAction_RunUnlockOrDLCPSN: - SQRNetworkManager_Orbis::AttemptPSNSignIn(&UIScene_MainMenu::UnlockFullGame_SignInReturned, pClass, true, iPad); - break; - } - -#endif - } - else - { - if( pClass->m_eAction == eAction_RunGamePSN ) - { - if( result == C4JStorage::EMessage_Cancelled) - CreateLoad_SignInReturned(pClass, false, 0); - else - CreateLoad_SignInReturned(pClass, true, 0); - } - else - { - pClass->m_bIgnorePress=false; - } - } - - return 0; -} -#endif - -#ifdef _XBOX_ONE -int UIScene_MainMenu::HelpAndOptions_SignInReturned(void *pParam,bool bContinue,int iPad, int iController) -#else -int UIScene_MainMenu::HelpAndOptions_SignInReturned(void *pParam,bool bContinue,int iPad) -#endif -{ - UIScene_MainMenu *pClass = static_cast(pParam); - - if(bContinue) - { - // 4J-JEV: Don't we only need to update rich-presence if the sign-in status changes. - ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); - -#if TO_BE_IMPLEMENTED - if(app.GetTMSDLCInfoRead()) -#endif - { - ProfileManager.SetLockedProfile(ProfileManager.GetPrimaryPad()); -#ifdef _XBOX_ONE - ui.ShowPlayerDisplayname(true); -#endif - proceedToScene(iPad, eUIScene_HelpAndOptionsMenu); - } -#if TO_BE_IMPLEMENTED - else - { - // Changing to async TMS calls - app.SetTMSAction(iPad,eTMSAction_TMSPP_RetrieveFiles_HelpAndOptions); - - // block all input - pClass->m_bIgnorePress=true; - // We want to hide everything in this scene and display a timer until we get a completion for the TMS files - for(int i=0;im_Buttons[i].SetShow(FALSE); - } - - pClass->updateTooltips(); - - pClass->m_Timer.SetShow(TRUE); - } -#endif - } - else - { - pClass->m_bIgnorePress=false; - // unlock the profile - ProfileManager.SetLockedProfile(-1); - for(int i=0;im_bIgnorePress = false; - pClass->updateTooltips(); - return 0; -} -#endif - -#ifdef _XBOX_ONE -int UIScene_MainMenu::CreateLoad_SignInReturned(void *pParam, bool bContinue, int iPad, int iController) -#else -int UIScene_MainMenu::CreateLoad_SignInReturned(void *pParam, bool bContinue, int iPad) -#endif -{ - UIScene_MainMenu* pClass = static_cast(pParam); - - if(bContinue) - { - // 4J-JEV: We only need to update rich-presence if the sign-in status changes. - ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); - - UINT uiIDA[1] = { IDS_OK }; - - if(ProfileManager.IsGuest(ProfileManager.GetPrimaryPad())) - { - pClass->m_bIgnorePress=false; - ui.RequestErrorMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); - } - else - { - ProfileManager.SetLockedProfile(ProfileManager.GetPrimaryPad()); - - - // change the minecraft player name - Minecraft::GetInstance()->user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); - - if(ProfileManager.IsFullVersion()) - { - bool bSignedInLive = ProfileManager.IsSignedInLive(iPad); -#ifdef __PSVITA__ - if(CGameNetworkManager::usingAdhocMode()) - { - if(SQRNetworkManager_AdHoc_Vita::GetAdhocStatus()) - { - bSignedInLive = true; - } - else - { - // adhoc mode, but we didn't make the connection, turn off adhoc mode, and just go with whatever the regular online status is - CGameNetworkManager::setAdhocMode(false); - bSignedInLive = ProfileManager.IsSignedInLive(iPad); - } - } -#endif - - // Check if we're signed in to LIVE - if(bSignedInLive) - { - // 4J-PB - Need to check for installed DLC - if(!app.DLCInstallProcessCompleted()) app.StartInstallDLCProcess(iPad); - - if(ProfileManager.IsGuest(iPad)) - { - pClass->m_bIgnorePress=false; - ui.RequestErrorMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); - } - else - { - // 4J Stu - Not relevant to PS3 -#ifdef _XBOX_ONE -// if(app.GetTMSDLCInfoRead() && app.GetBanListRead(iPad)) - if(app.GetBanListRead(iPad)) - { - Minecraft *pMinecraft=Minecraft::GetInstance(); - pMinecraft->user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); - - // ensure we've applied this player's settings - app.ApplyGameSettingsChanged(iPad); - -#ifdef _XBOX_ONE - ui.ShowPlayerDisplayname(true); -#endif - proceedToScene(ProfileManager.GetPrimaryPad(), eUIScene_LoadCreateJoinMenu); - } - else - { - app.SetTMSAction(iPad,eTMSAction_TMSPP_RetrieveFiles_RunPlayGame); - - // block all input - pClass->m_bIgnorePress=true; - // We want to hide everything in this scene and display a timer until we get a completion for the TMS files - // for(int i=0;iupdateTooltips(); - - pClass->m_controlTimer.setVisible( true ); - } -#endif -#if TO_BE_IMPLEMENTED - // check if all the TMS files are loaded - if(app.GetTMSDLCInfoRead() && app.GetTMSXUIDsFileRead() && app.GetBanListRead(iPad)) - { - if(StorageManager.SetSaveDevice(&UIScene_MainMenu::DeviceSelectReturned,pClass)==true) - { - // save device already selected - - // ensure we've applied this player's settings - app.ApplyGameSettingsChanged(ProfileManager.GetPrimaryPad()); - // check for DLC - // start timer to track DLC check finished - pClass->m_Timer.SetShow(TRUE); - XuiSetTimer(pClass->m_hObj,DLC_INSTALLED_TIMER_ID,DLC_INSTALLED_TIMER_TIME); - //app.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_MultiGameJoinLoad); - } - } - else - { - // Changing to async TMS calls - app.SetTMSAction(iPad,eTMSAction_TMSPP_RetrieveFiles_RunPlayGame); - - // block all input - pClass->m_bIgnorePress=true; - // We want to hide everything in this scene and display a timer until we get a completion for the TMS files - for(int i=0;im_Buttons[i].SetShow(FALSE); - } - - updateTooltips(); - - pClass->m_Timer.SetShow(TRUE); - } -#else - Minecraft *pMinecraft=Minecraft::GetInstance(); - pMinecraft->user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); - - // ensure we've applied this player's settings - app.ApplyGameSettingsChanged(iPad); - -#ifdef _XBOX_ONE - ui.ShowPlayerDisplayname(true); -#endif - proceedToScene(ProfileManager.GetPrimaryPad(), eUIScene_LoadCreateJoinMenu); -#endif - } - } - else - { -#if TO_BE_IMPLEMENTED - // offline - ProfileManager.DisplayOfflineProfile(&CScene_Main::CreateLoad_OfflineProfileReturned,pClass, ProfileManager.GetPrimaryPad() ); -#else - app.DebugPrintf("Offline Profile returned not implemented\n"); -#ifdef _XBOX_ONE - ui.ShowPlayerDisplayname(true); -#endif - proceedToScene(ProfileManager.GetPrimaryPad(), eUIScene_LoadCreateJoinMenu); -#endif - } - } - else - { - // 4J-PB - if this is the trial game, we can't have any networking - // Can't apply the player's settings here - they haven't come back from the QuerySignInStatud call above yet. - // Need to let them action in the main loop when they come in - // ensure we've applied this player's settings - //app.ApplyGameSettingsChanged(iPad); - -#if defined(__PS3__) || defined(__ORBIS__) || defined( __PSVITA__) - // ensure we've applied this player's settings - we do have them on PS3 - app.ApplyGameSettingsChanged(iPad); -#endif - -#ifdef __ORBIS__ - if(!g_NetworkManager.IsReadyToPlayOrIdle()) - { - pClass->m_bLoadTrialOnNetworkManagerReady = true; - ui.NavigateToScene(iPad, eUIScene_Timer); - } - else -#endif - { - // go straight in to the trial level - LoadTrial(); - } - } - } - } - else - { - pClass->m_bIgnorePress=false; - - // unlock the profile - ProfileManager.SetLockedProfile(-1); - for(int i=0;i(pParam); - - if(bContinue) - { - // 4J-JEV: We only need to update rich-presence if the sign-in status changes. - ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); - - UINT uiIDA[1] = { IDS_OK }; - - // guests can't look at leaderboards - if(ProfileManager.IsGuest(ProfileManager.GetPrimaryPad())) - { - pClass->m_bIgnorePress=false; - ui.RequestErrorMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); - } - else if(!ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad())) - { - pClass->m_bIgnorePress=false; - ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_XBOXLIVE_NOTIFICATION, uiIDA, 1); - } - else - { - bool bContentRestricted=false; -#if defined(__PS3__) || defined(__PSVITA__) - ProfileManager.GetChatAndContentRestrictions(iPad,true,nullptr,&bContentRestricted,nullptr); -#endif - if(bContentRestricted) - { - pClass->m_bIgnorePress=false; -#if !(defined(_XBOX) || defined(_WINDOWS64) || defined(_XBOX_ONE) ) // 4J Stu - Temp to get the win build running, but so we check this for other platforms - // you can't see leaderboards - UINT uiIDA[1]; - uiIDA[0]=IDS_CONFIRM_OK; - ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); -#endif - } - else - { - ProfileManager.SetLockedProfile(ProfileManager.GetPrimaryPad()); -#ifdef _XBOX_ONE - ui.ShowPlayerDisplayname(true); -#endif - proceedToScene(ProfileManager.GetPrimaryPad(), eUIScene_LeaderboardsMenu); - } - } - } - else - { - pClass->m_bIgnorePress=false; - // unlock the profile - ProfileManager.SetLockedProfile(-1); - for(int i=0;i(pParam); - - if (bContinue) - { - pClass->m_bIgnorePress=false; - // 4J-JEV: We only need to update rich-presence if the sign-in status changes. - ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); - - XShowAchievementsUI( ProfileManager.GetPrimaryPad() ); - } - else - { - pClass->m_bIgnorePress=false; - // unlock the profile - ProfileManager.SetLockedProfile(-1); - for(int i=0;i(pParam); - - if (bContinue) - { - // 4J-JEV: We only need to update rich-presence if the sign-in status changes. - ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); - - pClass->RunUnlockOrDLC(iPad); - } - else - { - pClass->m_bIgnorePress=false; - // unlock the profile - ProfileManager.SetLockedProfile(-1); - for(int i=0;im_errorCode = ProfileManager.getNPAvailability(ProfileManager.GetPrimaryPad()); - - bool bPatchAvailable; - switch(pClass->m_errorCode) - { - case SCE_NP_ERROR_LATEST_PATCH_PKG_EXIST: - case SCE_NP_ERROR_LATEST_PATCH_PKG_DOWNLOADED: - bPatchAvailable=true; - break; - default: - bPatchAvailable=false; - break; - } - - if(!bPatchAvailable) - { - pClass->m_eAction=eAction_RunGame; - signInReturnedFunc = &UIScene_MainMenu::CreateLoad_SignInReturned; - } - else - { - pClass->m_bRunGameChosen=true; - pClass->m_bErrorDialogRunning=true; - int32_t ret=sceErrorDialogInitialize(); - if ( ret==SCE_OK ) - { - SceErrorDialogParam param; - sceErrorDialogParamInitialize( ¶m ); - // 4J-PB - We want to display the option to get the patch now - param.errorCode = SCE_NP_ERROR_LATEST_PATCH_PKG_DOWNLOADED;//pClass->m_errorCode; - ret = sceUserServiceGetInitialUser( ¶m.userId ); - if ( ret == SCE_OK ) - { - ret=sceErrorDialogOpen( ¶m ); - } - return; - } - -// UINT uiIDA[1]; -// uiIDA[0]=IDS_OK; -// ui.RequestMessageBox(IDS_PATCH_AVAILABLE_TITLE, IDS_PATCH_AVAILABLE_TEXT, uiIDA, 1, XUSER_INDEX_ANY,nullptr,pClass); - } - - // Check if PSN is unavailable because of age restriction - if (pClass->m_errorCode == SCE_NP_ERROR_AGE_RESTRICTION) - { - UINT uiIDA[1]; - uiIDA[0]=IDS_PRO_NOTONLINE_DECLINE; - ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad(), &UIScene_MainMenu::PlayOfflineReturned, pClass); - - return; - } - - bool confirmUser = false; - - // Note: if no sign in returned func, assume this isn't required - if (signInReturnedFunc != nullptr) - { - if(ProfileManager.IsSignedIn(primaryPad)) - { - if (confirmUser) - { - ProfileManager.RequestSignInUI(false, false, true, false, true, signInReturnedFunc, pClass, primaryPad); - } - else - { - pClass->RunAction(primaryPad); - } - } - else - { - // Ask user to sign in - UINT uiIDA[2]; - uiIDA[0]=IDS_CONFIRM_OK; - uiIDA[1]=IDS_CONFIRM_CANCEL; - ui.RequestErrorMessage(IDS_MUST_SIGN_IN_TITLE, IDS_MUST_SIGN_IN_TEXT, uiIDA, 2, primaryPad, &UIScene_MainMenu::MustSignInReturned, pClass); - } - } -} - -void UIScene_MainMenu::RefreshChatAndContentRestrictionsReturned_Leaderboards(void *pParam) -{ - int primaryPad = ProfileManager.GetPrimaryPad(); - - UIScene_MainMenu* pClass = (UIScene_MainMenu*)pParam; - - int (*signInReturnedFunc) (LPVOID,const bool, const int iPad) = nullptr; - - // 4J-PB - Check if there is a patch for the game - pClass->m_errorCode = ProfileManager.getNPAvailability(ProfileManager.GetPrimaryPad()); - - bool bPatchAvailable; - switch(pClass->m_errorCode) - { - case SCE_NP_ERROR_LATEST_PATCH_PKG_EXIST: - case SCE_NP_ERROR_LATEST_PATCH_PKG_DOWNLOADED: - bPatchAvailable=true; - break; - default: - bPatchAvailable=false; - break; - } - - if(!bPatchAvailable) - { - pClass->m_eAction=eAction_RunLeaderboards; - signInReturnedFunc = &UIScene_MainMenu::Leaderboards_SignInReturned; - } - else - { - int32_t ret=sceErrorDialogInitialize(); - pClass->m_bErrorDialogRunning=true; - if ( ret==SCE_OK ) - { - SceErrorDialogParam param; - sceErrorDialogParamInitialize( ¶m ); - // 4J-PB - We want to display the option to get the patch now - param.errorCode = SCE_NP_ERROR_LATEST_PATCH_PKG_DOWNLOADED;//pClass->m_errorCode; - ret = sceUserServiceGetInitialUser( ¶m.userId ); - if ( ret == SCE_OK ) - { - ret=sceErrorDialogOpen( ¶m ); - } - } - -// UINT uiIDA[1]; -// uiIDA[0]=IDS_OK; -// ui.RequestMessageBox(IDS_PATCH_AVAILABLE_TITLE, IDS_PATCH_AVAILABLE_TEXT, uiIDA, 1, XUSER_INDEX_ANY,nullptr,pClass); - } - - bool confirmUser = false; - - // Update error code - pClass->m_errorCode = ProfileManager.getNPAvailability(ProfileManager.GetPrimaryPad()); - - // Check if PSN is unavailable because of age restriction - if (pClass->m_errorCode == SCE_NP_ERROR_AGE_RESTRICTION) - { - UINT uiIDA[1]; - uiIDA[0] = IDS_CONFIRM_OK; - ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad(), nullptr, pClass); - - return; - } - - // Note: if no sign in returned func, assume this isn't required - if (signInReturnedFunc != nullptr) - { - if(ProfileManager.IsSignedIn(primaryPad)) - { - if (confirmUser) - { - ProfileManager.RequestSignInUI(false, false, true, false, true, signInReturnedFunc, pClass, primaryPad); - } - else - { - pClass->RunAction(primaryPad); - } - } - else - { - // Ask user to sign in - UINT uiIDA[2]; - uiIDA[0]=IDS_CONFIRM_OK; - uiIDA[1]=IDS_CONFIRM_CANCEL; - ui.RequestErrorMessage(IDS_MUST_SIGN_IN_TITLE, IDS_MUST_SIGN_IN_TEXT, uiIDA, 2, primaryPad, &UIScene_MainMenu::MustSignInReturned, pClass); - } - } -} - -int UIScene_MainMenu::PlayOfflineReturned(void *pParam, int iPad, C4JStorage::EMessageResult result) -{ - UIScene_MainMenu* pClass = (UIScene_MainMenu*)pParam; - - if(result==C4JStorage::EMessage_ResultAccept) - { - if (pClass->m_eAction == eAction_RunGame) - { - CreateLoad_SignInReturned(pClass, true, 0); - } - else - { - pClass->m_bIgnorePress=false; - } - } - else - { - pClass->m_bIgnorePress=false; - } - - return 0; -} -#endif - -void UIScene_MainMenu::RunPlayGame(int iPad) -{ - Minecraft *pMinecraft=Minecraft::GetInstance(); - - // clear the remembered signed in users so their profiles get read again - app.ClearSignInChangeUsersMask(); - - app.ReleaseSaveThumbnail(); - - if(ProfileManager.IsGuest(iPad)) - { - UINT uiIDA[1]; - uiIDA[0]=IDS_OK; - - m_bIgnorePress=false; - ui.RequestErrorMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); - } - else - { - ProfileManager.SetLockedProfile(iPad); - - // If the player was signed in before selecting play, we'll not have read the profile yet, so query the sign-in status to get this to happen - ProfileManager.QuerySigninStatus(); - - // 4J-PB - Need to check for installed DLC - if(!app.DLCInstallProcessCompleted()) app.StartInstallDLCProcess(iPad); - - if(ProfileManager.IsFullVersion()) - { - // are we offline? - bool bSignedInLive = ProfileManager.IsSignedInLive(iPad); -#ifdef __PSVITA__ - if(app.GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_PSVita_NetworkModeAdhoc) == true) - { - CGameNetworkManager::setAdhocMode(true); - bSignedInLive = SQRNetworkManager_AdHoc_Vita::GetAdhocStatus(); - app.DebugPrintf("Adhoc mode signed in : %s\n", bSignedInLive ? "true" : "false"); - } - else - { - CGameNetworkManager::setAdhocMode(false); - app.DebugPrintf("PSN mode signed in : %s\n", bSignedInLive ? "true" : "false"); - } - -#endif //__PSVITA__ - - if(!bSignedInLive) - { -#if defined(__PS3__) || defined __PSVITA__ - // enable input again - m_bIgnorePress=false; - - // Not sure why 360 doesn't need this, but leaving as __PS3__ only for now until we see that it does. Without this, on a PS3 offline game, the primary player just gets the default Player1234 type name - pMinecraft->user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); - - m_eAction=eAction_RunGamePSN; - // get them to sign in to online - UINT uiIDA[2]; - uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; - uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; - -#ifdef __PSVITA__ - if(CGameNetworkManager::usingAdhocMode()) - { - uiIDA[0]=IDS_NETWORK_ADHOC; - // this should be "Connect to adhoc network" - ui.RequestErrorMessage(IDS_PRO_NOTADHOCONLINE_TITLE, IDS_PRO_NOTADHOCONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&UIScene_MainMenu::MustSignInReturnedPSN,this); - } - else - { - /* 4J-PB - Add this after release - // Determine why they're not "signed in live" - if (ProfileManager.IsSignedInPSN(iPad)) - { - m_eAction=eAction_RunGame; - // Signed in to PSN but not connected (no internet access) - - UINT uiIDA[1]; - uiIDA[0] = IDS_PRO_NOTONLINE_DECLINE; - ui.RequestMessageBox( IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, iPad, UIScene_MainMenu::PlayOfflineReturned, this, app.GetStringTable()); - } - else - { - m_eAction=eAction_RunGamePSN; - // Not signed in to PSN - ui.RequestMessageBox( IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, iPad, &UIScene_MainMenu::MustSignInReturnedPSN, this, app.GetStringTable()); - return; - } */ - ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&UIScene_MainMenu::MustSignInReturnedPSN,this); - - } -#else - - ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, iPad, &UIScene_MainMenu::MustSignInReturnedPSN, this); -#endif - -#elif defined __ORBIS__ - - // Determine why they're not "signed in live" - if (ProfileManager.isSignedInPSN(iPad)) - { - m_eAction=eAction_RunGame; - // Signed in to PSN but not connected (no internet access) - assert(!ProfileManager.isConnectedToPSN(iPad)); - - UINT uiIDA[1]; - uiIDA[0] = IDS_PRO_NOTONLINE_DECLINE; - ui.RequestErrorMessage( IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, iPad, UIScene_MainMenu::PlayOfflineReturned, this); - } - else - { - m_eAction=eAction_RunGamePSN; - // Not signed in to PSN - UINT uiIDA[2]; - uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; - uiIDA[1] = IDS_PRO_NOTONLINE_DECLINE; - ui.RequestAlertMessage( IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, iPad, &UIScene_MainMenu::MustSignInReturnedPSN, this); - return; - } -#else - ProfileManager.SetLockedProfile(iPad); -#ifdef _XBOX_ONE - ui.ShowPlayerDisplayname(true); -#endif - proceedToScene(ProfileManager.GetPrimaryPad(), eUIScene_LoadCreateJoinMenu); -#endif - } - else - { -#ifdef _XBOX_ONE - if(!app.GetBanListRead(iPad)) - { - app.SetTMSAction(iPad,eTMSAction_TMSPP_RetrieveFiles_RunPlayGame); - - // block all input - m_bIgnorePress=true; - // We want to hide everything in this scene and display a timer until we get a completion for the TMS files -// for(int i=0;iuser->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); - // save device already selected - - // ensure we've applied this player's settings - app.ApplyGameSettingsChanged(iPad); - // check for DLC - // start timer to track DLC check finished - m_Timer.SetShow(TRUE); - XuiSetTimer(m_hObj,DLC_INSTALLED_TIMER_ID,DLC_INSTALLED_TIMER_TIME); - //app.NavigateToScene(iPad,eUIScene_MultiGameJoinLoad); - } - } - else - { - // Changing to async TMS calls - app.SetTMSAction(iPad,eTMSAction_TMSPP_RetrieveFiles_RunPlayGame); - - // block all input - m_bIgnorePress=true; - // We want to hide everything in this scene and display a timer until we get a completion for the TMS files - for(int i=0;iuser->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); - - // ensure we've applied this player's settings - app.ApplyGameSettingsChanged(iPad); - -#ifdef _XBOX_ONE - ui.ShowPlayerDisplayname(true); -#endif - proceedToScene(ProfileManager.GetPrimaryPad(), eUIScene_LoadCreateJoinMenu); -#endif - } - } - else - { - // 4J-PB - if this is the trial game, we can't have any networking - // go straight in to the trial level - // change the minecraft player name - Minecraft::GetInstance()->user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); - - // Can't apply the player's settings here - they haven't come back from the QuerySignInStatud call above yet. - // Need to let them action in the main loop when they come in - // ensure we've applied this player's settings - //app.ApplyGameSettingsChanged(iPad); - -#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) - // ensure we've applied this player's settings - we do have them on PS3 - app.ApplyGameSettingsChanged(iPad); -#endif - -#ifdef __ORBIS__ - if(!g_NetworkManager.IsReadyToPlayOrIdle()) - { - m_bLoadTrialOnNetworkManagerReady = true; - ui.NavigateToScene(iPad, eUIScene_Timer); - } - else -#endif - { - LoadTrial(); - } - } - } -} - -void UIScene_MainMenu::RunLeaderboards(int iPad) -{ - UINT uiIDA[1]; - uiIDA[0]=IDS_OK; - - // guests can't look at leaderboards - if(ProfileManager.IsGuest(iPad)) - { - ui.RequestErrorMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); - } - else if(!ProfileManager.IsSignedInLive(iPad)) - { -#if defined __PS3__ || defined __PSVITA__ - m_eAction=eAction_RunLeaderboardsPSN; - // get them to sign in to online - UINT uiIDA[1]; - uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; - ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad(),&UIScene_MainMenu::MustSignInReturnedPSN,this); - -/* 4J-PB - Add this after release -#elif defined __PSVITA__ - m_eAction=eAction_RunLeaderboardsPSN; - // Determine why they're not "signed in live" - if (ProfileManager.IsSignedInPSN(iPad)) - { - // Signed in to PSN but not connected (no internet access) - UINT uiIDA[1]; - uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; - ui.RequestMessageBox(IDS_PRO_CURRENTLY_NOT_ONLINE_TITLE, IDS_PRO_PSNOFFLINE_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad(), &UIScene_MainMenu::MustSignInReturnedPSN, this, app.GetStringTable()); - } - else - { - // Not signed in to PSN - UINT uiIDA[1]; - uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; - ui.RequestMessageBox(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad(), &UIScene_MainMenu::MustSignInReturnedPSN, this, app.GetStringTable()); - return; - }*/ -#elif defined __ORBIS__ - m_eAction=eAction_RunLeaderboardsPSN; - // Determine why they're not "signed in live" - if (ProfileManager.isSignedInPSN(iPad)) - { - // Signed in to PSN but not connected (no internet access) - assert(!ProfileManager.isConnectedToPSN(iPad)); - - UINT uiIDA[1]; - uiIDA[0] = IDS_OK; - ui.RequestErrorMessage( IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, iPad); - } - else - { - // Not signed in to PSN - UINT uiIDA[1]; - uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; - ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad(), &UIScene_MainMenu::MustSignInReturnedPSN, this); - return; - } -#else - ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_XBOXLIVE_NOTIFICATION, uiIDA, 1); -#endif - } - else - { - // we're supposed to check for parental control restrictions before showing leaderboards - // The title enforces the user's NP parental control setting for age-based content - //restriction in network communications. - // If age restrictions are in place and the user's age does not meet - // the age restriction of the title's online service content rating (CERO, ESRB, PEGI, etc.), then the title must - //display a message such as the following and disallow online service for this user. - - bool bContentRestricted=false; -#if defined(__PS3__) || defined(__PSVITA__) - ProfileManager.GetChatAndContentRestrictions(iPad,true,nullptr,&bContentRestricted,nullptr); -#endif - if(bContentRestricted) - { -#if !(defined(_XBOX) || defined(_WINDOWS64) || defined(_XBOX_ONE)) // 4J Stu - Temp to get the win build running, but so we check this for other platforms - // you can't see leaderboards - UINT uiIDA[1]; - uiIDA[0]=IDS_CONFIRM_OK; - ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad(),nullptr,this); -#endif - } - else - { - ProfileManager.SetLockedProfile(iPad); - // If the player was signed in before selecting play, we'll not have read the profile yet, so query the sign-in status to get this to happen - ProfileManager.QuerySigninStatus(); - -#ifdef _XBOX_ONE - ui.ShowPlayerDisplayname(true); -#endif - proceedToScene(iPad, eUIScene_LeaderboardsMenu); - } - } -} -void UIScene_MainMenu::RunUnlockOrDLC(int iPad) -{ - UINT uiIDA[1]; - uiIDA[0]=IDS_OK; - - // Check if this means downloadable content - if(ProfileManager.IsFullVersion()) - { -#ifdef __ORBIS__ - // 4J-PB - Check if there is a patch for the game - m_errorCode = ProfileManager.getNPAvailability(ProfileManager.GetPrimaryPad()); - - bool bPatchAvailable; - switch(m_errorCode) - { - case SCE_NP_ERROR_LATEST_PATCH_PKG_EXIST: - case SCE_NP_ERROR_LATEST_PATCH_PKG_DOWNLOADED: - bPatchAvailable=true; - break; - default: - bPatchAvailable=false; - break; - } - - if(bPatchAvailable) - { - m_bIgnorePress=false; - - int32_t ret=sceErrorDialogInitialize(); - m_bErrorDialogRunning=true; - if ( ret==SCE_OK ) - { - SceErrorDialogParam param; - sceErrorDialogParamInitialize( ¶m ); - // 4J-PB - We want to display the option to get the patch now - param.errorCode = SCE_NP_ERROR_LATEST_PATCH_PKG_DOWNLOADED;//pClass->m_errorCode; - ret = sceUserServiceGetInitialUser( ¶m.userId ); - if ( ret == SCE_OK ) - { - ret=sceErrorDialogOpen( ¶m ); - } - } - -// UINT uiIDA[1]; -// uiIDA[0]=IDS_OK; -// ui.RequestMessageBox(IDS_PATCH_AVAILABLE_TITLE, IDS_PATCH_AVAILABLE_TEXT, uiIDA, 1, XUSER_INDEX_ANY,nullptr,this); - return; - } - - // Check if PSN is unavailable because of age restriction - if (m_errorCode == SCE_NP_ERROR_AGE_RESTRICTION) - { - m_bIgnorePress=false; - UINT uiIDA[1]; - uiIDA[0] = IDS_OK; - ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad(), nullptr, this); - - return; - } -#endif - // downloadable content - if(ProfileManager.IsSignedInLive(iPad)) - { - if(ProfileManager.IsGuest(iPad)) - { - m_bIgnorePress=false; - ui.RequestErrorMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); - } - else - { - - // If the player was signed in before selecting play, we'll not have read the profile yet, so query the sign-in status to get this to happen - ProfileManager.QuerySigninStatus(); - -#if defined _XBOX_ONE - if(app.GetTMSDLCInfoRead()) -#endif - { - bool bContentRestricted=false; -#if defined(__PS3__) || defined(__PSVITA__) - ProfileManager.GetChatAndContentRestrictions(iPad,true,nullptr,&bContentRestricted,nullptr); -#endif - if(bContentRestricted) - { - m_bIgnorePress=false; -#if !(defined(_XBOX) || defined(_WINDOWS64) || defined(_XBOX_ONE)) // 4J Stu - Temp to get the win build running, but so we check this for other platforms - // you can't see the store - UINT uiIDA[1]; - uiIDA[0]=IDS_CONFIRM_OK; - ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad(),nullptr,this); -#endif - } - else - { - ProfileManager.SetLockedProfile(iPad); -#ifdef _XBOX_ONE - ui.ShowPlayerDisplayname(true); -#endif - proceedToScene(ProfileManager.GetPrimaryPad(), eUIScene_DLCMainMenu); - } - } -#if defined _XBOX_ONE - else - { - // Changing to async TMS calls - app.SetTMSAction(iPad,eTMSAction_TMSPP_RetrieveFiles_DLCMain); - - // block all input - m_bIgnorePress=true; - // We want to hide everything in this scene and display a timer until we get a completion for the TMS files -// for(int i=0;iRecordUpsellPresented(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID); - ProfileManager.DisplayFullVersionPurchase(false,iPad,eSen_UpsellID_Full_Version_Of_Game); -#endif - } - } -} - -void UIScene_MainMenu::tick() -{ - UIScene::tick(); - - if ( (eNavigateWhenReady >= 0) ) - { - - int lockedProfile = ProfileManager.GetLockedProfile(); - -#ifdef _DURANGO - // 4J-JEV: DLC menu contains text localised to system language which we can't change. - // We need to switch to this language in-case it uses a different font. - if (eNavigateWhenReady == eUIScene_DLCMainMenu) setLanguageOverride(false); - - bool isSignedIn; - C4JStorage::eOptionsCallback status; - bool pendingFontChange; - if (lockedProfile >= 0) - { - isSignedIn = ProfileManager.IsSignedIn(lockedProfile); - status = app.GetOptionsCallbackStatus(lockedProfile); - pendingFontChange = ui.PendingFontChange(); - - if(status == C4JStorage::eOptions_Callback_Idle) - { - // make sure the TMS banned list data is ditched - the player may have gone in to help & options, backed out, and signed out - app.InvalidateBannedList(lockedProfile); - - // need to ditch any DLCOffers info - StorageManager.ClearDLCOffers(); - app.ClearAndResetDLCDownloadQueue(); - app.ClearDLCInstalled(); - } - } - - if ( (lockedProfile >= 0) - && isSignedIn - && ((status == C4JStorage::eOptions_Callback_Read)||(status == C4JStorage::eOptions_Callback_Write)) - && !pendingFontChange - ) -#endif - { - app.DebugPrintf("[MainMenu] Navigating away from MainMenu.\n"); - ui.NavigateToScene(lockedProfile, eNavigateWhenReady); - eNavigateWhenReady = static_cast(-1); - } -#ifdef _DURANGO - else - { - app.DebugPrintf("[MainMenu] Delaying navigation: lockedProfile=%i, %s, status=%ls, %s.\n", - lockedProfile, - isSignedIn ? "SignedIn" : "SignedOut", - app.toStringOptionsStatus(status).c_str(), - pendingFontChange ? "Pending font change" : "font OK"); - } -#endif - } - -#if defined(__PS3__) || defined (__ORBIS__) || defined(__PSVITA__) - if(m_bLaunchFullVersionPurchase) - { - int iCommerceState=app.GetCommerceState(); - // 4J-PB - if there's a commerce error - store down, player can't access store - let the DisplayFullVersionPurchase show the error - if((iCommerceState==CConsoleMinecraftApp::eCommerce_State_Online) || (iCommerceState==CConsoleMinecraftApp::eCommerce_State_Error)) - { - m_bLaunchFullVersionPurchase=false; - m_bIgnorePress=false; - updateTooltips(); - - // 4J-PB - need to check this user can access the store - bool bContentRestricted=false; - ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,nullptr,&bContentRestricted,nullptr); - if(bContentRestricted) - { - UINT uiIDA[1]; - uiIDA[0]=IDS_CONFIRM_OK; - ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); - } - else - { - TelemetryManager->RecordUpsellPresented(ProfileManager.GetPrimaryPad(), eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID); - ProfileManager.DisplayFullVersionPurchase(false,ProfileManager.GetPrimaryPad(),eSen_UpsellID_Full_Version_Of_Game); - } - } - } - - // 4J-PB - check for a trial version changing to a full version - if(m_bTrialVersion) - { - if(ProfileManager.IsFullVersion()) - { - m_bTrialVersion=false; - m_buttons[(int)eControl_UnlockOrDLC].init(app.GetString(IDS_DOWNLOADABLECONTENT),eControl_UnlockOrDLC); - } - } -#endif - -#if defined _XBOX_ONE - if(m_bWaitingForDLCInfo) - { - if(app.GetTMSDLCInfoRead()) - { - m_bWaitingForDLCInfo=false; - ProfileManager.SetLockedProfile(m_iPad); - proceedToScene(ProfileManager.GetPrimaryPad(), eUIScene_DLCMainMenu); - } - } - - if(g_NetworkManager.ShouldMessageForFullSession()) - { - UINT uiIDA[1]; - uiIDA[0]=IDS_CONFIRM_OK; - ui.RequestErrorMessage( IDS_CONNECTION_FAILED, IDS_IN_PARTY_SESSION_FULL, uiIDA,1,ProfileManager.GetPrimaryPad()); - } -#endif - -#ifdef __ORBIS__ - - // process the error dialog (for a patch being available) - // SQRNetworkManager_Orbis::tickErrorDialog also runs the error dialog, so wrap this so this doesn't terminate a signin dialog - if(m_bErrorDialogRunning) - { - SceErrorDialogStatus stat = sceErrorDialogUpdateStatus(); - if( stat == SCE_ERROR_DIALOG_STATUS_FINISHED ) - { - sceErrorDialogTerminate(); - // if m_bRunGameChosen is true, we're here after selecting play game, and we should let the user continue with an offline game - if(m_bRunGameChosen) - { - m_bRunGameChosen=false; - m_eAction = eAction_RunGame; - - // give the option of continuing offline - UINT uiIDA[1]; - uiIDA[0]=IDS_PRO_NOTONLINE_DECLINE; - ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION_PATCH_AVAILABLE, uiIDA, 1, ProfileManager.GetPrimaryPad(), &UIScene_MainMenu::PlayOfflineReturned, this); - - } - m_bErrorDialogRunning=false; - } - } - - if(m_bLoadTrialOnNetworkManagerReady && g_NetworkManager.IsReadyToPlayOrIdle()) - { - m_bLoadTrialOnNetworkManagerReady = false; - LoadTrial(); - } - -#endif -} - -void UIScene_MainMenu::RunAchievements(int iPad) -{ -#if TO_BE_IMPLEMENTED - UINT uiIDA[1]; - uiIDA[0]=IDS_OK; - - // guests can't look at achievements - if(ProfileManager.IsGuest(iPad)) - { - ui.RequestErrorMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); - } - else - { - XShowAchievementsUI( iPad ); - } -#endif - ui.NavigateToScene(iPad, eUIScene_AchievementsMenu); -} - -void UIScene_MainMenu::RunHelpAndOptions(int iPad) -{ - if(ProfileManager.IsGuest(iPad)) - { - UINT uiIDA[1]; - uiIDA[0]=IDS_OK; - ui.RequestErrorMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); - } - else - { - // If the player was signed in before selecting play, we'll not have read the profile yet, so query the sign-in status to get this to happen - ProfileManager.QuerySigninStatus(); - -#if TO_BE_IMPLEMENTED - // 4J-PB - You can be offline and still can go into help and options - if(app.GetTMSDLCInfoRead() || !ProfileManager.IsSignedInLive(iPad)) -#endif - { - ProfileManager.SetLockedProfile(iPad); -#ifdef _XBOX_ONE - ui.ShowPlayerDisplayname(true); -#endif - proceedToScene(iPad, eUIScene_HelpAndOptionsMenu); - } -#if TO_BE_IMPLEMENTED - else - { - // Changing to async TMS calls - app.SetTMSAction(iPad,eTMSAction_TMSPP_RetrieveFiles_HelpAndOptions); - - // block all input - m_bIgnorePress=true; - // We want to hide everything in this scene and display a timer until we get a completion for the TMS files - for(int i=0;iseed = 0; - param->saveData = nullptr; - param->settings = app.GetGameHostOption( eGameHostOption_Tutorial ) | app.GetGameHostOption(eGameHostOption_DisableSaving); - - vector *generators = app.getLevelGenerators(); - param->levelGen = generators->at(0); - - LoadingInputParams *loadingParams = new LoadingInputParams(); - loadingParams->func = &CGameNetworkManager::RunNetworkGameThreadProc; - loadingParams->lpParam = static_cast(param); - - UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); - completionData->bShowBackground=TRUE; - completionData->bShowLogo=TRUE; - completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes; - completionData->iPad = ProfileManager.GetPrimaryPad(); - loadingParams->completionData = completionData; - - ui.ShowTrialTimer(true); - -#ifdef _XBOX_ONE - ui.ShowPlayerDisplayname(true); -#endif - ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); -} - -void UIScene_MainMenu::handleUnlockFullVersion() -{ - m_buttons[static_cast(eControl_UnlockOrDLC)].setLabel(IDS_DOWNLOADABLECONTENT,true); -} - - -#ifdef __PSVITA__ -int UIScene_MainMenu::SelectNetworkModeReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) -{ - UIScene_MainMenu* pClass = (UIScene_MainMenu*)pParam; - - if(result==C4JStorage::EMessage_ResultAccept) - { - app.DebugPrintf("Setting network mode to PSN\n"); - app.SetGameSettings(0, eGameSetting_PSVita_NetworkModeAdhoc, 0); - } - else if(result==C4JStorage::EMessage_ResultDecline) - { - app.DebugPrintf("Setting network mode to Adhoc\n"); - app.SetGameSettings(0, eGameSetting_PSVita_NetworkModeAdhoc, 1); - } - pClass->updateTooltips(); - return 0; -} -#endif //__PSVITA__ +#include "stdafx.h" +#include "../../../Minecraft.World/Mth.h" +#include "../../../Minecraft.World/StringHelpers.h" +#include "../../../Minecraft.World/Random.h" +#include "../../User.h" +#include "../../MinecraftServer.h" +#include "UI.h" +#include "UIScene_MainMenu.h" +#ifdef __ORBIS__ +#include +#endif + +Random *UIScene_MainMenu::random = new Random(); + +EUIScene UIScene_MainMenu::eNavigateWhenReady = static_cast(-1); + +UIScene_MainMenu::UIScene_MainMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer) +{ +#ifdef __ORBIS + //m_ePatchCheckState=ePatchCheck_Idle; + m_bRunGameChosen=false; + m_bErrorDialogRunning=false; +#endif + + + // Setup all the Iggy references we need for this scene + initialiseMovie(); + + parentLayer->addComponent(iPad,eUIComponent_Panorama); + parentLayer->addComponent(iPad,eUIComponent_Logo); + + m_eAction=eAction_None; + m_bIgnorePress=false; + + + m_buttons[static_cast(eControl_PlayGame)].init(IDS_PLAY_GAME,eControl_PlayGame); + m_buttons[(int)eControl_MiniGames].init(L"Mini Games",eControl_MiniGames); + +#ifdef _XBOX_ONE + if(!ProfileManager.IsFullVersion()) m_buttons[(int)eControl_PlayGame].setLabel(IDS_PLAY_TRIAL_GAME); + app.SetReachedMainMenu(); +#endif + + m_buttons[static_cast(eControl_Leaderboards)].init(IDS_LEADERBOARDS,eControl_Leaderboards); + m_buttons[static_cast(eControl_Achievements)].init( (UIString)IDS_ACHIEVEMENTS,eControl_Achievements); + m_buttons[static_cast(eControl_HelpAndOptions)].init(IDS_HELP_AND_OPTIONS,eControl_HelpAndOptions); + if(ProfileManager.IsFullVersion()) + { + m_bTrialVersion=false; + m_buttons[static_cast(eControl_UnlockOrDLC)].init(IDS_DOWNLOADABLECONTENT,eControl_UnlockOrDLC); + } + else + { + m_bTrialVersion=true; + m_buttons[static_cast(eControl_UnlockOrDLC)].init(IDS_UNLOCK_FULL_GAME,eControl_UnlockOrDLC); + } + +#ifndef _DURANGO + m_buttons[static_cast(eControl_Exit)].init(app.GetString(IDS_EXIT_GAME),eControl_Exit); +#else + m_buttons[(int)eControl_XboxHelp].init(IDS_XBOX_HELP_APP, eControl_XboxHelp); +#endif + + removeControl( &m_buttons[(int)eControl_MiniGames], false ); + int controlType = app.GetGameSettings(m_iPad, eGameSetting_ControlType); + if (controlType == 3 || controlType == 4) + { + // ps3, ps4 + removeControl( &m_buttons[(int)eControl_Exit], false ); + // We don't have a way to display trophies/achievements, so remove the button + removeControl( &m_buttons[(int)eControl_Achievements], false ); + } + else if (controlType == 1) + { + // xbox one + removeControl( &m_buttons[(int)eControl_Achievements], false ); + } + else if (controlType == 5) + { + // wiiU + removeControl( &m_buttons[(int)eControl_Leaderboards], false ); + } + +#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) + m_bLaunchFullVersionPurchase=false; +#endif +#ifdef _DURANGO + // Allowed to not have achievements in the menu + //removeControl( &m_buttons[(int)eControl_Achievements], false ); + // Not allowed to exit from a Xbox One game from the game - have to use the Home button + //removeControl( &m_buttons[(int)eControl_Exit], false ); + m_bWaitingForDLCInfo=false; +#endif + + doHorizontalResizeCheck(); + + m_splash = L""; + + wstring filename = L"splashes.txt"; + if( app.hasArchiveFile(filename) ) + { + byteArray splashesArray = app.getArchiveFile(filename); + ByteArrayInputStream bais(splashesArray); + InputStreamReader isr( &bais ); + BufferedReader br( &isr ); + + wstring line = L""; + while ( !(line = br.readLine()).empty() ) + { + line = trimString( line ); + if (line.length() > 0) + { + m_splashes.push_back(line); + } + } + + br.close(); + } + + m_bIgnorePress=false; + m_bLoadTrialOnNetworkManagerReady = false; + + // 4J Stu - Clear out any loaded game rules + app.setLevelGenerationOptions(nullptr); + + // 4J Stu - Reset the leaving game flag so that we correctly handle signouts while in the menus + g_NetworkManager.ResetLeavingGame(); + +#if TO_BE_IMPLEMENTED + // Fix for #45154 - Frontend: DLC: Content can only be downloaded from the frontend if you have not joined/exited multiplayer + XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); +#endif +} + +UIScene_MainMenu::~UIScene_MainMenu() +{ + m_parentLayer->removeComponent(eUIComponent_Panorama); + m_parentLayer->removeComponent(eUIComponent_Logo); +} + +void UIScene_MainMenu::updateTooltips() +{ + int iX = -1; + int iA = -1; + if(!m_bIgnorePress) + { + iA = IDS_TOOLTIPS_SELECT; + +#ifdef _XBOX_ONE + iX = IDS_TOOLTIPS_CHOOSE_USER; +#elif defined __PSVITA__ + if(ProfileManager.IsFullVersion()) + { + iX = IDS_TOOLTIP_CHANGE_NETWORK_MODE; + } +#endif + } + ui.SetTooltips( DEFAULT_XUI_MENU_USER, iA, -1, iX); +} + +void UIScene_MainMenu::updateComponents() +{ + m_parentLayer->showComponent(m_iPad,eUIComponent_Panorama,true); + m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,true); +} + +void UIScene_MainMenu::handleGainFocus(bool navBack) +{ + UIScene::handleGainFocus(navBack); + handleReload(); + ui.ShowPlayerDisplayname(false); + m_bIgnorePress=false; + + if (eNavigateWhenReady >= 0) + { + return; + } + + // 4J-JEV: This needs to come before SetLockedProfile(-1) as it wipes the XbLive contexts. + if (!navBack) + { + for (int iPad = 0; iPad < MAX_LOCAL_PLAYERS; iPad++) + { + // For returning to menus after exiting a game. + if (ProfileManager.IsSignedIn(iPad) ) + { + ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + } + } + } + ProfileManager.SetLockedProfile(-1); + + m_bIgnorePress = false; + updateTooltips(); + +#ifdef _DURANGO + ProfileManager.ClearGameUsers(); +#endif + + if(navBack && ProfileManager.IsFullVersion()) + { + // Replace the Unlock Full Game with Downloadable Content + m_buttons[static_cast(eControl_UnlockOrDLC)].setLabel(IDS_DOWNLOADABLECONTENT); + } + +#if TO_BE_IMPLEMENTED + // Fix for #45154 - Frontend: DLC: Content can only be downloaded from the frontend if you have not joined/exited multiplayer + XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); + m_Timer.SetShow(FALSE); +#endif + m_controlTimer.setVisible( false ); + + // 4J-PB - remove the "hobo humping" message legal say we can't have, and the 1080p one for Vita +#ifdef __PSVITA__ + int splashIndex = eSplashRandomStart + 2 + random->nextInt( (int)m_splashes.size() - (eSplashRandomStart + 2) ); +#else + int splashIndex = eSplashRandomStart + 1 + random->nextInt( static_cast(m_splashes.size()) - (eSplashRandomStart + 1) ); +#endif + + // Override splash text on certain dates + SYSTEMTIME LocalSysTime; + GetLocalTime( &LocalSysTime ); + if (LocalSysTime.wMonth == 11 && LocalSysTime.wDay == 9) + { + splashIndex = eSplashHappyBirthdayEx; + } + else if (LocalSysTime.wMonth == 6 && LocalSysTime.wDay == 1) + { + splashIndex = eSplashHappyBirthdayNotch; + } + else if (LocalSysTime.wMonth == 12 && LocalSysTime.wDay == 24) // the Java game shows this on Christmas Eve, so we will too + { + splashIndex = eSplashMerryXmas; + } + else if (LocalSysTime.wMonth == 1 && LocalSysTime.wDay == 1) + { + splashIndex = eSplashHappyNewYear; + } + //splashIndex = 47; // Very short string + //splashIndex = 194; // Very long string + //splashIndex = 295; // Coloured + //splashIndex = 296; // Noise + m_splash = m_splashes.at( splashIndex ); +} + +wstring UIScene_MainMenu::getMoviePath() +{ + return L"MainMenu"; +} + +void UIScene_MainMenu::handleReload() +{ + removeControl( &m_buttons[(int)eControl_MiniGames], false ); + int controlType = app.GetGameSettings(m_iPad, eGameSetting_ControlType); + if (controlType == 3 || controlType == 4) + { + // ps3, ps4 + removeControl( &m_buttons[(int)eControl_Exit], false ); + // We don't have a way to display trophies/achievements, so remove the button + removeControl( &m_buttons[(int)eControl_Achievements], false ); + } + else if (controlType == 1) + { + // xbox one + removeControl( &m_buttons[(int)eControl_Achievements], false ); + } + else if (controlType == 5) + { + // wiiu + removeControl( &m_buttons[(int)eControl_Leaderboards], false ); + } +} + +void UIScene_MainMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled) +{ + //app.DebugPrintf("UIScene_DebugOverlay handling input for pad %d, key %d, down- %s, pressed- %s, released- %s\n", iPad, key, down?"TRUE":"FALSE", pressed?"TRUE":"FALSE", released?"TRUE":"FALSE"); + + if ( m_bIgnorePress || (eNavigateWhenReady >= 0) ) return; + +#if defined (__ORBIS__) || defined (__PSVITA__) + // ignore all players except player 0 - it's their profile that is currently being used + if(iPad!=0) return; +#endif + + ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released); + + switch(key) + { + case ACTION_MENU_OK: +#ifdef __ORBIS__ + case ACTION_MENU_TOUCHPAD_PRESS: +#endif + if(pressed) + { + ProfileManager.SetPrimaryPad(iPad); + ProfileManager.SetLockedProfile(-1); + sendInputToMovie(key, repeat, pressed, released); + } + break; +#ifdef _XBOX_ONE + case ACTION_MENU_X: + if(pressed) + { + m_bIgnorePress = true; + ProfileManager.RequestSignInUI(false, false, false, false, false, ChooseUser_SignInReturned, this, iPad); + } + break; +#endif +#ifdef __PSVITA__ + case ACTION_MENU_X: + if(pressed && ProfileManager.IsFullVersion()) + { + UINT uiIDA[2]; + uiIDA[0]=IDS__NETWORK_PSN; + uiIDA[1]=IDS_NETWORK_ADHOC; + ui.RequestErrorMessage(IDS_SELECT_NETWORK_MODE_TITLE, IDS_SELECT_NETWORK_MODE_TEXT, uiIDA, 2, XUSER_INDEX_ANY, &UIScene_MainMenu::SelectNetworkModeReturned,this); + } + break; +#endif + + case ACTION_MENU_UP: + case ACTION_MENU_DOWN: + sendInputToMovie(key, repeat, pressed, released); + break; + } +} + +void UIScene_MainMenu::handlePress(F64 controlId, F64 childId) +{ + int primaryPad = ProfileManager.GetPrimaryPad(); + +#ifdef _XBOX_ONE + int (*signInReturnedFunc) (LPVOID,const bool, const int iPad, const int iController) = nullptr; +#else + int (*signInReturnedFunc) (LPVOID,const bool, const int iPad) = nullptr; +#endif + + switch(static_cast(controlId)) + { + case eControl_PlayGame: +#ifdef __ORBIS__ + { + m_bIgnorePress=true; + + //CD - Added for audio + ui.PlayUISFX(eSFX_Press); + + ProfileManager.RefreshChatAndContentRestrictions(RefreshChatAndContentRestrictionsReturned_PlayGame, this); + } +#else + m_eAction=eAction_RunGame; + //CD - Added for audio + ui.PlayUISFX(eSFX_Press); + + signInReturnedFunc = &UIScene_MainMenu::CreateLoad_SignInReturned; +#endif + break; + case eControl_MiniGames: + #ifdef __ORBIS__ + { + m_bIgnorePress=true; + + //CD - Added for audio + ui.PlayUISFX(eSFX_Press); + + ProfileManager.RefreshChatAndContentRestrictions(RefreshChatAndContentRestrictionsReturned_PlayGame, this); + } +#else + m_eAction=eAction_RunGame; + //CD - Added for audio + ui.PlayUISFX(eSFX_Press); + + signInReturnedFunc = &UIScene_MainMenu::CreateLoad_SignInReturned; +#endif + break; + case eControl_Leaderboards: + //CD - Added for audio + ui.PlayUISFX(eSFX_Press); +#ifdef __ORBIS__ + ProfileManager.RefreshChatAndContentRestrictions(RefreshChatAndContentRestrictionsReturned_Leaderboards, this); +#else + m_eAction=eAction_RunLeaderboards; + signInReturnedFunc = &UIScene_MainMenu::Leaderboards_SignInReturned; +#endif + break; + case eControl_Achievements: + //CD - Added for audio + ui.PlayUISFX(eSFX_Press); + + m_eAction=eAction_RunAchievements; + signInReturnedFunc = &UIScene_MainMenu::Achievements_SignInReturned; + break; + case eControl_HelpAndOptions: + //CD - Added for audio + ui.PlayUISFX(eSFX_Press); + + m_eAction=eAction_RunHelpAndOptions; + signInReturnedFunc = &UIScene_MainMenu::HelpAndOptions_SignInReturned; + break; + case eControl_UnlockOrDLC: + //CD - Added for audio + ui.PlayUISFX(eSFX_Press); + + m_eAction=eAction_RunUnlockOrDLC; + signInReturnedFunc = &UIScene_MainMenu::UnlockFullGame_SignInReturned; + break; + case eControl_Exit: + //CD - Added for audio + ui.PlayUISFX(eSFX_Press); + + if( ProfileManager.IsFullVersion() ) + { + UINT uiIDA[2]; + uiIDA[0]=IDS_CANCEL; + uiIDA[1]=IDS_OK; + ui.RequestErrorMessage(IDS_WINDOWS_EXIT, IDS_WARNING_ARCADE_TEXT, uiIDA, 2, XUSER_INDEX_ANY,&UIScene_MainMenu::ExitGameReturned,this); + } + else + { +#ifdef _XBOX +#ifdef _XBOX_ONE + ui.ShowPlayerDisplayname(true); +#endif + ui.NavigateToScene(primaryPad,eUIScene_TrialExitUpsell); +#endif + } + break; + +#ifdef _DURANGO + case eControl_XboxHelp: + ui.PlayUISFX(eSFX_Press); + + m_eAction=eAction_RunXboxHelp; + signInReturnedFunc = &UIScene_MainMenu::XboxHelp_SignInReturned; + break; +#endif + + default: DEBUG_BREAK(); + } + + bool confirmUser = false; + + // Note: if no sign in returned func, assume this isn't required + if (signInReturnedFunc != nullptr) + { + if(ProfileManager.IsSignedIn(primaryPad)) + { + if (confirmUser) + { + ProfileManager.RequestSignInUI(false, false, true, false, true, signInReturnedFunc, this, primaryPad); + } + else + { + RunAction(primaryPad); + } + } + else + { + // Ask user to sign in + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_OK; + uiIDA[1]=IDS_CONFIRM_CANCEL; + ui.RequestErrorMessage(IDS_MUST_SIGN_IN_TITLE, IDS_MUST_SIGN_IN_TEXT, uiIDA, 2, primaryPad, &UIScene_MainMenu::MustSignInReturned, this); + } + } +} + +// Run current action +void UIScene_MainMenu::RunAction(int iPad) +{ + switch(m_eAction) + { + case eAction_RunGame: + RunPlayGame(iPad); + break; + case eAction_RunLeaderboards: + RunLeaderboards(iPad); + break; + case eAction_RunAchievements: + RunAchievements(iPad); + break; + case eAction_RunHelpAndOptions: + RunHelpAndOptions(iPad); + break; + case eAction_RunUnlockOrDLC: + RunUnlockOrDLC(iPad); + break; +#ifdef _DURANGO + case eAction_RunXboxHelp: + // 4J: Launch the dummy xbox help application. + WXS::User^ user = ProfileManager.GetUser(ProfileManager.GetPrimaryPad()); + Windows::Xbox::ApplicationModel::Help::Show(user); + break; +#endif + } +} + +void UIScene_MainMenu::customDraw(IggyCustomDrawCallbackRegion *region) +{ + if(wcscmp((wchar_t *)region->name,L"Splash")==0) + { + PIXBeginNamedEvent(0,"Custom draw splash"); + customDrawSplash(region); + PIXEndNamedEvent(); + } +} + +void UIScene_MainMenu::customDrawSplash(IggyCustomDrawCallbackRegion *region) +{ + Minecraft *pMinecraft = Minecraft::GetInstance(); + + // 4J Stu - Move this to the ctor when the main menu is not the first scene we navigate to + ScreenSizeCalculator ssc(pMinecraft->options, pMinecraft->width_phys, pMinecraft->height_phys); + m_fScreenWidth=static_cast(pMinecraft->width_phys); + m_fRawWidth=static_cast(ssc.rawWidth); + m_fScreenHeight=static_cast(pMinecraft->height_phys); + m_fRawHeight=static_cast(ssc.rawHeight); + + + // Setup GDraw, normal game render states and matrices + CustomDrawData *customDrawRegion = ui.setupCustomDraw(this,region); + delete customDrawRegion; + + + Font *font = pMinecraft->font; + + // build and render with the game call + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + + glPushMatrix(); + + float width = region->x1 - region->x0; + float height = region->y1 - region->y0; + float xo = width/2; + float yo = height; + + glTranslatef(xo, yo, 0); + + glRotatef(-17, 0, 0, 1); + float sss = 1.8f - Mth::abs(Mth::sin(System::currentTimeMillis() % 1000 / 1000.0f * PI * 2) * 0.1f); + sss*=(m_fScreenWidth/m_fRawWidth); + + sss = sss * 100 / (font->width(m_splash) + 8 * 4); + glScalef(sss, sss, sss); + //drawCenteredString(font, splash, 0, -8, 0xffff00); + font->drawShadow(m_splash, 0 - (font->width(m_splash)) / 2, -8, 0xffff00); + glPopMatrix(); + + glDisable(GL_RESCALE_NORMAL); + + glEnable(GL_DEPTH_TEST); + + + // Finish GDraw and anything else that needs to be finalised + ui.endCustomDraw(region); +} + +int UIScene_MainMenu::MustSignInReturned(void *pParam, int iPad, C4JStorage::EMessageResult result) +{ + UIScene_MainMenu* pClass = static_cast(pParam); + + if(result==C4JStorage::EMessage_ResultAccept) + { + // we need to specify local game here to display local and LIVE profiles in the list + switch(pClass->m_eAction) + { + case eAction_RunGame: ProfileManager.RequestSignInUI(false, true, false, false, true, &UIScene_MainMenu::CreateLoad_SignInReturned, pClass, iPad ); break; + case eAction_RunHelpAndOptions: ProfileManager.RequestSignInUI(false, false, true, false, true, &UIScene_MainMenu::HelpAndOptions_SignInReturned, pClass, iPad ); break; + case eAction_RunLeaderboards: ProfileManager.RequestSignInUI(false, false, true, false, true, &UIScene_MainMenu::Leaderboards_SignInReturned, pClass, iPad ); break; + case eAction_RunAchievements: ProfileManager.RequestSignInUI(false, false, true, false, true, &UIScene_MainMenu::Achievements_SignInReturned, pClass, iPad ); break; + case eAction_RunUnlockOrDLC: ProfileManager.RequestSignInUI(false, false, true, false, true, &UIScene_MainMenu::UnlockFullGame_SignInReturned, pClass, iPad ); break; +#ifdef _DURANGO + case eAction_RunXboxHelp: ProfileManager.RequestSignInUI(false, false, true, false, true, &UIScene_MainMenu::XboxHelp_SignInReturned, pClass, iPad ); break; +#endif + } + } + else + { + pClass->m_bIgnorePress=false; + // unlock the profile + ProfileManager.SetLockedProfile(-1); + for(int i=0;im_eAction) + { + case eAction_RunLeaderboardsPSN: + SQRNetworkManager_PS3::AttemptPSNSignIn(&UIScene_MainMenu::Leaderboards_SignInReturned, pClass); + break; + case eAction_RunGamePSN: + SQRNetworkManager_PS3::AttemptPSNSignIn(&UIScene_MainMenu::CreateLoad_SignInReturned, pClass); + break; + case eAction_RunUnlockOrDLCPSN: + SQRNetworkManager_PS3::AttemptPSNSignIn(&UIScene_MainMenu::UnlockFullGame_SignInReturned, pClass); + break; + } +#elif defined __PSVITA__ + switch(pClass->m_eAction) + { + case eAction_RunLeaderboardsPSN: + //CD - Must force Ad-Hoc off if they want leaderboard PSN sign-in + //Save settings change + app.SetGameSettings(0, eGameSetting_PSVita_NetworkModeAdhoc, 0); + //Force off + CGameNetworkManager::setAdhocMode(false); + //Now Sign-in + SQRNetworkManager_Vita::AttemptPSNSignIn(&UIScene_MainMenu::Leaderboards_SignInReturned, pClass); + break; + case eAction_RunGamePSN: + if(CGameNetworkManager::usingAdhocMode()) + { + SQRNetworkManager_AdHoc_Vita::AttemptAdhocSignIn(&UIScene_MainMenu::CreateLoad_SignInReturned, pClass); + } + else + { + SQRNetworkManager_Vita::AttemptPSNSignIn(&UIScene_MainMenu::CreateLoad_SignInReturned, pClass); + + } + break; + case eAction_RunUnlockOrDLCPSN: + //CD - Must force Ad-Hoc off if they want commerce PSN sign-in + //Save settings change + app.SetGameSettings(0, eGameSetting_PSVita_NetworkModeAdhoc, 0); + //Force off + CGameNetworkManager::setAdhocMode(false); + //Now Sign-in + SQRNetworkManager_Vita::AttemptPSNSignIn(&UIScene_MainMenu::UnlockFullGame_SignInReturned, pClass); + break; + } +#else + switch(pClass->m_eAction) + { + case eAction_RunLeaderboardsPSN: + SQRNetworkManager_Orbis::AttemptPSNSignIn(&UIScene_MainMenu::Leaderboards_SignInReturned, pClass, true, iPad); + break; + case eAction_RunGamePSN: + SQRNetworkManager_Orbis::AttemptPSNSignIn(&UIScene_MainMenu::CreateLoad_SignInReturned, pClass, true, iPad); + break; + case eAction_RunUnlockOrDLCPSN: + SQRNetworkManager_Orbis::AttemptPSNSignIn(&UIScene_MainMenu::UnlockFullGame_SignInReturned, pClass, true, iPad); + break; + } + +#endif + } + else + { + if( pClass->m_eAction == eAction_RunGamePSN ) + { + if( result == C4JStorage::EMessage_Cancelled) + CreateLoad_SignInReturned(pClass, false, 0); + else + CreateLoad_SignInReturned(pClass, true, 0); + } + else + { + pClass->m_bIgnorePress=false; + } + } + + return 0; +} +#endif + +#ifdef _XBOX_ONE +int UIScene_MainMenu::HelpAndOptions_SignInReturned(void *pParam,bool bContinue,int iPad, int iController) +#else +int UIScene_MainMenu::HelpAndOptions_SignInReturned(void *pParam,bool bContinue,int iPad) +#endif +{ + UIScene_MainMenu *pClass = static_cast(pParam); + + if(bContinue) + { + // 4J-JEV: Don't we only need to update rich-presence if the sign-in status changes. + ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + +#if TO_BE_IMPLEMENTED + if(app.GetTMSDLCInfoRead()) +#endif + { + ProfileManager.SetLockedProfile(ProfileManager.GetPrimaryPad()); +#ifdef _XBOX_ONE + ui.ShowPlayerDisplayname(true); +#endif + proceedToScene(iPad, eUIScene_HelpAndOptionsMenu); + } +#if TO_BE_IMPLEMENTED + else + { + // Changing to async TMS calls + app.SetTMSAction(iPad,eTMSAction_TMSPP_RetrieveFiles_HelpAndOptions); + + // block all input + pClass->m_bIgnorePress=true; + // We want to hide everything in this scene and display a timer until we get a completion for the TMS files + for(int i=0;im_Buttons[i].SetShow(FALSE); + } + + pClass->updateTooltips(); + + pClass->m_Timer.SetShow(TRUE); + } +#endif + } + else + { + pClass->m_bIgnorePress=false; + // unlock the profile + ProfileManager.SetLockedProfile(-1); + for(int i=0;im_bIgnorePress = false; + pClass->updateTooltips(); + return 0; +} +#endif + +#ifdef _XBOX_ONE +int UIScene_MainMenu::CreateLoad_SignInReturned(void *pParam, bool bContinue, int iPad, int iController) +#else +int UIScene_MainMenu::CreateLoad_SignInReturned(void *pParam, bool bContinue, int iPad) +#endif +{ + UIScene_MainMenu* pClass = static_cast(pParam); + + if(bContinue) + { + // 4J-JEV: We only need to update rich-presence if the sign-in status changes. + ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + + UINT uiIDA[1] = { IDS_OK }; + + if(ProfileManager.IsGuest(ProfileManager.GetPrimaryPad())) + { + pClass->m_bIgnorePress=false; + ui.RequestErrorMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); + } + else + { + ProfileManager.SetLockedProfile(ProfileManager.GetPrimaryPad()); + + + // change the minecraft player name + Minecraft::GetInstance()->user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); + + if(ProfileManager.IsFullVersion()) + { + bool bSignedInLive = ProfileManager.IsSignedInLive(iPad); +#ifdef __PSVITA__ + if(CGameNetworkManager::usingAdhocMode()) + { + if(SQRNetworkManager_AdHoc_Vita::GetAdhocStatus()) + { + bSignedInLive = true; + } + else + { + // adhoc mode, but we didn't make the connection, turn off adhoc mode, and just go with whatever the regular online status is + CGameNetworkManager::setAdhocMode(false); + bSignedInLive = ProfileManager.IsSignedInLive(iPad); + } + } +#endif + + // Check if we're signed in to LIVE + if(bSignedInLive) + { + // 4J-PB - Need to check for installed DLC + if(!app.DLCInstallProcessCompleted()) app.StartInstallDLCProcess(iPad); + + if(ProfileManager.IsGuest(iPad)) + { + pClass->m_bIgnorePress=false; + ui.RequestErrorMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); + } + else + { + // 4J Stu - Not relevant to PS3 +#ifdef _XBOX_ONE +// if(app.GetTMSDLCInfoRead() && app.GetBanListRead(iPad)) + if(app.GetBanListRead(iPad)) + { + Minecraft *pMinecraft=Minecraft::GetInstance(); + pMinecraft->user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); + + // ensure we've applied this player's settings + app.ApplyGameSettingsChanged(iPad); + +#ifdef _XBOX_ONE + ui.ShowPlayerDisplayname(true); +#endif + proceedToScene(ProfileManager.GetPrimaryPad(), eUIScene_LoadCreateJoinMenu); + } + else + { + app.SetTMSAction(iPad,eTMSAction_TMSPP_RetrieveFiles_RunPlayGame); + + // block all input + pClass->m_bIgnorePress=true; + // We want to hide everything in this scene and display a timer until we get a completion for the TMS files + // for(int i=0;iupdateTooltips(); + + pClass->m_controlTimer.setVisible( true ); + } +#endif +#if TO_BE_IMPLEMENTED + // check if all the TMS files are loaded + if(app.GetTMSDLCInfoRead() && app.GetTMSXUIDsFileRead() && app.GetBanListRead(iPad)) + { + if(StorageManager.SetSaveDevice(&UIScene_MainMenu::DeviceSelectReturned,pClass)==true) + { + // save device already selected + + // ensure we've applied this player's settings + app.ApplyGameSettingsChanged(ProfileManager.GetPrimaryPad()); + // check for DLC + // start timer to track DLC check finished + pClass->m_Timer.SetShow(TRUE); + XuiSetTimer(pClass->m_hObj,DLC_INSTALLED_TIMER_ID,DLC_INSTALLED_TIMER_TIME); + //app.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_MultiGameJoinLoad); + } + } + else + { + // Changing to async TMS calls + app.SetTMSAction(iPad,eTMSAction_TMSPP_RetrieveFiles_RunPlayGame); + + // block all input + pClass->m_bIgnorePress=true; + // We want to hide everything in this scene and display a timer until we get a completion for the TMS files + for(int i=0;im_Buttons[i].SetShow(FALSE); + } + + updateTooltips(); + + pClass->m_Timer.SetShow(TRUE); + } +#else + Minecraft *pMinecraft=Minecraft::GetInstance(); + pMinecraft->user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); + + // ensure we've applied this player's settings + app.ApplyGameSettingsChanged(iPad); + +#ifdef _XBOX_ONE + ui.ShowPlayerDisplayname(true); +#endif + proceedToScene(ProfileManager.GetPrimaryPad(), eUIScene_LoadCreateJoinMenu); +#endif + } + } + else + { +#if TO_BE_IMPLEMENTED + // offline + ProfileManager.DisplayOfflineProfile(&CScene_Main::CreateLoad_OfflineProfileReturned,pClass, ProfileManager.GetPrimaryPad() ); +#else + app.DebugPrintf("Offline Profile returned not implemented\n"); +#ifdef _XBOX_ONE + ui.ShowPlayerDisplayname(true); +#endif + proceedToScene(ProfileManager.GetPrimaryPad(), eUIScene_LoadCreateJoinMenu); +#endif + } + } + else + { + // 4J-PB - if this is the trial game, we can't have any networking + // Can't apply the player's settings here - they haven't come back from the QuerySignInStatud call above yet. + // Need to let them action in the main loop when they come in + // ensure we've applied this player's settings + //app.ApplyGameSettingsChanged(iPad); + +#if defined(__PS3__) || defined(__ORBIS__) || defined( __PSVITA__) + // ensure we've applied this player's settings - we do have them on PS3 + app.ApplyGameSettingsChanged(iPad); +#endif + +#ifdef __ORBIS__ + if(!g_NetworkManager.IsReadyToPlayOrIdle()) + { + pClass->m_bLoadTrialOnNetworkManagerReady = true; + ui.NavigateToScene(iPad, eUIScene_Timer); + } + else +#endif + { + // go straight in to the trial level + LoadTrial(); + } + } + } + } + else + { + pClass->m_bIgnorePress=false; + + // unlock the profile + ProfileManager.SetLockedProfile(-1); + for(int i=0;i(pParam); + + if(bContinue) + { + // 4J-JEV: We only need to update rich-presence if the sign-in status changes. + ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + + UINT uiIDA[1] = { IDS_OK }; + + // guests can't look at leaderboards + if(ProfileManager.IsGuest(ProfileManager.GetPrimaryPad())) + { + pClass->m_bIgnorePress=false; + ui.RequestErrorMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); + } + else if(!ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad())) + { + pClass->m_bIgnorePress=false; + ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_XBOXLIVE_NOTIFICATION, uiIDA, 1); + } + else + { + bool bContentRestricted=false; +#if defined(__PS3__) || defined(__PSVITA__) + ProfileManager.GetChatAndContentRestrictions(iPad,true,nullptr,&bContentRestricted,nullptr); +#endif + if(bContentRestricted) + { + pClass->m_bIgnorePress=false; +#if !(defined(_XBOX) || defined(_WINDOWS64) || defined(_XBOX_ONE) ) // 4J Stu - Temp to get the win build running, but so we check this for other platforms + // you can't see leaderboards + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); +#endif + } + else + { + ProfileManager.SetLockedProfile(ProfileManager.GetPrimaryPad()); +#ifdef _XBOX_ONE + ui.ShowPlayerDisplayname(true); +#endif + proceedToScene(ProfileManager.GetPrimaryPad(), eUIScene_LeaderboardsMenu); + } + } + } + else + { + pClass->m_bIgnorePress=false; + // unlock the profile + ProfileManager.SetLockedProfile(-1); + for(int i=0;i(pParam); + + if (bContinue) + { + pClass->m_bIgnorePress=false; + // 4J-JEV: We only need to update rich-presence if the sign-in status changes. + ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + + XShowAchievementsUI( ProfileManager.GetPrimaryPad() ); + } + else + { + pClass->m_bIgnorePress=false; + // unlock the profile + ProfileManager.SetLockedProfile(-1); + for(int i=0;i(pParam); + + if (bContinue) + { + // 4J-JEV: We only need to update rich-presence if the sign-in status changes. + ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + + pClass->RunUnlockOrDLC(iPad); + } + else + { + pClass->m_bIgnorePress=false; + // unlock the profile + ProfileManager.SetLockedProfile(-1); + for(int i=0;im_errorCode = ProfileManager.getNPAvailability(ProfileManager.GetPrimaryPad()); + + bool bPatchAvailable; + switch(pClass->m_errorCode) + { + case SCE_NP_ERROR_LATEST_PATCH_PKG_EXIST: + case SCE_NP_ERROR_LATEST_PATCH_PKG_DOWNLOADED: + bPatchAvailable=true; + break; + default: + bPatchAvailable=false; + break; + } + + if(!bPatchAvailable) + { + pClass->m_eAction=eAction_RunGame; + signInReturnedFunc = &UIScene_MainMenu::CreateLoad_SignInReturned; + } + else + { + pClass->m_bRunGameChosen=true; + pClass->m_bErrorDialogRunning=true; + int32_t ret=sceErrorDialogInitialize(); + if ( ret==SCE_OK ) + { + SceErrorDialogParam param; + sceErrorDialogParamInitialize( ¶m ); + // 4J-PB - We want to display the option to get the patch now + param.errorCode = SCE_NP_ERROR_LATEST_PATCH_PKG_DOWNLOADED;//pClass->m_errorCode; + ret = sceUserServiceGetInitialUser( ¶m.userId ); + if ( ret == SCE_OK ) + { + ret=sceErrorDialogOpen( ¶m ); + } + return; + } + +// UINT uiIDA[1]; +// uiIDA[0]=IDS_OK; +// ui.RequestMessageBox(IDS_PATCH_AVAILABLE_TITLE, IDS_PATCH_AVAILABLE_TEXT, uiIDA, 1, XUSER_INDEX_ANY,nullptr,pClass); + } + + // Check if PSN is unavailable because of age restriction + if (pClass->m_errorCode == SCE_NP_ERROR_AGE_RESTRICTION) + { + UINT uiIDA[1]; + uiIDA[0]=IDS_PRO_NOTONLINE_DECLINE; + ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad(), &UIScene_MainMenu::PlayOfflineReturned, pClass); + + return; + } + + bool confirmUser = false; + + // Note: if no sign in returned func, assume this isn't required + if (signInReturnedFunc != nullptr) + { + if(ProfileManager.IsSignedIn(primaryPad)) + { + if (confirmUser) + { + ProfileManager.RequestSignInUI(false, false, true, false, true, signInReturnedFunc, pClass, primaryPad); + } + else + { + pClass->RunAction(primaryPad); + } + } + else + { + // Ask user to sign in + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_OK; + uiIDA[1]=IDS_CONFIRM_CANCEL; + ui.RequestErrorMessage(IDS_MUST_SIGN_IN_TITLE, IDS_MUST_SIGN_IN_TEXT, uiIDA, 2, primaryPad, &UIScene_MainMenu::MustSignInReturned, pClass); + } + } +} + +void UIScene_MainMenu::RefreshChatAndContentRestrictionsReturned_Leaderboards(void *pParam) +{ + int primaryPad = ProfileManager.GetPrimaryPad(); + + UIScene_MainMenu* pClass = (UIScene_MainMenu*)pParam; + + int (*signInReturnedFunc) (LPVOID,const bool, const int iPad) = nullptr; + + // 4J-PB - Check if there is a patch for the game + pClass->m_errorCode = ProfileManager.getNPAvailability(ProfileManager.GetPrimaryPad()); + + bool bPatchAvailable; + switch(pClass->m_errorCode) + { + case SCE_NP_ERROR_LATEST_PATCH_PKG_EXIST: + case SCE_NP_ERROR_LATEST_PATCH_PKG_DOWNLOADED: + bPatchAvailable=true; + break; + default: + bPatchAvailable=false; + break; + } + + if(!bPatchAvailable) + { + pClass->m_eAction=eAction_RunLeaderboards; + signInReturnedFunc = &UIScene_MainMenu::Leaderboards_SignInReturned; + } + else + { + int32_t ret=sceErrorDialogInitialize(); + pClass->m_bErrorDialogRunning=true; + if ( ret==SCE_OK ) + { + SceErrorDialogParam param; + sceErrorDialogParamInitialize( ¶m ); + // 4J-PB - We want to display the option to get the patch now + param.errorCode = SCE_NP_ERROR_LATEST_PATCH_PKG_DOWNLOADED;//pClass->m_errorCode; + ret = sceUserServiceGetInitialUser( ¶m.userId ); + if ( ret == SCE_OK ) + { + ret=sceErrorDialogOpen( ¶m ); + } + } + +// UINT uiIDA[1]; +// uiIDA[0]=IDS_OK; +// ui.RequestMessageBox(IDS_PATCH_AVAILABLE_TITLE, IDS_PATCH_AVAILABLE_TEXT, uiIDA, 1, XUSER_INDEX_ANY,nullptr,pClass); + } + + bool confirmUser = false; + + // Update error code + pClass->m_errorCode = ProfileManager.getNPAvailability(ProfileManager.GetPrimaryPad()); + + // Check if PSN is unavailable because of age restriction + if (pClass->m_errorCode == SCE_NP_ERROR_AGE_RESTRICTION) + { + UINT uiIDA[1]; + uiIDA[0] = IDS_CONFIRM_OK; + ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad(), nullptr, pClass); + + return; + } + + // Note: if no sign in returned func, assume this isn't required + if (signInReturnedFunc != nullptr) + { + if(ProfileManager.IsSignedIn(primaryPad)) + { + if (confirmUser) + { + ProfileManager.RequestSignInUI(false, false, true, false, true, signInReturnedFunc, pClass, primaryPad); + } + else + { + pClass->RunAction(primaryPad); + } + } + else + { + // Ask user to sign in + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_OK; + uiIDA[1]=IDS_CONFIRM_CANCEL; + ui.RequestErrorMessage(IDS_MUST_SIGN_IN_TITLE, IDS_MUST_SIGN_IN_TEXT, uiIDA, 2, primaryPad, &UIScene_MainMenu::MustSignInReturned, pClass); + } + } +} + +int UIScene_MainMenu::PlayOfflineReturned(void *pParam, int iPad, C4JStorage::EMessageResult result) +{ + UIScene_MainMenu* pClass = (UIScene_MainMenu*)pParam; + + if(result==C4JStorage::EMessage_ResultAccept) + { + if (pClass->m_eAction == eAction_RunGame) + { + CreateLoad_SignInReturned(pClass, true, 0); + } + else + { + pClass->m_bIgnorePress=false; + } + } + else + { + pClass->m_bIgnorePress=false; + } + + return 0; +} +#endif + +void UIScene_MainMenu::RunPlayGame(int iPad) +{ + Minecraft *pMinecraft=Minecraft::GetInstance(); + + // clear the remembered signed in users so their profiles get read again + app.ClearSignInChangeUsersMask(); + + app.ReleaseSaveThumbnail(); + + if(ProfileManager.IsGuest(iPad)) + { + UINT uiIDA[1]; + uiIDA[0]=IDS_OK; + + m_bIgnorePress=false; + ui.RequestErrorMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); + } + else + { + ProfileManager.SetLockedProfile(iPad); + + // If the player was signed in before selecting play, we'll not have read the profile yet, so query the sign-in status to get this to happen + ProfileManager.QuerySigninStatus(); + + // 4J-PB - Need to check for installed DLC + if(!app.DLCInstallProcessCompleted()) app.StartInstallDLCProcess(iPad); + + if(ProfileManager.IsFullVersion()) + { + // are we offline? + bool bSignedInLive = ProfileManager.IsSignedInLive(iPad); +#ifdef __PSVITA__ + if(app.GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_PSVita_NetworkModeAdhoc) == true) + { + CGameNetworkManager::setAdhocMode(true); + bSignedInLive = SQRNetworkManager_AdHoc_Vita::GetAdhocStatus(); + app.DebugPrintf("Adhoc mode signed in : %s\n", bSignedInLive ? "true" : "false"); + } + else + { + CGameNetworkManager::setAdhocMode(false); + app.DebugPrintf("PSN mode signed in : %s\n", bSignedInLive ? "true" : "false"); + } + +#endif //__PSVITA__ + + if(!bSignedInLive) + { +#if defined(__PS3__) || defined __PSVITA__ + // enable input again + m_bIgnorePress=false; + + // Not sure why 360 doesn't need this, but leaving as __PS3__ only for now until we see that it does. Without this, on a PS3 offline game, the primary player just gets the default Player1234 type name + pMinecraft->user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); + + m_eAction=eAction_RunGamePSN; + // get them to sign in to online + UINT uiIDA[2]; + uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; + uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; + +#ifdef __PSVITA__ + if(CGameNetworkManager::usingAdhocMode()) + { + uiIDA[0]=IDS_NETWORK_ADHOC; + // this should be "Connect to adhoc network" + ui.RequestErrorMessage(IDS_PRO_NOTADHOCONLINE_TITLE, IDS_PRO_NOTADHOCONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&UIScene_MainMenu::MustSignInReturnedPSN,this); + } + else + { + /* 4J-PB - Add this after release + // Determine why they're not "signed in live" + if (ProfileManager.IsSignedInPSN(iPad)) + { + m_eAction=eAction_RunGame; + // Signed in to PSN but not connected (no internet access) + + UINT uiIDA[1]; + uiIDA[0] = IDS_PRO_NOTONLINE_DECLINE; + ui.RequestMessageBox( IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, iPad, UIScene_MainMenu::PlayOfflineReturned, this, app.GetStringTable()); + } + else + { + m_eAction=eAction_RunGamePSN; + // Not signed in to PSN + ui.RequestMessageBox( IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, iPad, &UIScene_MainMenu::MustSignInReturnedPSN, this, app.GetStringTable()); + return; + } */ + ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&UIScene_MainMenu::MustSignInReturnedPSN,this); + + } +#else + + ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, iPad, &UIScene_MainMenu::MustSignInReturnedPSN, this); +#endif + +#elif defined __ORBIS__ + + // Determine why they're not "signed in live" + if (ProfileManager.isSignedInPSN(iPad)) + { + m_eAction=eAction_RunGame; + // Signed in to PSN but not connected (no internet access) + assert(!ProfileManager.isConnectedToPSN(iPad)); + + UINT uiIDA[1]; + uiIDA[0] = IDS_PRO_NOTONLINE_DECLINE; + ui.RequestErrorMessage( IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, iPad, UIScene_MainMenu::PlayOfflineReturned, this); + } + else + { + m_eAction=eAction_RunGamePSN; + // Not signed in to PSN + UINT uiIDA[2]; + uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; + uiIDA[1] = IDS_PRO_NOTONLINE_DECLINE; + ui.RequestAlertMessage( IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, iPad, &UIScene_MainMenu::MustSignInReturnedPSN, this); + return; + } +#else + ProfileManager.SetLockedProfile(iPad); +#ifdef _XBOX_ONE + ui.ShowPlayerDisplayname(true); +#endif + proceedToScene(ProfileManager.GetPrimaryPad(), eUIScene_LoadCreateJoinMenu); +#endif + } + else + { +#ifdef _XBOX_ONE + if(!app.GetBanListRead(iPad)) + { + app.SetTMSAction(iPad,eTMSAction_TMSPP_RetrieveFiles_RunPlayGame); + + // block all input + m_bIgnorePress=true; + // We want to hide everything in this scene and display a timer until we get a completion for the TMS files +// for(int i=0;iuser->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); + // save device already selected + + // ensure we've applied this player's settings + app.ApplyGameSettingsChanged(iPad); + // check for DLC + // start timer to track DLC check finished + m_Timer.SetShow(TRUE); + XuiSetTimer(m_hObj,DLC_INSTALLED_TIMER_ID,DLC_INSTALLED_TIMER_TIME); + //app.NavigateToScene(iPad,eUIScene_MultiGameJoinLoad); + } + } + else + { + // Changing to async TMS calls + app.SetTMSAction(iPad,eTMSAction_TMSPP_RetrieveFiles_RunPlayGame); + + // block all input + m_bIgnorePress=true; + // We want to hide everything in this scene and display a timer until we get a completion for the TMS files + for(int i=0;iuser->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); + + // ensure we've applied this player's settings + app.ApplyGameSettingsChanged(iPad); + +#ifdef _XBOX_ONE + ui.ShowPlayerDisplayname(true); +#endif + proceedToScene(ProfileManager.GetPrimaryPad(), eUIScene_LoadCreateJoinMenu); +#endif + } + } + else + { + // 4J-PB - if this is the trial game, we can't have any networking + // go straight in to the trial level + // change the minecraft player name + Minecraft::GetInstance()->user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); + + // Can't apply the player's settings here - they haven't come back from the QuerySignInStatud call above yet. + // Need to let them action in the main loop when they come in + // ensure we've applied this player's settings + //app.ApplyGameSettingsChanged(iPad); + +#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) + // ensure we've applied this player's settings - we do have them on PS3 + app.ApplyGameSettingsChanged(iPad); +#endif + +#ifdef __ORBIS__ + if(!g_NetworkManager.IsReadyToPlayOrIdle()) + { + m_bLoadTrialOnNetworkManagerReady = true; + ui.NavigateToScene(iPad, eUIScene_Timer); + } + else +#endif + { + LoadTrial(); + } + } + } +} + +void UIScene_MainMenu::RunLeaderboards(int iPad) +{ + UINT uiIDA[1]; + uiIDA[0]=IDS_OK; + + // guests can't look at leaderboards + if(ProfileManager.IsGuest(iPad)) + { + ui.RequestErrorMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); + } + else if(!ProfileManager.IsSignedInLive(iPad)) + { +#if defined __PS3__ || defined __PSVITA__ + m_eAction=eAction_RunLeaderboardsPSN; + // get them to sign in to online + UINT uiIDA[1]; + uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; + ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad(),&UIScene_MainMenu::MustSignInReturnedPSN,this); + +/* 4J-PB - Add this after release +#elif defined __PSVITA__ + m_eAction=eAction_RunLeaderboardsPSN; + // Determine why they're not "signed in live" + if (ProfileManager.IsSignedInPSN(iPad)) + { + // Signed in to PSN but not connected (no internet access) + UINT uiIDA[1]; + uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; + ui.RequestMessageBox(IDS_PRO_CURRENTLY_NOT_ONLINE_TITLE, IDS_PRO_PSNOFFLINE_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad(), &UIScene_MainMenu::MustSignInReturnedPSN, this, app.GetStringTable()); + } + else + { + // Not signed in to PSN + UINT uiIDA[1]; + uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; + ui.RequestMessageBox(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad(), &UIScene_MainMenu::MustSignInReturnedPSN, this, app.GetStringTable()); + return; + }*/ +#elif defined __ORBIS__ + m_eAction=eAction_RunLeaderboardsPSN; + // Determine why they're not "signed in live" + if (ProfileManager.isSignedInPSN(iPad)) + { + // Signed in to PSN but not connected (no internet access) + assert(!ProfileManager.isConnectedToPSN(iPad)); + + UINT uiIDA[1]; + uiIDA[0] = IDS_OK; + ui.RequestErrorMessage( IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, iPad); + } + else + { + // Not signed in to PSN + UINT uiIDA[1]; + uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; + ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad(), &UIScene_MainMenu::MustSignInReturnedPSN, this); + return; + } +#else + ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_XBOXLIVE_NOTIFICATION, uiIDA, 1); +#endif + } + else + { + // we're supposed to check for parental control restrictions before showing leaderboards + // The title enforces the user's NP parental control setting for age-based content + //restriction in network communications. + // If age restrictions are in place and the user's age does not meet + // the age restriction of the title's online service content rating (CERO, ESRB, PEGI, etc.), then the title must + //display a message such as the following and disallow online service for this user. + + bool bContentRestricted=false; +#if defined(__PS3__) || defined(__PSVITA__) + ProfileManager.GetChatAndContentRestrictions(iPad,true,nullptr,&bContentRestricted,nullptr); +#endif + if(bContentRestricted) + { +#if !(defined(_XBOX) || defined(_WINDOWS64) || defined(_XBOX_ONE)) // 4J Stu - Temp to get the win build running, but so we check this for other platforms + // you can't see leaderboards + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad(),nullptr,this); +#endif + } + else + { + ProfileManager.SetLockedProfile(iPad); + // If the player was signed in before selecting play, we'll not have read the profile yet, so query the sign-in status to get this to happen + ProfileManager.QuerySigninStatus(); + +#ifdef _XBOX_ONE + ui.ShowPlayerDisplayname(true); +#endif + proceedToScene(iPad, eUIScene_LeaderboardsMenu); + } + } +} +void UIScene_MainMenu::RunUnlockOrDLC(int iPad) +{ + UINT uiIDA[1]; + uiIDA[0]=IDS_OK; + + // Check if this means downloadable content + if(ProfileManager.IsFullVersion()) + { +#ifdef __ORBIS__ + // 4J-PB - Check if there is a patch for the game + m_errorCode = ProfileManager.getNPAvailability(ProfileManager.GetPrimaryPad()); + + bool bPatchAvailable; + switch(m_errorCode) + { + case SCE_NP_ERROR_LATEST_PATCH_PKG_EXIST: + case SCE_NP_ERROR_LATEST_PATCH_PKG_DOWNLOADED: + bPatchAvailable=true; + break; + default: + bPatchAvailable=false; + break; + } + + if(bPatchAvailable) + { + m_bIgnorePress=false; + + int32_t ret=sceErrorDialogInitialize(); + m_bErrorDialogRunning=true; + if ( ret==SCE_OK ) + { + SceErrorDialogParam param; + sceErrorDialogParamInitialize( ¶m ); + // 4J-PB - We want to display the option to get the patch now + param.errorCode = SCE_NP_ERROR_LATEST_PATCH_PKG_DOWNLOADED;//pClass->m_errorCode; + ret = sceUserServiceGetInitialUser( ¶m.userId ); + if ( ret == SCE_OK ) + { + ret=sceErrorDialogOpen( ¶m ); + } + } + +// UINT uiIDA[1]; +// uiIDA[0]=IDS_OK; +// ui.RequestMessageBox(IDS_PATCH_AVAILABLE_TITLE, IDS_PATCH_AVAILABLE_TEXT, uiIDA, 1, XUSER_INDEX_ANY,nullptr,this); + return; + } + + // Check if PSN is unavailable because of age restriction + if (m_errorCode == SCE_NP_ERROR_AGE_RESTRICTION) + { + m_bIgnorePress=false; + UINT uiIDA[1]; + uiIDA[0] = IDS_OK; + ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad(), nullptr, this); + + return; + } +#endif + // downloadable content + if(ProfileManager.IsSignedInLive(iPad)) + { + if(ProfileManager.IsGuest(iPad)) + { + m_bIgnorePress=false; + ui.RequestErrorMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); + } + else + { + + // If the player was signed in before selecting play, we'll not have read the profile yet, so query the sign-in status to get this to happen + ProfileManager.QuerySigninStatus(); + +#if defined _XBOX_ONE + if(app.GetTMSDLCInfoRead()) +#endif + { + bool bContentRestricted=false; +#if defined(__PS3__) || defined(__PSVITA__) + ProfileManager.GetChatAndContentRestrictions(iPad,true,nullptr,&bContentRestricted,nullptr); +#endif + if(bContentRestricted) + { + m_bIgnorePress=false; +#if !(defined(_XBOX) || defined(_WINDOWS64) || defined(_XBOX_ONE)) // 4J Stu - Temp to get the win build running, but so we check this for other platforms + // you can't see the store + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad(),nullptr,this); +#endif + } + else + { + ProfileManager.SetLockedProfile(iPad); +#ifdef _XBOX_ONE + ui.ShowPlayerDisplayname(true); +#endif + proceedToScene(ProfileManager.GetPrimaryPad(), eUIScene_DLCMainMenu); + } + } +#if defined _XBOX_ONE + else + { + // Changing to async TMS calls + app.SetTMSAction(iPad,eTMSAction_TMSPP_RetrieveFiles_DLCMain); + + // block all input + m_bIgnorePress=true; + // We want to hide everything in this scene and display a timer until we get a completion for the TMS files +// for(int i=0;iRecordUpsellPresented(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID); + ProfileManager.DisplayFullVersionPurchase(false,iPad,eSen_UpsellID_Full_Version_Of_Game); +#endif + } + } +} + +void UIScene_MainMenu::tick() +{ + UIScene::tick(); + + if ( (eNavigateWhenReady >= 0) ) + { + + int lockedProfile = ProfileManager.GetLockedProfile(); + +#ifdef _DURANGO + // 4J-JEV: DLC menu contains text localised to system language which we can't change. + // We need to switch to this language in-case it uses a different font. + if (eNavigateWhenReady == eUIScene_DLCMainMenu) setLanguageOverride(false); + + bool isSignedIn; + C4JStorage::eOptionsCallback status; + bool pendingFontChange; + if (lockedProfile >= 0) + { + isSignedIn = ProfileManager.IsSignedIn(lockedProfile); + status = app.GetOptionsCallbackStatus(lockedProfile); + pendingFontChange = ui.PendingFontChange(); + + if(status == C4JStorage::eOptions_Callback_Idle) + { + // make sure the TMS banned list data is ditched - the player may have gone in to help & options, backed out, and signed out + app.InvalidateBannedList(lockedProfile); + + // need to ditch any DLCOffers info + StorageManager.ClearDLCOffers(); + app.ClearAndResetDLCDownloadQueue(); + app.ClearDLCInstalled(); + } + } + + if ( (lockedProfile >= 0) + && isSignedIn + && ((status == C4JStorage::eOptions_Callback_Read)||(status == C4JStorage::eOptions_Callback_Write)) + && !pendingFontChange + ) +#endif + { + app.DebugPrintf("[MainMenu] Navigating away from MainMenu.\n"); + ui.NavigateToScene(lockedProfile, eNavigateWhenReady); + eNavigateWhenReady = static_cast(-1); + } +#ifdef _DURANGO + else + { + app.DebugPrintf("[MainMenu] Delaying navigation: lockedProfile=%i, %s, status=%ls, %s.\n", + lockedProfile, + isSignedIn ? "SignedIn" : "SignedOut", + app.toStringOptionsStatus(status).c_str(), + pendingFontChange ? "Pending font change" : "font OK"); + } +#endif + } + +#if defined(__PS3__) || defined (__ORBIS__) || defined(__PSVITA__) + if(m_bLaunchFullVersionPurchase) + { + int iCommerceState=app.GetCommerceState(); + // 4J-PB - if there's a commerce error - store down, player can't access store - let the DisplayFullVersionPurchase show the error + if((iCommerceState==CConsoleMinecraftApp::eCommerce_State_Online) || (iCommerceState==CConsoleMinecraftApp::eCommerce_State_Error)) + { + m_bLaunchFullVersionPurchase=false; + m_bIgnorePress=false; + updateTooltips(); + + // 4J-PB - need to check this user can access the store + bool bContentRestricted=false; + ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,nullptr,&bContentRestricted,nullptr); + if(bContentRestricted) + { + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); + } + else + { + TelemetryManager->RecordUpsellPresented(ProfileManager.GetPrimaryPad(), eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID); + ProfileManager.DisplayFullVersionPurchase(false,ProfileManager.GetPrimaryPad(),eSen_UpsellID_Full_Version_Of_Game); + } + } + } + + // 4J-PB - check for a trial version changing to a full version + if(m_bTrialVersion) + { + if(ProfileManager.IsFullVersion()) + { + m_bTrialVersion=false; + m_buttons[(int)eControl_UnlockOrDLC].init(app.GetString(IDS_DOWNLOADABLECONTENT),eControl_UnlockOrDLC); + } + } +#endif + +#if defined _XBOX_ONE + if(m_bWaitingForDLCInfo) + { + if(app.GetTMSDLCInfoRead()) + { + m_bWaitingForDLCInfo=false; + ProfileManager.SetLockedProfile(m_iPad); + proceedToScene(ProfileManager.GetPrimaryPad(), eUIScene_DLCMainMenu); + } + } + + if(g_NetworkManager.ShouldMessageForFullSession()) + { + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + ui.RequestErrorMessage( IDS_CONNECTION_FAILED, IDS_IN_PARTY_SESSION_FULL, uiIDA,1,ProfileManager.GetPrimaryPad()); + } +#endif + +#ifdef __ORBIS__ + + // process the error dialog (for a patch being available) + // SQRNetworkManager_Orbis::tickErrorDialog also runs the error dialog, so wrap this so this doesn't terminate a signin dialog + if(m_bErrorDialogRunning) + { + SceErrorDialogStatus stat = sceErrorDialogUpdateStatus(); + if( stat == SCE_ERROR_DIALOG_STATUS_FINISHED ) + { + sceErrorDialogTerminate(); + // if m_bRunGameChosen is true, we're here after selecting play game, and we should let the user continue with an offline game + if(m_bRunGameChosen) + { + m_bRunGameChosen=false; + m_eAction = eAction_RunGame; + + // give the option of continuing offline + UINT uiIDA[1]; + uiIDA[0]=IDS_PRO_NOTONLINE_DECLINE; + ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION_PATCH_AVAILABLE, uiIDA, 1, ProfileManager.GetPrimaryPad(), &UIScene_MainMenu::PlayOfflineReturned, this); + + } + m_bErrorDialogRunning=false; + } + } + + if(m_bLoadTrialOnNetworkManagerReady && g_NetworkManager.IsReadyToPlayOrIdle()) + { + m_bLoadTrialOnNetworkManagerReady = false; + LoadTrial(); + } + +#endif +} + +void UIScene_MainMenu::RunAchievements(int iPad) +{ +#if TO_BE_IMPLEMENTED + UINT uiIDA[1]; + uiIDA[0]=IDS_OK; + + // guests can't look at achievements + if(ProfileManager.IsGuest(iPad)) + { + ui.RequestErrorMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); + } + else + { + XShowAchievementsUI( iPad ); + } +#endif + ui.NavigateToScene(iPad, eUIScene_AchievementsMenu); +} + +void UIScene_MainMenu::RunHelpAndOptions(int iPad) +{ + if(ProfileManager.IsGuest(iPad)) + { + UINT uiIDA[1]; + uiIDA[0]=IDS_OK; + ui.RequestErrorMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); + } + else + { + // If the player was signed in before selecting play, we'll not have read the profile yet, so query the sign-in status to get this to happen + ProfileManager.QuerySigninStatus(); + +#if TO_BE_IMPLEMENTED + // 4J-PB - You can be offline and still can go into help and options + if(app.GetTMSDLCInfoRead() || !ProfileManager.IsSignedInLive(iPad)) +#endif + { + ProfileManager.SetLockedProfile(iPad); +#ifdef _XBOX_ONE + ui.ShowPlayerDisplayname(true); +#endif + proceedToScene(iPad, eUIScene_HelpAndOptionsMenu); + } +#if TO_BE_IMPLEMENTED + else + { + // Changing to async TMS calls + app.SetTMSAction(iPad,eTMSAction_TMSPP_RetrieveFiles_HelpAndOptions); + + // block all input + m_bIgnorePress=true; + // We want to hide everything in this scene and display a timer until we get a completion for the TMS files + for(int i=0;iseed = 0; + param->saveData = nullptr; + param->settings = app.GetGameHostOption( eGameHostOption_Tutorial ) | app.GetGameHostOption(eGameHostOption_DisableSaving); + + vector *generators = app.getLevelGenerators(); + param->levelGen = generators->at(0); + + LoadingInputParams *loadingParams = new LoadingInputParams(); + loadingParams->func = &CGameNetworkManager::RunNetworkGameThreadProc; + loadingParams->lpParam = static_cast(param); + + UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); + completionData->bShowBackground=TRUE; + completionData->bShowLogo=TRUE; + completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes; + completionData->iPad = ProfileManager.GetPrimaryPad(); + loadingParams->completionData = completionData; + + ui.ShowTrialTimer(true); + +#ifdef _XBOX_ONE + ui.ShowPlayerDisplayname(true); +#endif + ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); +} + +void UIScene_MainMenu::handleUnlockFullVersion() +{ + m_buttons[static_cast(eControl_UnlockOrDLC)].setLabel(IDS_DOWNLOADABLECONTENT,true); +} + + +#ifdef __PSVITA__ +int UIScene_MainMenu::SelectNetworkModeReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + UIScene_MainMenu* pClass = (UIScene_MainMenu*)pParam; + + if(result==C4JStorage::EMessage_ResultAccept) + { + app.DebugPrintf("Setting network mode to PSN\n"); + app.SetGameSettings(0, eGameSetting_PSVita_NetworkModeAdhoc, 0); + } + else if(result==C4JStorage::EMessage_ResultDecline) + { + app.DebugPrintf("Setting network mode to Adhoc\n"); + app.SetGameSettings(0, eGameSetting_PSVita_NetworkModeAdhoc, 1); + } + pClass->updateTooltips(); + return 0; +} +#endif //__PSVITA__ diff --git a/Minecraft.Client/Common/UI/UIScene_SettingsAudioMenu.cpp b/Minecraft.Client/Common/UI/UIScene_SettingsAudioMenu.cpp index 083fbd35..6e19fdd2 100644 --- a/Minecraft.Client/Common/UI/UIScene_SettingsAudioMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_SettingsAudioMenu.cpp @@ -7,12 +7,11 @@ UIScene_SettingsAudioMenu::UIScene_SettingsAudioMenu(int iPad, void *initData, U // Setup all the Iggy references we need for this scene initialiseMovie(); - WCHAR TempString[256]; - swprintf( (WCHAR *)TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_MUSIC ),app.GetGameSettings(m_iPad,eGameSetting_MusicVolume)); - m_sliderMusic.init(TempString,eControl_Music,0,100,app.GetGameSettings(m_iPad,eGameSetting_MusicVolume)); - - swprintf( (WCHAR *)TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_SOUND ),app.GetGameSettings(m_iPad,eGameSetting_SoundFXVolume)); - m_sliderSound.init(TempString,eControl_Sound,0,100,app.GetGameSettings(m_iPad,eGameSetting_SoundFXVolume)); + m_bNeedsMultiListPopulate = true; + m_bInitialPopulateDone = false; + m_bPendingSliderUpdate = false; + m_iPendingSliderId = 0; + m_iPendingSliderValue = 0; doHorizontalResizeCheck(); @@ -32,14 +31,76 @@ wstring UIScene_SettingsAudioMenu::getMoviePath() { if(app.GetLocalPlayerCount() > 1) { - return L"SettingsAudioMenuSplit"; + return L"MultilistMenuSplit"; } else { - return L"SettingsAudioMenu"; + return L"MultilistMenu"; } } +void UIScene_SettingsAudioMenu::tick() +{ + if(m_bNeedsMultiListPopulate) + { + m_bNeedsMultiListPopulate = false; + m_multiList.setupControl(this, m_rootPath, "MultiList"); + m_controls.push_back(&m_multiList); + m_multiList.clearList(); + m_multiList.init(eControl_MultiList); + + WCHAR TempString[256]; + int musicVol = app.GetGameSettings(m_iPad, eGameSetting_MusicVolume); + int soundVol = app.GetGameSettings(m_iPad, eGameSetting_SoundFXVolume); + bool caveSounds = app.GetGameSettings(m_iPad, eGameSetting_CaveSounds) != 0; + bool minecartSounds = app.GetGameSettings(m_iPad, eGameSetting_MinecartSounds) != 0; + bool gameChat = app.GetGameSettings(m_iPad, eGameSetting_GameChat) != 0; + + swprintf(TempString, 256, L"%ls: %d%%", app.GetString(IDS_SLIDER_MUSIC), musicVol); + m_multiList.AddNewSlider(TempString, eControl_Music, 0, 100, 1, musicVol); + + swprintf(TempString, 256, L"%ls: %d%%", app.GetString(IDS_SLIDER_SOUND), soundVol); + m_multiList.AddNewSlider(TempString, eControl_Sound, 0, 100, 1, soundVol); + m_multiList.AddNewCheckbox(app.GetString(IDS_CHECKBOX_CAVE_SOUNDS), eControl_CaveSounds, caveSounds); + m_multiList.AddNewCheckbox(app.GetString(IDS_CHECKBOX_MINECART_SOUNDS), eControl_MinecartSounds, minecartSounds); + m_multiList.AddNewCheckbox(L"Game Chat", eControl_GameChat, gameChat); + m_multiList.EnableItem(eControl_GameChat, false); + + IggyName funcDoVert = registerFastName(L"DoVerticalResizeCheck"); + IggyName funcHideDesc = registerFastName(L"HideDescription"); + IggyDataValue result; + IggyPlayerCallMethodRS(getMovie(), &result, m_rootPath, funcDoVert, 0, nullptr); + doHorizontalResizeCheck(); + IggyPlayerCallMethodRS(getMovie(), &result, m_rootPath, funcHideDesc, 0, nullptr); + m_multiList.HighlightItem(eControl_Sound); + m_multiList.HighlightItem(eControl_Music); + } + + if(m_bPendingSliderUpdate) + { + m_bPendingSliderUpdate = false; + m_multiList.SetSliderValue(m_iPendingSliderId, m_iPendingSliderValue); + + WCHAR TempString[256]; + switch(m_iPendingSliderId) + { + case eControl_Music: + app.SetGameSettings(m_iPad, eGameSetting_MusicVolume, m_iPendingSliderValue); + swprintf(TempString, 256, L"%ls: %d%%", app.GetString(IDS_SLIDER_MUSIC), m_iPendingSliderValue); + m_multiList.SetSliderLabel(eControl_Music, TempString); + break; + case eControl_Sound: + app.SetGameSettings(m_iPad, eGameSetting_SoundFXVolume, m_iPendingSliderValue); + swprintf(TempString, 256, L"%ls: %d%%", app.GetString(IDS_SLIDER_SOUND), m_iPendingSliderValue); + m_multiList.SetSliderLabel(eControl_Sound, TempString); + break; + } + } + + UIScene::tick(); + m_bInitialPopulateDone = true; +} + void UIScene_SettingsAudioMenu::updateTooltips() { ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK); @@ -72,6 +133,7 @@ void UIScene_SettingsAudioMenu::handleInput(int iPad, int key, bool repeat, bool case ACTION_MENU_CANCEL: if(pressed) { + setGameSettings(); navigateBack(); } break; @@ -92,25 +154,57 @@ void UIScene_SettingsAudioMenu::handleInput(int iPad, int key, bool repeat, bool void UIScene_SettingsAudioMenu::handleSliderMove(F64 sliderId, F64 currentValue) { - WCHAR TempString[256]; + int sliderIdInt = static_cast(sliderId); int value = static_cast(currentValue); - switch(static_cast(sliderId)) + + ui.PlayUISFX(eSFX_Scroll); + + switch(sliderIdInt) { case eControl_Music: - m_sliderMusic.handleSliderMove(value); - - app.SetGameSettings(m_iPad,eGameSetting_MusicVolume,value); - swprintf( (WCHAR *)TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_MUSIC ),value); - m_sliderMusic.setLabel(TempString); - - break; case eControl_Sound: - m_sliderSound.handleSliderMove(value); - - app.SetGameSettings(m_iPad,eGameSetting_SoundFXVolume,value); - swprintf( (WCHAR *)TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_SOUND ),value); - m_sliderSound.setLabel(TempString); - + m_bPendingSliderUpdate = true; + m_iPendingSliderId = sliderIdInt; + m_iPendingSliderValue = value; break; } } + +void UIScene_SettingsAudioMenu::handleCheckboxToggled(F64 controlId, bool selected) +{ + if(m_bInitialPopulateDone) + ui.PlayUISFX(eSFX_Press); + + switch(static_cast(controlId)) + { + case eControl_CaveSounds: + app.SetGameSettings(m_iPad, eGameSetting_CaveSounds, selected ? 1 : 0); + break; + case eControl_MinecartSounds: + app.SetGameSettings(m_iPad, eGameSetting_MinecartSounds, selected ? 1 : 0); + break; + } +} + +void UIScene_SettingsAudioMenu::handlePress(F64 controlId, F64 childId) +{ + ui.PlayUISFX(eSFX_Press); +} + +void UIScene_SettingsAudioMenu::setGameSettings() +{ + app.SetGameSettings(m_iPad, eGameSetting_MusicVolume, m_multiList.GetSliderValue(eControl_Music)); + app.SetGameSettings(m_iPad, eGameSetting_SoundFXVolume, m_multiList.GetSliderValue(eControl_Sound)); + app.SetGameSettings(m_iPad, eGameSetting_CaveSounds, m_multiList.GetCheckboxValue(eControl_CaveSounds) ? 1 : 0); + app.SetGameSettings(m_iPad, eGameSetting_MinecartSounds, m_multiList.GetCheckboxValue(eControl_MinecartSounds) ? 1 : 0); + app.SetGameSettings(m_iPad, eGameSetting_GameChat, m_multiList.GetCheckboxValue(eControl_GameChat) ? 1 : 0); +} + +void UIScene_SettingsAudioMenu::handleGainFocus(bool navBack) +{ + if(navBack) + { + m_bNeedsMultiListPopulate = true; + m_bInitialPopulateDone = false; + } +} diff --git a/Minecraft.Client/Common/UI/UIScene_SettingsAudioMenu.h b/Minecraft.Client/Common/UI/UIScene_SettingsAudioMenu.h index 6c48b22b..03f7bb27 100644 --- a/Minecraft.Client/Common/UI/UIScene_SettingsAudioMenu.h +++ b/Minecraft.Client/Common/UI/UIScene_SettingsAudioMenu.h @@ -1,20 +1,29 @@ #pragma once #include "UIScene.h" +#include "UIControl_MultiList.h" class UIScene_SettingsAudioMenu : public UIScene { private: enum EControls { - eControl_Music, - eControl_Sound + eControl_MultiList = 0, + eControl_Music = 1, + eControl_Sound = 2, + eControl_CaveSounds = 3, + eControl_MinecartSounds = 4, + eControl_GameChat = 5 }; - UIControl_Slider m_sliderMusic, m_sliderSound; // Sliders + UIControl_MultiList m_multiList; + bool m_bNeedsMultiListPopulate; + bool m_bInitialPopulateDone; + bool m_bPendingSliderUpdate; + int m_iPendingSliderId; + int m_iPendingSliderValue; + UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) - UI_MAP_ELEMENT( m_sliderMusic, "Music") - UI_MAP_ELEMENT( m_sliderSound, "Sound") UI_END_MAP_ELEMENTS_AND_NAMES() public: @@ -23,6 +32,7 @@ public: virtual EUIScene getSceneType() { return eUIScene_SettingsAudioMenu;} + virtual void tick(); virtual void updateTooltips(); virtual void updateComponents(); @@ -35,4 +45,9 @@ public: virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled); virtual void handleSliderMove(F64 sliderId, F64 currentValue); -}; \ No newline at end of file + virtual void handleCheckboxToggled(F64 controlId, bool selected); + virtual void handlePress(F64 controlId, F64 childId); + virtual void handleGainFocus(bool navBack); + + void setGameSettings(); +}; diff --git a/Minecraft.Client/Common/UI/UIScene_SettingsControlMenu.cpp b/Minecraft.Client/Common/UI/UIScene_SettingsControlMenu.cpp deleted file mode 100644 index 7dbd243b..00000000 --- a/Minecraft.Client/Common/UI/UIScene_SettingsControlMenu.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "stdafx.h" -#include "UI.h" -#include "UIScene_SettingsControlMenu.h" - -UIScene_SettingsControlMenu::UIScene_SettingsControlMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer) -{ - // Setup all the Iggy references we need for this scene - initialiseMovie(); - - WCHAR TempString[256]; - swprintf( (WCHAR *)TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_SENSITIVITY_INGAME ),app.GetGameSettings(m_iPad,eGameSetting_Sensitivity_InGame)); - m_sliderSensitivityInGame.init(TempString,eControl_SensitivityInGame,0,200,app.GetGameSettings(m_iPad,eGameSetting_Sensitivity_InGame)); - - swprintf( (WCHAR *)TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_SENSITIVITY_INMENU ),app.GetGameSettings(m_iPad,eGameSetting_Sensitivity_InMenu)); - m_sliderSensitivityInMenu.init(TempString,eControl_SensitivityInMenu,0,200,app.GetGameSettings(m_iPad,eGameSetting_Sensitivity_InMenu)); - - doHorizontalResizeCheck(); - - if(app.GetLocalPlayerCount()>1) - { -#if TO_BE_IMPLEMENTED - app.AdjustSplitscreenScene(m_hObj,&m_OriginalPosition,m_iPad,false); -#endif - } -} - -UIScene_SettingsControlMenu::~UIScene_SettingsControlMenu() -{ -} - -wstring UIScene_SettingsControlMenu::getMoviePath() -{ - if(app.GetLocalPlayerCount() > 1) - { - return L"SettingsControlMenuSplit"; - } - else - { - return L"SettingsControlMenu"; - } -} - -void UIScene_SettingsControlMenu::updateTooltips() -{ - ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK); -} - -void UIScene_SettingsControlMenu::updateComponents() -{ - bool bNotInGame=(Minecraft::GetInstance()->level==nullptr); - if(bNotInGame) - { - m_parentLayer->showComponent(m_iPad,eUIComponent_Panorama,true); - m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,true); - } - else - { - m_parentLayer->showComponent(m_iPad,eUIComponent_Panorama,false); - - if( app.GetLocalPlayerCount() == 1 ) m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,true); - else m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,false); - } -} - -void UIScene_SettingsControlMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled) -{ - ui.AnimateKeyPress(iPad, key, repeat, pressed, released); - - switch(key) - { - case ACTION_MENU_CANCEL: - if(pressed) - { - navigateBack(); - handled = true; - } - break; - case ACTION_MENU_OK: -#ifdef __ORBIS__ - case ACTION_MENU_TOUCHPAD_PRESS: -#endif - sendInputToMovie(key, repeat, pressed, released); - break; - case ACTION_MENU_UP: - case ACTION_MENU_DOWN: - case ACTION_MENU_LEFT: - case ACTION_MENU_RIGHT: - sendInputToMovie(key, repeat, pressed, released); - break; - } -} - -void UIScene_SettingsControlMenu::handleSliderMove(F64 sliderId, F64 currentValue) -{ - WCHAR TempString[256]; - int value = static_cast(currentValue); - switch(static_cast(sliderId)) - { - case eControl_SensitivityInGame: - m_sliderSensitivityInGame.handleSliderMove(value); - - app.SetGameSettings(m_iPad,eGameSetting_Sensitivity_InGame,value); - swprintf( (WCHAR *)TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_SENSITIVITY_INGAME ),value); - m_sliderSensitivityInGame.setLabel(TempString); - - break; - case eControl_SensitivityInMenu: - m_sliderSensitivityInMenu.handleSliderMove(value); - - app.SetGameSettings(m_iPad,eGameSetting_Sensitivity_InMenu,value); - swprintf( (WCHAR *)TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_SENSITIVITY_INMENU ),value); - m_sliderSensitivityInMenu.setLabel(TempString); - - break; - } -} diff --git a/Minecraft.Client/Common/UI/UIScene_SettingsControlMenu.h b/Minecraft.Client/Common/UI/UIScene_SettingsControlMenu.h deleted file mode 100644 index 6d3b864c..00000000 --- a/Minecraft.Client/Common/UI/UIScene_SettingsControlMenu.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "UIScene.h" - -class UIScene_SettingsControlMenu : public UIScene -{ -private: - enum EControls - { - eControl_SensitivityInGame, - eControl_SensitivityInMenu - }; - - UIControl_Slider m_sliderSensitivityInGame, m_sliderSensitivityInMenu; // Sliders - UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) - UI_MAP_ELEMENT( m_sliderSensitivityInGame, "SensitivityInGame") - UI_MAP_ELEMENT( m_sliderSensitivityInMenu, "SensitivityInMenu") - UI_END_MAP_ELEMENTS_AND_NAMES() -public: - UIScene_SettingsControlMenu(int iPad, void *initData, UILayer *parentLayer); - virtual ~UIScene_SettingsControlMenu(); - - virtual EUIScene getSceneType() { return eUIScene_SettingsControlMenu;} - - virtual void updateTooltips(); - virtual void updateComponents(); - -protected: - // TODO: This should be pure virtual in this class - virtual wstring getMoviePath(); - -public: - // INPUT - virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled); - - virtual void handleSliderMove(F64 sliderId, F64 currentValue); -}; \ No newline at end of file diff --git a/Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.cpp b/Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.cpp index f3eab6d3..8b559450 100644 --- a/Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.cpp @@ -60,81 +60,16 @@ UIScene_SettingsGraphicsMenu::UIScene_SettingsGraphicsMenu(int iPad, void *initD { // Setup all the Iggy references we need for this scene initialiseMovie(); - Minecraft* pMinecraft = Minecraft::GetInstance(); - - m_bNotInGame=(Minecraft::GetInstance()->level==nullptr); - m_checkboxClouds.init(app.GetString(IDS_CHECKBOX_RENDER_CLOUDS),eControl_Clouds,(app.GetGameSettings(m_iPad,eGameSetting_Clouds)!=0)); - m_checkboxBedrockFog.init(app.GetString(IDS_CHECKBOX_RENDER_BEDROCKFOG),eControl_BedrockFog,(app.GetGameSettings(m_iPad,eGameSetting_BedrockFog)!=0)); - m_checkboxCustomSkinAnim.init(app.GetString(IDS_CHECKBOX_CUSTOM_SKIN_ANIM),eControl_CustomSkinAnim,(app.GetGameSettings(m_iPad,eGameSetting_CustomSkinAnim)!=0)); - m_checkboxVSync.init(L"VSync",eControl_VSync,(app.GetGameSettings(m_iPad,eGameSetting_VSync)!=0)); - m_checkboxExclusiveFullscreen.init(L"Fullscreen",eControl_ExclusiveFullscreen,(app.GetGameSettings(m_iPad,eGameSetting_ExclusiveFullscreen)!=0)); - - - WCHAR TempString[256]; - - swprintf(TempString, 256, L"Render Distance: %d",app.GetGameSettings(m_iPad,eGameSetting_RenderDistance)); - m_sliderRenderDistance.init(TempString,eControl_RenderDistance,0,3,DistanceToLevel(app.GetGameSettings(m_iPad,eGameSetting_RenderDistance))); - - swprintf( TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_GAMMA ),app.GetGameSettings(m_iPad,eGameSetting_Gamma)); - m_sliderGamma.init(TempString,eControl_Gamma,0,100,app.GetGameSettings(m_iPad,eGameSetting_Gamma)); - - const int initialFovSlider = app.GetGameSettings(m_iPad, eGameSetting_FOV); - const int initialFovDeg = sliderValueToFov(initialFovSlider); - swprintf(TempString, 256, L"FOV: %d", initialFovDeg); - m_sliderFOV.init(TempString, eControl_FOV, 0, FOV_SLIDER_MAX, initialFovSlider); - - swprintf( TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_INTERFACEOPACITY ),app.GetGameSettings(m_iPad,eGameSetting_InterfaceOpacity)); - m_sliderInterfaceOpacity.init(TempString,eControl_InterfaceOpacity,0,100,app.GetGameSettings(m_iPad,eGameSetting_InterfaceOpacity)); + m_bNotInGame = (Minecraft::GetInstance()->level == nullptr); + m_bNeedsMultiListPopulate = true; + m_bInitialPopulateDone = false; + m_bPendingSliderUpdate = false; + m_iPendingSliderId = 0; + m_iPendingSliderValue = 0; doHorizontalResizeCheck(); -#ifndef _WINDOWS64 - // VSync and Exclusive Fullscreen are only available on PC - removeControl(&m_checkboxVSync, true); - removeControl(&m_checkboxExclusiveFullscreen, true); -#else - // The SWF's original focus chain skips VSync, Fullscreen, and RenderDistance - // (CustomSkinAnim -> Gamma). Rewire the navigation so all controls are reachable: - // CustomSkinAnim -> VSync -> Fullscreen -> RenderDistance -> Gamma - { - IggyName navDown = registerFastName(L"m_objNavDown"); - IggyName navUp = registerFastName(L"m_objNavUp"); - - IggyValueSetStringUTF8RS(m_checkboxCustomSkinAnim.getIggyValuePath(), navDown, nullptr, "VSync", -1); - - IggyValueSetStringUTF8RS(m_checkboxVSync.getIggyValuePath(), navUp, nullptr, "CustomSkinAnim", -1); - IggyValueSetStringUTF8RS(m_checkboxVSync.getIggyValuePath(), navDown, nullptr, "ExclusiveFullscreen", -1); - - IggyValueSetStringUTF8RS(m_checkboxExclusiveFullscreen.getIggyValuePath(), navUp, nullptr, "VSync", -1); - IggyValueSetStringUTF8RS(m_checkboxExclusiveFullscreen.getIggyValuePath(), navDown, nullptr, "RenderDistance", -1); - - IggyValueSetStringUTF8RS(m_sliderRenderDistance.getIggyValuePath(), navUp, nullptr, "ExclusiveFullscreen", -1); - } -#endif - - const bool bInGame=(Minecraft::GetInstance()->level!=nullptr); - const bool bIsPrimaryPad=(ProfileManager.GetPrimaryPad()==m_iPad); - // if we're not in the game, we need to use basescene 0 - if(bInGame) - { -#ifndef _WINDOWS64 - // Console splitscreen: non-host and non-primary players can't change world-level settings - if(bIsPrimaryPad) - { - if(!g_NetworkManager.IsHost()) - { - removeControl(&m_checkboxBedrockFog, true); - } - } - else - { - removeControl(&m_checkboxBedrockFog, true); - removeControl(&m_checkboxCustomSkinAnim, true); - } -#endif - } - if(app.GetLocalPlayerCount()>1) { #if TO_BE_IMPLEMENTED @@ -151,14 +86,97 @@ wstring UIScene_SettingsGraphicsMenu::getMoviePath() { if(app.GetLocalPlayerCount() > 1) { - return L"SettingsGraphicsMenuSplit"; + return L"MultilistMenuSplit"; } else { - return L"SettingsGraphicsMenu"; + return L"MultilistMenu"; } } +void UIScene_SettingsGraphicsMenu::tick() +{ + if (m_bNeedsMultiListPopulate) + { + m_bNeedsMultiListPopulate = false; + m_multiList.setupControl(this, m_rootPath, "MultiList"); + m_controls.push_back(&m_multiList); + m_multiList.clearList(); + m_multiList.init(eControl_MultiList); + + WCHAR TempString[256]; + + m_multiList.AddNewCheckbox(app.GetString(IDS_CHECKBOX_RENDER_CLOUDS), eControl_Clouds, (app.GetGameSettings(m_iPad, eGameSetting_Clouds) != 0)); + m_multiList.AddNewCheckbox(app.GetString(IDS_CHECKBOX_CUSTOM_SKIN_ANIM), eControl_CustomSkinAnim, (app.GetGameSettings(m_iPad, eGameSetting_CustomSkinAnim) != 0)); + m_multiList.AddNewCheckbox(app.GetString(IDS_CHECKBOX_RENDER_BEDROCKFOG), eControl_BedrockFog, (app.GetGameSettings(m_iPad, eGameSetting_BedrockFog) != 0)); + +#ifdef _WINDOWS64 + m_multiList.AddNewCheckbox(L"VSync", eControl_VSync, (app.GetGameSettings(m_iPad, eGameSetting_VSync) != 0)); + m_multiList.AddNewCheckbox(L"Fullscreen", eControl_ExclusiveFullscreen, (app.GetGameSettings(m_iPad, eGameSetting_ExclusiveFullscreen) != 0)); +#endif + + int gammaVal = app.GetGameSettings(m_iPad, eGameSetting_Gamma); + swprintf(TempString, 256, L"%ls: %d%%", app.GetString(IDS_SLIDER_GAMMA), gammaVal); + m_multiList.AddNewSlider(TempString, eControl_Gamma, 0, 100, 1, gammaVal); + + int renderDistLevel = DistanceToLevel(app.GetGameSettings(m_iPad, eGameSetting_RenderDistance)); + swprintf(TempString, 256, L"Render Distance: %d", LevelToDistance(renderDistLevel)); + m_multiList.AddNewSlider(TempString, eControl_RenderDistance, 0, 3, 1, renderDistLevel); + + int fovSlider = app.GetGameSettings(m_iPad, eGameSetting_FOV); + int fovDeg = sliderValueToFov(fovSlider); + swprintf(TempString, 256, L"FOV: %d", fovDeg); + m_multiList.AddNewSlider(TempString, eControl_FOV, 0, FOV_SLIDER_MAX, 1, fovSlider); + + IggyName funcDoVert = registerFastName(L"DoVerticalResizeCheck"); + IggyName funcHideDesc = registerFastName(L"HideDescription"); + IggyDataValue result; + IggyPlayerCallMethodRS(getMovie(), &result, m_rootPath, funcDoVert, 0, nullptr); + doHorizontalResizeCheck(); + IggyPlayerCallMethodRS(getMovie(), &result, m_rootPath, funcHideDesc, 0, nullptr); + m_multiList.HighlightItem(eControl_Clouds); + } + + if (m_bPendingSliderUpdate) + { + m_bPendingSliderUpdate = false; + m_multiList.SetSliderValue(m_iPendingSliderId, m_iPendingSliderValue); + + WCHAR TempString[256]; + switch (m_iPendingSliderId) + { + case eControl_RenderDistance: + { + int dist = LevelToDistance(m_iPendingSliderValue); + app.SetGameSettings(m_iPad, eGameSetting_RenderDistance, dist); + Minecraft *pMinecraft = Minecraft::GetInstance(); + pMinecraft->options->viewDistance = 3 - m_iPendingSliderValue; + swprintf(TempString, 256, L"Render Distance: %d", dist); + m_multiList.SetSliderLabel(eControl_RenderDistance, TempString); + break; + } + case eControl_Gamma: + app.SetGameSettings(m_iPad, eGameSetting_Gamma, m_iPendingSliderValue); + swprintf(TempString, 256, L"%ls: %d%%", app.GetString(IDS_SLIDER_GAMMA), m_iPendingSliderValue); + m_multiList.SetSliderLabel(eControl_Gamma, TempString); + break; + case eControl_FOV: + { + int fovDeg = sliderValueToFov(m_iPendingSliderValue); + Minecraft *pMinecraft = Minecraft::GetInstance(); + pMinecraft->gameRenderer->SetFovVal(static_cast(fovDeg)); + app.SetGameSettings(m_iPad, eGameSetting_FOV, m_iPendingSliderValue); + swprintf(TempString, 256, L"FOV: %d", fovDeg); + m_multiList.SetSliderLabel(eControl_FOV, TempString); + break; + } + } + } + + UIScene::tick(); + m_bInitialPopulateDone = true; +} + void UIScene_SettingsGraphicsMenu::updateTooltips() { ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK); @@ -166,7 +184,7 @@ void UIScene_SettingsGraphicsMenu::updateTooltips() void UIScene_SettingsGraphicsMenu::updateComponents() { - const bool bNotInGame=(Minecraft::GetInstance()->level==nullptr); + bool bNotInGame=(Minecraft::GetInstance()->level==nullptr); if(bNotInGame) { m_parentLayer->showComponent(m_iPad,eUIComponent_Panorama,true); @@ -190,19 +208,8 @@ void UIScene_SettingsGraphicsMenu::handleInput(int iPad, int key, bool repeat, b case ACTION_MENU_CANCEL: if(pressed) { - // check the checkboxes - app.SetGameSettings(m_iPad,eGameSetting_Clouds,m_checkboxClouds.IsChecked()?1:0); - app.SetGameSettings(m_iPad,eGameSetting_BedrockFog,m_checkboxBedrockFog.IsChecked()?1:0); - app.SetGameSettings(m_iPad,eGameSetting_CustomSkinAnim,m_checkboxCustomSkinAnim.IsChecked()?1:0); - app.SetGameSettings(m_iPad,eGameSetting_VSync,m_checkboxVSync.IsChecked()?1:0); - app.SetGameSettings(m_iPad,eGameSetting_ExclusiveFullscreen,m_checkboxExclusiveFullscreen.IsChecked()?1:0); -#ifdef _WINDOWS64 - g_bVSync = m_checkboxVSync.IsChecked(); - SetExclusiveFullscreen(m_checkboxExclusiveFullscreen.IsChecked()); -#endif - + setGameSettings(); navigateBack(); - handled = true; } break; case ACTION_MENU_OK: @@ -222,53 +229,56 @@ void UIScene_SettingsGraphicsMenu::handleInput(int iPad, int key, bool repeat, b void UIScene_SettingsGraphicsMenu::handleSliderMove(F64 sliderId, F64 currentValue) { - WCHAR TempString[256]; - const int value = static_cast(currentValue); - switch(static_cast(sliderId)) + int sliderIdInt = static_cast(sliderId); + int value = static_cast(currentValue); + + ui.PlayUISFX(eSFX_Scroll); + + switch (sliderIdInt) { case eControl_RenderDistance: - { - m_sliderRenderDistance.handleSliderMove(value); - - const int dist = LevelToDistance(value); - - app.SetGameSettings(m_iPad,eGameSetting_RenderDistance,dist); - - const Minecraft* mc = Minecraft::GetInstance(); - mc->options->viewDistance = 3 - value; - swprintf(TempString,256,L"Render Distance: %d",dist); - m_sliderRenderDistance.setLabel(TempString); - } - break; - case eControl_Gamma: - m_sliderGamma.handleSliderMove(value); - - app.SetGameSettings(m_iPad,eGameSetting_Gamma,value); - swprintf( TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_GAMMA ),value); - m_sliderGamma.setLabel(TempString); - - break; - case eControl_FOV: - { - m_sliderFOV.handleSliderMove(value); - const Minecraft* pMinecraft = Minecraft::GetInstance(); - const int fovValue = sliderValueToFov(value); - pMinecraft->gameRenderer->SetFovVal(static_cast(fovValue)); - app.SetGameSettings(m_iPad, eGameSetting_FOV, value); - swprintf(TempString, 256, L"FOV: %d", fovValue); - m_sliderFOV.setLabel(TempString); - } - break; - - case eControl_InterfaceOpacity: - m_sliderInterfaceOpacity.handleSliderMove(value); - - app.SetGameSettings(m_iPad,eGameSetting_InterfaceOpacity,value); - swprintf( TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_INTERFACEOPACITY ),value); - m_sliderInterfaceOpacity.setLabel(TempString); - + m_bPendingSliderUpdate = true; + m_iPendingSliderId = sliderIdInt; + m_iPendingSliderValue = value; break; } } + +void UIScene_SettingsGraphicsMenu::handleCheckboxToggled(F64 controlId, bool selected) +{ + if (m_bInitialPopulateDone) + ui.PlayUISFX(eSFX_Press); +} + +void UIScene_SettingsGraphicsMenu::handlePress(F64 controlId, F64 childId) +{ + ui.PlayUISFX(eSFX_Press); +} + +void UIScene_SettingsGraphicsMenu::setGameSettings() +{ + app.SetGameSettings(m_iPad, eGameSetting_Clouds, m_multiList.GetCheckboxValue(eControl_Clouds) ? 1 : 0); + app.SetGameSettings(m_iPad, eGameSetting_BedrockFog, m_multiList.GetCheckboxValue(eControl_BedrockFog) ? 1 : 0); + app.SetGameSettings(m_iPad, eGameSetting_CustomSkinAnim, m_multiList.GetCheckboxValue(eControl_CustomSkinAnim) ? 1 : 0); + app.SetGameSettings(m_iPad, eGameSetting_RenderDistance, LevelToDistance(m_multiList.GetSliderValue(eControl_RenderDistance))); + app.SetGameSettings(m_iPad, eGameSetting_Gamma, m_multiList.GetSliderValue(eControl_Gamma)); + app.SetGameSettings(m_iPad, eGameSetting_FOV, m_multiList.GetSliderValue(eControl_FOV)); + +#ifdef _WINDOWS64 + app.SetGameSettings(m_iPad, eGameSetting_VSync, m_multiList.GetCheckboxValue(eControl_VSync) ? 1 : 0); + app.SetGameSettings(m_iPad, eGameSetting_ExclusiveFullscreen, m_multiList.GetCheckboxValue(eControl_ExclusiveFullscreen) ? 1 : 0); + g_bVSync = m_multiList.GetCheckboxValue(eControl_VSync); + SetExclusiveFullscreen(m_multiList.GetCheckboxValue(eControl_ExclusiveFullscreen)); +#endif +} + +void UIScene_SettingsGraphicsMenu::handleGainFocus(bool navBack) +{ + if (navBack) + { + m_bNeedsMultiListPopulate = true; + m_bInitialPopulateDone = false; + } +} diff --git a/Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.h b/Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.h index ef150f39..d4ac2106 100644 --- a/Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.h +++ b/Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.h @@ -1,46 +1,43 @@ #pragma once #include "UIScene.h" -#include "Common/UI/UIControl_CheckBox.h" -#include "Common/UI/UIControl_Slider.h" +#include "UIControl_MultiList.h" class UIScene_SettingsGraphicsMenu : public UIScene { private: enum EControls { - eControl_Clouds, - eControl_BedrockFog, - eControl_CustomSkinAnim, - eControl_VSync, - eControl_ExclusiveFullscreen, - eControl_RenderDistance, - eControl_Gamma, - eControl_FOV, - eControl_InterfaceOpacity + eControl_MultiList = 0, + eControl_Clouds = 1, + eControl_BedrockFog = 2, + eControl_CustomSkinAnim = 3, + eControl_VSync = 4, + eControl_ExclusiveFullscreen = 5, + eControl_RenderDistance = 6, + eControl_Gamma = 7, + eControl_FOV = 8, }; - UIControl_CheckBox m_checkboxClouds, m_checkboxBedrockFog, m_checkboxCustomSkinAnim, m_checkboxVSync, m_checkboxExclusiveFullscreen; // Checkboxes - UIControl_Slider m_sliderRenderDistance, m_sliderGamma, m_sliderFOV, m_sliderInterfaceOpacity; // Sliders - UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) - UI_MAP_ELEMENT( m_checkboxClouds, "Clouds") - UI_MAP_ELEMENT( m_checkboxBedrockFog, "BedrockFog") - UI_MAP_ELEMENT( m_checkboxCustomSkinAnim, "CustomSkinAnim") - UI_MAP_ELEMENT( m_checkboxVSync, "VSync") - UI_MAP_ELEMENT( m_checkboxExclusiveFullscreen, "ExclusiveFullscreen") - UI_MAP_ELEMENT( m_sliderRenderDistance, "RenderDistance") - UI_MAP_ELEMENT( m_sliderGamma, "Gamma") - UI_MAP_ELEMENT(m_sliderFOV, "FOV") - UI_MAP_ELEMENT( m_sliderInterfaceOpacity, "InterfaceOpacity") - UI_END_MAP_ELEMENTS_AND_NAMES() + UIControl_MultiList m_multiList; + bool m_bNeedsMultiListPopulate; + bool m_bInitialPopulateDone; + bool m_bPendingSliderUpdate; + int m_iPendingSliderId; + int m_iPendingSliderValue; bool m_bNotInGame; + + UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) + UI_END_MAP_ELEMENTS_AND_NAMES() + public: UIScene_SettingsGraphicsMenu(int iPad, void *initData, UILayer *parentLayer); virtual ~UIScene_SettingsGraphicsMenu(); virtual EUIScene getSceneType() { return eUIScene_SettingsGraphicsMenu;} - + + virtual void tick(); virtual void updateTooltips(); virtual void updateComponents(); @@ -53,8 +50,13 @@ public: virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled); virtual void handleSliderMove(F64 sliderId, F64 currentValue); + virtual void handleCheckboxToggled(F64 controlId, bool selected); + virtual void handlePress(F64 controlId, F64 childId); + virtual void handleGainFocus(bool navBack); + + void setGameSettings(); static int LevelToDistance(int dist); static int DistanceToLevel(int dist); -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/Common/UI/UIScene_SettingsMenu.cpp b/Minecraft.Client/Common/UI/UIScene_SettingsMenu.cpp index 8b777875..98e47a02 100644 --- a/Minecraft.Client/Common/UI/UIScene_SettingsMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_SettingsMenu.cpp @@ -12,7 +12,6 @@ UIScene_SettingsMenu::UIScene_SettingsMenu(int iPad, void *initData, UILayer *pa m_buttons[BUTTON_ALL_OPTIONS].init(IDS_OPTIONS,BUTTON_ALL_OPTIONS); m_buttons[BUTTON_ALL_AUDIO].init(IDS_AUDIO,BUTTON_ALL_AUDIO); - m_buttons[BUTTON_ALL_CONTROL].init(IDS_CONTROL,BUTTON_ALL_CONTROL); m_buttons[BUTTON_ALL_GRAPHICS].init(IDS_GRAPHICS,BUTTON_ALL_GRAPHICS); m_buttons[BUTTON_ALL_UI].init(IDS_USER_INTERFACE,BUTTON_ALL_UI); m_buttons[BUTTON_ALL_RESETTODEFAULTS].init(IDS_RESET_TO_DEFAULTS,BUTTON_ALL_RESETTODEFAULTS); @@ -127,9 +126,6 @@ void UIScene_SettingsMenu::handlePress(F64 controlId, F64 childId) case BUTTON_ALL_AUDIO: ui.NavigateToScene(m_iPad, eUIScene_SettingsAudioMenu); break; - case BUTTON_ALL_CONTROL: - ui.NavigateToScene(m_iPad, eUIScene_SettingsControlMenu); - break; case BUTTON_ALL_GRAPHICS: ui.NavigateToScene(m_iPad, eUIScene_SettingsGraphicsMenu); break; diff --git a/Minecraft.Client/Common/UI/UIScene_SettingsMenu.h b/Minecraft.Client/Common/UI/UIScene_SettingsMenu.h index 7f5fe169..612a15d3 100644 --- a/Minecraft.Client/Common/UI/UIScene_SettingsMenu.h +++ b/Minecraft.Client/Common/UI/UIScene_SettingsMenu.h @@ -4,10 +4,9 @@ #define BUTTON_ALL_OPTIONS 0 #define BUTTON_ALL_AUDIO 1 -#define BUTTON_ALL_CONTROL 2 -#define BUTTON_ALL_GRAPHICS 4 -#define BUTTON_ALL_UI 5 -#define BUTTON_ALL_RESETTODEFAULTS 6 +#define BUTTON_ALL_GRAPHICS 3 +#define BUTTON_ALL_UI 4 +#define BUTTON_ALL_RESETTODEFAULTS 5 #define BUTTONS_ALL_MAX BUTTON_ALL_RESETTODEFAULTS + 1 class UIScene_SettingsMenu : public UIScene @@ -17,10 +16,9 @@ private: UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) UI_MAP_ELEMENT( m_buttons[BUTTON_ALL_OPTIONS], "Button1") UI_MAP_ELEMENT( m_buttons[BUTTON_ALL_AUDIO], "Button2") - UI_MAP_ELEMENT( m_buttons[BUTTON_ALL_CONTROL], "Button3") - UI_MAP_ELEMENT( m_buttons[BUTTON_ALL_GRAPHICS], "Button4") - UI_MAP_ELEMENT( m_buttons[BUTTON_ALL_UI], "Button5") - UI_MAP_ELEMENT( m_buttons[BUTTON_ALL_RESETTODEFAULTS], "Button6") + UI_MAP_ELEMENT( m_buttons[BUTTON_ALL_GRAPHICS], "Button3") + UI_MAP_ELEMENT( m_buttons[BUTTON_ALL_UI], "Button4") + UI_MAP_ELEMENT( m_buttons[BUTTON_ALL_RESETTODEFAULTS], "Button5") UI_END_MAP_ELEMENTS_AND_NAMES() public: UIScene_SettingsMenu(int iPad, void *initData, UILayer *parentLayer); diff --git a/Minecraft.Client/Common/UI/UIScene_SettingsOptionsMenu.cpp b/Minecraft.Client/Common/UI/UIScene_SettingsOptionsMenu.cpp index 7b4d3d9d..42f057a8 100644 --- a/Minecraft.Client/Common/UI/UIScene_SettingsOptionsMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_SettingsOptionsMenu.cpp @@ -2,18 +2,6 @@ #include "UI.h" #include "UIScene_SettingsOptionsMenu.h" -#if defined(_XBOX_ONE) -#define _ENABLE_LANGUAGE_SELECT -#endif - -int UIScene_SettingsOptionsMenu::m_iDifficultySettingA[4]= -{ - IDS_DIFFICULTY_PEACEFUL, - IDS_DIFFICULTY_EASY, - IDS_DIFFICULTY_NORMAL, - IDS_DIFFICULTY_HARD -}; - int UIScene_SettingsOptionsMenu::m_iDifficultyTitleSettingA[4]= { IDS_DIFFICULTY_TITLE_PEACEFUL, @@ -24,130 +12,18 @@ int UIScene_SettingsOptionsMenu::m_iDifficultyTitleSettingA[4]= UIScene_SettingsOptionsMenu::UIScene_SettingsOptionsMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer) { - m_bNavigateToLanguageSelector = false; + // m_bNavigateToLanguageSelector = false; // Setup all the Iggy references we need for this scene initialiseMovie(); - - m_bNotInGame=(Minecraft::GetInstance()->level==nullptr); - m_checkboxViewBob.init(IDS_VIEW_BOBBING,eControl_ViewBob,(app.GetGameSettings(m_iPad,eGameSetting_ViewBob)!=0)); - m_checkboxShowHints.init(IDS_HINTS,eControl_ShowHints,(app.GetGameSettings(m_iPad,eGameSetting_Hints)!=0)); - m_checkboxShowTooltips.init(IDS_IN_GAME_TOOLTIPS,eControl_ShowTooltips,(app.GetGameSettings(m_iPad,eGameSetting_Tooltips)!=0)); - m_checkboxInGameGamertags.init(IDS_IN_GAME_GAMERTAGS,eControl_InGameGamertags,(app.GetGameSettings(m_iPad,eGameSetting_GamertagsVisible)!=0)); - - // check if we should display the mash-up option - if(m_bNotInGame && app.GetMashupPackWorlds(m_iPad)!=0xFFFFFFFF) - { - // the mash-up option is needed - m_bMashUpWorldsUnhideOption=true; - m_checkboxMashupWorlds.init(IDS_UNHIDE_MASHUP_WORLDS,eControl_ShowMashUpWorlds,false); - } - else - { - //m_checkboxMashupWorlds.init(L"",eControl_ShowMashUpWorlds,false); - removeControl(&m_checkboxMashupWorlds, true); - m_bMashUpWorldsUnhideOption=false; - } - - unsigned char ucValue=app.GetGameSettings(m_iPad,eGameSetting_Autosave); - - wchar_t autosaveLabels[9][256]; - for(unsigned int i = 0; i < 9; ++i) - { - if(i==0) - { - swprintf( autosaveLabels[i], 256, L"%ls", app.GetString( IDS_SLIDER_AUTOSAVE_OFF )); - } - else - { - swprintf( autosaveLabels[i], 256, L"%ls: %d %ls", app.GetString( IDS_SLIDER_AUTOSAVE ),i*15, app.GetString( IDS_MINUTES )); - } - - } - m_sliderAutosave.setAllPossibleLabels(9,autosaveLabels); - m_sliderAutosave.init(autosaveLabels[ucValue],eControl_Autosave,0,8,ucValue); - -#if defined(_XBOX_ONE) || defined(__ORBIS__) - removeControl(&m_sliderAutosave,true); -#endif - - ucValue = app.GetGameSettings(m_iPad,eGameSetting_Difficulty); - wchar_t difficultyLabels[4][256]; - for(unsigned int i = 0; i < 4; ++i) - { - swprintf( difficultyLabels[i], 256, L"%ls: %ls", app.GetString( IDS_SLIDER_DIFFICULTY ),app.GetString(m_iDifficultyTitleSettingA[i])); - } - m_sliderDifficulty.setAllPossibleLabels(4,difficultyLabels); - m_sliderDifficulty.init(difficultyLabels[ucValue],eControl_Difficulty,0,3,ucValue); - - wstring wsText=app.GetString(m_iDifficultySettingA[app.GetGameSettings(m_iPad,eGameSetting_Difficulty)]); - EHTMLFontSize size = eHTMLSize_Normal; - if(!RenderManager.IsHiDef() && !RenderManager.IsWidescreen()) - { - size = eHTMLSize_Splitscreen; - } - wchar_t startTags[64]; - swprintf(startTags,64,L"",app.GetHTMLColour(eHTMLColor_White)); - wsText= startTags + wsText; - - m_labelDifficultyText.init(wsText); - - // If you are in-game, only the game host can change in-game gamertags, and you can't change difficulty - // only the primary player gets to change the autosave and difficulty settings - bool bRemoveDifficulty=false; - bool bRemoveAutosave=false; - bool bRemoveInGameGamertags=false; - - bool bNotInGame=(Minecraft::GetInstance()->level==nullptr); - bool bPrimaryPlayer = ProfileManager.GetPrimaryPad()==m_iPad; - if(!bPrimaryPlayer) - { - bRemoveDifficulty=true; - bRemoveAutosave=true; - bRemoveInGameGamertags=true; - } - - if(!bNotInGame) // in the game - { - bRemoveDifficulty=true; - if(!g_NetworkManager.IsHost()) - { - bRemoveAutosave=true; - bRemoveInGameGamertags=true; - } - } - if(bRemoveDifficulty) - { - m_labelDifficultyText.setVisible( false ); - removeControl(&m_sliderDifficulty, true); - } - - if(bRemoveAutosave) - { - removeControl(&m_sliderAutosave, true); - } - - if(bRemoveInGameGamertags) - { - removeControl(&m_checkboxInGameGamertags, true); - } - - // 4J-JEV: Changing languages in-game will produce many a bug. - // MGH - disabled the language select for the patch build, we'll re-enable afterwards - // 4J Stu - Removed it with a preprocessor def as we turn this off in various places -#ifdef _ENABLE_LANGUAGE_SELECT - if (app.GetGameStarted()) - { - removeControl( &m_buttonLanguageSelect, false ); - } - else - { - m_buttonLanguageSelect.init(IDS_LANGUAGE_SELECTOR, eControl_Languages); - } -#else - removeControl( &m_buttonLanguageSelect, false ); -#endif + m_bNotInGame = (Minecraft::GetInstance()->level==nullptr); + m_bNeedsMultiListPopulate = true; + m_bNavigateToLanguageSelector = false; + m_bInitialPopulateDone = false; + m_bPendingSliderUpdate = false; + m_iPendingSliderId = 0; + m_iPendingSliderValue = 0; doHorizontalResizeCheck(); @@ -157,36 +33,109 @@ UIScene_SettingsOptionsMenu::UIScene_SettingsOptionsMenu(int iPad, void *initDat app.AdjustSplitscreenScene(m_hObj,&m_OriginalPosition,m_iPad); #endif } - - m_labelDifficultyText.disableReinitialisation(); } UIScene_SettingsOptionsMenu::~UIScene_SettingsOptionsMenu() { } +wstring UIScene_SettingsOptionsMenu::getMoviePath() +{ + if(app.GetLocalPlayerCount() > 1) + { + return L"MultilistMenuSplit"; + } + else + { + return L"MultilistMenu"; + } +} + void UIScene_SettingsOptionsMenu::tick() { - UIScene::tick(); + if(m_bNeedsMultiListPopulate) + { + m_bNeedsMultiListPopulate = false; + m_multiList.setupControl(this, m_rootPath, "MultiList"); + m_controls.push_back(&m_multiList); + m_multiList.clearList(); + m_multiList.init(eControl_MultiList); - if (m_bNavigateToLanguageSelector) + m_multiList.AddNewCheckbox(app.GetString(IDS_CHECKBOX_VERTICAL_SPLIT_SCREEN), eControl_VerticalSplitscreen, (app.GetGameSettings(m_iPad,eGameSetting_SplitScreenVertical)!=0)); + m_multiList.AddNewCheckbox(app.GetString(IDS_VIEW_BOBBING), eControl_ViewBob, (app.GetGameSettings(m_iPad,eGameSetting_ViewBob)!=0)); + m_multiList.AddNewCheckbox(app.GetString(IDS_HINTS), eControl_Hints, (app.GetGameSettings(m_iPad,eGameSetting_Hints)!=0)); + m_multiList.AddNewCheckbox(app.GetString(IDS_CHECKBOX_DEATH_MESSAGES), eControl_DeathMessages, (app.GetGameSettings(m_iPad,eGameSetting_DeathMessages)!=0)); + + if(m_bNotInGame) + { + m_multiList.AddNewButton(app.GetString(IDS_LANGUAGE_SELECTOR), eControl_Languages); + } + + WCHAR TempString[256]; + + int autosaveVal = app.GetGameSettings(m_iPad,eGameSetting_Autosave); + if(autosaveVal == 0) + swprintf(TempString, 256, L"%ls", app.GetString(IDS_SLIDER_AUTOSAVE_OFF)); + else + swprintf(TempString, 256, L"%ls: %d %ls", app.GetString(IDS_SLIDER_AUTOSAVE), autosaveVal*15, app.GetString(IDS_MINUTES)); + m_multiList.AddNewSlider(TempString, eControl_Autosave, 0, 8, 1, autosaveVal); + + swprintf(TempString, 256, L"%ls: %d%%", app.GetString(IDS_SLIDER_SENSITIVITY_INGAME), app.GetGameSettings(m_iPad,eGameSetting_Sensitivity_InGame)); + m_multiList.AddNewSlider(TempString, eControl_Sensitivity_InGame, 0, 200, 1, app.GetGameSettings(m_iPad,eGameSetting_Sensitivity_InGame)); + + int diffVal = app.GetGameSettings(m_iPad,eGameSetting_Difficulty); + swprintf(TempString, 256, L"%ls: %ls", app.GetString(IDS_SLIDER_DIFFICULTY), app.GetString(m_iDifficultyTitleSettingA[diffVal])); + m_multiList.AddNewSlider(TempString, eControl_Difficulty, 0, 3, 1, diffVal); + + IggyName funcDoVert = registerFastName(L"DoVerticalResizeCheck"); + IggyName funcHideDesc = registerFastName(L"HideDescription"); + IggyDataValue result; + IggyPlayerCallMethodRS(getMovie(), &result, m_rootPath, funcDoVert, 0, nullptr); + doHorizontalResizeCheck(); + IggyPlayerCallMethodRS(getMovie(), &result, m_rootPath, funcHideDesc, 0, nullptr); + m_multiList.HighlightItem(eControl_ViewBob); + m_multiList.HighlightItem(eControl_VerticalSplitscreen); + } + + if(m_bNavigateToLanguageSelector) { m_bNavigateToLanguageSelector = false; setGameSettings(); ui.NavigateToScene(m_iPad, eUIScene_LanguageSelector); } -} -wstring UIScene_SettingsOptionsMenu::getMoviePath() -{ - if(app.GetLocalPlayerCount() > 1) + if(m_bPendingSliderUpdate) { - return L"SettingsOptionsMenuSplit"; - } - else - { - return L"SettingsOptionsMenu"; + m_bPendingSliderUpdate = false; + m_multiList.SetSliderValue(m_iPendingSliderId, m_iPendingSliderValue); + + WCHAR TempString[256]; + switch(m_iPendingSliderId) + { + case eControl_Autosave: + app.SetGameSettings(m_iPad, eGameSetting_Autosave, m_iPendingSliderValue); + app.SetAutosaveTimerTime(); + if(m_iPendingSliderValue == 0) + swprintf(TempString, 256, L"%ls", app.GetString(IDS_SLIDER_AUTOSAVE_OFF)); + else + swprintf(TempString, 256, L"%ls: %d %ls", app.GetString(IDS_SLIDER_AUTOSAVE), m_iPendingSliderValue*15, app.GetString(IDS_MINUTES)); + m_multiList.SetSliderLabel(eControl_Autosave, TempString); + break; + case eControl_Sensitivity_InGame: + app.SetGameSettings(m_iPad, eGameSetting_Sensitivity_InGame, m_iPendingSliderValue); + swprintf(TempString, 256, L"%ls: %d%%", app.GetString(IDS_SLIDER_SENSITIVITY_INGAME), m_iPendingSliderValue); + m_multiList.SetSliderLabel(eControl_Sensitivity_InGame, TempString); + break; + case eControl_Difficulty: + app.SetGameSettings(m_iPad, eGameSetting_Difficulty, m_iPendingSliderValue); + swprintf(TempString, 256, L"%ls: %ls", app.GetString(IDS_SLIDER_DIFFICULTY), app.GetString(m_iDifficultyTitleSettingA[m_iPendingSliderValue])); + m_multiList.SetSliderLabel(eControl_Difficulty, TempString); + break; + } } + + UIScene::tick(); + m_bInitialPopulateDone = true; } void UIScene_SettingsOptionsMenu::updateTooltips() @@ -206,14 +155,14 @@ void UIScene_SettingsOptionsMenu::updateComponents() { m_parentLayer->showComponent(m_iPad,eUIComponent_Panorama,false); - if( app.GetLocalPlayerCount() == 1 ) m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,RenderManager.IsHiDef()); + if( app.GetLocalPlayerCount() == 1 ) m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,true); else m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,false); } } void UIScene_SettingsOptionsMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled) { - ui.AnimateKeyPress(iPad, key, repeat, pressed, released); + ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released); switch(key) { case ACTION_MENU_CANCEL: @@ -243,7 +192,7 @@ void UIScene_SettingsOptionsMenu::handlePress(F64 controlId, F64 childId) //CD - Added for audio ui.PlayUISFX(eSFX_Press); - switch(static_cast(controlId)) + switch(static_cast(childId)) { case eControl_Languages: m_bNavigateToLanguageSelector = true; @@ -251,178 +200,59 @@ void UIScene_SettingsOptionsMenu::handlePress(F64 controlId, F64 childId) } } -void UIScene_SettingsOptionsMenu::handleReload() +void UIScene_SettingsOptionsMenu::handleCheckboxToggled(F64 controlId, bool selected) { - m_bNavigateToLanguageSelector = false; - - m_checkboxViewBob.init(IDS_VIEW_BOBBING,eControl_ViewBob,(app.GetGameSettings(m_iPad,eGameSetting_ViewBob)!=0)); - m_checkboxShowHints.init(IDS_HINTS,eControl_ShowHints,(app.GetGameSettings(m_iPad,eGameSetting_Hints)!=0)); - m_checkboxShowTooltips.init(IDS_IN_GAME_TOOLTIPS,eControl_ShowTooltips,(app.GetGameSettings(m_iPad,eGameSetting_Tooltips)!=0)); - m_checkboxInGameGamertags.init(IDS_IN_GAME_GAMERTAGS,eControl_InGameGamertags,(app.GetGameSettings(m_iPad,eGameSetting_GamertagsVisible)!=0)); - - // check if we should display the mash-up option - if(m_bNotInGame && app.GetMashupPackWorlds(m_iPad)!=0xFFFFFFFF) - { - // the mash-up option is needed - m_bMashUpWorldsUnhideOption=true; - } - else - { - //m_checkboxMashupWorlds.init(L"",eControl_ShowMashUpWorlds,false); - removeControl(&m_checkboxMashupWorlds, true); - m_bMashUpWorldsUnhideOption=false; - } - - unsigned char ucValue=app.GetGameSettings(m_iPad,eGameSetting_Autosave); - - wchar_t autosaveLabels[9][256]; - for(unsigned int i = 0; i < 9; ++i) - { - if(i==0) - { - swprintf( autosaveLabels[i], 256, L"%ls", app.GetString( IDS_SLIDER_AUTOSAVE_OFF )); - } - else - { - swprintf( autosaveLabels[i], 256, L"%ls: %d %ls", app.GetString( IDS_SLIDER_AUTOSAVE ),i*15, app.GetString( IDS_MINUTES )); - } - - } - m_sliderAutosave.setAllPossibleLabels(9,autosaveLabels); - m_sliderAutosave.init(autosaveLabels[ucValue],eControl_Autosave,0,8,ucValue); - -#if defined(_XBOX_ONE) || defined(__ORBIS__) - removeControl(&m_sliderAutosave,true); -#endif - - ucValue = app.GetGameSettings(m_iPad,eGameSetting_Difficulty); - - wchar_t difficultyLabels[4][256]; - for(unsigned int i = 0; i < 4; ++i) - { - swprintf( difficultyLabels[i], 256, L"%ls: %ls", app.GetString( IDS_SLIDER_DIFFICULTY ),app.GetString(m_iDifficultyTitleSettingA[i])); - } - m_sliderDifficulty.setAllPossibleLabels(4,difficultyLabels); - m_sliderDifficulty.init(difficultyLabels[ucValue],eControl_Difficulty,0,3,ucValue); - - wstring wsText=app.GetString(m_iDifficultySettingA[app.GetGameSettings(m_iPad,eGameSetting_Difficulty)]); - EHTMLFontSize size = eHTMLSize_Normal; - if(!RenderManager.IsHiDef() && !RenderManager.IsWidescreen()) - { - size = eHTMLSize_Splitscreen; - } - wchar_t startTags[64]; - swprintf(startTags,64,L"",app.GetHTMLColour(eHTMLColor_White)); - wsText= startTags + wsText; - - m_labelDifficultyText.init(wsText); - - - // If you are in-game, only the game host can change in-game gamertags, and you can't change difficulty - // only the primary player gets to change the autosave and difficulty settings - bool bRemoveDifficulty=false; - bool bRemoveAutosave=false; - bool bRemoveInGameGamertags=false; - - bool bNotInGame=(Minecraft::GetInstance()->level==nullptr); - bool bPrimaryPlayer = ProfileManager.GetPrimaryPad()==m_iPad; - if(!bPrimaryPlayer) - { - bRemoveDifficulty=true; - bRemoveAutosave=true; - bRemoveInGameGamertags=true; - } - - if(!bNotInGame) // in the game - { - bRemoveDifficulty=true; - if(!g_NetworkManager.IsHost()) - { - bRemoveAutosave=true; - bRemoveInGameGamertags=true; - } - } - if(bRemoveDifficulty) - { - m_labelDifficultyText.setVisible( false ); - removeControl(&m_sliderDifficulty, true); - } - - if(bRemoveAutosave) - { - removeControl(&m_sliderAutosave, true); - } - - if(bRemoveInGameGamertags) - { - removeControl(&m_checkboxInGameGamertags, true); - } - - // MGH - disabled the language select for the patch build, we'll re-enable afterwards - // 4J Stu - Removed it with a preprocessor def as we turn this off in various places -#ifdef _ENABLE_LANGUAGE_SELECT - // 4J-JEV: Changing languages in-game will produce many a bug. - if (app.GetGameStarted()) - { - removeControl( &m_buttonLanguageSelect, false ); - } - else - { - } -#else - removeControl( &m_buttonLanguageSelect, false ); -#endif - - doHorizontalResizeCheck(); + if(m_bInitialPopulateDone) + ui.PlayUISFX(eSFX_Press); } void UIScene_SettingsOptionsMenu::handleSliderMove(F64 sliderId, F64 currentValue) { + int sliderIdInt = static_cast(sliderId); int value = static_cast(currentValue); - switch(static_cast(sliderId)) + + ui.PlayUISFX(eSFX_Scroll); + + switch(sliderIdInt) { case eControl_Autosave: - m_sliderAutosave.handleSliderMove(value); - - app.SetGameSettings(m_iPad,eGameSetting_Autosave,value); - // Update the autosave timer - app.SetAutosaveTimerTime(); - - break; + case eControl_Sensitivity_InGame: case eControl_Difficulty: - m_sliderDifficulty.handleSliderMove(value); - - app.SetGameSettings(m_iPad,eGameSetting_Difficulty,value); - - wstring wsText=app.GetString(m_iDifficultySettingA[value]); - EHTMLFontSize size = eHTMLSize_Normal; - if(!RenderManager.IsHiDef() && !RenderManager.IsWidescreen()) - { - size = eHTMLSize_Splitscreen; - } - wchar_t startTags[64]; - swprintf(startTags,64,L"",app.GetHTMLColour(eHTMLColor_White)); - wsText= startTags + wsText; - m_labelDifficultyText.setLabel(wsText.c_str()); + m_bPendingSliderUpdate = true; + m_iPendingSliderId = sliderIdInt; + m_iPendingSliderValue = value; break; } } void UIScene_SettingsOptionsMenu::setGameSettings() { - // check the checkboxes - app.SetGameSettings(m_iPad,eGameSetting_ViewBob,m_checkboxViewBob.IsChecked()?1:0); - app.SetGameSettings(m_iPad,eGameSetting_GamertagsVisible,m_checkboxInGameGamertags.IsChecked()?1:0); - app.SetGameSettings(m_iPad,eGameSetting_Hints,m_checkboxShowHints.IsChecked()?1:0); - app.SetGameSettings(m_iPad,eGameSetting_Tooltips,m_checkboxShowTooltips.IsChecked()?1:0); + bool bSplitChanged = (app.GetGameSettings(m_iPad,eGameSetting_SplitScreenVertical)!=(m_multiList.GetCheckboxValue(eControl_VerticalSplitscreen)?1:0)); - // the mashup option will only be shown if some worlds have been previously hidden - if(m_bMashUpWorldsUnhideOption && m_checkboxMashupWorlds.IsChecked()) + app.SetGameSettings(m_iPad,eGameSetting_SplitScreenVertical,m_multiList.GetCheckboxValue(eControl_VerticalSplitscreen)?1:0); + app.SetGameSettings(m_iPad,eGameSetting_ViewBob,m_multiList.GetCheckboxValue(eControl_ViewBob)?1:0); + app.SetGameSettings(m_iPad,eGameSetting_Hints,m_multiList.GetCheckboxValue(eControl_Hints)?1:0); + app.SetGameSettings(m_iPad,eGameSetting_DeathMessages,m_multiList.GetCheckboxValue(eControl_DeathMessages)?1:0); + app.SetGameSettings(m_iPad,eGameSetting_Autosave,m_multiList.GetSliderValue(eControl_Autosave)); + app.SetGameSettings(m_iPad,eGameSetting_Sensitivity_InGame,m_multiList.GetSliderValue(eControl_Sensitivity_InGame)); + app.SetGameSettings(m_iPad,eGameSetting_Difficulty,m_multiList.GetSliderValue(eControl_Difficulty)); + + if(bSplitChanged && app.GetLocalPlayerCount()==2) { - // unhide all worlds - app.EnableMashupPackWorlds(m_iPad); + ui.CloseAllPlayersScenes(); } +} + +void UIScene_SettingsOptionsMenu::handleGainFocus(bool navBack) +{ + if(navBack) + { + m_bNeedsMultiListPopulate = true; + m_bInitialPopulateDone = false; + } +} + // handled = true; + // if the splitscreen vertical/horizontal has changed, need to update the scenes // 4J-PB - don't action changes here or we might write to the profile on backing out here and then get a change in the settings all, and write again on backing out there - //app.CheckGameSettingsChanged(true,pInputData->UserIndex); -} \ No newline at end of file + //app.CheckGameSettingsChanged(true,pInputData->UserIndex); \ No newline at end of file diff --git a/Minecraft.Client/Common/UI/UIScene_SettingsOptionsMenu.h b/Minecraft.Client/Common/UI/UIScene_SettingsOptionsMenu.h index e9abb0a9..1b18fc4f 100644 --- a/Minecraft.Client/Common/UI/UIScene_SettingsOptionsMenu.h +++ b/Minecraft.Client/Common/UI/UIScene_SettingsOptionsMenu.h @@ -1,46 +1,42 @@ #pragma once #include "UIScene.h" +#include "UIControl_MultiList.h" class UIScene_SettingsOptionsMenu : public UIScene { private: enum EControls { - eControl_ViewBob, - eControl_ShowHints, - eControl_ShowTooltips, - eControl_InGameGamertags, - eControl_ShowMashUpWorlds, - eControl_Autosave, - eControl_Languages, - eControl_Difficulty + eControl_MultiList = 0, + eControl_VerticalSplitscreen = 1, + eControl_ViewBob = 2, + eControl_Hints = 3, + eControl_DeathMessages = 4, + eControl_Languages = 5, + eControl_Autosave = 6, + eControl_Sensitivity_InGame = 7, + eControl_Difficulty = 8, }; -protected: - static int m_iDifficultySettingA[4]; + + UIControl_MultiList m_multiList; + bool m_bNeedsMultiListPopulate; + bool m_bNavigateToLanguageSelector; + bool m_bInitialPopulateDone; + bool m_bPendingSliderUpdate; + int m_iPendingSliderId; + int m_iPendingSliderValue; + static int m_iDifficultyTitleSettingA[4]; -private: - UIControl_CheckBox m_checkboxViewBob, m_checkboxShowHints, m_checkboxShowTooltips, m_checkboxInGameGamertags, m_checkboxMashupWorlds; // Checkboxes - UIControl_Slider m_sliderAutosave, m_sliderDifficulty; // Sliders - UIControl_Label m_labelDifficultyText; //Text - UIControl_Button m_buttonLanguageSelect; + bool m_bNotInGame; UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) - UI_MAP_ELEMENT( m_checkboxViewBob, "ViewBob") - UI_MAP_ELEMENT( m_checkboxShowHints, "ShowHints") - UI_MAP_ELEMENT( m_checkboxShowTooltips, "ShowTooltips") - UI_MAP_ELEMENT( m_checkboxInGameGamertags, "InGameGamertags") - UI_MAP_ELEMENT( m_checkboxMashupWorlds, "ShowMashUpWorlds") - UI_MAP_ELEMENT( m_sliderAutosave, "Autosave") - UI_MAP_ELEMENT( m_sliderDifficulty, "Difficulty") - UI_MAP_ELEMENT( m_labelDifficultyText, "DifficultyText") - UI_MAP_ELEMENT( m_buttonLanguageSelect, "Languages") UI_END_MAP_ELEMENTS_AND_NAMES() - bool m_bNotInGame; - bool m_bMashUpWorldsUnhideOption; - bool m_bNavigateToLanguageSelector; + //bool m_bNotInGame; + // bool m_bMashUpWorldsUnhideOption; + // bool m_bNavigateToLanguageSelector; public: UIScene_SettingsOptionsMenu(int iPad, void *initData, UILayer *parentLayer); @@ -61,12 +57,9 @@ public: // INPUT virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled); virtual void handlePress(F64 controlId, F64 childId); - - virtual void handleReload(); - virtual void handleSliderMove(F64 sliderId, F64 currentValue); + virtual void handleCheckboxToggled(F64 controlId, bool selected); + virtual void handleGainFocus(bool navBack); -protected: void setGameSettings(); - -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/Common/UI/UIScene_SettingsUIMenu.cpp b/Minecraft.Client/Common/UI/UIScene_SettingsUIMenu.cpp index b5b15a4a..72346886 100644 --- a/Minecraft.Client/Common/UI/UIScene_SettingsUIMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_SettingsUIMenu.cpp @@ -3,49 +3,32 @@ #include "UI.h" #include "UIScene_SettingsUIMenu.h" +int UIScene_SettingsUIMenu::m_iControlTypeSettingA[6]= +{ + IDS_CONTROLTYPE_KBM, + IDS_CONTROLTYPE_XBOXONE, + IDS_CONTROLTYPE_XBOX360, + // IDS_CONTROLTYPE_VITA, + IDS_CONTROLTYPE_PLAYSTATION3, + IDS_CONTROLTYPE_PLAYSTATION4, + IDS_CONTROLTYPE_WIIU, + // IDS_CONTROLTYPE_SWITCH, +}; + UIScene_SettingsUIMenu::UIScene_SettingsUIMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer) { // Setup all the Iggy references we need for this scene initialiseMovie(); - - m_bNotInGame=(Minecraft::GetInstance()->level==nullptr); - - m_checkboxDisplayHUD.init(app.GetString(IDS_CHECKBOX_DISPLAY_HUD),eControl_DisplayHUD,(app.GetGameSettings(m_iPad,eGameSetting_DisplayHUD)!=0)); - m_checkboxDisplayHand.init(app.GetString(IDS_CHECKBOX_DISPLAY_HAND),eControl_DisplayHand,(app.GetGameSettings(m_iPad,eGameSetting_DisplayHand)!=0)); - m_checkboxDisplayDeathMessages.init(app.GetString(IDS_CHECKBOX_DEATH_MESSAGES),eControl_DisplayDeathMessages,(app.GetGameSettings(m_iPad,eGameSetting_DeathMessages)!=0)); - m_checkboxDisplayAnimatedCharacter.init(app.GetString(IDS_CHECKBOX_ANIMATED_CHARACTER),eControl_DisplayAnimatedCharacter,(app.GetGameSettings(m_iPad,eGameSetting_AnimatedCharacter)!=0)); - m_checkboxSplitscreen.init(app.GetString(IDS_CHECKBOX_VERTICAL_SPLIT_SCREEN),eControl_Splitscreen,(app.GetGameSettings(m_iPad,eGameSetting_SplitScreenVertical)!=0)); - m_checkboxShowSplitscreenGamertags.init(app.GetString(IDS_CHECKBOX_DISPLAY_SPLITSCREENGAMERTAGS),eControl_ShowSplitscreenGamertags,(app.GetGameSettings(m_iPad,eGameSetting_DisplaySplitscreenGamertags)!=0)); - m_checkboxShowClassicCrafting.init(app.GetString(IDS_CHECKBOX_CLASSICCRAFTING), eControl_ShowClassicCrafting, (app.GetGameSettings(m_iPad, eGameSetting_ClassicCrafting) != 0)); - // label is hardcoded for now (no IDS_* yet) - m_checkboxHideLoadCreateJoinSaveSizeBar.init(L"Hide world disk space bar", eControl_HideSaveSizeBar, (app.GetGameSettings(m_iPad, eGameSetting_HideSaveSizeBar) != 0)); - - WCHAR TempString[256]; - - swprintf( (WCHAR *)TempString, 256, L"%ls: %d", app.GetString( IDS_SLIDER_UISIZE ),app.GetGameSettings(m_iPad,eGameSetting_UISize)+1); - m_sliderUISize.init(TempString,eControl_UISize,1,3,app.GetGameSettings(m_iPad,eGameSetting_UISize)+1); - - swprintf( (WCHAR *)TempString, 256, L"%ls: %d", app.GetString( IDS_SLIDER_UISIZESPLITSCREEN ),app.GetGameSettings(m_iPad,eGameSetting_UISizeSplitscreen)+1); - m_sliderUISizeSplitscreen.init(TempString,eControl_UISizeSplitscreen,1,3,app.GetGameSettings(m_iPad,eGameSetting_UISizeSplitscreen)+1); + m_bControlTypeChanged = false; + m_bNotInGame = (Minecraft::GetInstance()->level == nullptr); + m_bNeedsMultiListPopulate = true; + m_bInitialPopulateDone = false; + m_bPendingSliderUpdate = false; + m_iPendingSliderId = 0; + m_iPendingSliderValue = 0; doHorizontalResizeCheck(); - bool bInGame=(Minecraft::GetInstance()->level!=nullptr); - bool bPrimaryPlayer = ProfileManager.GetPrimaryPad()==m_iPad; - - // if we're not in the game, we need to use basescene 0 - if(bInGame) - { - // If the game has started, then you need to be the host to change the in-game gamertags - if(!bPrimaryPlayer) - { - // hide things we don't want the splitscreen player changing - removeControl(&m_checkboxSplitscreen, true); - removeControl(&m_checkboxShowSplitscreenGamertags, true); - } - } - - if(app.GetLocalPlayerCount()>1) { #if TO_BE_IMPLEMENTED @@ -54,29 +37,6 @@ UIScene_SettingsUIMenu::UIScene_SettingsUIMenu(int iPad, void *initData, UILayer } } -void UIScene_SettingsUIMenu::updateTooltips() -{ - ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK); -} - -void UIScene_SettingsUIMenu::updateComponents() -{ - bool bNotInGame=(Minecraft::GetInstance()->level==nullptr); - if(bNotInGame) - { - m_parentLayer->showComponent(m_iPad,eUIComponent_Panorama,true); - m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,true); - } - else - { - m_parentLayer->showComponent(m_iPad,eUIComponent_Panorama,false); - - if( app.GetLocalPlayerCount() == 1 ) m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,true); - else m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,false); - - } -} - UIScene_SettingsUIMenu::~UIScene_SettingsUIMenu() { } @@ -85,11 +45,151 @@ wstring UIScene_SettingsUIMenu::getMoviePath() { if(app.GetLocalPlayerCount() > 1) { - return L"SettingsUIMenuSplit"; + return L"MultilistMenuSplit"; } else { - return L"SettingsUIMenu"; + return L"MultilistMenu"; + } +} + +void UIScene_SettingsUIMenu::tick() +{ + if(m_bNeedsMultiListPopulate) + { + m_bNeedsMultiListPopulate = false; + m_multiList.setupControl(this, m_rootPath, "MultiList"); + m_controls.push_back(&m_multiList); + m_multiList.clearList(); + m_multiList.init(eControl_MultiList); + + bool bPrimaryPlayer = (ProfileManager.GetPrimaryPad() == m_iPad); + bool bInGame = !m_bNotInGame; + + WCHAR TempString[256]; + + m_multiList.AddNewCheckbox(app.GetString(IDS_CHECKBOX_DISPLAY_HUD), eControl_DisplayHUD, (app.GetGameSettings(m_iPad, eGameSetting_DisplayHUD) != 0)); + m_multiList.AddNewCheckbox(app.GetString(IDS_CHECKBOX_DISPLAY_HAND), eControl_DisplayHand, (app.GetGameSettings(m_iPad, eGameSetting_DisplayHand) != 0)); + + int opacityVal = app.GetGameSettings(m_iPad, eGameSetting_InterfaceOpacity); + swprintf(TempString, 256, L"%ls: %d%%", app.GetString(IDS_SLIDER_INTERFACEOPACITY), opacityVal); + m_multiList.AddNewSlider(TempString, eControl_InterfaceOpacity, 0, 100, 1, opacityVal); + + m_multiList.AddNewCheckbox(app.GetString(IDS_IN_GAME_TOOLTIPS), eControl_ShowTooltips, (app.GetGameSettings(m_iPad, eGameSetting_Tooltips) != 0)); + m_multiList.AddNewCheckbox(app.GetString(IDS_CHECKBOX_ANIMATED_CHARACTER), eControl_DisplayAnimatedCharacter, (app.GetGameSettings(m_iPad, eGameSetting_AnimatedCharacter) != 0)); + + int sensitivityVal = app.GetGameSettings(m_iPad, eGameSetting_Sensitivity_InMenu); + swprintf(TempString, 256, L"%ls: %d%%", app.GetString(IDS_SLIDER_SENSITIVITY_INMENU), sensitivityVal); + m_multiList.AddNewSlider(TempString, eControl_SensitivityInMenu, 0, 200, 1, sensitivityVal); + + if(bPrimaryPlayer) + { + m_multiList.AddNewCheckbox(app.GetString(IDS_IN_GAME_GAMERTAGS), eControl_InGameGamertags, (app.GetGameSettings(m_iPad, eGameSetting_GamertagsVisible) != 0)); + } + + if(!bInGame || bPrimaryPlayer) + { + m_multiList.AddNewCheckbox(app.GetString(IDS_CHECKBOX_DISPLAY_SPLITSCREENGAMERTAGS), eControl_ShowSplitscreenGamertags, (app.GetGameSettings(m_iPad, eGameSetting_DisplaySplitscreenGamertags) != 0)); + } + + m_multiList.AddNewCheckbox(app.GetString(IDS_CHECKBOX_CLASSICCRAFTING), eControl_ShowClassicCrafting, (app.GetGameSettings(m_iPad, eGameSetting_ClassicCrafting) != 0)); + m_multiList.AddNewCheckbox(L"Hide world disk space bar", eControl_HideSaveSizeBar, (app.GetGameSettings(m_iPad, eGameSetting_HideSaveSizeBar) != 0)); + + int uiSizeVal = app.GetGameSettings(m_iPad, eGameSetting_UISize) + 1; + swprintf(TempString, 256, L"%ls: %d", app.GetString(IDS_SLIDER_UISIZE), uiSizeVal); + m_multiList.AddNewSlider(TempString, eControl_UISize, 1, 3, 1, uiSizeVal); + + int uiSizeSplitVal = app.GetGameSettings(m_iPad, eGameSetting_UISizeSplitscreen) + 1; + swprintf(TempString, 256, L"%ls: %d", app.GetString(IDS_SLIDER_UISIZESPLITSCREEN), uiSizeSplitVal); + m_multiList.AddNewSlider(TempString, eControl_UISizeSplitscreen, 1, 3, 1, uiSizeSplitVal); + + if(!bInGame) + { + int controlTypeVal = app.GetGameSettings(m_iPad, eGameSetting_ControlType); + swprintf(TempString, 256, L"%ls: %ls", app.GetString(IDS_SLIDER_CONTROLTYPE), app.GetString(m_iControlTypeSettingA[controlTypeVal])); + m_multiList.AddNewSlider(TempString, eControl_ControlType, 0, 5, 1, controlTypeVal); + } + + IggyName funcDoVert = registerFastName(L"DoVerticalResizeCheck"); + IggyName funcHideDesc = registerFastName(L"HideDescription"); + IggyDataValue result; + IggyPlayerCallMethodRS(getMovie(), &result, m_rootPath, funcDoVert, 0, nullptr); + doHorizontalResizeCheck(); + IggyPlayerCallMethodRS(getMovie(), &result, m_rootPath, funcHideDesc, 0, nullptr); + m_multiList.HighlightItem(eControl_DisplayHUD); + } + + if(m_bPendingSliderUpdate) + { + m_bPendingSliderUpdate = false; + m_multiList.SetSliderValue(m_iPendingSliderId, m_iPendingSliderValue); + + WCHAR TempString[256]; + switch(m_iPendingSliderId) + { + case eControl_InterfaceOpacity: + app.SetGameSettings(m_iPad, eGameSetting_InterfaceOpacity, m_iPendingSliderValue); + swprintf(TempString, 256, L"%ls: %d%%", app.GetString(IDS_SLIDER_INTERFACEOPACITY), m_iPendingSliderValue); + m_multiList.SetSliderLabel(eControl_InterfaceOpacity, TempString); + break; + case eControl_SensitivityInMenu: + app.SetGameSettings(m_iPad, eGameSetting_Sensitivity_InMenu, m_iPendingSliderValue); + swprintf(TempString, 256, L"%ls: %d%%", app.GetString(IDS_SLIDER_SENSITIVITY_INMENU), m_iPendingSliderValue); + m_multiList.SetSliderLabel(eControl_SensitivityInMenu, TempString); + break; + case eControl_UISize: + app.SetGameSettings(m_iPad, eGameSetting_UISize, m_iPendingSliderValue - 1); + ui.UpdateSelectedItemPos(m_iPad); + swprintf(TempString, 256, L"%ls: %d", app.GetString(IDS_SLIDER_UISIZE), m_iPendingSliderValue); + m_multiList.SetSliderLabel(eControl_UISize, TempString); + break; + case eControl_UISizeSplitscreen: + app.SetGameSettings(m_iPad, eGameSetting_UISizeSplitscreen, m_iPendingSliderValue - 1); + ui.UpdateSelectedItemPos(m_iPad); + swprintf(TempString, 256, L"%ls: %d", app.GetString(IDS_SLIDER_UISIZESPLITSCREEN), m_iPendingSliderValue); + m_multiList.SetSliderLabel(eControl_UISizeSplitscreen, TempString); + break; + case eControl_ControlType: + app.SetGameSettings(m_iPad, eGameSetting_ControlType, m_iPendingSliderValue); + m_bControlTypeChanged = true; + swprintf(TempString, 256, L"%ls: %ls", app.GetString(IDS_SLIDER_CONTROLTYPE), app.GetString(m_iControlTypeSettingA[m_iPendingSliderValue])); + m_multiList.SetSliderLabel(eControl_ControlType, TempString); + break; + } + } + + UIScene::tick(); + m_bInitialPopulateDone = true; +} + +void UIScene_SettingsUIMenu::updateTooltips() +{ + ui.SetTooltips(m_iPad, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK); +} + +void UIScene_SettingsUIMenu::updateComponents() +{ + bool bNotInGame = (Minecraft::GetInstance()->level == nullptr); + if(bNotInGame) + { + m_parentLayer->showComponent(m_iPad, eUIComponent_Panorama, true); + m_parentLayer->showComponent(m_iPad, eUIComponent_Logo, true); + } + else + { + m_parentLayer->showComponent(m_iPad, eUIComponent_Panorama, false); + + if(app.GetLocalPlayerCount() == 1) m_parentLayer->showComponent(m_iPad, eUIComponent_Logo, true); + else m_parentLayer->showComponent(m_iPad, eUIComponent_Logo, false); + } +} + +void UIScene_SettingsUIMenu::handleGainFocus(bool navBack) +{ + if(navBack) + { + m_bNeedsMultiListPopulate = true; + m_bInitialPopulateDone = false; } } @@ -102,37 +202,13 @@ void UIScene_SettingsUIMenu::handleInput(int iPad, int key, bool repeat, bool pr case ACTION_MENU_CANCEL: if(pressed) { - // check the checkboxes - app.SetGameSettings(m_iPad,eGameSetting_DisplayHUD,m_checkboxDisplayHUD.IsChecked()?1:0); - app.SetGameSettings(m_iPad,eGameSetting_DisplayHand,m_checkboxDisplayHand.IsChecked()?1:0); - app.SetGameSettings(m_iPad,eGameSetting_DisplaySplitscreenGamertags,m_checkboxShowSplitscreenGamertags.IsChecked()?1:0); - app.SetGameSettings(m_iPad,eGameSetting_DeathMessages,m_checkboxDisplayDeathMessages.IsChecked()?1:0); - app.SetGameSettings(m_iPad,eGameSetting_AnimatedCharacter,m_checkboxDisplayAnimatedCharacter.IsChecked()?1:0); - app.SetGameSettings(m_iPad, eGameSetting_ClassicCrafting, m_checkboxShowClassicCrafting.IsChecked() ? 1 : 0); - app.SetGameSettings(m_iPad, eGameSetting_HideSaveSizeBar, m_checkboxHideLoadCreateJoinSaveSizeBar.IsChecked() ? 1 : 0); - - - // if the splitscreen vertical/horizontal has changed, need to update the scenes - if(app.GetGameSettings(m_iPad,eGameSetting_SplitScreenVertical)!=(m_checkboxSplitscreen.IsChecked()?1:0)) + const bool reloadControlTypeSkin = m_bControlTypeChanged; + setGameSettings(); + navigateBack(); + if(reloadControlTypeSkin) { - // changed - app.SetGameSettings(m_iPad,eGameSetting_SplitScreenVertical,m_checkboxSplitscreen.IsChecked()?1:0); - - // close the xui scenes, so we don't have the navigate backed to menu at the wrong place - if(app.GetLocalPlayerCount()==2) - { - ui.CloseAllPlayersScenes(); - } - else - { - navigateBack(); - } + ui.ReloadSkin(); } - else - { - navigateBack(); - } - handled = true; } break; case ACTION_MENU_OK: @@ -152,39 +228,66 @@ void UIScene_SettingsUIMenu::handleInput(int iPad, int key, bool repeat, bool pr void UIScene_SettingsUIMenu::handleSliderMove(F64 sliderId, F64 currentValue) { - WCHAR TempString[256]; + int sliderIdInt = static_cast(sliderId); int value = static_cast(currentValue); - switch(static_cast(sliderId)) + + ui.PlayUISFX(eSFX_Scroll); + + switch(sliderIdInt) { + case eControl_InterfaceOpacity: + case eControl_SensitivityInMenu: case eControl_UISize: - m_sliderUISize.handleSliderMove(value); - - swprintf( (WCHAR *)TempString, 256, L"%ls: %d", app.GetString( IDS_SLIDER_UISIZE ),value); - m_sliderUISize.setLabel(TempString); - - // is this different from the current value? - if(value != app.GetGameSettings(m_iPad,eGameSetting_UISize)+1) - { - app.SetGameSettings(m_iPad,eGameSetting_UISize,value-1); - // Apply the changes to the selected text position - ui.UpdateSelectedItemPos(m_iPad); - } - - break; case eControl_UISizeSplitscreen: - m_sliderUISizeSplitscreen.handleSliderMove(value); - - swprintf( (WCHAR *)TempString, 256, L"%ls: %d", app.GetString( IDS_SLIDER_UISIZESPLITSCREEN ),value); - m_sliderUISizeSplitscreen.setLabel(TempString); - - if(value != app.GetGameSettings(m_iPad,eGameSetting_UISizeSplitscreen)+1) - { - // slider is 1 to 3 - app.SetGameSettings(m_iPad,eGameSetting_UISizeSplitscreen,value-1); - // Apply the changes to the selected text position - ui.UpdateSelectedItemPos(m_iPad); - } - + case eControl_ControlType: + m_bPendingSliderUpdate = true; + m_iPendingSliderId = sliderIdInt; + m_iPendingSliderValue = value; break; } } + +void UIScene_SettingsUIMenu::handleCheckboxToggled(F64 controlId, bool selected) +{ + if(m_bInitialPopulateDone) + ui.PlayUISFX(eSFX_Press); +} + +void UIScene_SettingsUIMenu::handlePress(F64 controlId, F64 childId) +{ + ui.PlayUISFX(eSFX_Press); +} + +void UIScene_SettingsUIMenu::setGameSettings() +{ + bool bPrimaryPlayer = (ProfileManager.GetPrimaryPad() == m_iPad); + bool bInGame = !m_bNotInGame; + + app.SetGameSettings(m_iPad, eGameSetting_DisplayHUD, m_multiList.GetCheckboxValue(eControl_DisplayHUD) ? 1 : 0); + app.SetGameSettings(m_iPad, eGameSetting_DisplayHand, m_multiList.GetCheckboxValue(eControl_DisplayHand) ? 1 : 0); + app.SetGameSettings(m_iPad, eGameSetting_Tooltips, m_multiList.GetCheckboxValue(eControl_ShowTooltips) ? 1 : 0); + app.SetGameSettings(m_iPad, eGameSetting_AnimatedCharacter, m_multiList.GetCheckboxValue(eControl_DisplayAnimatedCharacter) ? 1 : 0); + + if(bPrimaryPlayer) + { + app.SetGameSettings(m_iPad, eGameSetting_GamertagsVisible, m_multiList.GetCheckboxValue(eControl_InGameGamertags) ? 1 : 0); + } + + if(!bInGame || bPrimaryPlayer) + { + app.SetGameSettings(m_iPad, eGameSetting_DisplaySplitscreenGamertags, m_multiList.GetCheckboxValue(eControl_ShowSplitscreenGamertags) ? 1 : 0); + } + + app.SetGameSettings(m_iPad, eGameSetting_ClassicCrafting, m_multiList.GetCheckboxValue(eControl_ShowClassicCrafting) ? 1 : 0); + app.SetGameSettings(m_iPad, eGameSetting_HideSaveSizeBar, m_multiList.GetCheckboxValue(eControl_HideSaveSizeBar) ? 1 : 0); + + app.SetGameSettings(m_iPad, eGameSetting_InterfaceOpacity, m_multiList.GetSliderValue(eControl_InterfaceOpacity)); + app.SetGameSettings(m_iPad, eGameSetting_Sensitivity_InMenu, m_multiList.GetSliderValue(eControl_SensitivityInMenu)); + app.SetGameSettings(m_iPad, eGameSetting_UISize, m_multiList.GetSliderValue(eControl_UISize) - 1); + app.SetGameSettings(m_iPad, eGameSetting_UISizeSplitscreen, m_multiList.GetSliderValue(eControl_UISizeSplitscreen) - 1); + + if(!bInGame) + { + app.SetGameSettings(m_iPad, eGameSetting_ControlType, m_multiList.GetSliderValue(eControl_ControlType)); + } +} diff --git a/Minecraft.Client/Common/UI/UIScene_SettingsUIMenu.h b/Minecraft.Client/Common/UI/UIScene_SettingsUIMenu.h index 34ffaebc..97b9bfec 100644 --- a/Minecraft.Client/Common/UI/UIScene_SettingsUIMenu.h +++ b/Minecraft.Client/Common/UI/UIScene_SettingsUIMenu.h @@ -1,49 +1,53 @@ #pragma once #include "UIScene.h" +#include "UIControl_MultiList.h" class UIScene_SettingsUIMenu : public UIScene { +protected: + static int m_iControlTypeSettingA[6]; private: enum EControls { - eControl_DisplayHUD, - eControl_DisplayHand, - eControl_DisplayDeathMessages, - eControl_DisplayAnimatedCharacter, - eControl_Splitscreen, - eControl_ShowSplitscreenGamertags, - eControl_ShowClassicCrafting, - eControl_HideSaveSizeBar, - eControl_UISize, - eControl_UISizeSplitscreen + eControl_MultiList = 0, + eControl_DisplayHUD = 1, + eControl_DisplayHand = 2, + eControl_ShowTooltips = 3, + eControl_DisplayAnimatedCharacter = 4, + eControl_InGameGamertags = 5, + eControl_ShowSplitscreenGamertags = 6, + eControl_ShowClassicCrafting = 7, + eControl_HideSaveSizeBar = 8, + eControl_InterfaceOpacity = 9, + eControl_SensitivityInMenu = 10, + eControl_UISize = 11, + eControl_UISizeSplitscreen = 12, + eControl_ControlType = 13, }; - UIControl_CheckBox m_checkboxDisplayHUD, m_checkboxDisplayHand, m_checkboxDisplayDeathMessages, m_checkboxDisplayAnimatedCharacter, m_checkboxSplitscreen, m_checkboxShowSplitscreenGamertags, m_checkboxShowClassicCrafting, m_checkboxHideLoadCreateJoinSaveSizeBar; // Checkboxes - UIControl_Slider m_sliderUISize, m_sliderUISizeSplitscreen; // Sliders - UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) - UI_MAP_ELEMENT( m_checkboxDisplayHUD, "DisplayHUD") - UI_MAP_ELEMENT( m_checkboxDisplayHand, "DisplayHand") - UI_MAP_ELEMENT( m_checkboxDisplayDeathMessages, "DisplayDeathMessages") - UI_MAP_ELEMENT( m_checkboxDisplayAnimatedCharacter, "DisplayAnimatedCharacter") - UI_MAP_ELEMENT( m_checkboxSplitscreen, "Splitscreen") - UI_MAP_ELEMENT( m_checkboxShowSplitscreenGamertags, "ShowSplitscreenGamertags") - UI_MAP_ELEMENT(m_checkboxShowClassicCrafting, "ShowClassicCrafting") - UI_MAP_ELEMENT(m_checkboxHideLoadCreateJoinSaveSizeBar, "LoadCreateJoinSaveSizeBar") + UIControl_MultiList m_multiList; + bool m_bNeedsMultiListPopulate; + bool m_bInitialPopulateDone; + bool m_bPendingSliderUpdate; + int m_iPendingSliderId; + int m_iPendingSliderValue; + bool m_bControlTypeChanged; + bool m_bNotInGame; - UI_MAP_ELEMENT( m_sliderUISize, "UISize") - UI_MAP_ELEMENT( m_sliderUISizeSplitscreen, "UISizeSplitscreen") + UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) UI_END_MAP_ELEMENTS_AND_NAMES() - bool m_bNotInGame; public: UIScene_SettingsUIMenu(int iPad, void *initData, UILayer *parentLayer); virtual ~UIScene_SettingsUIMenu(); virtual EUIScene getSceneType() { return eUIScene_SettingsUIMenu;} - + + virtual void tick(); virtual void updateTooltips(); virtual void updateComponents(); + virtual void handleGainFocus(bool navBack); protected: // TODO: This should be pure virtual in this class @@ -54,4 +58,8 @@ public: virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled); virtual void handleSliderMove(F64 sliderId, F64 currentValue); + virtual void handleCheckboxToggled(F64 controlId, bool selected); + virtual void handlePress(F64 controlId, F64 childId); + + void setGameSettings(); }; diff --git a/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.cpp b/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.cpp index 05996f55..6b2f762c 100644 --- a/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.cpp @@ -2,6 +2,7 @@ #include "UI.h" #include "UIScene_SkinSelectMenu.h" #include "../../../Minecraft.World/StringHelpers.h" +#include "TexturePackRepository.h" #ifdef __ORBIS__ #include #elif defined __PSVITA__ @@ -41,7 +42,7 @@ UIScene_SkinSelectMenu::UIScene_SkinSelectMenu(int iPad, void *initData, UILayer // Setup all the Iggy references we need for this scene initialiseMovie(); - m_labelSelected.init( app.GetString( IDS_SELECTED ) ); + //m_labelSelected.init( app.GetString( IDS_SELECTED ) ); #ifdef __ORBIS__ m_bErrorDialogRunning=false; @@ -64,6 +65,8 @@ UIScene_SkinSelectMenu::UIScene_SkinSelectMenu(int iPad, void *initData, UILayer m_bSlidingSkins = false; m_bAnimatingMove = false; m_bSkinIndexChanged = false; + m_bFocusDirty = false; + m_bNeedButtonListRefresh = true; m_currentNavigation = eSkinNavigation_Skin; @@ -73,20 +76,16 @@ UIScene_SkinSelectMenu::UIScene_SkinSelectMenu(int iPad, void *initData, UILayer m_characters[eCharacter_Next1].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Left); m_characters[eCharacter_Next2].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Left); - m_characters[eCharacter_Next3].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Left); - m_characters[eCharacter_Next4].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Left); m_characters[eCharacter_Previous1].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Right); m_characters[eCharacter_Previous2].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Right); - m_characters[eCharacter_Previous3].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Right); - m_characters[eCharacter_Previous4].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Right); m_labelSkinName.init(L""); - m_labelSkinOrigin.init(L""); + //m_labelSkinOrigin.init(L""); - m_leftLabel = L""; - m_centreLabel = L""; - m_rightLabel = L""; + //m_leftLabel = L""; + //m_centreLabel = L""; + //m_rightLabel = L""; #ifdef __PSVITA__ // initialise vita tab controls with ids @@ -104,7 +103,7 @@ UIScene_SkinSelectMenu::UIScene_SkinSelectMenu(int iPad, void *initData, UILayer m_controlTimer.setVisible( true ); m_controlIggyCharacters.setVisible( false ); - m_controlSkinNamePlate.setVisible( false ); + //m_controlSkinNamePlate.setVisible( false ); setCharacterLocked(false); setCharacterSelected(false); @@ -113,26 +112,8 @@ UIScene_SkinSelectMenu::UIScene_SkinSelectMenu(int iPad, void *initData, UILayer { m_controlTimer.setVisible( false ); - if(app.m_dlcManager.getPackCount(DLCManager::e_DLCType_Skin)>0) - { - // Change to display the favorites if there are any. The current skin will be in there (probably) - need to check for it - m_currentPack = app.m_dlcManager.getPackContainingSkin(m_currentSkinPath); - bool bFound; - if(m_currentPack != nullptr) - { - m_packIndex = app.m_dlcManager.getPackIndex(m_currentPack,bFound,DLCManager::e_DLCType_Skin) + SKIN_SELECT_MAX_DEFAULTS; - } - } - - // If we have any favourites, set this to the favourites - // first validate the favorite skins - we might have uninstalled the DLC needed for them app.ValidateFavoriteSkins(m_iPad); - - if(app.GetPlayerFavoriteSkinsCount(m_iPad)>0) - { - m_packIndex = SKIN_SELECT_PACK_FAVORITES; - } - + setActivePackIndex(); handlePackIndexChanged(); } @@ -146,7 +127,47 @@ UIScene_SkinSelectMenu::UIScene_SkinSelectMenu(int iPad, void *initData, UILayer void UIScene_SkinSelectMenu::updateTooltips() { - ui.SetTooltips( m_iPad, m_bNoSkinsToShow?-1:IDS_TOOLTIPS_SELECT_SKIN,IDS_TOOLTIPS_CANCEL,-1,-1,-1,-1,-1,-1,IDS_TOOLTIPS_NAVIGATE); + int iFav = -1; + int favCount = app.GetPlayerFavoriteSkinsCount(m_iPad); + + if(m_packIndex == SKIN_SELECT_PACK_FAVORITES) + { + iFav = (favCount > 0) ? IDS_TOOLTIPS_REMOVE_FAVORITE : -1; + } + else if(m_packIndex == SKIN_SELECT_PACK_DEFAULT) + { + // check if current skin is in favorites + iFav = IDS_TOOLTIPS_ADD_FAVORITE; + for(int i = 0; i < favCount; i++) + { + if(app.GetPlayerFavoriteSkin(m_iPad, i) == (unsigned int)m_skinIndex) + { + iFav = IDS_TOOLTIPS_REMOVE_FAVORITE; + break; + } + } + } + else if(m_currentPack != nullptr) + { + // dlc pack is checked via skin ID + DLCSkinFile *skinFile = m_currentPack->getSkinFile(m_skinIndex); + if(skinFile != nullptr) + { + DWORD skinId = skinFile->getSkinID(); + iFav = IDS_TOOLTIPS_ADD_FAVORITE; + for(int i = 0; i < favCount; i++) + { + if(app.GetPlayerFavoriteSkin(m_iPad, i) == skinId) + { + iFav = IDS_TOOLTIPS_REMOVE_FAVORITE; + break; + } + } + } + } + + ui.SetTooltips(m_iPad, m_bNoSkinsToShow?-1:IDS_TOOLTIPS_SELECT_SKIN, + IDS_TOOLTIPS_CANCEL, -1, iFav, -1, -1, -1, -1, -1, IDS_TOOLTIPS_NAVIGATE); } void UIScene_SkinSelectMenu::updateComponents() @@ -170,12 +191,23 @@ void UIScene_SkinSelectMenu::tick() { UIScene::tick(); + if(m_bFocusDirty) + { + m_bFocusDirty = false; + handlePackIndexChanged(); + } + if(m_bSkinIndexChanged) { m_bSkinIndexChanged = false; handleSkinIndexChanged(); } + if(m_bAnimatingMove && !m_characters[eCharacter_Current].IsAnimatingToFacing()) + { + handleAnimationEnd(); + } + // check for new DLC installed // check for the patch error dialog @@ -225,6 +257,7 @@ void UIScene_SkinSelectMenu::handleInput(int iPad, int key, bool repeat, bool pr ui.AnimateKeyPress(iPad, key, repeat, pressed, released); app.CheckGameSettingsChanged(true,iPad); navigateBack(); + handled = true; } break; case ACTION_MENU_OK: @@ -234,46 +267,45 @@ void UIScene_SkinSelectMenu::handleInput(int iPad, int key, bool repeat, bool pr if(pressed) { InputActionOK(iPad); + handled = true; + } + break; + case ACTION_MENU_Y: + if(pressed) + { + ui.AnimateKeyPress(iPad, key, repeat, pressed, released); + InputActionFavorite(iPad); + handled = true; } break; case ACTION_MENU_UP: case ACTION_MENU_DOWN: if(pressed) { - if(m_packIndex==SKIN_SELECT_PACK_FAVORITES) - { - if(app.GetPlayerFavoriteSkinsCount(iPad)==0) - { - // ignore this, since there are no skins being displayed - break; - } - } + DWORD startingIndex = m_packIndex; + if(key == ACTION_MENU_UP) + m_packIndex = getPreviousPackIndex(m_packIndex); + else + m_packIndex = getNextPackIndex(m_packIndex); - ui.AnimateKeyPress(iPad, key, repeat, pressed, released); - ui.PlayUISFX(eSFX_Scroll); - switch(m_currentNavigation) + if(startingIndex != m_packIndex) { - case eSkinNavigation_Pack: - m_currentNavigation = eSkinNavigation_Skin; - break; - case eSkinNavigation_Skin: - m_currentNavigation = eSkinNavigation_Pack; - break; - }; - sendInputToMovie(key, repeat, pressed, released); + ui.PlayUISFX(eSFX_Scroll); + m_controlSkinButtonList.HighlightItem(m_packIndex, true); + handlePackIndexChanged(); + } + handled = true; } break; case ACTION_MENU_LEFT: if(pressed) - { - if( m_currentNavigation == eSkinNavigation_Skin ) { if(!m_bAnimatingMove) { ui.AnimateKeyPress(iPad, key, repeat, pressed, released); ui.PlayUISFX(eSFX_Scroll); - m_skinIndex = getPreviousSkinIndex(m_skinIndex); + m_skinIndex = getPreviousSkinIndex(m_skinIndex); //handleSkinIndexChanged(); m_bSlidingSkins = true; @@ -283,54 +315,30 @@ void UIScene_SkinSelectMenu::handleInput(int iPad, int key, bool repeat, bool pr m_characters[eCharacter_Previous1].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Forward, true); // 4J Stu - Swapped nav buttons - sendInputToMovie(ACTION_MENU_RIGHT, repeat, pressed, released); - } - } - else if( m_currentNavigation == eSkinNavigation_Pack ) - { - ui.AnimateKeyPress(iPad, key, repeat, pressed, released); - ui.PlayUISFX(eSFX_Scroll); - DWORD startingIndex = m_packIndex; - m_packIndex = getPreviousPackIndex(m_packIndex); - if(startingIndex != m_packIndex) - { - handlePackIndexChanged(); - } + sendInputToMovie(ACTION_MENU_RIGHT, repeat, pressed, released); + handled = true; } } break; case ACTION_MENU_RIGHT: if(pressed) { - if( m_currentNavigation == eSkinNavigation_Skin ) - { - if(!m_bAnimatingMove) - { - ui.AnimateKeyPress(iPad, key, repeat, pressed, released); - ui.PlayUISFX(eSFX_Scroll); - m_skinIndex = getNextSkinIndex(m_skinIndex); - //handleSkinIndexChanged(); - - m_bSlidingSkins = true; - m_bAnimatingMove = true; - - m_characters[eCharacter_Current].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Right, true); - m_characters[eCharacter_Next1].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Forward, true); - - // 4J Stu - Swapped nav buttons - sendInputToMovie(ACTION_MENU_LEFT, repeat, pressed, released); - } - } - else if( m_currentNavigation == eSkinNavigation_Pack ) + if(!m_bAnimatingMove) { ui.AnimateKeyPress(iPad, key, repeat, pressed, released); ui.PlayUISFX(eSFX_Scroll); - DWORD startingIndex = m_packIndex; - m_packIndex = getNextPackIndex(m_packIndex); - if(startingIndex != m_packIndex) - { - handlePackIndexChanged(); - } + m_skinIndex = getNextSkinIndex(m_skinIndex); + //handleSkinIndexChanged(); + + m_bSlidingSkins = true; + m_bAnimatingMove = true; + + m_characters[eCharacter_Current].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Right, true); + m_characters[eCharacter_Next1].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Forward, true); + + // 4J Stu - Swapped nav buttons + sendInputToMovie(ACTION_MENU_LEFT, repeat, pressed, released); + handled = true; } } break; @@ -338,23 +346,15 @@ void UIScene_SkinSelectMenu::handleInput(int iPad, int key, bool repeat, bool pr if(pressed) { ui.PlayUISFX(eSFX_Press); - if( m_currentNavigation == eSkinNavigation_Skin ) - { - m_characters[eCharacter_Current].ResetRotation(); - } + m_characters[eCharacter_Current].ResetRotation(); + handled = true; } break; case ACTION_MENU_OTHER_STICK_LEFT: if(pressed) { - if( m_currentNavigation == eSkinNavigation_Skin ) - { - m_characters[eCharacter_Current].m_incYRot = true; - } - else - { - ui.PlayUISFX(eSFX_Scroll); - } + m_characters[eCharacter_Current].m_incYRot = true; + handled = true; } else if(released) { @@ -364,14 +364,8 @@ void UIScene_SkinSelectMenu::handleInput(int iPad, int key, bool repeat, bool pr case ACTION_MENU_OTHER_STICK_RIGHT: if(pressed) { - if( m_currentNavigation == eSkinNavigation_Skin ) - { - m_characters[eCharacter_Current].m_decYRot = true; - } - else - { - ui.PlayUISFX(eSFX_Scroll); - } + m_characters[eCharacter_Current].m_decYRot = true; + handled = true; } else if(released) { @@ -381,29 +375,17 @@ void UIScene_SkinSelectMenu::handleInput(int iPad, int key, bool repeat, bool pr case ACTION_MENU_OTHER_STICK_UP: if(pressed) { - if( m_currentNavigation == eSkinNavigation_Skin ) - { //m_previewControl->m_incXRot = true; - m_characters[eCharacter_Current].CyclePreviousAnimation(); - } - else - { - ui.PlayUISFX(eSFX_Scroll); - } + m_characters[eCharacter_Current].CyclePreviousAnimation(); + handled = true; } break; case ACTION_MENU_OTHER_STICK_DOWN: if(pressed) { - if( m_currentNavigation == eSkinNavigation_Skin ) - { //m_previewControl->m_decXRot = true; - m_characters[eCharacter_Current].CycleNextAnimation(); - } - else - { - ui.PlayUISFX(eSFX_Scroll); - } + m_characters[eCharacter_Current].CycleNextAnimation(); + handled = true; } break; } @@ -430,7 +412,7 @@ void UIScene_SkinSelectMenu::InputActionOK(unsigned int iPad) { // get the pack number from the skin id wchar_t chars[256]; - swprintf(chars, 256, L"dlcskin%08d.png", app.GetPlayerFavoriteSkin(iPad,m_skinIndex)); + swprintf(chars, 256, L"dlcskin%08d.png", GET_DLC_SKIN_ID_FROM_BITMASK(app.GetPlayerFavoriteSkin(iPad,m_skinIndex))); DLCPack *Pack=app.m_dlcManager.getPackContainingSkin(chars); @@ -581,7 +563,7 @@ void UIScene_SkinSelectMenu::InputActionOK(unsigned int iPad) m_originalSkinId = app.GetPlayerSkinId(iPad); // push this onto the favorite list - AddFavoriteSkin(m_iPad,GET_DLC_SKIN_ID_FROM_BITMASK(m_originalSkinId)); + //AddFavoriteSkin(m_iPad,GET_DLC_SKIN_ID_FROM_BITMASK(m_originalSkinId)); } } else @@ -611,7 +593,7 @@ void UIScene_SkinSelectMenu::customDraw(IggyCustomDrawCallbackRegion *region) { int characterId = -1; swscanf(static_cast(region->name),L"Character%d",&characterId); - if (characterId == -1) + if (characterId == -1 || characterId >= eCharacter_COUNT) { app.DebugPrintf("Invalid character to render found\n"); } @@ -619,6 +601,15 @@ void UIScene_SkinSelectMenu::customDraw(IggyCustomDrawCallbackRegion *region) { // Setup GDraw, normal game render states and matrices CustomDrawData *customDrawRegion = ui.setupCustomDraw(this,region); + + // don't draw hidden characters + if(!m_characters[characterId].isVisible()) + { + ui.endCustomDraw(region); + delete customDrawRegion; + return; + } + delete customDrawRegion; //app.DebugPrintf("Scissor x0= %d, y0= %d, x1= %d, y1= %d\n", region->scissor_x0, region->scissor_y0, region->scissor_x1, region->scissor_y1); @@ -654,8 +645,9 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() TEXTURE_NAME backupTexture = TN_MOB_CHAR; setCharacterSelected(false); + setCharacterBlocked(false); - m_controlSkinNamePlate.setVisible( false ); + //m_controlSkinNamePlate.setVisible( false ); if( m_currentPack != nullptr ) { @@ -679,7 +671,7 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() setCharacterLocked(!(bSkinIsFree || bLicensed)); m_characters[eCharacter_Current].setVisible(true); - m_controlSkinNamePlate.setVisible( true ); + //m_controlSkinNamePlate.setVisible( true ); } else { @@ -697,58 +689,85 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() { skinName = app.GetString(IDS_DEFAULT_SKINS); } - else - { - skinName = wchDefaultNamesA[m_skinIndex]; - } - - if( m_originalSkinId == m_skinIndex ) - { + else if (m_skinIndex < eDefaultSkins_Count) + { + skinName = wchDefaultNamesA[m_skinIndex]; + } + else + { + skinName = L""; setCharacterSelected(true); } setCharacterLocked(false); setCharacterLocked(false); m_characters[eCharacter_Current].setVisible(true); - m_controlSkinNamePlate.setVisible( true ); + //m_controlSkinNamePlate.setVisible( true ); break; case SKIN_SELECT_PACK_FAVORITES: if(app.GetPlayerFavoriteSkinsCount(m_iPad)>0) - { - // get the pack number from the skin id - wchar_t chars[256]; - swprintf(chars, 256, L"dlcskin%08d.png", app.GetPlayerFavoriteSkin(m_iPad,m_skinIndex)); + { + unsigned int favSkinId = app.GetPlayerFavoriteSkin(m_iPad,m_skinIndex); + if(GET_IS_DLC_SKIN_FROM_BITMASK(favSkinId)) + { + wchar_t chars[256]; + swprintf(chars, 256, L"dlcskin%08d.png", GET_DLC_SKIN_ID_FROM_BITMASK(favSkinId)); - Pack=app.m_dlcManager.getPackContainingSkin(chars); - if(Pack) - { - skinFile = Pack->getSkinFile(chars); + Pack=app.m_dlcManager.getPackContainingSkin(chars); + if(Pack) + { + skinFile = Pack->getSkinFile(chars); - m_selectedSkinPath = skinFile->getPath(); - m_selectedCapePath = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); - m_vAdditionalSkinBoxes = skinFile->getAdditionalBoxes(); - m_vSkinOffsets = skinFile->getOffsets(); + m_selectedSkinPath = skinFile->getPath(); + m_selectedCapePath = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); + m_vAdditionalSkinBoxes = skinFile->getAdditionalBoxes(); + m_vSkinOffsets = skinFile->getOffsets(); - skinName = skinFile->getParameterAsString( DLCManager::e_DLCParamType_DisplayName ); - skinOrigin = skinFile->getParameterAsString( DLCManager::e_DLCParamType_ThemeName ); + skinName = skinFile->getParameterAsString( DLCManager::e_DLCParamType_DisplayName ); + skinOrigin = skinFile->getParameterAsString( DLCManager::e_DLCParamType_ThemeName ); - if( m_selectedSkinPath.compare( m_currentSkinPath ) == 0 ) - { - setCharacterSelected(true); - } + if( m_selectedSkinPath.compare( m_currentSkinPath ) == 0 ) + { + setCharacterSelected(true); + } - bSkinIsFree = skinFile->getParameterAsBool( DLCManager::e_DLCParamType_Free ); - bLicensed = Pack->hasPurchasedFile( DLCManager::e_DLCType_Skin, m_selectedSkinPath ); + bSkinIsFree = skinFile->getParameterAsBool( DLCManager::e_DLCParamType_Free ); + bLicensed = Pack->hasPurchasedFile( DLCManager::e_DLCType_Skin, m_selectedSkinPath ); - setCharacterLocked(!(bSkinIsFree || bLicensed)); - m_controlSkinNamePlate.setVisible( true ); + setCharacterLocked(!(bSkinIsFree || bLicensed)); + //m_controlSkinNamePlate.setVisible( true ); + } + else + { + setCharacterSelected(false); + setCharacterBlocked(false); + setCharacterLocked(false); + } } else { - setCharacterSelected(false); + // this fix a thingy with the default skin packs + DWORD defaultSkinIndex = favSkinId; + backupTexture = getTextureId(defaultSkinIndex); + + if( defaultSkinIndex == eDefaultSkins_ServerSelected ) + { + skinName = app.GetString(IDS_DEFAULT_SKINS); + } + else if (defaultSkinIndex < eDefaultSkins_Count) + { + skinName = wchDefaultNamesA[defaultSkinIndex]; + } + else + { + skinName = L""; + setCharacterSelected(true); + } setCharacterLocked(false); + + m_characters[eCharacter_Current].setVisible(true); } } else @@ -794,6 +813,7 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() app.SetAnimOverrideBitmask(skinFile->getSkinID(),skinFile->getAnimOverrideBitmask()); } + // printf("[SkinSelectMenu] Setting current character skin: path='%ls' pack=%d skinIndex=%d\n", m_selectedSkinPath.c_str(), m_packIndex, m_skinIndex); m_characters[eCharacter_Current].SetTexture(m_selectedSkinPath, backupTexture); m_characters[eCharacter_Current].SetCapeTexture(m_selectedCapePath); @@ -876,20 +896,32 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() break; case SKIN_SELECT_PACK_FAVORITES: if(uiCurrentFavoriteC>0) - { - // get the pack number from the skin id - swprintf(chars, 256, L"dlcskin%08d.png", app.GetPlayerFavoriteSkin(m_iPad,nextIndex)); + { + unsigned int favSkinIdNext = app.GetPlayerFavoriteSkin(m_iPad,nextIndex); + if(GET_IS_DLC_SKIN_FROM_BITMASK(favSkinIdNext)) + { + // get the pack number from the skin id + swprintf(chars, 256, L"dlcskin%08d.png", GET_DLC_SKIN_ID_FROM_BITMASK(favSkinIdNext)); - Pack=app.m_dlcManager.getPackContainingSkin(chars); - if(Pack) - { - skinFile = Pack->getSkinFile(chars); + Pack=app.m_dlcManager.getPackContainingSkin(chars); + if(Pack) + { + skinFile = Pack->getSkinFile(chars); - otherSkinPath = skinFile->getPath(); - otherCapePath = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); - othervAdditionalSkinBoxes = skinFile->getAdditionalBoxes(); - othervSkinOffsets = skinFile->getOffsets(); + otherSkinPath = skinFile->getPath(); + otherCapePath = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); + othervAdditionalSkinBoxes = skinFile->getAdditionalBoxes(); + othervSkinOffsets = skinFile->getOffsets(); backupTexture = TN_MOB_CHAR; + } + } + else + { + // default skin favorite + backupTexture = getTextureId(favSkinIdNext); + otherSkinPath = L""; + otherCapePath = L""; + othervAdditionalSkinBoxes = nullptr; } } break; @@ -926,15 +958,16 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() nextIndex = getNextSkinIndex(nextIndex); } - + static const ECharacters s_previousSlots[2] = { eCharacter_Previous1, eCharacter_Previous2 }; for(BYTE i = 0; i < sidePreviewControlsL; ++i) { if(showPrevious) { - skinFile=nullptr; - - m_characters[eCharacter_Previous1 + i].setVisible(true); + skinFile = nullptr; + ECharacters slot = s_previousSlots[i]; + + m_characters[slot].setVisible(true); if( m_currentPack != nullptr ) { @@ -958,20 +991,32 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() break; case SKIN_SELECT_PACK_FAVORITES: if(uiCurrentFavoriteC>0) - { - // get the pack number from the skin id - swprintf(chars, 256, L"dlcskin%08d.png", app.GetPlayerFavoriteSkin(m_iPad,previousIndex)); - - Pack=app.m_dlcManager.getPackContainingSkin(chars); - if(Pack) + { + unsigned int favSkinIdPrev = app.GetPlayerFavoriteSkin(m_iPad,previousIndex); + if(GET_IS_DLC_SKIN_FROM_BITMASK(favSkinIdPrev)) { - skinFile = Pack->getSkinFile(chars); + // get the pack number from the skin id + swprintf(chars, 256, L"dlcskin%08d.png", GET_DLC_SKIN_ID_FROM_BITMASK(favSkinIdPrev)); - otherSkinPath = skinFile->getPath(); - otherCapePath = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); - othervAdditionalSkinBoxes = skinFile->getAdditionalBoxes(); - othervSkinOffsets = skinFile->getOffsets(); + Pack=app.m_dlcManager.getPackContainingSkin(chars); + if(Pack) + { + skinFile = Pack->getSkinFile(chars); + + otherSkinPath = skinFile->getPath(); + otherCapePath = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); + othervAdditionalSkinBoxes = skinFile->getAdditionalBoxes(); + othervSkinOffsets = skinFile->getOffsets(); backupTexture = TN_MOB_CHAR; + } + } + else + { + // default skin favorite + backupTexture = getTextureId(favSkinIdPrev); + otherSkinPath = L""; + otherCapePath = L""; + othervAdditionalSkinBoxes = nullptr; } } @@ -1001,13 +1046,50 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged() { app.SetAnimOverrideBitmask(skinFile->getSkinID(),skinFile->getAnimOverrideBitmask()); } - m_characters[eCharacter_Previous1 + i].SetTexture(otherSkinPath, backupTexture); - m_characters[eCharacter_Previous1 + i].SetCapeTexture(otherCapePath); + m_characters[slot].SetTexture(otherSkinPath, backupTexture); + m_characters[slot].SetCapeTexture(otherCapePath); } previousIndex = getPreviousSkinIndex(previousIndex); } + setCharacterFavourite(false); + int favCount = app.GetPlayerFavoriteSkinsCount(m_iPad); + if(favCount > 0) + { + for(int i = 0; i < favCount; i++) + { + unsigned int favSkinId = app.GetPlayerFavoriteSkin(m_iPad, i); + bool bFound = false; + + if(m_currentPack != nullptr) + { + DLCSkinFile *favSkinFile = m_currentPack->getSkinFile(m_skinIndex); + if(favSkinFile != nullptr && favSkinId == favSkinFile->getSkinID()) + { + bFound = true; + } + } + else if(m_packIndex == SKIN_SELECT_PACK_DEFAULT) + { + if(favSkinId == (unsigned int)m_skinIndex) + { + bFound = true; + } + } + else if(m_packIndex == SKIN_SELECT_PACK_FAVORITES) + { + bFound = true; + } + + if(bFound) + { + setCharacterFavourite(true); + break; + } + } + } + updateTooltips(); } @@ -1151,6 +1233,12 @@ int UIScene_SkinSelectMenu::getPreviousSkinIndex(DWORD sourceIndex) void UIScene_SkinSelectMenu::handlePackIndexChanged() { + // sync m_packIndex from flash MultiList selection + if(!m_bIgnoreInput && m_controlSkinButtonList.getItemCount() > 0) + { + m_packIndex = m_controlSkinButtonList.getCurrentSelection(); + } + if(m_packIndex >= SKIN_SELECT_MAX_DEFAULTS) { m_currentPack = app.m_dlcManager.getPack(m_packIndex - SKIN_SELECT_MAX_DEFAULTS, DLCManager::e_DLCType_Skin); @@ -1182,18 +1270,16 @@ void UIScene_SkinSelectMenu::handlePackIndexChanged() } break; case SKIN_SELECT_PACK_FAVORITES: - if(app.GetPlayerFavoriteSkinsCount(m_iPad)>0) { - bool found; - wchar_t chars[256]; - // get the pack number from the skin id - swprintf(chars, 256, L"dlcskin%08d.png", app.GetPlayerFavoriteSkin(m_iPad,app.GetPlayerFavoriteSkinsPos(m_iPad))); - - DLCPack *Pack=app.m_dlcManager.getPackContainingSkin(chars); - if(Pack) + unsigned int favCount = app.GetPlayerFavoriteSkinsCount(m_iPad); + if(favCount > 0) { - DWORD currentSkinIndex = Pack->getSkinIndexAt(m_currentSkinPath, found); - if(found) m_skinIndex = app.GetPlayerFavoriteSkinsPos(m_iPad); + unsigned int pos = app.GetPlayerFavoriteSkinsPos(m_iPad); + if(pos >= favCount) + { + pos = 0; // stale/invalid position — fall back to the first favorite + } + m_skinIndex = pos; } } break; @@ -1201,70 +1287,97 @@ void UIScene_SkinSelectMenu::handlePackIndexChanged() break; } } + // register pack image or whatever texture and set it on the BitmapIcon + // control type is used to determine which default image to use if the pack image is not available + int controlType = app.GetGameSettings(m_iPad, eGameSetting_ControlType); + wstring controlTypeTextureName = L"default"; + + switch(controlType) + { + case 2: // Xbox 360 + controlTypeTextureName = L"xbox360"; + break; + case 3: // PS3 + controlTypeTextureName = L"playStation"; + break; + case 4: // PS4 + controlTypeTextureName = L"playStation"; + break; + case 5: // WiiU + controlTypeTextureName = L"wiiU"; + break; + default: + controlTypeTextureName = L"default"; + break; + } + + wstring textureName = L""; + if(m_currentPack != nullptr) + { + DWORD packId = m_currentPack->GetPackId(); + // printf("Pack name: %ls, packId: %d\n", m_currentPack->getName().c_str(), packId); + if(packId >= 1) + { + wchar_t packIdStr[16]; + swprintf(packIdStr, 16, L"%i", packId); + textureName = packIdStr; + } + } + if(textureName.empty() || !registerTexture(textureName)) + { + textureName = controlTypeTextureName; + registerTexture(textureName); + } + m_controlTexturePackIcon.setTextureName(textureName); + handleSkinIndexChanged(); - updatePackDisplay(); + SetSkinPackButtonList(); + setPackLabel(); } void UIScene_SkinSelectMenu::updatePackDisplay() { m_currentPackCount = app.m_dlcManager.getPackCount(DLCManager::e_DLCType_Skin) + SKIN_SELECT_MAX_DEFAULTS; - if(m_packIndex >= SKIN_SELECT_MAX_DEFAULTS) +} + +void UIScene_SkinSelectMenu::handlePress(F64 controlId, F64 childId) +{ +} + +void UIScene_SkinSelectMenu::handleFocusChange(F64 controlId, F64 childId) +{ + if((int)controlId == 0) { - DLCPack *thisPack = app.m_dlcManager.getPack(m_packIndex - SKIN_SELECT_MAX_DEFAULTS, DLCManager::e_DLCType_Skin); - setCentreLabel(thisPack->getName().c_str()); + m_controlSkinButtonList.updateChildFocus((int)childId); + m_bFocusDirty = true; } - else +} + +int UIScene_SkinSelectMenu::relativePackIndex(DWORD base, int offset) +{ + if(offset == 0) { - switch(m_packIndex) + if(m_bHasTexturePack && base == 2) { - case SKIN_SELECT_PACK_DEFAULT: - setCentreLabel(app.GetString(IDS_NO_SKIN_PACK)); - break; - case SKIN_SELECT_PACK_FAVORITES: - setCentreLabel(app.GetString(IDS_FAVORITES_SKIN_PACK)); - break; + return m_iTexturePackIndex; } + return base; } - int nextPackIndex = getNextPackIndex(m_packIndex); - if(nextPackIndex >= SKIN_SELECT_MAX_DEFAULTS) + int packCount = app.m_dlcManager.getPackCount(DLCManager::e_DLCType_Skin); + int newIndex = base + offset; + + if(packCount + SKIN_SELECT_MAX_DEFAULTS < newIndex) { - DLCPack *thisPack = app.m_dlcManager.getPack(nextPackIndex - SKIN_SELECT_MAX_DEFAULTS, DLCManager::e_DLCType_Skin); - setRightLabel(thisPack->getName().c_str()); + newIndex = SKIN_SELECT_PACK_DEFAULT; } - else + else if(newIndex < 0) { - switch(nextPackIndex) - { - case SKIN_SELECT_PACK_DEFAULT: - setRightLabel(app.GetString(IDS_NO_SKIN_PACK)); - break; - case SKIN_SELECT_PACK_FAVORITES: - setRightLabel(app.GetString(IDS_FAVORITES_SKIN_PACK)); - break; - } - } - - int previousPackIndex = getPreviousPackIndex(m_packIndex); - if(previousPackIndex >= SKIN_SELECT_MAX_DEFAULTS) - { - DLCPack *thisPack = app.m_dlcManager.getPack(previousPackIndex - SKIN_SELECT_MAX_DEFAULTS, DLCManager::e_DLCType_Skin); - setLeftLabel(thisPack->getName().c_str()); - } - else - { - switch(previousPackIndex) - { - case SKIN_SELECT_PACK_DEFAULT: - setLeftLabel(app.GetString(IDS_NO_SKIN_PACK)); - break; - case SKIN_SELECT_PACK_FAVORITES: - setLeftLabel(app.GetString(IDS_FAVORITES_SKIN_PACK)); - break; - } + newIndex = packCount + SKIN_SELECT_MAX_DEFAULTS; } + return newIndex; } int UIScene_SkinSelectMenu::getNextPackIndex(DWORD sourceIndex) @@ -1303,6 +1416,223 @@ int UIScene_SkinSelectMenu::getPreviousPackIndex(DWORD sourceIndex) return previousPack; } +void UIScene_SkinSelectMenu::SetSkinPackButtonList() +{ + if(!m_bNeedButtonListRefresh) + return; + + m_bNeedButtonListRefresh = false; + + TexturePack *selectedTP = Minecraft::GetInstance()->skins->getSelected(); + DLCPack *texturePackDLC = nullptr; + if(selectedTP != nullptr && !Minecraft::GetInstance()->skins->isUsingDefaultSkin()) + { + texturePackDLC = selectedTP->getDLCPack(); + } + + m_controlSkinButtonList.clearList(); + + m_controlSkinButtonList.AddNewButton(app.GetString(IDS_NO_SKIN_PACK), SKIN_SELECT_PACK_DEFAULT); + + m_controlSkinButtonList.AddNewButton(app.GetString(IDS_FAVORITES_SKIN_PACK), SKIN_SELECT_PACK_FAVORITES); + + m_bHasTexturePack = false; + if(texturePackDLC != nullptr) + { + DWORD tpPackId = texturePackDLC->GetPackId(); + if(tpPackId > 0x3FF) + { + wstring tpName = texturePackDLC->getName(); + if(texturePackDLC->getSkinCount() > 0) + { + m_controlSkinButtonList.AddNewButton(tpName, SKIN_SELECT_MAX_DEFAULTS); + m_bHasTexturePack = true; + } + } + } + // dlc pack buttons + int packCount = app.m_dlcManager.getPackCount(DLCManager::e_DLCType_Skin); + int highlightIdx = m_packIndex; + + for(int i = 0; i < packCount; i++) + { + DLCPack *pack = app.m_dlcManager.getPack(i, DLCManager::e_DLCType_Skin); + if(pack != nullptr) + { + // skip the pack that matches the active texture pack + if(m_bHasTexturePack && texturePackDLC != nullptr) + { + if(pack->GetPackId() == texturePackDLC->GetPackId()) + { + m_iTexturePackIndex = i + SKIN_SELECT_MAX_DEFAULTS; + continue; + } + } + + wstring displayName = pack->getName(); + m_controlSkinButtonList.AddNewButton(displayName, i + SKIN_SELECT_MAX_DEFAULTS); + + if(m_currentPack != nullptr && pack->GetPackId() == m_currentPack->GetPackId()) + { + highlightIdx = i + SKIN_SELECT_MAX_DEFAULTS; + } + } + } + + m_controlSkinButtonList.HighlightItem(highlightIdx, true); +} + +void UIScene_SkinSelectMenu::setPackLabel() +{ + int relIdx = relativePackIndex(m_packIndex, 0); + + if(relIdx == 0) + { + m_labelPackName.setLabel(app.GetString(IDS_NO_SKIN_PACK)); + } + else if(relIdx == 1) + { + m_labelPackName.setLabel(app.GetString(IDS_FAVORITES_SKIN_PACK)); + } + else if(relIdx >= SKIN_SELECT_MAX_DEFAULTS) + { + DLCPack *pack = app.m_dlcManager.getPack(relIdx - SKIN_SELECT_MAX_DEFAULTS, DLCManager::e_DLCType_Skin); + if(pack != nullptr) + { + m_labelPackName.setLabel(pack->getName()); + } + else + { + m_labelPackName.setLabel(L""); + } + } + else + { + m_labelPackName.setLabel(L""); + } + + DWORD packId = 0; + if(m_currentPack != nullptr) + { + packId = m_currentPack->GetPackId(); + } + + if(packId >= 0x400) + { + m_labelPackType.setLabel(app.GetString(IDS_TEXTURE_PACK)); + } + else + { + m_labelPackType.setLabel(app.GetString(IDS_SKIN_PACK)); + } +} + +bool UIScene_SkinSelectMenu::registerTexture(const wstring &texturePath) +{ + wchar_t texPath[64]; + swprintf(texPath, 64, L"Graphics\\PackGraphics\\%ls.png", texturePath.c_str()); + + if(app.hasArchiveFile(texPath)) + { + byteArray fileData = app.getArchiveFile(texPath); + if(fileData.data != nullptr && fileData.length > 0) + { + registerSubstitutionTexture(texturePath, fileData.data, fileData.length); + return true; + } + } + return false; +} + +void UIScene_SkinSelectMenu::setActivePackIndex() +{ + int favCount = app.GetPlayerFavoriteSkinsCount(m_iPad); + if(favCount == 0) + { + return; + } + + if(app.m_dlcManager.getPackCount(DLCManager::e_DLCType_Skin) == 0) + { + return; + } + + m_currentPack = app.m_dlcManager.getPackContainingSkin(m_currentSkinPath); + + // check if current skin is in the favorites list + for(int i = 0; i < favCount; i++) + { + unsigned int favSkinId = app.GetPlayerFavoriteSkin(m_iPad, i); + if(favSkinId == m_originalSkinId) + { + m_packIndex = SKIN_SELECT_PACK_FAVORITES; + return; + } + } +} + +void UIScene_SkinSelectMenu::InputActionFavorite(unsigned int iPad) +{ + if(m_packIndex == SKIN_SELECT_PACK_DEFAULT) + { + SetFavoriteSkin(iPad, m_skinIndex); + handleSkinIndexChanged(); + } + else if(m_packIndex == SKIN_SELECT_PACK_FAVORITES) + { + int favCount = app.GetPlayerFavoriteSkinsCount(iPad); + if(favCount == 0) return; + + unsigned int skinId = app.GetPlayerFavoriteSkin(iPad, m_skinIndex); + + SetFavoriteSkin(iPad, skinId); + + int newCount = app.GetPlayerFavoriteSkinsCount(iPad); + if(newCount > 0 && newCount <= m_skinIndex) + m_skinIndex = newCount - 1; + + handleSkinIndexChanged(); + } + else if(m_currentPack != nullptr) + { + DLCSkinFile *skinFile = m_currentPack->getSkinFile(m_skinIndex); + if(skinFile == nullptr) return; + + SetFavoriteSkin(iPad, skinFile->getSkinID()); + m_bSkinIndexChanged = true; + return; + } + + unsigned int pos = app.GetPlayerFavoriteSkinsPos(iPad); + app.SetPlayerFavoriteSkinsPos(iPad, pos); +} + +void UIScene_SkinSelectMenu::SetFavoriteSkin(unsigned int pad, int skinId) +{ + int favCount = app.GetPlayerFavoriteSkinsCount(pad); + + for(int i = 0; i < favCount; i++) + { + if(app.GetPlayerFavoriteSkin(pad, i) == (unsigned int)skinId) + { + for(int j = i; j < favCount - 1; j++) + { + app.SetPlayerFavoriteSkin(pad, j, app.GetPlayerFavoriteSkin(pad, j + 1)); + } + app.SetPlayerFavoriteSkin(pad, favCount - 1, 0xFFFFFFFF); + setCharacterFavourite(false); + return; + } + } + + if(favCount < MAX_FAVORITE_SKINS) + { + app.SetPlayerFavoriteSkin(pad, favCount, skinId); + app.SetPlayerFavoriteSkinsPos(pad, favCount); + setCharacterFavourite(true); + } +} + void UIScene_SkinSelectMenu::setCharacterSelected(bool selected) { IggyDataValue result; @@ -1321,61 +1651,22 @@ void UIScene_SkinSelectMenu::setCharacterLocked(bool locked) IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetCharacterLocked , 1 , value ); } -void UIScene_SkinSelectMenu::setLeftLabel(const wstring &label) +void UIScene_SkinSelectMenu::setCharacterFavourite(bool favourite) { - if(label.compare(m_leftLabel) != 0) - { - m_leftLabel = label; - - IggyDataValue result; - IggyDataValue value[1]; - - IggyStringUTF16 stringVal; - stringVal.string = (IggyUTF16*)label.c_str(); - stringVal.length = label.length(); - - value[0].type = IGGY_DATATYPE_string_UTF16; - value[0].string16 = stringVal; - IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetLeftLabel , 1 , value ); - } + IggyDataValue result; + IggyDataValue value[1]; + value[0].type = IGGY_DATATYPE_boolean; + value[0].boolval = favourite; + IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetCharacterFavourite , 1 , value ); } -void UIScene_SkinSelectMenu::setCentreLabel(const wstring &label) +void UIScene_SkinSelectMenu::setCharacterBlocked(bool blocked) { - if(label.compare(m_centreLabel) != 0) - { - m_centreLabel = label; - - IggyDataValue result; - IggyDataValue value[1]; - - IggyStringUTF16 stringVal; - stringVal.string = (IggyUTF16*)label.c_str(); - stringVal.length = label.length(); - - value[0].type = IGGY_DATATYPE_string_UTF16; - value[0].string16 = stringVal; - IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetCentreLabel , 1 , value ); - } -} - -void UIScene_SkinSelectMenu::setRightLabel(const wstring &label) -{ - if(label.compare(m_rightLabel) != 0) - { - m_rightLabel = label; - - IggyDataValue result; - IggyDataValue value[1]; - - IggyStringUTF16 stringVal; - stringVal.string = (IggyUTF16*)label.c_str(); - stringVal.length = label.length(); - - value[0].type = IGGY_DATATYPE_string_UTF16; - value[0].string16 = stringVal; - IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetRightLabel , 1 , value ); - } + IggyDataValue result; + IggyDataValue value[1]; + value[0].type = IGGY_DATATYPE_boolean; + value[0].boolval = blocked; + IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetCharacterBlocked , 1 , value ); } #ifdef __PSVITA__ @@ -1536,7 +1827,7 @@ void UIScene_SkinSelectMenu::HandleDLCInstalled() m_bIgnoreInput=true; m_controlTimer.setVisible( true ); m_controlIggyCharacters.setVisible( false ); - m_controlSkinNamePlate.setVisible( false ); + //m_controlSkinNamePlate.setVisible( false ); } // this will send a CustomMessage_DLCMountingComplete when done @@ -1556,7 +1847,7 @@ void UIScene_SkinSelectMenu::HandleDLCMountingComplete() app.DebugPrintf(4,"UIScene_SkinSelectMenu::HandleDLCMountingComplete\n"); m_controlTimer.setVisible( false ); m_controlIggyCharacters.setVisible( true ); - m_controlSkinNamePlate.setVisible( true ); + //m_controlSkinNamePlate.setVisible( true ); m_packIndex = SKIN_SELECT_PACK_DEFAULT; @@ -1711,37 +2002,32 @@ int UIScene_SkinSelectMenu::RenableInput(LPVOID lpVoid, int, int) void UIScene_SkinSelectMenu::AddFavoriteSkin(int iPad,int iSkinID) { - // Is this favorite skin already in the array? - unsigned int uiCurrentFavoriteSkinsCount=app.GetPlayerFavoriteSkinsCount(iPad); + unsigned int favCount = app.GetPlayerFavoriteSkinsCount(iPad); - for(int i=0;i0) - { - ucPos++; - } - else - { - ucPos=0; - } + // replace the next skin in the list + unsigned char ucPos = app.GetPlayerFavoriteSkinsPos(iPad); + ucPos = (ucPos + 1) % MAX_FAVORITE_SKINS; + app.SetPlayerFavoriteSkin(iPad, ucPos, iSkinID); + app.SetPlayerFavoriteSkinsPos(iPad, ucPos); } - - app.SetPlayerFavoriteSkin(iPad,(int)ucPos,iSkinID); - app.SetPlayerFavoriteSkinsPos(m_iPad,ucPos); } @@ -1750,16 +2036,12 @@ void UIScene_SkinSelectMenu::handleReload() // Reinitialise a few values to prevent problems on reload m_bIgnoreInput=false; - m_currentNavigation = eSkinNavigation_Skin; + //m_currentNavigation = eSkinNavigation_Skin; m_currentPackCount = 0; m_labelSkinName.init(L""); m_labelSkinOrigin.init(L""); - m_leftLabel = L""; - m_centreLabel = L""; - m_rightLabel = L""; - handlePackIndexChanged(); } diff --git a/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.h b/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.h index bef2d4fc..79f33e6c 100644 --- a/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.h +++ b/Minecraft.Client/Common/UI/UIScene_SkinSelectMenu.h @@ -2,6 +2,8 @@ #include "../../../Minecraft.World/Definitions.h" #include "UIScene.h" #include "UIControl_PlayerSkinPreview.h" +#include "UIControl_MultiList.h" +#include "UIControl_BitmapIcon.h" class UIScene_SkinSelectMenu : public UIScene { @@ -9,7 +11,7 @@ private: static const WCHAR *wchDefaultNamesA[eDefaultSkins_Count]; // 4J Stu - How many to show on each side of the main control - static const BYTE sidePreviewControls = 4; + static const BYTE sidePreviewControls = 2; #ifdef __PSVITA__ enum ETouchInput @@ -33,45 +35,37 @@ private: enum ECharacters { - eCharacter_Current, - eCharacter_Next1, - eCharacter_Next2, - eCharacter_Next3, - eCharacter_Next4, - eCharacter_Previous1, - eCharacter_Previous2, - eCharacter_Previous3, - eCharacter_Previous4, + eCharacter_Current = 0, + eCharacter_Next1 = 1, + eCharacter_Next2 = 2, + eCharacter_Previous1 = 4, + eCharacter_Previous2 = 5, - eCharacter_COUNT, + eCharacter_COUNT = 7, }; UIControl_PlayerSkinPreview m_characters[eCharacter_COUNT]; UIControl_Label m_labelSkinName, m_labelSkinOrigin; - UIControl_Label m_labelSelected; - UIControl m_controlSkinNamePlate, m_controlSelectedPanel, m_controlIggyCharacters, m_controlTimer; -#ifdef __PSVITA__ - UIControl_Touch m_TouchTabLeft, m_TouchTabRight, m_TouchTabCenter, m_TouchIggyCharacters; -#endif + UIControl m_controlBlocked, m_controlFavourite, m_controlLocked, m_controlSelected; + UIControl_Label m_labelPackName, m_labelPackType; + UIControl_MultiList m_controlSkinButtonList; + UIControl_BitmapIcon m_controlTexturePackIcon; + UIControl m_controlIggyCharacters, m_controlTimer; IggyName m_funcSetPlayerCharacterSelected, m_funcSetCharacterLocked; - IggyName m_funcSetLeftLabel, m_funcSetRightLabel, m_funcSetCentreLabel; + IggyName m_funcSetCharacterFavourite, m_funcSetCharacterBlocked; UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) -#ifdef __PSVITA__ - UI_MAP_ELEMENT( m_TouchTabLeft, "TouchTabLeft" ) - UI_MAP_ELEMENT( m_TouchTabRight, "TouchTabRight" ) - UI_MAP_ELEMENT( m_TouchTabCenter, "TouchTabCenter" ) - UI_MAP_ELEMENT( m_TouchIggyCharacters, "TouchIggyCharacters" ) -#endif - UI_MAP_ELEMENT( m_controlSkinNamePlate, "SkinNamePlate") - UI_BEGIN_MAP_CHILD_ELEMENTS( m_controlSkinNamePlate ) - UI_MAP_ELEMENT( m_labelSkinName, "SkinTitle1") - UI_MAP_ELEMENT( m_labelSkinOrigin, "SkinTitle2") - UI_END_MAP_CHILD_ELEMENTS() - - UI_MAP_ELEMENT( m_controlSelectedPanel, "SelectedPanel" ) - UI_BEGIN_MAP_CHILD_ELEMENTS( m_controlSelectedPanel ) - UI_MAP_ELEMENT( m_labelSelected, "SelectedPanelLabel" ) - UI_END_MAP_CHILD_ELEMENTS() + UI_MAP_ELEMENT( m_controlBlocked, "Blocked" ) + UI_MAP_ELEMENT( m_controlFavourite, "Favourite" ) + UI_MAP_ELEMENT( m_controlLocked, "Locked" ) + UI_MAP_ELEMENT( m_controlSelected, "Selected" ) + + UI_MAP_ELEMENT( m_labelSkinName, "SkinTitle1" ) + UI_MAP_ELEMENT( m_labelSkinOrigin, "SkinTitle2" ) + UI_MAP_ELEMENT( m_labelPackName, "Pack_Name" ) + UI_MAP_ELEMENT( m_labelPackType, "Pack_Type" ) + + UI_MAP_ELEMENT( m_controlTexturePackIcon, "TexturePackIcon" ) + UI_MAP_ELEMENT( m_controlSkinButtonList, "SkinButtonList" ) UI_MAP_ELEMENT( m_controlTimer, "Timer" ) @@ -79,24 +73,16 @@ private: UI_MAP_ELEMENT( m_controlIggyCharacters, "IggyCharacters" ) UI_BEGIN_MAP_CHILD_ELEMENTS( m_controlIggyCharacters ) UI_MAP_ELEMENT( m_characters[eCharacter_Current], "iggy_Character0" ) - UI_MAP_ELEMENT( m_characters[eCharacter_Next1], "iggy_Character1" ) UI_MAP_ELEMENT( m_characters[eCharacter_Next2], "iggy_Character2" ) - UI_MAP_ELEMENT( m_characters[eCharacter_Next3], "iggy_Character3" ) - UI_MAP_ELEMENT( m_characters[eCharacter_Next4], "iggy_Character4" ) - - UI_MAP_ELEMENT( m_characters[eCharacter_Previous1], "iggy_Character5" ) - UI_MAP_ELEMENT( m_characters[eCharacter_Previous2], "iggy_Character6" ) - UI_MAP_ELEMENT( m_characters[eCharacter_Previous3], "iggy_Character7" ) - UI_MAP_ELEMENT( m_characters[eCharacter_Previous4], "iggy_Character8" ) + UI_MAP_ELEMENT( m_characters[eCharacter_Previous1], "iggy_Character6" ) + UI_MAP_ELEMENT( m_characters[eCharacter_Previous2], "iggy_Character5" ) UI_END_MAP_CHILD_ELEMENTS() UI_MAP_NAME( m_funcSetPlayerCharacterSelected, L"SetPlayerCharacterSelected" ) UI_MAP_NAME( m_funcSetCharacterLocked, L"SetCharacterLocked" ) - - UI_MAP_NAME( m_funcSetLeftLabel, L"SetLeftLabel" ) - UI_MAP_NAME( m_funcSetCentreLabel, L"SetCenterLabel" ) - UI_MAP_NAME( m_funcSetRightLabel, L"SetRightLabel" ) + UI_MAP_NAME( m_funcSetCharacterFavourite, L"SetCharacterFavourite" ) + UI_MAP_NAME( m_funcSetCharacterBlocked, L"SetCharacterBlocked" ) UI_END_MAP_ELEMENTS_AND_NAMES() DLCPack *m_currentPack; @@ -113,7 +99,10 @@ private: DWORD m_currentPackCount; bool m_bIgnoreInput; bool m_bSkinIndexChanged; - wstring m_leftLabel, m_centreLabel, m_rightLabel; + bool m_bFocusDirty; + bool m_bNeedButtonListRefresh; + bool m_bHasTexturePack; + int m_iTexturePackIndex; S32 m_iTouchXStart; bool m_bTouchScrolled; @@ -132,6 +121,7 @@ public: virtual void handleAnimationEnd(); + virtual void handleFocusChange(F64 controlId, F64 childId); protected: // TODO: This should be pure virtual in this class @@ -157,10 +147,14 @@ private: void setCharacterSelected(bool selected); void setCharacterLocked(bool locked); - - void setLeftLabel(const wstring &label); - void setCentreLabel(const wstring &label); - void setRightLabel(const wstring &label); + void setCharacterFavourite(bool favourite); + void setCharacterBlocked(bool blocked); + void SetSkinPackButtonList(); + void setPackLabel(); + int relativePackIndex(DWORD base, int offset); + void handlePress(F64 controlId, F64 childId); + void setActivePackIndex(); + bool registerTexture(const wstring &texturePath); virtual void HandleDLCMountingComplete(); virtual void HandleDLCInstalled(); @@ -175,6 +169,8 @@ private: void AddFavoriteSkin(int iPad,int iSkinID); void InputActionOK(unsigned int iPad); + void InputActionFavorite(unsigned int iPad); + void SetFavoriteSkin(unsigned int pad, int skinId); #ifdef __PSVITA__ virtual void handleTouchInput(unsigned int iPad, S32 x, S32 y, int iId, bool bPressed, bool bRepeat, bool bReleased); #endif //__PSVITA__ diff --git a/Minecraft.Client/Common/XUI/XUI_Leaderboards.cpp b/Minecraft.Client/Common/XUI/XUI_Leaderboards.cpp index aea3c92f..0d914c8c 100644 --- a/Minecraft.Client/Common/XUI/XUI_Leaderboards.cpp +++ b/Minecraft.Client/Common/XUI/XUI_Leaderboards.cpp @@ -34,7 +34,7 @@ LPCWSTR CScene_Leaderboards::m_TextColumnNameA[7]= const int CScene_Leaderboards::TitleIcons[CScene_Leaderboards::NUM_LEADERBOARDS][7] = { { XZP_ICON_WALKED, XZP_ICON_FALLEN, Item::minecart_Id, Item::boat_Id, nullptr }, - { Tile::dirt_Id, Tile::stoneBrick_Id, Tile::sand_Id, Tile::rock_Id, Tile::gravel_Id, Tile::clay_Id, Tile::obsidian_Id }, + { Tile::dirt_Id, Tile::stonebrick_Id, Tile::sand_Id, Tile::rock_Id, Tile::gravel_Id, Tile::clay_Id, Tile::obsidian_Id }, { Item::egg_Id, Item::wheat_Id, Tile::mushroom1_Id, Tile::reeds_Id, Item::milk_Id, Tile::pumpkin_Id, nullptr }, { XZP_ICON_ZOMBIE, XZP_ICON_SKELETON, XZP_ICON_CREEPER, XZP_ICON_SPIDER, XZP_ICON_SPIDERJOCKEY, XZP_ICON_ZOMBIEPIGMAN, XZP_ICON_SLIME }, }; diff --git a/Minecraft.Client/Common/XUI/XUI_TutorialPopup.cpp b/Minecraft.Client/Common/XUI/XUI_TutorialPopup.cpp index 0be89d4c..c56ac063 100644 --- a/Minecraft.Client/Common/XUI/XUI_TutorialPopup.cpp +++ b/Minecraft.Client/Common/XUI/XUI_TutorialPopup.cpp @@ -390,7 +390,7 @@ wstring CScene_TutorialPopup::_SetIcon(int icon, int iAuxVal, bool isFoil, LPCWS } else if(temp.find(L"{*PoweredRailIcon*}")!=wstring::npos) { - m_pCraftingPic->SetIcon(m_iPad, Tile::goldenRail_Id,0,1,10,31,false); + m_pCraftingPic->SetIcon(m_iPad, Tile::golden_rail_Id,0,1,10,31,false); } else if(temp.find(L"{*StructuresIcon*}")!=wstring::npos) { diff --git a/Minecraft.Client/Common/res/TitleUpdate/res/colours.col b/Minecraft.Client/Common/res/TitleUpdate/res/colours.col deleted file mode 100644 index 60257b37..00000000 Binary files a/Minecraft.Client/Common/res/TitleUpdate/res/colours.col and /dev/null differ diff --git a/Minecraft.Client/Common/res/TitleUpdate/res/colours.xml b/Minecraft.Client/Common/res/TitleUpdate/res/colours.xml index 4e823132..3bc4010f 100644 --- a/Minecraft.Client/Common/res/TitleUpdate/res/colours.xml +++ b/Minecraft.Client/Common/res/TitleUpdate/res/colours.xml @@ -87,6 +87,7 @@ + @@ -113,6 +114,7 @@ + diff --git a/Minecraft.Client/CompassTexture.cpp b/Minecraft.Client/CompassTexture.cpp index dd5f5213..78d3e5fa 100644 --- a/Minecraft.Client/CompassTexture.cpp +++ b/Minecraft.Client/CompassTexture.cpp @@ -77,13 +77,19 @@ void CompassTexture::updateFromPosition(Level *level, double x, double z, double rot += rota; } + int frameCount = getFrames(); + if (frameCount <= 0) + { + return; + } + // 4J Stu - We share data with another texture if(m_dataTexture != nullptr) { - int newFrame = static_cast(((rot / (PI * 2)) + 1.0) * m_dataTexture->frames->size()) % m_dataTexture->frames->size(); + int newFrame = static_cast(((rot / (PI * 2)) + 1.0) * frameCount) % frameCount; while (newFrame < 0) { - newFrame = (newFrame + m_dataTexture->frames->size()) % m_dataTexture->frames->size(); + newFrame = (newFrame + frameCount) % frameCount; } if (newFrame != frame) { @@ -93,10 +99,10 @@ void CompassTexture::updateFromPosition(Level *level, double x, double z, double } else { - int newFrame = static_cast(((rot / (PI * 2)) + 1.0) * frames->size()) % frames->size(); + int newFrame = static_cast(((rot / (PI * 2)) + 1.0) * frameCount) % frameCount; while (newFrame < 0) { - newFrame = (newFrame + frames->size()) % frames->size(); + newFrame = (newFrame + frameCount) % frameCount; } if (newFrame != frame) { diff --git a/Minecraft.Client/DLCTexturePack.cpp b/Minecraft.Client/DLCTexturePack.cpp index 3cb68521..6b935a89 100644 --- a/Minecraft.Client/DLCTexturePack.cpp +++ b/Minecraft.Client/DLCTexturePack.cpp @@ -144,9 +144,27 @@ InputStream *DLCTexturePack::getResourceImplementation(const wstring &name) //th bool DLCTexturePack::hasFile(const wstring &name) { - bool hasFile = false; - if(m_dlcDataPack != nullptr) hasFile = m_dlcDataPack->doesPackContainFile(DLCManager::e_DLCType_Texture, name); - return hasFile; + if(m_dlcDataPack == nullptr) + { + return false; + } + + wstring normalized = replaceAll(name, L"\\", L"/"); + if(!normalized.empty() && normalized[0] == L'/') + { + normalized = normalized.substr(1); + } + if(normalized.rfind(L"res/", 0) != 0) + { + normalized = L"res/" + normalized; + } + + if(m_dlcDataPack->doesPackContainFile(DLCManager::e_DLCType_Texture, normalized)) + { + return true; + } + + return false; } bool DLCTexturePack::isTerrainUpdateCompatible() @@ -163,10 +181,28 @@ wstring DLCTexturePack::getAnimationString(const wstring &textureName, const wst { wstring result = L""; - wstring fullpath = L"res/" + path + textureName + L".png"; - if(hasFile(fullpath)) + wstring fullpath = path; + if(!fullpath.empty() && fullpath[0] == L'/') { - result = m_dlcDataPack->getFile(DLCManager::e_DLCType_Texture, fullpath)->getParameterAsString(DLCManager::e_DLCParamType_Anim); + fullpath = fullpath.substr(1); + } + if(fullpath.rfind(L"res/", 0) != 0) + { + fullpath = L"res/" + fullpath; + } + fullpath += textureName + L".png"; + if(m_dlcDataPack != nullptr && m_dlcDataPack->doesPackContainFile(DLCManager::e_DLCType_Texture, fullpath)) + { + DLCFile *dlcFile = m_dlcDataPack->getFile(DLCManager::e_DLCType_Texture, fullpath); + if(dlcFile != nullptr) + { + result = dlcFile->getParameterAsString(DLCManager::e_DLCParamType_Anim); + } + } + + if(result.empty() && fallback != nullptr) + { + result = fallback->getAnimationString(textureName, path, true); } return result; @@ -174,8 +210,33 @@ wstring DLCTexturePack::getAnimationString(const wstring &textureName, const wst BufferedImage *DLCTexturePack::getImageResource(const wstring& File, bool filenameHasExtension /*= false*/, bool bTitleUpdateTexture /*=false*/, const wstring &drive /*=L""*/) { - if(m_dlcDataPack) return new BufferedImage(m_dlcDataPack, L"/" + File, filenameHasExtension); - else return fallback->getImageResource(File, filenameHasExtension, bTitleUpdateTexture, drive); + if(m_dlcDataPack != nullptr) + { + wstring dlcPath = File; + if(!dlcPath.empty() && dlcPath[0] == L'/') + { + dlcPath = dlcPath.substr(1); + } + if(dlcPath.rfind(L"res/", 0) != 0) + { + dlcPath = L"res/" + dlcPath; + } + bool hasTexture = m_dlcDataPack->doesPackContainFile(DLCManager::e_DLCType_Texture, dlcPath); + if(!hasTexture && !filenameHasExtension) + { + hasTexture = m_dlcDataPack->doesPackContainFile(DLCManager::e_DLCType_Texture, dlcPath + L".png"); + } + if(!hasTexture && filenameHasExtension && dlcPath.size() > 4) + { + wstring noExt = dlcPath.substr(0, dlcPath.size() - 4); + hasTexture = m_dlcDataPack->doesPackContainFile(DLCManager::e_DLCType_Texture, noExt + L".png"); + } + if(hasTexture) + { + return new BufferedImage(m_dlcDataPack, L"/" + File, filenameHasExtension); + } + } + return fallback->getImageResource(File, filenameHasExtension, bTitleUpdateTexture, drive); } DLCPack * DLCTexturePack::getDLCPack() @@ -354,8 +415,16 @@ int DLCTexturePack::packMounted(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicen } } #else - File archivePath(getFilePath(texturePack->m_dlcInfoPack->GetPackID(), wstring(L"media.arc") ) ); - if(archivePath.exists()) texturePack->m_archiveFile = new ArchiveFile(archivePath); + File mediaFolder(getFilePath(texturePack->m_dlcInfoPack->GetPackID(), wstring(L"media"))); + if(mediaFolder.exists() && mediaFolder.isDirectory()) + { + texturePack->m_archiveFile = new ArchiveFile(mediaFolder, true); + } + else + { + File archivePath(getFilePath(texturePack->m_dlcInfoPack->GetPackID(), wstring(L"media.arc") ) ); + if(archivePath.exists()) texturePack->m_archiveFile = new ArchiveFile(archivePath); + } #endif /** @@ -364,16 +433,73 @@ int DLCTexturePack::packMounted(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicen */ DLCPack *pack = texturePack->m_dlcInfoPack->GetParentPack(); LevelGenerationOptions *levelGen = app.getLevelGenerationOptions(); - if (levelGen != nullptr && !levelGen->hasLoadedData()) + bool shouldLoadGameRules = levelGen != nullptr && levelGen->isFromDLC(); + if (shouldLoadGameRules) { - int gameRulesCount = pack->getDLCItemsCount(DLCManager::e_DLCType_GameRulesHeader); - for(int i = 0; i < gameRulesCount; ++i) + bool needsReload = !levelGen->hasLoadedData() + || levelGen->getRequiredTexturePackId() != texturePack->getDLCParentPackId(); + if(needsReload) { - DLCGameRulesHeader *dlcFile = static_cast(pack->getFile(DLCManager::e_DLCType_GameRulesHeader, i)); - - if (!dlcFile->getGrfPath().empty()) + int gameRulesCount = pack->getDLCItemsCount(DLCManager::e_DLCType_GameRulesHeader); + for(int i = 0; i < gameRulesCount; ++i) { - File grf( getFilePath(texturePack->m_dlcInfoPack->GetPackID(), dlcFile->getGrfPath() ) ); + DLCGameRulesHeader *dlcFile = static_cast(pack->getFile(DLCManager::e_DLCType_GameRulesHeader, i)); + + if (!dlcFile->getGrfPath().empty()) + { + File grf( getFilePath(texturePack->m_dlcInfoPack->GetPackID(), dlcFile->getGrfPath() ) ); + if (grf.exists()) + { +#ifdef _UNICODE + wstring path = grf.getPath(); + const WCHAR *pchFilename=path.c_str(); + HANDLE fileHandle = CreateFile( + pchFilename, // file name + GENERIC_READ, // access mode + 0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but... + nullptr, // Unused + OPEN_EXISTING , // how to create // TODO 4J Stu - Assuming that the file already exists if we are opening to read from it + FILE_FLAG_SEQUENTIAL_SCAN, // file attributes + nullptr // Unsupported + ); +#else + const char *pchFilename=wstringtofilename(grf.getPath()); + HANDLE fileHandle = CreateFile( + pchFilename, // file name + GENERIC_READ, // access mode + 0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but... + nullptr, // Unused + OPEN_EXISTING , // how to create // TODO 4J Stu - Assuming that the file already exists if we are opening to read from it + FILE_FLAG_SEQUENTIAL_SCAN, // file attributes + nullptr // Unsupported + ); +#endif + + if( fileHandle != INVALID_HANDLE_VALUE ) + { + DWORD dwFileSize = grf.length(); + DWORD bytesRead; + PBYTE pbData = (PBYTE) new BYTE[dwFileSize]; + BOOL bSuccess = ReadFile(fileHandle,pbData,dwFileSize,&bytesRead,nullptr); + if(bSuccess==FALSE) + { + app.FatalLoadError(); + } + CloseHandle(fileHandle); + + // 4J-PB - is it possible that we can get here after a read fail and it's not an error? + dlcFile->setGrfData(pbData, dwFileSize, texturePack->m_stringTable); + + delete [] pbData; + + app.m_gameRules.setLevelGenerationOptions( dlcFile->lgo ); + } + } + } + } + if(levelGen->requiresBaseSave() && !levelGen->getBaseSavePath().empty() ) + { + File grf(getFilePath(texturePack->m_dlcInfoPack->GetPackID(), levelGen->getBaseSavePath() )); if (grf.exists()) { #ifdef _UNICODE @@ -403,8 +529,7 @@ int DLCTexturePack::packMounted(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicen if( fileHandle != INVALID_HANDLE_VALUE ) { - DWORD dwFileSize = grf.length(); - DWORD bytesRead; + DWORD bytesRead,dwFileSize = GetFileSize(fileHandle,nullptr); PBYTE pbData = (PBYTE) new BYTE[dwFileSize]; BOOL bSuccess = ReadFile(fileHandle,pbData,dwFileSize,&bytesRead,nullptr); if(bSuccess==FALSE) @@ -414,61 +539,11 @@ int DLCTexturePack::packMounted(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicen CloseHandle(fileHandle); // 4J-PB - is it possible that we can get here after a read fail and it's not an error? - dlcFile->setGrfData(pbData, dwFileSize, texturePack->m_stringTable); - - delete [] pbData; - - app.m_gameRules.setLevelGenerationOptions( dlcFile->lgo ); + levelGen->setBaseSaveData(pbData, dwFileSize); } } } } - if(levelGen->requiresBaseSave() && !levelGen->getBaseSavePath().empty() ) - { - File grf(getFilePath(texturePack->m_dlcInfoPack->GetPackID(), levelGen->getBaseSavePath() )); - if (grf.exists()) - { -#ifdef _UNICODE - wstring path = grf.getPath(); - const WCHAR *pchFilename=path.c_str(); - HANDLE fileHandle = CreateFile( - pchFilename, // file name - GENERIC_READ, // access mode - 0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but... - nullptr, // Unused - OPEN_EXISTING , // how to create // TODO 4J Stu - Assuming that the file already exists if we are opening to read from it - FILE_FLAG_SEQUENTIAL_SCAN, // file attributes - nullptr // Unsupported - ); -#else - const char *pchFilename=wstringtofilename(grf.getPath()); - HANDLE fileHandle = CreateFile( - pchFilename, // file name - GENERIC_READ, // access mode - 0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but... - nullptr, // Unused - OPEN_EXISTING , // how to create // TODO 4J Stu - Assuming that the file already exists if we are opening to read from it - FILE_FLAG_SEQUENTIAL_SCAN, // file attributes - nullptr // Unsupported - ); -#endif - - if( fileHandle != INVALID_HANDLE_VALUE ) - { - DWORD bytesRead,dwFileSize = GetFileSize(fileHandle,nullptr); - PBYTE pbData = (PBYTE) new BYTE[dwFileSize]; - BOOL bSuccess = ReadFile(fileHandle,pbData,dwFileSize,&bytesRead,nullptr); - if(bSuccess==FALSE) - { - app.FatalLoadError(); - } - CloseHandle(fileHandle); - - // 4J-PB - is it possible that we can get here after a read fail and it's not an error? - levelGen->setBaseSaveData(pbData, dwFileSize); - } - } - } } diff --git a/Minecraft.Client/DispenserBootstrap.h b/Minecraft.Client/DispenserBootstrap.h index 84dde91a..80020ed6 100644 --- a/Minecraft.Client/DispenserBootstrap.h +++ b/Minecraft.Client/DispenserBootstrap.h @@ -11,19 +11,19 @@ public: { DispenserTile::REGISTRY.add(Item::arrow, new ArrowDispenseBehavior()); DispenserTile::REGISTRY.add(Item::egg, new EggDispenseBehavior()); - DispenserTile::REGISTRY.add(Item::snowBall, new SnowballDispenseBehavior()); - DispenserTile::REGISTRY.add(Item::expBottle, new ExpBottleDispenseBehavior()); + DispenserTile::REGISTRY.add(Item::snowball, new SnowballDispenseBehavior()); + DispenserTile::REGISTRY.add(Item::experience_bottle, new ExpBottleDispenseBehavior()); DispenserTile::REGISTRY.add(Item::potion, new PotionDispenseBehavior()); - DispenserTile::REGISTRY.add(Item::spawnEgg, new SpawnEggDispenseBehavior()); + DispenserTile::REGISTRY.add(Item::spawn_egg, new SpawnEggDispenseBehavior()); DispenserTile::REGISTRY.add(Item::fireworks, new FireworksDispenseBehavior()); DispenserTile::REGISTRY.add(Item::fireball, new FireballDispenseBehavior()); DispenserTile::REGISTRY.add(Item::boat, new BoatDispenseBehavior()); - DispenserTile::REGISTRY.add(Item::bucket_lava, new FilledBucketDispenseBehavior()); - DispenserTile::REGISTRY.add(Item::bucket_water, new FilledBucketDispenseBehavior()); - DispenserTile::REGISTRY.add(Item::bucket_empty, new EmptyBucketDispenseBehavior()); - DispenserTile::REGISTRY.add(Item::flintAndSteel, new FlintAndSteelDispenseBehavior()); - DispenserTile::REGISTRY.add(Item::dye_powder, new DyeDispenseBehavior()); + DispenserTile::REGISTRY.add(Item::lava_bucket, new FilledBucketDispenseBehavior()); + DispenserTile::REGISTRY.add(Item::water_bucket, new FilledBucketDispenseBehavior()); + DispenserTile::REGISTRY.add(Item::bucket, new EmptyBucketDispenseBehavior()); + DispenserTile::REGISTRY.add(Item::flint_and_steel, new FlintAndSteelDispenseBehavior()); + DispenserTile::REGISTRY.add(Item::dye, new DyeDispenseBehavior()); DispenserTile::REGISTRY.add(Item::items[Tile::tnt_Id], new TntDispenseBehavior()); } }; \ No newline at end of file diff --git a/Minecraft.Client/Durango/Leaderboards/DurangoStatsDebugger.cpp b/Minecraft.Client/Durango/Leaderboards/DurangoStatsDebugger.cpp index 07259162..b9210005 100644 --- a/Minecraft.Client/Durango/Leaderboards/DurangoStatsDebugger.cpp +++ b/Minecraft.Client/Durango/Leaderboards/DurangoStatsDebugger.cpp @@ -135,14 +135,14 @@ DurangoStatsDebugger *DurangoStatsDebugger::Initialize() sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::dirt_Id); // works sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::milk_Id); // works. sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Tile::dirt_Id); // works. - sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::porkChop_cooked_Id); // BROKEN! (ach 'Pork Chop' configured incorrectly) + sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::cooked_porkchop_Id); // BROKEN! (ach 'Pork Chop' configured incorrectly) sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::cake_Id); // works. (ach 'The Lie' configured incorrectly) sp->addArgs(DsItemEvent::eAcquisitionMethod_Bought, Item::emerald_Id); // fixed (+ach) - sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::ironIngot_Id); // works. (+ach 'Acquired Hardware') - sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Item::fish_raw_Id); // works. (+ach 'Delicious Fish') - sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::fish_cooked_Id); // works. (+ach 'Delicious Fish') - sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::sign_Id); - sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::flowerPot_Id); // FIXING! + sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::iron_ingot_Id); // works. (+ach 'Acquired Hardware') + sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Item::fish_Id); // works. (+ach 'Delicious Fish') + sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::cooked_fish_Id); // works. (+ach 'Delicious Fish') + sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::standing_sign_Id); + sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::flower_pot_Id); // FIXING! out->m_stats.push_back(sp); sp = new StatParam(L"McItemAcquired.DifficultyLevelId.*.AcquisitionMethodId.*.ItemId.*"); @@ -153,21 +153,21 @@ DurangoStatsDebugger *DurangoStatsDebugger::Initialize() sp = new StatParam(L"McItemUsed.ItemId.*.ItemAux.*"); //sp->addArgs(Item::apple_Id, 0); //sp->addArgs(Item::cake_Id, 0); - sp->addArgs(Item::beef_raw_Id, 0); // works - sp->addArgs(Item::porkChop_cooked_Id, 0); // works + sp->addArgs(Item::beef_Id, 0); // works + sp->addArgs(Item::cooked_porkchop_Id, 0); // works out->m_stats.push_back(sp); sp = new StatParam(L"MinHungerWhenEaten.ItemId.*"); //sp->addArgs(Item::apple_Id); //sp->addArgs(Item::cake_Id); - sp->addArgs(Item::beef_raw_Id); // works + sp->addArgs(Item::beef_Id); // works sp->addArgs(Item::rotten_flesh_Id); // works (+ach IronBelly) out->m_stats.push_back(sp); sp = new StatParam(L"BlockBroken.BlockId.*"); sp->addArgs( Tile::dirt_Id ); sp->addArgs( Tile::rock_Id ); - sp->addArgs( Tile::emeraldOre_Id ); + sp->addArgs( Tile::emerald_ore_Id ); out->m_stats.push_back(sp); sp = new StatParam(L"BlockBroken.BlockId.*.BlockAux.*"); @@ -188,21 +188,21 @@ DurangoStatsDebugger *DurangoStatsDebugger::Initialize() sp = new StatParam(L"BlockPlaced.BlockId.*"); sp->addArgs( Tile::dirt_Id ); - sp->addArgs( Tile::stoneBrick_Id ); + sp->addArgs( Tile::stonebrick_Id ); sp->addArgs( Tile::sand_Id ); // works - sp->addArgs( Tile::sign_Id ); // fixed - sp->addArgs( Tile::wallSign_Id ); // fixed + sp->addArgs( Tile::standing_sign_Id ); // fixed + sp->addArgs( Tile::wall_standing_sign_Id ); // fixed out->m_stats.push_back(sp); sp = new StatParam(L"MobKilled.KillTypeId.*.EnemyRoleId.*.PlayerWeaponId.*"); // BROKEN! sp->addArgs( /*MELEE*/ 0, ioid_Cow, 0 ); - sp->addArgs( /*MELEE*/ 0, ioid_Cow, Item::sword_stone_Id ); - sp->addArgs( /*MELEE*/ 0, ioid_Pig, Item::sword_stone_Id ); + sp->addArgs( /*MELEE*/ 0, ioid_Cow, Item::stone_sword_Id ); + sp->addArgs( /*MELEE*/ 0, ioid_Pig, Item::stone_sword_Id ); out->m_stats.push_back(sp); sp = new StatParam(L"MaxKillDistance.KillTypeId.*.EnemyRoleId.*.PlayerWeaponId.*"); // BROKEN! - sp->addArgs( /*MELEE*/ 0, ioid_Cow, Item::sword_stone_Id ); - sp->addArgs( /*MELEE*/ 0, ioid_Pig, Item::sword_stone_Id ); + sp->addArgs( /*MELEE*/ 0, ioid_Cow, Item::stone_sword_Id ); + sp->addArgs( /*MELEE*/ 0, ioid_Pig, Item::stone_sword_Id ); sp->addArgs( /*RANGE*/ 1, ioid_Creeper, ioid_Arrow ); // FIXING! out->m_stats.push_back(sp); diff --git a/Minecraft.Client/EntityRenderDispatcher.cpp b/Minecraft.Client/EntityRenderDispatcher.cpp index 95a806f0..accda0f7 100644 --- a/Minecraft.Client/EntityRenderDispatcher.cpp +++ b/Minecraft.Client/EntityRenderDispatcher.cpp @@ -149,12 +149,12 @@ EntityRenderDispatcher::EntityRenderDispatcher() renderers[eTYPE_ITEM_FRAME] = new ItemFrameRenderer(); renderers[eTYPE_LEASHFENCEKNOT] = new LeashKnotRenderer(); renderers[eTYPE_ARROW] = new ArrowRenderer(); - renderers[eTYPE_SNOWBALL] = new ItemSpriteRenderer(Item::snowBall); - renderers[eTYPE_THROWNENDERPEARL] = new ItemSpriteRenderer(Item::enderPearl); - renderers[eTYPE_EYEOFENDERSIGNAL] = new ItemSpriteRenderer(Item::eyeOfEnder); + renderers[eTYPE_SNOWBALL] = new ItemSpriteRenderer(Item::snowball); + renderers[eTYPE_THROWNENDERPEARL] = new ItemSpriteRenderer(Item::ender_pearl); + renderers[eTYPE_EYEOFENDERSIGNAL] = new ItemSpriteRenderer(Item::eye_of_ender); renderers[eTYPE_THROWNEGG] = new ItemSpriteRenderer(Item::egg); renderers[eTYPE_THROWNPOTION] = new ItemSpriteRenderer(Item::potion, PotionBrewing::THROWABLE_MASK); - renderers[eTYPE_THROWNEXPBOTTLE] = new ItemSpriteRenderer(Item::expBottle); + renderers[eTYPE_THROWNEXPBOTTLE] = new ItemSpriteRenderer(Item::experience_bottle); renderers[eTYPE_FIREWORKS_ROCKET] = new ItemSpriteRenderer(Item::fireworks); renderers[eTYPE_LARGE_FIREBALL] = new FireballRenderer(2.0f); renderers[eTYPE_SMALL_FIREBALL] = new FireballRenderer(0.5f); diff --git a/Minecraft.Client/EntityRenderer.cpp b/Minecraft.Client/EntityRenderer.cpp index 46fc2687..4900d5c0 100644 --- a/Minecraft.Client/EntityRenderer.cpp +++ b/Minecraft.Client/EntityRenderer.cpp @@ -212,9 +212,11 @@ void EntityRenderer::renderShadow(shared_ptr e, double x, double y, doub for (int zt = z0; zt <= z1; zt++) { int t = level->getTile(xt, yt - 1, zt); + Tile *tile = Tile::tiles[t]; + if (tile == nullptr) continue; // tu31 tutorial world fix if (t > 0 && level->getRawBrightness(xt, yt, zt) > 3) { - renderTileShadow(Tile::tiles[t], x, y + e->getShadowHeightOffs() + fYLocalPlayerShadowOffset, z, xt, yt , zt, pow, r, xo, yo + e->getShadowHeightOffs() + fYLocalPlayerShadowOffset, zo); + renderTileShadow(tile, x, y + e->getShadowHeightOffs() + fYLocalPlayerShadowOffset, z, xt, yt , zt, pow, r, xo, yo + e->getShadowHeightOffs() + fYLocalPlayerShadowOffset, zo); } } tt->end(); diff --git a/Minecraft.Client/EntityTileRenderer.cpp b/Minecraft.Client/EntityTileRenderer.cpp index d54801d3..2b598d9d 100644 --- a/Minecraft.Client/EntityTileRenderer.cpp +++ b/Minecraft.Client/EntityTileRenderer.cpp @@ -15,7 +15,7 @@ EntityTileRenderer::EntityTileRenderer() void EntityTileRenderer::render(Tile *tile, int data, float brightness, float alpha, bool setColor, bool useCompiled) { - if (tile->id == Tile::enderChest_Id) + if (tile->id == Tile::ender_chest_Id) { TileEntityRenderDispatcher::instance->render(enderChest, 0, 0, 0, 0, setColor, alpha, useCompiled); } diff --git a/Minecraft.Client/Extrax64Stubs.cpp b/Minecraft.Client/Extrax64Stubs.cpp index 5bdb155c..db2da718 100644 --- a/Minecraft.Client/Extrax64Stubs.cpp +++ b/Minecraft.Client/Extrax64Stubs.cpp @@ -565,8 +565,17 @@ void XMemDestroyDecompressionContext(XMEMDECOMPRESSION_CONTEXT Context) //#ifndef __PS3__ #if !(defined _DURANGO || defined __PS3__ || defined __ORBIS__ || defined __PSVITA__) -DWORD XGetLanguage() { return 1; } -DWORD XGetLocale() { return 0; } +DWORD XGetLanguage() { + unsigned char lang = app.GetMinecraftLanguage(0); + if (lang != 0) return lang; + return 1; +} +DWORD XGetLocale() { + unsigned char loc = app.GetMinecraftLocale(0); + if (loc != 0) return loc; + return 0; +} + DWORD XEnableGuestSignin(BOOL fEnable) { return 0; } #endif diff --git a/Minecraft.Client/FishingHookRenderer.cpp b/Minecraft.Client/FishingHookRenderer.cpp index a9b0d91a..29d443ff 100644 --- a/Minecraft.Client/FishingHookRenderer.cpp +++ b/Minecraft.Client/FishingHookRenderer.cpp @@ -67,7 +67,7 @@ void FishingHookRenderer::render(shared_ptr _hook, double x, double y, d if (ownerPlayer != nullptr) { shared_ptr selected = ownerPlayer->inventory->getSelected(); - if (selected == nullptr || selected->id != Item::fishingRod_Id) + if (selected == nullptr || selected->id != Item::fishing_rod_Id) { handDir = -handDir; } diff --git a/Minecraft.Client/GameRenderer.cpp b/Minecraft.Client/GameRenderer.cpp index e8121509..891c595f 100644 --- a/Minecraft.Client/GameRenderer.cpp +++ b/Minecraft.Client/GameRenderer.cpp @@ -163,6 +163,8 @@ GameRenderer::GameRenderer(Minecraft *mc) lightTexture[i] = mc->textures->getTexture(img); // 4J - changed to one light texture per level to support split screen } delete img; +#endif +#ifndef MINECRAFT_SERVER_BUILD #ifdef __PS3__ // we're using the RSX now to upload textures to vram, so we need the main ram textures allocated from io space for(int i=0;irender(cameraEntity, 3, a, updateChunks); + PIXEndNamedEvent(); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + if (visibleTopTransparentChunksLayer3 > 0) + { + PIXBeginNamedEvent(0,"Fourth pass level direct render"); + levelRenderer->renderChunksDirect(3, a); + PIXEndNamedEvent(); + } + GL11::glShadeModel(GL11::GL_FLAT); } else @@ -1666,6 +1680,9 @@ void GameRenderer::renderLevel(float a, int64_t until) PIXBeginNamedEvent(0,"Third pass level render"); levelRenderer->render(cameraEntity, 2, a, updateChunks); PIXEndNamedEvent(); + PIXBeginNamedEvent(0,"Fourth pass level render"); + levelRenderer->render(cameraEntity, 3, a, updateChunks); + PIXEndNamedEvent(); } // 4J - added - have split out translucent particle rendering so that it happens after the water is rendered, primarily for fireworks diff --git a/Minecraft.Client/Gui.cpp b/Minecraft.Client/Gui.cpp index 8c30b1ff..731eb480 100644 --- a/Minecraft.Client/Gui.cpp +++ b/Minecraft.Client/Gui.cpp @@ -28,7 +28,14 @@ #include "../Minecraft.World/net.minecraft.world.h" #include "../Minecraft.World/LevelChunk.h" #include "../Minecraft.World/Biome.h" +#include "../Minecraft.World/HitResult.h" #include +#include "../Minecraft.World/Tile.h" +#include "../Minecraft.World/BlockStateDecoderRegistry.h" +#include "../Minecraft.World/BlockStateDecoder.h" +#include +#include +#include ResourceLocation Gui::PUMPKIN_BLUR_LOCATION = ResourceLocation(TN__BLUR__MISC_PUMPKINBLUR); @@ -1157,6 +1164,111 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) lines.push_back(L"Facing: " + std::wstring(cardinals[direction]) + L" (" + angleString + L")"); // We have to limit y to 256 as we don't get any information past that + // target block state + if (minecraft->hitResult != nullptr && minecraft->hitResult->type == HitResult::TILE) + { + int hx = minecraft->hitResult->x; + int hy = minecraft->hitResult->y; + int hz = minecraft->hitResult->z; + if (minecraft->level != NULL && minecraft->level->hasChunkAt(hx, hy, hz)) + { + int tid = minecraft->level->getTile(hx, hy, hz); + if (tid >= 0 && tid < Tile::TILE_NUM_COUNT) + { + Tile *t = Tile::tiles[tid]; + if (t != nullptr) + { + Tile::BlockState st = t->getBlockState(minecraft->level, hx, hy, hz); + // check registry so we dont end up with random integers + std::wstring decoded = BlockStateDecoderRegistry::decode(tid, st.value); + + if (decoded.empty()) { + if (tid == Tile::wooden_door_Id || tid == Tile::iron_door_Id || tid == Tile::spruce_door_Id || tid == Tile::birch_door_Id || tid == Tile::jungle_door_Id || tid == Tile::acacia_door_Id || tid == Tile::dark_oak_door_Id) { + decoded = BlockStateDecoder::doorPropsToString(BlockStateDecoder::decodeDoor(st.value)); + } + } + + if (!decoded.empty()) + { + std::map props; + std::set shownProps; + auto appendProp = [&](const std::wstring &key) { + auto it = props.find(key); + if (it != props.end()) { + lines.push_back(key + L": " + it->second); + shownProps.insert(key); + } + }; + size_t start = 0; + while (start < decoded.size()) { + size_t pos = decoded.find(L'\n', start); + std::wstring line = (pos == std::wstring::npos) ? decoded.substr(start) : decoded.substr(start, pos - start); + size_t colon = line.find(L':'); + if (colon != std::wstring::npos) { + std::wstring key = line.substr(0, colon); + std::wstring val = line.substr(colon + 1); + auto trim = [](std::wstring &s) { + size_t i = 0; + while (i < s.size() && iswspace(s[i])) ++i; + if (i) s.erase(0, i); + // right + if (!s.empty()) { + size_t j = s.size() - 1; + while (j != (size_t)-1 && iswspace(s[j])) --j; + s.erase(j + 1); + } + }; + trim(key); + trim(val); + props[key] = val; + } + if (pos == std::wstring::npos) break; + start = pos + 1; + } + lines.push_back(L"State:"); + appendProp(L"age"); + appendProp(L"moisture"); + appendProp(L"facing"); + appendProp(L"part"); + appendProp(L"occupied"); + appendProp(L"north"); + appendProp(L"south"); + appendProp(L"east"); + appendProp(L"west"); + appendProp(L"type"); + appendProp(L"variant"); + appendProp(L"axis"); + appendProp(L"hinge"); + appendProp(L"half"); + appendProp(L"shape"); + appendProp(L"up"); + appendProp(L"extended"); + appendProp(L"open"); + appendProp(L"in_wall"); + appendProp(L"attached"); + appendProp(L"powered"); + appendProp(L"power"); + appendProp(L"triggered"); + appendProp(L"explode"); + appendProp(L"bites"); + appendProp(L"mode"); + appendProp(L"delay"); + appendProp(L"enabled"); + appendProp(L"eye"); + appendProp(L"bottle_0"); + appendProp(L"bottle_1"); + appendProp(L"bottle_2"); + appendProp(L"has_record"); + for (const auto &entry : props) { + if (shownProps.find(entry.first) == shownProps.end()) { + lines.push_back(entry.first + L": " + entry.second); + } + } + } + } + } + } + } if (minecraft->level != NULL && minecraft->level->hasChunkAt(xBlockPos, fmod(yBlockPos, 256), zBlockPos)) { LevelChunk *chunkAt = minecraft->level->getChunkAt(xBlockPos, zBlockPos); diff --git a/Minecraft.Client/ItemFrameRenderer.cpp b/Minecraft.Client/ItemFrameRenderer.cpp index a9fb5899..b297c546 100644 --- a/Minecraft.Client/ItemFrameRenderer.cpp +++ b/Minecraft.Client/ItemFrameRenderer.cpp @@ -18,6 +18,7 @@ #include "../Minecraft.World/net.minecraft.h" #include "CompassTexture.h" #include "Minimap.h" +#include "../Minecraft.World/Level.h" ResourceLocation ItemFrameRenderer::MAP_BACKGROUND_LOCATION = ResourceLocation(TN_MISC_MAPBG); @@ -41,7 +42,22 @@ void ItemFrameRenderer::render(shared_ptr _itemframe, double x, double int yt = itemFrame->yTile; int zt = itemFrame->zTile + Direction::STEP_Z[itemFrame->dir]; - glTranslatef(static_cast(xt) - xOffs, static_cast(yt) - yOffs, static_cast(zt) - zOffs); + float back = 0.0f; + + // set offset to 1 if the item frame is not placed by the player + if (itemFrame->level->isClientSide && !itemFrame->placedByPlayer) + { + back = 1.0f; + } + + int dx = Direction::STEP_X[itemFrame->dir]; + int dz = Direction::STEP_Z[itemFrame->dir]; + + glTranslatef( + static_cast(xt) - xOffs - dx * back, + static_cast(yt) - yOffs, + static_cast(zt) - zOffs - dz * back + ); drawFrame(itemFrame); drawItem(itemFrame); diff --git a/Minecraft.Client/ItemInHandRenderer.cpp b/Minecraft.Client/ItemInHandRenderer.cpp index 4d91b4f0..8bd5ca99 100644 --- a/Minecraft.Client/ItemInHandRenderer.cpp +++ b/Minecraft.Client/ItemInHandRenderer.cpp @@ -228,7 +228,7 @@ void ItemInHandRenderer::renderItem(shared_ptr mob, shared_ptrid]->getColor(item, layer); float red = ((col >> 16) & 0xff) / 255.0f; @@ -240,15 +240,20 @@ void ItemInHandRenderer::renderItem(shared_ptr mob, shared_ptrid == Item::skull_Id && SkullTileRenderer::instance != nullptr) + if (dynamic_cast(item->getItem()) != nullptr && SkullTileRenderer::instance != nullptr) { - wstring extra = L""; + std::wstring extra = L""; if (item->hasTag() && item->getTag()->contains(L"SkullOwner")) extra = item->getTag()->getString(L"SkullOwner"); - SkullTileRenderer::instance->renderSkull(-0.5f, 0.0f, -0.5f, Facing::UP, 0.0f, item->getAuxValue(), extra); + glRotatef(-45, 1, 1, 0); + glRotatef(-70, 0, 1, 0); // lower = rotate left + glRotatef(5, 1, 0, 0); + glRotatef(-20, 0, 0, 1); + SkullTileRenderer::instance->renderSkull(-1.0f, -0.9f, 0.0f, Facing::UP, 0.0f, item->getAuxValue(), extra); + glScalef(0.5f, 0.5f, 0.5f); glPopMatrix(); return; - }*/ + } Tile *tile = Tile::tiles[item->id]; if ((item->getIconType() == Icon::TYPE_TERRAIN && tile != nullptr && TileRenderer::canRender(tile->getRenderShape())) && item->id != AirTile::barrier_Id) @@ -692,16 +697,18 @@ void ItemInHandRenderer::render(float a) renderItem(player, item, 1, false); } - //else if (item->id == Item::skull_Id && SkullTileRenderer::instance != nullptr) - //{ - // wstring extra = L""; - // if (item->hasTag() && item->getTag()->contains(L"SkullOwner")) - // extra = item->getTag()->getString(L"SkullOwner"); - // glEnable(GL_RESCALE_NORMAL); - // glScalef(2.0f, 2.0f, 2.0f); - // SkullTileRenderer::instance->renderSkull(-0.5f, 0.0f, -0.5f, Facing::UP, 0.0f, item->getAuxValue(), extra); - // glDisable(GL_RESCALE_NORMAL); - //} + else if (item->id == Item::skull_Id && SkullTileRenderer::instance != nullptr) + { + std::wstring extra = L""; + if (item->hasTag() && item->getTag()->contains(L"SkullOwner")) + extra = item->getTag()->getString(L"SkullOwner"); + glRotatef(-49.5f, 0.0f, 1.0f, 0.0f); + glRotatef(5.0f, 0.0f, 0.0f, 1.0f); + glRotatef(5.0f, 1.0f, 0.0f, 0.0f); + SkullTileRenderer::instance->renderSkull(-1.0f, 0.26f, 0.35f, Facing::UP, 0.0f, item->getAuxValue(), extra); + glPopMatrix(); + return; + } else { renderItem(player, item, 0, false); diff --git a/Minecraft.Client/ItemRenderer.cpp b/Minecraft.Client/ItemRenderer.cpp index 25b53637..ae6e730d 100644 --- a/Minecraft.Client/ItemRenderer.cpp +++ b/Minecraft.Client/ItemRenderer.cpp @@ -2,6 +2,9 @@ #include "ItemRenderer.h" #include "TileRenderer.h" #include "EntityRenderDispatcher.h" +#include "SkullTileRenderer.h" +#include "../Minecraft.World/SkullItem.h" +#include "../Minecraft.World/Facing.h" #include "../Minecraft.World/JavaMath.h" #include "../Minecraft.World/net.minecraft.world.entity.item.h" #include "../Minecraft.World/net.minecraft.world.item.h" @@ -81,8 +84,17 @@ void ItemRenderer::render(shared_ptr _itemEntity, double x, double y, do glEnable(GL_RESCALE_NORMAL); Tile *tile = Tile::tiles[item->id]; + if (dynamic_cast(item->getItem()) != nullptr && SkullTileRenderer::instance != nullptr) + { + std::wstring extra = L""; + if (item->hasTag() && item->getTag()->contains(L"SkullOwner")) + extra = item->getTag()->getString(L"SkullOwner"); - if ((item->getIconType() == Icon::TYPE_TERRAIN && tile != nullptr && TileRenderer::canRender(tile->getRenderShape())) && item->id != Tile::barrier_Id) + glRotatef(spin, 0, 1, 0); + glScalef(0.5f, 0.5f, 0.5f); + SkullTileRenderer::instance->renderSkull(-0.5f, -0.25f, -0.5f, Facing::UP, 0.0f, item->getAuxValue(), extra); + } + else if ((item->getIconType() == Icon::TYPE_TERRAIN && tile != nullptr && TileRenderer::canRender(tile->getRenderShape())) && item->id != Tile::barrier_Id) { glRotatef(spin, 0, 1, 0); @@ -101,7 +113,17 @@ void ItemRenderer::render(shared_ptr _itemEntity, double x, double y, do } glScalef(s, s, s); - for (int i = 0; i < count; i++) + + bool bSlimeItem = (tile != nullptr && tile->id == Tile::slimeBlock->id); + if (bSlimeItem) + { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_ALPHA_TEST); + glEnable(GL_BLEND); + glDepthMask(false); + } + + for (int i = 0; i < count; i++) { glPushMatrix(); if (i > 0) @@ -116,6 +138,13 @@ void ItemRenderer::render(shared_ptr _itemEntity, double x, double y, do tileRenderer->renderTile(tile, item->getAuxValue(), br); glPopMatrix(); } + + if (bSlimeItem) + { + glDepthMask(true); + glEnable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + } } else if (item->getIconType() == Icon::TYPE_ITEM && item->getItem()->hasMultipleSpriteLayers()) { @@ -355,6 +384,25 @@ void ItemRenderer::renderGuiItem(Font *font, Textures *textures, shared_ptrgetAuxValue(); Icon *itemIcon = item->getIcon(); + if (dynamic_cast(item->getItem()) != nullptr && SkullTileRenderer::instance != nullptr) + { + std::wstring extra = L""; + if (item->hasTag() && item->getTag()->contains(L"SkullOwner")) + { + extra = item->getTag()->getString(L"SkullOwner"); + } + + glPushMatrix(); + glTranslatef(x, y, 0.0f); + glScalef(16.0f * fScaleX, 16.0f * fScaleY, 1.0f); + glTranslatef(0.5f, 0.725f, 0.0f); + glRotatef(180.0f - 30.0f, 1.0f, 0.0f, 0.0f); + glRotatef(-45.0f, 0.0f, 1.0f, 0.0f); + SkullTileRenderer::instance->renderSkull(-0.5f, 0.0f, -0.5f, Facing::UP, 0.0f, itemAuxValue, extra); + glPopMatrix(); + return; + } + if ((item->getIconType() == Icon::TYPE_TERRAIN && TileRenderer::canRender(Tile::tiles[itemId]->getRenderShape())) && itemId != Tile::barrier_Id) { PIXBeginNamedEvent(0,"3D gui item render %d\n",itemId); diff --git a/Minecraft.Client/LevelRenderer.cpp b/Minecraft.Client/LevelRenderer.cpp index 7ea382a2..2bb48002 100644 --- a/Minecraft.Client/LevelRenderer.cpp +++ b/Minecraft.Client/LevelRenderer.cpp @@ -66,6 +66,7 @@ #include "FrustumCuller.h" #include "../Minecraft.World/BasicTypeContainers.h" #include "Common/UI/UIScene_SettingsGraphicsMenu.h" +#include "ParticleUtils.h" #include //#define DISABLE_SPU_CODE @@ -166,9 +167,11 @@ LevelRenderer::LevelRenderer(Minecraft *mc, Textures *textures) visibleLists_layer0 = nullptr; visibleLists_layer1 = nullptr; visibleLists_layer2 = nullptr; + visibleLists_layer3 = nullptr; visibleCount_layer0 = 0; visibleCount_layer1 = 0; visibleCount_layer2 = 0; + visibleCount_layer3 = 0; this->mc = mc; this->textures = textures; @@ -473,9 +476,11 @@ void LevelRenderer::allChanged(int playerIndex) delete[] visibleLists_layer0; delete[] visibleLists_layer1; delete[] visibleLists_layer2; + delete[] visibleLists_layer3; visibleLists_layer0 = nullptr; visibleLists_layer1 = nullptr; visibleLists_layer2 = nullptr; + visibleLists_layer3 = nullptr; chunks[playerIndex] = ClipChunkArray(xChunks * yChunks * zChunks); // sortedChunks[playerIndex] = new vector(xChunks * yChunks * zChunks); // 4J - removed - not sorting our chunks anymore @@ -514,9 +519,11 @@ void LevelRenderer::allChanged(int playerIndex) visibleLists_layer0 = new int[totalChunkCount]; visibleLists_layer1 = new int[totalChunkCount]; visibleLists_layer2 = new int[totalChunkCount]; + visibleLists_layer3 = new int[totalChunkCount]; visibleCount_layer0 = 0; visibleCount_layer1 = 0; visibleCount_layer2 = 0; + visibleCount_layer3 = 0; if (level != nullptr) { @@ -810,6 +817,11 @@ void LevelRenderer::renderChunksDirect(int layer, double alpha) lists = visibleLists_layer1; numVisible = visibleCount_layer1; } + else if (layer == 3) + { + lists = visibleLists_layer3; + numVisible = visibleCount_layer3; + } bool first = true; if (lists != nullptr) { @@ -909,6 +921,11 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) lists = visibleLists_layer1; numVisible = visibleCount_layer1; } + else if (layer == 3) + { + lists = visibleLists_layer3; + numVisible = visibleCount_layer3; + } if (lists != nullptr) { for (int i = 0; i < numVisible; i++) @@ -2684,6 +2701,7 @@ void LevelRenderer::cull(Culler *culler, float a) visibleCount_layer0 = 0; visibleCount_layer1 = 0; visibleCount_layer2 = 0; + visibleCount_layer3 = 0; // Column-level frustum culling: test one AABB per XZ column before testing individual Y chunks. // At dist 64 this reduces ~278K clip() calls to ~17K column tests + per-chunk tests only for visible columns. @@ -2743,6 +2761,7 @@ void LevelRenderer::cull(Culler *culler, float a) if (!((flags & CHUNK_FLAG_EMPTY1) == CHUNK_FLAG_EMPTY1)) visibleLists_layer1[visibleCount_layer1++] = list + 1; visibleLists_layer2[visibleCount_layer2++] = list + 2; + visibleLists_layer3[visibleCount_layer3++] = list + 3; } } } @@ -2821,9 +2840,9 @@ else if (name== L"footstep") mc->particleEngine->add(shared_ptrparticleEngine->add(shared_ptr( new SplashParticle(level[playerIndex], x, y, z, xa, ya, za) ) ); else if (name== L"largesmoke") mc->particleEngine->add(shared_ptr( new SmokeParticle(level[playerIndex], x, y, z, xa, ya, za, 2.5f) ) ); else if (name== L"reddust") mc->particleEngine->add(shared_ptr( new RedDustParticle(level[playerIndex], x, y, z, (float) xa, (float) ya, (float) za) ) ); -else if (name== L"snowballpoof") mc->particleEngine->add(shared_ptr( new BreakingItemParticle(level[playerIndex], x, y, z, Item::snowBall) ) ); +else if (name== L"snowballpoof") mc->particleEngine->add(shared_ptr( new BreakingItemParticle(level[playerIndex], x, y, z, Item::snowball) ) ); else if (name== L"snowshovel") mc->particleEngine->add(shared_ptr( new SnowShovelParticle(level[playerIndex], x, y, z, xa, ya, za) ) ); -else if (name== L"slime") mc->particleEngine->add(shared_ptr( new BreakingItemParticle(level[playerIndex], x, y, z, Item::slimeBall)) ) ; +else if (name== L"slime") mc->particleEngine->add(shared_ptr( new BreakingItemParticle(level[playerIndex], x, y, z, Item::slime_ball)) ) ; else if (name== L"heart") mc->particleEngine->add(shared_ptr( new HeartParticle(level[playerIndex], x, y, z, xa, ya, za) ) ); } */ @@ -2835,7 +2854,7 @@ void LevelRenderer::addParticle(ePARTICLE_TYPE eParticleType, double x, double y shared_ptr LevelRenderer::addParticleInternal(ePARTICLE_TYPE eParticleType, double x, double y, double z, double xa, double ya, double za) { - if (mc == nullptr || mc->cameraTargetPlayer == nullptr || mc->particleEngine == nullptr) + if (mc == nullptr || mc->cameraTargetPlayer == nullptr || mc->particleEngine == nullptr || mc->options == nullptr) { return nullptr; } @@ -2845,18 +2864,46 @@ shared_ptr LevelRenderer::addParticleInternal(ePARTICLE_TYPE eParticle if( Double::isNaN(x) ) return nullptr; if( Double::isNaN(y) ) return nullptr; if( Double::isNaN(z) ) return nullptr; + if( Double::isNaN(xa) ) return nullptr; + if( Double::isNaN(ya) ) return nullptr; + if( Double::isNaN(za) ) return nullptr; int particleLevel = mc->options->particles; - Level *lev; - int playerIndex = mc->player->GetXboxPad(); // 4J added - lev = level[playerIndex]; + Level *lev = nullptr; + int playerIndex = -1; - if (particleLevel == 1) + shared_ptr sourcePlayer = mc->player; + if (sourcePlayer == nullptr && mc->cameraTargetPlayer != nullptr) + { + sourcePlayer = dynamic_pointer_cast(mc->cameraTargetPlayer); + } + if (sourcePlayer != nullptr) + { + playerIndex = sourcePlayer->GetXboxPad(); + if (playerIndex >= 0 && playerIndex < XUSER_MAX_COUNT && isReasonableLevelPointer(level[playerIndex]) && level[playerIndex]->dimension != nullptr) + { + lev = level[playerIndex]; + } + } + + if (lev == nullptr) + { + for (unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) + { + if (mc->localplayers[i] != nullptr && isReasonableLevelPointer(mc->localplayers[i]->level) && mc->localplayers[i]->level->dimension != nullptr) + { + lev = mc->localplayers[i]->level; + break; + } + } + } + + if (particleLevel == 1 && lev != nullptr) { // when playing at "decreased" particle level, randomly filter // particles by setting the level to "minimal" - if (level[playerIndex]->random->nextInt(3) == 0) + if (lev->random->nextInt(3) == 0) { particleLevel = 2; } @@ -2903,6 +2950,42 @@ shared_ptr LevelRenderer::addParticleInternal(ePARTICLE_TYPE eParticle lev = mc->animateTickLevel; } + if (lev == nullptr) + return nullptr; + + if (!isReasonableLevelPointer(lev) || !isReasonableDimensionPointer(lev->dimension)) + return nullptr; + + bool levIsKnown = false; + if (lev == mc->level || lev == mc->animateTickLevel) + { + levIsKnown = true; + } + else + { + for (unsigned int i = 0; i < XUSER_MAX_COUNT && !levIsKnown; ++i) + { + if (mc->localplayers[i] != nullptr && mc->localplayers[i]->level == lev && isReasonableLevelPointer(mc->localplayers[i]->level) && mc->localplayers[i]->level->dimension != nullptr) + { + levIsKnown = true; + } + } + for (int i = 0; i < 4 && !levIsKnown; ++i) + { + if (this->level[i] == lev && isReasonableLevelPointer(this->level[i]) && this->level[i]->dimension != nullptr) + { + levIsKnown = true; + } + } + } + if (!levIsKnown) + { + return nullptr; + } + + if (lev->dimension == nullptr) + return nullptr; + if (particleLevel > 1) { // TODO: If any of the particles below are necessary even if @@ -3048,7 +3131,7 @@ shared_ptr LevelRenderer::addParticleInternal(ePARTICLE_TYPE eParticle particle = std::make_shared(lev, x, y, z, static_cast(xa), static_cast(ya), static_cast(za)); break; case eParticleType_snowballpoof: - particle = std::make_shared(lev, x, y, z, Item::snowBall, textures); + particle = std::make_shared(lev, x, y, z, Item::snowball, textures); break; case eParticleType_dripWater: particle = std::make_shared(lev, x, y, z, Material::water); @@ -3060,7 +3143,7 @@ shared_ptr LevelRenderer::addParticleInternal(ePARTICLE_TYPE eParticle particle = std::make_shared(lev, x, y, z, xa, ya, za); break; case eParticleType_slime: - particle = std::make_shared(lev, x, y, z, Item::slimeBall, textures); + particle = std::make_shared(lev, x, y, z, Item::slime_ball, textures); break; case eParticleType_heart: particle = std::make_shared(lev, x, y, z, xa, ya, za); @@ -3341,7 +3424,7 @@ void LevelRenderer::levelEvent(shared_ptr source, int type, int x, int y double yp = y; double zp = z + 0.5; - ePARTICLE_TYPE particle = PARTICLE_ICONCRACK(Item::eyeOfEnder->id,0); + ePARTICLE_TYPE particle = PARTICLE_ICONCRACK(Item::eye_of_ender->id,0); for (int i = 0; i < 8; i++) { addParticle(particle, xp, yp, zp, random->nextGaussian() * 0.15, random->nextDouble() * 0.2, random->nextGaussian() * .15); @@ -4018,7 +4101,7 @@ int LevelRenderer::checkAllPresentChunks(bool *faultFound) for( int cz = 4; cz <= 12; cz++ ) { int t0 = levelChunk->getTile(cx, 0, cz); - if( ( t0 != Tile::unbreakable_Id ) && (t0 != Tile::dirt_Id) ) + if( ( t0 != Tile::bedrock_Id ) && (t0 != Tile::dirt_Id) ) { *faultFound = true; } diff --git a/Minecraft.Client/LevelRenderer.h b/Minecraft.Client/LevelRenderer.h index 4ba0f6d7..43f35302 100644 --- a/Minecraft.Client/LevelRenderer.h +++ b/Minecraft.Client/LevelRenderer.h @@ -49,7 +49,7 @@ public: void doBarrierParticles(int posX, int posY, int posZ); static const int CHUNK_XZSIZE = 16; - static const int CHUNK_RENDER_LAYERS = 3; + static const int CHUNK_RENDER_LAYERS = 4; #ifdef _LARGE_WORLDS static const int CHUNK_SIZE = 16; #else @@ -286,9 +286,11 @@ public: int *visibleLists_layer0; int *visibleLists_layer1; int *visibleLists_layer2; + int *visibleLists_layer3; int visibleCount_layer0; int visibleCount_layer1; int visibleCount_layer2; + int visibleCount_layer3; bool dirtyChunkPresent; int64_t lastDirtyChunkFound; diff --git a/Minecraft.Client/LivingEntityRenderer.cpp b/Minecraft.Client/LivingEntityRenderer.cpp index 67e78c7e..dc57af19 100644 --- a/Minecraft.Client/LivingEntityRenderer.cpp +++ b/Minecraft.Client/LivingEntityRenderer.cpp @@ -200,6 +200,7 @@ void LivingEntityRenderer::render(shared_ptr _mob, double x, double y, d { glColor4f(br, 0, 0, 0.4f); resModel->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, fScale, false); + /* removed in TU24 - Fireblade for (int i = 0; i < MAX_ARMOR_LAYERS; i++) { if (prepareArmorOverlay(mob, i, a) >= 0) @@ -208,6 +209,7 @@ void LivingEntityRenderer::render(shared_ptr _mob, double x, double y, d armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, fScale, false); } } + */ } if (((overlayColor >> 24) & 0xff) > 0) diff --git a/Minecraft.Client/LocalPlayer.cpp b/Minecraft.Client/LocalPlayer.cpp index 91ed1ec2..a3ce657e 100644 --- a/Minecraft.Client/LocalPlayer.cpp +++ b/Minecraft.Client/LocalPlayer.cpp @@ -752,11 +752,11 @@ bool LocalPlayer::openFurnace(shared_ptr furnace) return success; } -bool LocalPlayer::openBrewingStand(shared_ptr brewingStand) +bool LocalPlayer::openBrewingStand(shared_ptr brewing_stand) { - bool success = app.LoadBrewingStandMenu(GetXboxPad(),inventory, brewingStand); + bool success = app.LoadBrewingStandMenu(GetXboxPad(),inventory, brewing_stand); if( success ) ui.PlayUISFX(eSFX_Press); - //minecraft.setScreen(new BrewingStandScreen(inventory, brewingStand)); + //minecraft.setScreen(new BrewingStandScreen(inventory, brewing_stand)); return success; } @@ -978,26 +978,26 @@ void LocalPlayer::awardStat(Stat *stat, byteArray param) // MOAR TOOLS { Stat *toolStats[4][5]; - toolStats[0][0] = GenericStats::itemsCrafted(Item::shovel_wood->id); - toolStats[0][1] = GenericStats::itemsCrafted(Item::shovel_stone->id); - toolStats[0][2] = GenericStats::itemsCrafted(Item::shovel_iron->id); - toolStats[0][3] = GenericStats::itemsCrafted(Item::shovel_diamond->id); - toolStats[0][4] = GenericStats::itemsCrafted(Item::shovel_gold->id); - toolStats[1][0] = GenericStats::itemsCrafted(Item::pickAxe_wood->id); - toolStats[1][1] = GenericStats::itemsCrafted(Item::pickAxe_stone->id); - toolStats[1][2] = GenericStats::itemsCrafted(Item::pickAxe_iron->id); - toolStats[1][3] = GenericStats::itemsCrafted(Item::pickAxe_diamond->id); - toolStats[1][4] = GenericStats::itemsCrafted(Item::pickAxe_gold->id); - toolStats[2][0] = GenericStats::itemsCrafted(Item::hatchet_wood->id); - toolStats[2][1] = GenericStats::itemsCrafted(Item::hatchet_stone->id); - toolStats[2][2] = GenericStats::itemsCrafted(Item::hatchet_iron->id); - toolStats[2][3] = GenericStats::itemsCrafted(Item::hatchet_diamond->id); - toolStats[2][4] = GenericStats::itemsCrafted(Item::hatchet_gold->id); - toolStats[3][0] = GenericStats::itemsCrafted(Item::hoe_wood->id); - toolStats[3][1] = GenericStats::itemsCrafted(Item::hoe_stone->id); - toolStats[3][2] = GenericStats::itemsCrafted(Item::hoe_iron->id); - toolStats[3][3] = GenericStats::itemsCrafted(Item::hoe_diamond->id); - toolStats[3][4] = GenericStats::itemsCrafted(Item::hoe_gold->id); + toolStats[0][0] = GenericStats::itemsCrafted(Item::wooden_shovel->id); + toolStats[0][1] = GenericStats::itemsCrafted(Item::stone_shovel->id); + toolStats[0][2] = GenericStats::itemsCrafted(Item::iron_shovel->id); + toolStats[0][3] = GenericStats::itemsCrafted(Item::diamond_shovel->id); + toolStats[0][4] = GenericStats::itemsCrafted(Item::golden_shovel->id); + toolStats[1][0] = GenericStats::itemsCrafted(Item::wooden_pickaxe->id); + toolStats[1][1] = GenericStats::itemsCrafted(Item::stone_pickaxe->id); + toolStats[1][2] = GenericStats::itemsCrafted(Item::iron_pickaxe->id); + toolStats[1][3] = GenericStats::itemsCrafted(Item::diamond_pickaxe->id); + toolStats[1][4] = GenericStats::itemsCrafted(Item::golden_pickaxe->id); + toolStats[2][0] = GenericStats::itemsCrafted(Item::wooden_axe->id); + toolStats[2][1] = GenericStats::itemsCrafted(Item::stone_axe->id); + toolStats[2][2] = GenericStats::itemsCrafted(Item::iron_axe->id); + toolStats[2][3] = GenericStats::itemsCrafted(Item::diamond_axe->id); + toolStats[2][4] = GenericStats::itemsCrafted(Item::golden_axe->id); + toolStats[3][0] = GenericStats::itemsCrafted(Item::wooden_hoe->id); + toolStats[3][1] = GenericStats::itemsCrafted(Item::stone_hoe->id); + toolStats[3][2] = GenericStats::itemsCrafted(Item::iron_hoe->id); + toolStats[3][3] = GenericStats::itemsCrafted(Item::diamond_hoe->id); + toolStats[3][4] = GenericStats::itemsCrafted(Item::golden_hoe->id); bool justCraftedTool = false; for (int i=0; i<4; i++) @@ -1063,8 +1063,8 @@ void LocalPlayer::awardStat(Stat *stat, byteArray param) // AWARD : Porkchop, cook and eat a porkchop. { Stat *cookPorkchop, *eatPorkchop; - cookPorkchop = GenericStats::itemsSmelted(Item::porkChop_cooked_Id); - eatPorkchop = GenericStats::itemsUsed(Item::porkChop_cooked_Id); + cookPorkchop = GenericStats::itemsSmelted(Item::cooked_porkchop_Id); + eatPorkchop = GenericStats::itemsUsed(Item::cooked_porkchop_Id); if ( stat == cookPorkchop || stat == eatPorkchop ) { @@ -1111,7 +1111,7 @@ void LocalPlayer::awardStat(Stat *stat, byteArray param) // AWARD : The Haggler, Acquire 30 emeralds. { Stat *emeraldMined, *emeraldBought; - emeraldMined = GenericStats::blocksMined(Tile::emeraldOre_Id); + emeraldMined = GenericStats::blocksMined(Tile::emerald_ore_Id); emeraldBought = GenericStats::itemsBought(Item::emerald_Id); if ( stat == emeraldMined || stat == emeraldBought ) @@ -1134,8 +1134,8 @@ void LocalPlayer::awardStat(Stat *stat, byteArray param) // AWARD : Pot Planter, craft and place a flowerpot. { Stat *craftFlowerpot, *placeFlowerpot; - craftFlowerpot = GenericStats::itemsCrafted(Item::flowerPot_Id); - placeFlowerpot = GenericStats::blocksPlaced(Tile::flowerPot_Id); + craftFlowerpot = GenericStats::itemsCrafted(Item::flower_pot_Id); + placeFlowerpot = GenericStats::blocksPlaced(Tile::flower_pot_Id); if ( stat == craftFlowerpot || stat == placeFlowerpot ) { @@ -1149,9 +1149,9 @@ void LocalPlayer::awardStat(Stat *stat, byteArray param) // AWARD : It's a Sign, craft and place a sign. { Stat *craftSign, *placeWallsign, *placeSignpost; - craftSign = GenericStats::itemsCrafted(Item::sign_Id); - placeWallsign = GenericStats::blocksPlaced(Tile::wallSign_Id); - placeSignpost = GenericStats::blocksPlaced(Tile::sign_Id); + craftSign = GenericStats::itemsCrafted(Item::standing_sign_Id); + placeWallsign = GenericStats::blocksPlaced(Tile::wall_standing_sign_Id); + placeSignpost = GenericStats::blocksPlaced(Tile::standing_sign_Id); if ( stat == craftSign || stat == placeWallsign || stat == placeSignpost ) { @@ -1642,7 +1642,7 @@ bool LocalPlayer::handleMouseClick(int button) { // If I have an empty bucket in my hand, it's going to be filled with milk, so turn off mayUse shared_ptr item = inventory->getSelected(); - if(item && (item->id==Item::bucket_empty_Id)) + if(item && (item->id==Item::bucket_Id)) { mayUse=false; } @@ -1720,7 +1720,7 @@ void LocalPlayer::updateRichPresence() if((m_iPad!=-1)/* && !ui.GetMenuDisplayed(m_iPad)*/ ) { shared_ptr selectedItem = inventory->getSelected(); - if(selectedItem != nullptr && selectedItem->id == Item::fishingRod_Id) + if(selectedItem != nullptr && selectedItem->id == Item::fishing_rod_Id) { app.SetRichPresenceContext(m_iPad,CONTEXT_GAME_STATE_FISHING); } diff --git a/Minecraft.Client/LocalPlayer.h b/Minecraft.Client/LocalPlayer.h index b50dda75..f2d06878 100644 --- a/Minecraft.Client/LocalPlayer.h +++ b/Minecraft.Client/LocalPlayer.h @@ -120,7 +120,7 @@ public: virtual bool startEnchanting(int x, int y, int z, const wstring &name); // 4J added bool return virtual bool startRepairing(int x, int y, int z); virtual bool openFurnace(shared_ptr furnace); // 4J added bool return - virtual bool openBrewingStand(shared_ptr brewingStand); // 4J added bool return + virtual bool openBrewingStand(shared_ptr brewing_stand); // 4J added bool return virtual bool openBeacon(shared_ptr beacon); // 4J added bool return virtual bool openTrap(shared_ptr trap); // 4J added bool return virtual bool openTrading(shared_ptr traderTarget, const wstring &name); diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index 886b96a9..05194bef 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -2575,28 +2575,28 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) switch (itemInstance->getItem()->id) { // food - case Item::potatoBaked_Id: + case Item::baked_potato_Id: case Item::potato_Id: - case Item::pumpkinPie_Id: - case Item::potatoPoisonous_Id: - case Item::carrotGolden_Id: - case Item::carrots_Id: - case Item::mushroomStew_Id: + case Item::pumpkin_pie_Id: + case Item::poisonous_potato_Id: + case Item::golden_carrot_Id: + case Item::carrot_Id: + case Item::mushroom_stew_Id: case Item::apple_Id: case Item::bread_Id: - case Item::porkChop_raw_Id: - case Item::porkChop_cooked_Id: - case Item::apple_gold_Id: - case Item::fish_raw_Id: - case Item::fish_cooked_Id: + case Item::porkchop_Id: + case Item::cooked_porkchop_Id: + case Item::golden_apple_Id: + case Item::fish_Id: + case Item::cooked_fish_Id: case Item::cookie_Id: - case Item::beef_cooked_Id: - case Item::beef_raw_Id: - case Item::chicken_cooked_Id: - case Item::chicken_raw_Id: - case Item::melon_Id: + case Item::cooked_beef_Id: + case Item::beef_Id: + case Item::cooked_chicken_Id: + case Item::chicken_Id: + case Item::melon_block_Id: case Item::rotten_flesh_Id: - case Item::spiderEye_Id: + case Item::spider_eye_Id: // Check that we are actually hungry so will eat this item { FoodItem *food = static_cast(itemInstance->getItem()); @@ -2607,17 +2607,17 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) } break; - case Item::bucket_milk_Id: + case Item::milk_bucket_Id: *piUse=IDS_TOOLTIPS_DRINK; break; - case Item::fishingRod_Id: // use - case Item::emptyMap_Id: + case Item::fishing_rod_Id: // use + case Item::map_Id: *piUse=IDS_TOOLTIPS_USE; break; case Item::egg_Id: // throw - case Item::snowBall_Id: + case Item::snowball_Id: *piUse=IDS_TOOLTIPS_THROW; break; @@ -2629,26 +2629,26 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) } break; - case Item::sword_wood_Id: - case Item::sword_stone_Id: - case Item::sword_iron_Id: - case Item::sword_diamond_Id: - case Item::sword_gold_Id: + case Item::wooden_sword_Id: + case Item::stone_sword_Id: + case Item::iron_sword_Id: + case Item::diamond_sword_Id: + case Item::golden_sword_Id: *piUse=IDS_TOOLTIPS_BLOCK; break; - case Item::bucket_empty_Id: - case Item::glassBottle_Id: + case Item::bucket_Id: + case Item::glass_bottle_Id: if (bUseItem) *piUse=IDS_TOOLTIPS_COLLECT; break; - case Item::bucket_lava_Id: - case Item::bucket_water_Id: + case Item::lava_bucket_Id: + case Item::water_bucket_Id: *piUse=IDS_TOOLTIPS_EMPTY; break; case Item::boat_Id: - case Tile::waterLily_Id: + case Tile::waterlily_Id: if (bUseItem) *piUse=IDS_TOOLTIPS_PLACE; break; @@ -2660,11 +2660,11 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) } break; - case Item::enderPearl_Id: + case Item::ender_pearl_Id: if (bUseItem) *piUse=IDS_TOOLTIPS_THROW; break; - case Item::eyeOfEnder_Id: + case Item::eye_of_ender_Id: // This will only work if there is a stronghold in this dimension if ( bUseItem && (level->dimension->id==0) && level->getLevelData()->getHasStronghold() ) { @@ -2672,35 +2672,35 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) } break; - case Item::expBottle_Id: + case Item::experience_bottle_Id: if (bUseItem) *piUse=IDS_TOOLTIPS_THROW; break; - case Item::writingBook_Id: + case Item::writable_book_Id: *piUse = IDS_TOOLTIPS_OPEN; break; - case Item::writtenBook_Id: + case Item::written_book_Id: *piUse = IDS_TOOLTIPS_READ; break; - case Item::helmet_leather_Id: - case Item::helmet_chain_Id: - case Item::helmet_iron_Id: - case Item::helmet_gold_Id: - case Item::helmet_diamond_Id: - case Item::chestplate_leather_Id: - case Item::chestplate_chain_Id: - case Item::chestplate_iron_Id: - case Item::chestplate_gold_Id: - case Item::chestplate_diamond_Id: - case Item::leggings_leather_Id: - case Item::leggings_chain_Id: - case Item::leggings_iron_Id: - case Item::leggings_gold_Id: - case Item::leggings_diamond_Id: - case Item::boots_leather_Id: - case Item::boots_chain_Id: - case Item::boots_iron_Id: - case Item::boots_gold_Id: - case Item::boots_diamond_Id: + case Item::leather_helmet_Id: + case Item::chainmail_helmet_Id: + case Item::iron_helmet_Id: + case Item::golden_helmet_Id: + case Item::diamond_helmet_Id: + case Item::leather_chestplate_Id: + case Item::chainmail_chestplate_Id: + case Item::iron_chestplate_Id: + case Item::golden_chestplate_Id: + case Item::diamond_chestplate_Id: + case Item::leather_leggings_Id: + case Item::chainmail_leggings_Id: + case Item::iron_leggings_Id: + case Item::golden_leggings_Id: + case Item::diamond_leggings_Id: + case Item::leather_boots_Id: + case Item::chainmail_boots_Id: + case Item::iron_boots_Id: + case Item::golden_boots_Id: + case Item::diamond_boots_Id: *piUse = IDS_TOOLTIPS_EQUIP; break; } @@ -2745,26 +2745,26 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) case Tile::cactus_Id: case Tile::sapling_Id: case Tile::reeds_Id: - case Tile::flower_Id: - case Tile::rose_Id: + case Tile::yellow_flower_Id: + case Tile::red_flower_Id: *piUse=IDS_TOOLTIPS_PLANT; break; // Things to USE - case Item::hoe_wood_Id: - case Item::hoe_stone_Id: - case Item::hoe_iron_Id: - case Item::hoe_diamond_Id: - case Item::hoe_gold_Id: + case Item::wooden_hoe_Id: + case Item::stone_hoe_Id: + case Item::iron_hoe_Id: + case Item::diamond_hoe_Id: + case Item::golden_hoe_Id: *piUse=IDS_TOOLTIPS_TILL; break; - case Item::seeds_wheat_Id: + case Item::wheat_seeds_Id: case Item::netherwart_seeds_Id: *piUse=IDS_TOOLTIPS_PLANT; break; - case Item::dye_powder_Id: + case Item::dye_Id: // bonemeal grows various plants if (itemInstance->getAuxValue() == DyePowderItem::WHITE) { @@ -2775,8 +2775,8 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) case Tile::grass_Id: case Tile::mushroom_brown_Id: case Tile::mushroom_red_Id: - case Tile::melonStem_Id: - case Tile::pumpkinStem_Id: + case Tile::melon_stem_Id: + case Tile::pumpkin_stem_Id: case Tile::carrots_Id: case Tile::potatoes_Id: *piUse=IDS_TOOLTIPS_GROW; @@ -2789,8 +2789,8 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) *piUse=IDS_TOOLTIPS_HANG; break; - case Item::flintAndSteel_Id: - case Item::fireball_Id: + case Item::flint_and_steel_Id: + case Item::fire_charge_Id: *piUse=IDS_TOOLTIPS_IGNITE; break; @@ -2811,18 +2811,18 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) switch(iTileID) { case Tile::anvil_Id: - case Tile::enchantTable_Id: - case Tile::brewingStand_Id: - case Tile::workBench_Id: + case Tile::enchanting_table_Id: + case Tile::brewing_stand_Id: + case Tile::crafting_table_Id: case Tile::furnace_Id: - case Tile::furnace_lit_Id: - case Tile::door_wood_Id: + case Tile::lit_furnace_Id: + case Tile::wooden_door_Id: case Tile::dispenser_Id: case Tile::lever_Id: - case Tile::button_stone_Id: - case Tile::button_wood_Id: + case Tile::stone_button_Id: + case Tile::wooden_button_Id: case Tile::trapdoor_Id: - case Tile::fenceGate_Id: + case Tile::fence_gate_Id: case Tile::beacon_Id: *piAction=IDS_TOOLTIPS_MINE; *piUse=IDS_TOOLTIPS_USE; @@ -2833,7 +2833,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) *piUse = (Tile::chest->getContainer(level,x,y,z) != nullptr) ? IDS_TOOLTIPS_OPEN : -1; break; - case Tile::enderChest_Id: + case Tile::ender_chest_Id: case Tile::chest_trap_Id: case Tile::dropper_Id: case Tile::hopper_Id: @@ -2841,9 +2841,9 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) *piAction=IDS_TOOLTIPS_MINE; break; - case Tile::activatorRail_Id: - case Tile::goldenRail_Id: - case Tile::detectorRail_Id: + case Tile::activator_rail_Id: + case Tile::golden_rail_Id: + case Tile::detector_rail_Id: case Tile::rail_Id: if (bUseItemOn) *piUse=IDS_TOOLTIPS_PLACE; *piAction=IDS_TOOLTIPS_MINE; @@ -2861,7 +2861,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) *piUse=IDS_TOOLTIPS_CHANGEPITCH; break; - case Tile::sign_Id: + case Tile::standing_sign_Id: *piAction=IDS_TOOLTIPS_MINE; break; @@ -2871,7 +2871,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { int iID=itemInstance->getItem()->id; int currentData = level->getData(x, y, z); - if ((iID==Item::glassBottle_Id) && (currentData > 0)) + if ((iID==Item::glass_bottle_Id) && (currentData > 0)) { *piUse=IDS_TOOLTIPS_COLLECT; } @@ -2902,7 +2902,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) if (!bUseItemOn && itemInstance!=nullptr) { int iID=itemInstance->getItem()->id; - if ( (iID>=Item::record_01_Id) && (iID<=Item::record_12_Id) ) + if ( (iID>=Item::record_13_Id) && (iID<=Item::record_wait_Id) ) { *piUse=IDS_TOOLTIPS_PLAY; } @@ -2918,7 +2918,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) } break; - case Tile::flowerPot_Id: + case Tile::flower_pot_Id: if ( !bUseItemOn && (itemInstance != nullptr) && (iData == 0) ) { int iID = itemInstance->getItem()->id; @@ -2926,13 +2926,13 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { switch(iID) { - case Tile::flower_Id: - case Tile::rose_Id: + case Tile::yellow_flower_Id: + case Tile::red_flower_Id: case Tile::sapling_Id: case Tile::mushroom_brown_Id: case Tile::mushroom_red_Id: case Tile::cactus_Id: - case Tile::deadBush_Id: + case Tile::deadbush_Id: *piUse=IDS_TOOLTIPS_PLANT; break; @@ -2945,24 +2945,24 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) *piAction=IDS_TOOLTIPS_MINE; break; - case Tile::comparator_off_Id: - case Tile::comparator_on_Id: + case Tile::unpowered_comparator_Id: + case Tile::powered_comparator_Id: *piUse=IDS_TOOLTIPS_USE; *piAction=IDS_TOOLTIPS_MINE; break; - case Tile::diode_off_Id: - case Tile::diode_on_Id: + case Tile::unpowered_repeater_Id: + case Tile::powered_repeater_Id: *piUse=IDS_TOOLTIPS_USE; *piAction=IDS_TOOLTIPS_MINE; break; - case Tile::redStoneOre_Id: + case Tile::redstone_ore_Id: if (bUseItemOn) *piUse=IDS_TOOLTIPS_USE; *piAction=IDS_TOOLTIPS_MINE; break; - case Tile::door_iron_Id: + case Tile::iron_door_Id: if(*piUse==IDS_TOOLTIPS_PLACE) { *piUse = -1; @@ -3009,7 +3009,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) switch(heldItemId) { - case Item::nameTag_Id: + case Item::name_tag_Id: *piUse=IDS_TOOLTIPS_NAME; break; @@ -3046,13 +3046,13 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) switch (heldItemId) { // Things to USE - case Item::nameTag_Id: + case Item::name_tag_Id: *piUse=IDS_TOOLTIPS_NAME; break; case Item::lead_Id: if (!animal->isLeashed()) *piUse=IDS_TOOLTIPS_LEASH; break; - case Item::bucket_empty_Id: + case Item::bucket_Id: *piUse=IDS_TOOLTIPS_MILK; break; default: @@ -3085,7 +3085,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) switch(heldItemId) { // Things to USE - case Item::nameTag_Id: + case Item::name_tag_Id: *piUse=IDS_TOOLTIPS_NAME; break; @@ -3094,7 +3094,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) break; case Item::bowl_Id: - case Item::bucket_empty_Id: // You can milk a mooshroom with either a bowl (mushroom soup) or a bucket (milk)! + case Item::bucket_Id: // You can milk a mooshroom with either a bowl (mushroom soup) or a bucket (milk)! *piUse=IDS_TOOLTIPS_MILK; break; case Item::shears_Id: @@ -3160,7 +3160,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) switch(heldItemId) { - case Item::nameTag_Id: + case Item::name_tag_Id: *piUse=IDS_TOOLTIPS_NAME; break; @@ -3168,7 +3168,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) if (!sheep->isLeashed()) *piUse=IDS_TOOLTIPS_LEASH; break; - case Item::dye_powder_Id: + case Item::dye_Id: { // convert to tile-based color value (0 is white instead of black) int newColor = ColoredTile::getTileDataForItemAuxValue(heldItem->getAuxValue()); @@ -3220,7 +3220,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { if (!pig->isLeashed()) *piUse=IDS_TOOLTIPS_LEASH; } - else if (heldItemId == Item::nameTag_Id) + else if (heldItemId == Item::name_tag_Id) { *piUse = IDS_TOOLTIPS_NAME; }*/ @@ -3267,7 +3267,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) switch(heldItemId) { - case Item::nameTag_Id: + case Item::name_tag_Id: *piUse=IDS_TOOLTIPS_NAME; break; @@ -3293,10 +3293,10 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) } break; - case Item::enderPearl_Id: + case Item::ender_pearl_Id: // Use is throw, so don't change the tips for the wolf break; - case Item::dye_powder_Id: + case Item::dye_Id: if (wolf->isTame()) { if (ColoredTile::getTileDataForItemAuxValue(heldItem->getAuxValue()) != wolf->getCollarColor()) @@ -3363,7 +3363,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { if (!ocelot->isLeashed()) *piUse = IDS_TOOLTIPS_LEASH; } - else if (heldItemId == Item::nameTag_Id) + else if (heldItemId == Item::name_tag_Id) { *piUse = IDS_TOOLTIPS_NAME; } @@ -3458,10 +3458,10 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) case eTYPE_ZOMBIE: { shared_ptr zomb = dynamic_pointer_cast(hitResult->entity); - static GoldenAppleItem *goldapple = static_cast(Item::apple_gold); + static GoldenAppleItem *goldapple = static_cast(Item::golden_apple); //zomb->hasEffect(MobEffect::weakness) - not present on client. - if ( zomb->isVillager() && zomb->isWeakened() && (heldItemId == Item::apple_gold_Id) && !goldapple->isFoil(heldItem) ) + if ( zomb->isVillager() && zomb->isWeakened() && (heldItemId == Item::golden_apple_Id) && !goldapple->isFoil(heldItem) ) { *piUse=IDS_TOOLTIPS_CURE; } @@ -3480,18 +3480,18 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) case Item::wheat_Id: case Item::sugar_Id: case Item::bread_Id: - case Tile::hayBlock_Id: + case Tile::hay_block_Id: case Item::apple_Id: heldItemIsFood = true; break; - case Item::carrotGolden_Id: - case Item::apple_gold_Id: + case Item::golden_carrot_Id: + case Item::golden_apple_Id: heldItemIsLove = true; heldItemIsFood = true; break; - case Item::horseArmorDiamond_Id: - case Item::horseArmorGold_Id: - case Item::horseArmorMetal_Id: + case Item::diamond_horse_armor_Id: + case Item::golden_horse_armor_Id: + case Item::iron_horse_armor_Id: heldItemIsArmour = true; break; } @@ -3504,7 +3504,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { if (!horse->isLeashed()) *piUse=IDS_TOOLTIPS_LEASH; } - else if (heldItemId == Item::nameTag_Id) + else if (heldItemId == Item::name_tag_Id) { *piUse = IDS_TOOLTIPS_NAME; } @@ -3594,7 +3594,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { if (!mob->isLeashed()) *piUse=IDS_TOOLTIPS_LEASH; } - else if (heldItemId == Item::nameTag_Id) + else if (heldItemId == Item::name_tag_Id) { *piUse=IDS_TOOLTIPS_NAME; } @@ -3919,7 +3919,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) app.LoadCreativeMenu(iPad,player); } // 4J-PB - Microsoft request that we use the 3x3 crafting if someone presses X while at the workbench - else if ((hitResult!=nullptr) && (hitResult->type == HitResult::TILE) && (level->getTile(hitResult->x, hitResult->y, hitResult->z) == Tile::workBench_Id)) + else if ((hitResult!=nullptr) && (hitResult->type == HitResult::TILE) && (level->getTile(hitResult->x, hitResult->y, hitResult->z) == Tile::crafting_table_Id)) { //ui.PlayUISFX(eSFX_Press); //app.LoadXuiCrafting3x3Menu(iPad,player,hitResult->x, hitResult->y, hitResult->z); diff --git a/Minecraft.Client/MultiPlayerChunkCache.cpp b/Minecraft.Client/MultiPlayerChunkCache.cpp index 302ff119..19792432 100644 --- a/Minecraft.Client/MultiPlayerChunkCache.cpp +++ b/Minecraft.Client/MultiPlayerChunkCache.cpp @@ -47,7 +47,7 @@ MultiPlayerChunkCache::MultiPlayerChunkCache(Level *level) { unsigned char tileId = 0; if( y <= ( level->getSeaLevel() - 10 ) ) tileId = Tile::stone_Id; - else if( y < level->getSeaLevel() ) tileId = Tile::calmWater_Id; + else if( y < level->getSeaLevel() ) tileId = Tile::water_Id; bytes[x << 11 | z << 7 | y] = tileId; } diff --git a/Minecraft.Client/MultiPlayerLevel.cpp b/Minecraft.Client/MultiPlayerLevel.cpp index 49fa51f7..709756be 100644 --- a/Minecraft.Client/MultiPlayerLevel.cpp +++ b/Minecraft.Client/MultiPlayerLevel.cpp @@ -589,11 +589,11 @@ bool MultiPlayerLevel::doSetTileAndData(int x, int y, int z, int tile, int data) // water changing from static to dynamic for instance. Note that this is only called from a client connection, // and so the thing being notified of any update through tileUpdated is the renderer int prevTile = getTile(x, y, z); - bool visuallyImportant = (!( ( ( prevTile == Tile::water_Id ) && ( tile == Tile::calmWater_Id ) ) || - ( ( prevTile == Tile::calmWater_Id ) && ( tile == Tile::water_Id ) ) || - ( ( prevTile == Tile::lava_Id ) && ( tile == Tile::calmLava_Id ) ) || - ( ( prevTile == Tile::calmLava_Id ) && ( tile == Tile::calmLava_Id ) ) || - ( ( prevTile == Tile::calmLava_Id ) && ( tile == Tile::lava_Id ) ) ) ); + bool visuallyImportant = (!( ( ( prevTile == Tile::flowing_water_Id ) && ( tile == Tile::water_Id ) ) || + ( ( prevTile == Tile::water_Id ) && ( tile == Tile::flowing_water_Id ) ) || + ( ( prevTile == Tile::flowing_lava_Id ) && ( tile == Tile::lava_Id ) ) || + ( ( prevTile == Tile::lava_Id ) && ( tile == Tile::lava_Id ) ) || + ( ( prevTile == Tile::lava_Id ) && ( tile == Tile::flowing_lava_Id ) ) ) ); // If we're the host, need to tell the renderer for updates even if they don't change things as the host // might have been sharing data and so set it already, but the renderer won't know to update if( (Level::setTileAndData(x, y, z, tile, data, Tile::UPDATE_ALL) || g_NetworkManager.IsHost() ) ) @@ -721,13 +721,15 @@ void MultiPlayerLevel::animateTickDoWork() int y = cy + random->nextInt(8); int z = cz + random->nextInt(8); int t = getTile(x, y, z); + Tile *tile = Tile::tiles[t]; + if (tile == nullptr) return; // tu31 tutorial world fix if (random->nextInt(8) > y && t == 0 && dimension->hasBedrockFog()) // 4J - test for bedrock fog brought forward from 1.2.3 { addParticle(eParticleType_depthsuspend, x + random->nextFloat(), y + random->nextFloat(), z + random->nextFloat(), 0, 0, 0); } else if (t > 0) { - Tile::tiles[t]->animateTick(this, x, y, z, animateRandom); + tile->animateTick(this, x, y, z, animateRandom); } } } diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/BookshelfTile_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/BookshelfTile_SPU.h index 6a320a5f..9d7319e6 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/BookshelfTile_SPU.h +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/BookshelfTile_SPU.h @@ -11,7 +11,7 @@ public: virtual Icon_SPU *getTexture(int face, int data) { if (face == Facing::UP || face == Facing::DOWN) - return TileRef_SPU(wood_Id)->getTexture(face); + return TileRef_SPU(planks_Id)->getTexture(face); return Tile_SPU::getTexture(face, data); } }; \ No newline at end of file diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/ButtonTile_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/ButtonTile_SPU.h index 1009396c..4888ee1a 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/ButtonTile_SPU.h +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/ButtonTile_SPU.h @@ -10,8 +10,8 @@ public: Icon_SPU *getTexture(int face, int data) { - if(id == Tile_SPU::button_wood_Id) - return TileRef_SPU(wood_Id)->getTexture(Facing::UP); + if(id == Tile_SPU::wooden_button_Id) + return TileRef_SPU(planks_Id)->getTexture(Facing::UP); else return TileRef_SPU(rock_Id)->getTexture(Facing::UP); } diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/ChunkRebuildData.cpp b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/ChunkRebuildData.cpp index da45996a..54bbbb7a 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/ChunkRebuildData.cpp +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/ChunkRebuildData.cpp @@ -89,30 +89,30 @@ void ChunkRebuildData::disableUnseenTiles() // Establish whether this tile and its neighbours are all made of rock, dirt, unbreakable tiles, or have already // been determined to meet this criteria themselves and have a tile of 255 set. - if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::unbreakable_Id ) || ( flags & e_flag_NoRender) ) ) continue; + if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::bedrock_Id ) || ( flags & e_flag_NoRender) ) ) continue; tileID = getTile(iX-1, iY, iZ); flags = getFlags(iX-1, iY, iZ); - if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::unbreakable_Id ) || ( flags & e_flag_NoRender) ) ) continue; + if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::bedrock_Id ) || ( flags & e_flag_NoRender) ) ) continue; tileID = getTile(iX+1, iY, iZ); flags = getFlags(iX+1, iY, iZ); - if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::unbreakable_Id ) || ( flags & e_flag_NoRender) ) ) continue; + if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::bedrock_Id ) || ( flags & e_flag_NoRender) ) ) continue; tileID = getTile(iX, iY, iZ-1); flags = getFlags(iX, iY, iZ-1); - if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::unbreakable_Id ) || ( flags & e_flag_NoRender) ) ) continue; + if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::bedrock_Id ) || ( flags & e_flag_NoRender) ) ) continue; tileID = getTile(iX, iY, iZ+1); flags = getFlags(iX, iY, iZ+1); - if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::unbreakable_Id ) || ( flags & e_flag_NoRender) ) ) continue; + if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::bedrock_Id ) || ( flags & e_flag_NoRender) ) ) continue; // Treat the bottom of the world differently - we shouldn't ever be able to look up at this, so consider tiles as invisible // if they are surrounded on sides other than the bottom if( iY > 0 ) { tileID = getTile(iX, iY-1, iZ); flags = getFlags(iX, iY-1, iZ); - if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::unbreakable_Id ) || ( flags & e_flag_NoRender) ) ) continue; + if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::bedrock_Id ) || ( flags & e_flag_NoRender) ) ) continue; } tileID = getTile(iX, iY+1, iZ); flags = getFlags(iX, iY+1, iZ); - if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::unbreakable_Id ) || ( flags & e_flag_NoRender) ) ) continue; + if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::bedrock_Id ) || ( flags & e_flag_NoRender) ) ) continue; // This tile is surrounded. Flag it as not requiring to be rendered by setting its id to 255. setFlag(iX, iY, iZ, e_flag_NoRender); @@ -148,11 +148,11 @@ void ChunkRebuildData::buildMaterials() buildMaterial(Material_SPU::air_Id, Material::air); buildMaterial(Material_SPU::grass_Id, Material::grass); buildMaterial(Material_SPU::dirt_Id, Material::dirt); - buildMaterial(Material_SPU::wood_Id, Material::wood); + buildMaterial(Material_SPU::planks_Id, Material::wood); buildMaterial(Material_SPU::stone_Id, Material::stone); buildMaterial(Material_SPU::metal_Id, Material::metal); - buildMaterial(Material_SPU::water_Id, Material::water); - buildMaterial(Material_SPU::lava_Id, Material::lava); + buildMaterial(Material_SPU::flowing_water_Id, Material::water); + buildMaterial(Material_SPU::flowing_lava_Id, Material::lava); buildMaterial(Material_SPU::leaves_Id, Material::leaves); buildMaterial(Material_SPU::plant_Id, Material::plant); buildMaterial(Material_SPU::replaceable_plant_Id, Material::replaceable_plant); @@ -166,7 +166,7 @@ void ChunkRebuildData::buildMaterials() buildMaterial(Material_SPU::explosive_Id, Material::explosive); buildMaterial(Material_SPU::coral_Id, Material::coral); buildMaterial(Material_SPU::ice_Id, Material::ice); - buildMaterial(Material_SPU::topSnow_Id, Material::topSnow); + buildMaterial(Material_SPU::snow_layer_Id, Material::topSnow); buildMaterial(Material_SPU::snow_Id, Material::snow); buildMaterial(Material_SPU::cactus_Id, Material::cactus); buildMaterial(Material_SPU::clay_Id, Material::clay); @@ -186,11 +186,11 @@ int ChunkRebuildData::getMaterialID(Tile* pTile) if(m == Material::air) return Material_SPU::air_Id; if(m == Material::grass) return Material_SPU::grass_Id; if(m == Material::dirt) return Material_SPU::dirt_Id; - if(m == Material::wood) return Material_SPU::wood_Id; + if(m == Material::wood) return Material_SPU::planks_Id; if(m == Material::stone) return Material_SPU::stone_Id; if(m == Material::metal) return Material_SPU::metal_Id; - if(m == Material::water) return Material_SPU::water_Id; - if(m == Material::lava) return Material_SPU::lava_Id; + if(m == Material::water) return Material_SPU::flowing_water_Id; + if(m == Material::lava) return Material_SPU::flowing_lava_Id; if(m == Material::leaves) return Material_SPU::leaves_Id; if(m == Material::plant) return Material_SPU::plant_Id; if(m == Material::replaceable_plant)return Material_SPU::replaceable_plant_Id; @@ -204,7 +204,7 @@ int ChunkRebuildData::getMaterialID(Tile* pTile) if(m == Material::explosive) return Material_SPU::explosive_Id; if(m == Material::coral) return Material_SPU::coral_Id; if(m == Material::ice) return Material_SPU::ice_Id; - if(m == Material::topSnow) return Material_SPU::topSnow_Id; + if(m == Material::topSnow) return Material_SPU::snow_layer_Id; if(m == Material::snow) return Material_SPU::snow_Id; if(m == Material::cactus) return Material_SPU::cactus_Id; if(m == Material::clay) return Material_SPU::clay_Id; @@ -269,8 +269,8 @@ void ChunkRebuildData::createTileData() setIconSPUFromIcon(&m_tileData.grass_iconSideOverlay, Tile::grass->iconSideOverlay); // ThinFence - setIconSPUFromIcon(&m_tileData.ironFence_EdgeTexture, static_cast(Tile::ironFence)->getEdgeTexture()); - setIconSPUFromIcon(&m_tileData.thinGlass_EdgeTexture, static_cast(Tile::thinGlass)->getEdgeTexture()); + setIconSPUFromIcon(&m_tileData.iron_bars_EdgeTexture, static_cast(Tile::iron_bars)->getEdgeTexture()); + setIconSPUFromIcon(&m_tileData.glass_pane_EdgeTexture, static_cast(Tile::glass_pane)->getEdgeTexture()); //FarmTile setIconSPUFromIcon(&m_tileData.farmTile_Dry, static_cast(Tile::farmland)->iconDry); @@ -279,7 +279,7 @@ void ChunkRebuildData::createTileData() // DoorTile for(int i=0;i<8; i++) { - setIconSPUFromIcon(&m_tileData.doorTile_Icons[i], static_cast(Tile::door_wood)->icons[i]); + setIconSPUFromIcon(&m_tileData.doorTile_Icons[i], static_cast(Tile::wooden_door)->icons[i]); // we're not supporting flipped icons, so manually flip here if(i>=4) m_tileData.doorTile_Icons[i].flipHorizontal(); @@ -830,11 +830,11 @@ int ChunkRebuildData::getRawBrightness(int x, int y, int z, bool propagate) int id = getTile(x, y, z); switch(id) { - case Tile_SPU::stoneSlabHalf_Id: - case Tile_SPU::woodSlabHalf_Id: + case Tile_SPU::stone_slab_Id: + case Tile_SPU::wooden_slab_Id: case Tile_SPU::farmland_Id: - case Tile_SPU::stairs_stone_Id: - case Tile_SPU::stairs_wood_Id: + case Tile_SPU::stone_stairs_Id: + case Tile_SPU::oak_stairs_Id: { int br = getRawBrightness(x, y + 1, z, false); int br1 = getRawBrightness(x + 1, y, z, false); diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/DiodeTile_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/DiodeTile_SPU.h index 131bd490..2a3bd43c 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/DiodeTile_SPU.h +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/DiodeTile_SPU.h @@ -19,7 +19,7 @@ public: // down is used by the torch tesselator if (face == Facing::DOWN) { - if (id==diode_on_Id) + if (id==powered_repeater_Id) { return TileRef_SPU(notGate_on_Id)->getTexture(face); } @@ -30,7 +30,7 @@ public: return icon(); } // edge of stone half-step - return TileRef_SPU(stoneSlab_Id)->getTexture(Facing::UP); + return TileRef_SPU(double_stone_slab_Id)->getTexture(Facing::UP); } virtual bool shouldRenderFace(LevelSource *level, int x, int y, int z, int face) { diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FenceGateTile_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FenceGateTile_SPU.h index 5e99cc32..715dceee 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FenceGateTile_SPU.h +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FenceGateTile_SPU.h @@ -9,7 +9,7 @@ private: public: FenceGateTile_SPU(int id) : Tile_SPU(id) {} - Icon_SPU *getTexture(int face, int data) { return TileRef_SPU(wood_Id)->getTexture(face); } + Icon_SPU *getTexture(int face, int data) { return TileRef_SPU(planks_Id)->getTexture(face); } static int getDirection(int data) { return (data & DIRECTION_MASK); } virtual void updateShape(ChunkRebuildData *level, int x, int y, int z, int forceData = -1, TileEntity* forceEntity = nullptr) // 4J added forceData, forceEntity param // Brought forward from 1.2.3 diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FenceTile_SPU.cpp b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FenceTile_SPU.cpp index 63c206d1..1e7b90fc 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FenceTile_SPU.cpp +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FenceTile_SPU.cpp @@ -54,7 +54,7 @@ int FenceTile_SPU::getRenderShape() bool FenceTile_SPU::connectsTo(ChunkRebuildData *level, int x, int y, int z) { int tile = level->getTile(x, y, z); - if (tile == id || tile == Tile_SPU::fenceGate_Id) + if (tile == id || tile == Tile_SPU::fence_gate_Id) { return true; } diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FireTile_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FireTile_SPU.h index 1be5377e..46f2e9ff 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FireTile_SPU.h +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FireTile_SPU.h @@ -20,15 +20,15 @@ public: int id = level->getTile(x, y, z); switch (id) { - case Tile_SPU::wood_Id: - case Tile_SPU::woodSlab_Id: - case Tile_SPU::woodSlabHalf_Id: + case Tile_SPU::planks_Id: + case Tile_SPU::double_wooden_slab_Id: + case Tile_SPU::wooden_slab_Id: case Tile_SPU::fence_Id: - case Tile_SPU::stairs_wood_Id: - case Tile_SPU::stairs_birchwood_Id: - case Tile_SPU::stairs_sprucewood_Id: - case Tile_SPU::stairs_junglewood_Id: - case Tile_SPU::treeTrunk_Id: + case Tile_SPU::oak_stairs_Id: + case Tile_SPU::birch_stairs_Id: + case Tile_SPU::spruce_stairs_Id: + case Tile_SPU::jungle_stairs_Id: + case Tile_SPU::log_Id: case Tile_SPU::leaves_Id: case Tile_SPU::bookshelf_Id: case Tile_SPU::tnt_Id: diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FurnaceTile_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FurnaceTile_SPU.h index 5d677b44..1aeab4ec 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FurnaceTile_SPU.h +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FurnaceTile_SPU.h @@ -14,7 +14,7 @@ public: if (face != data) return icon(); if(id == furnace_Id) return &ms_pTileData->furnaceTile_iconFront; - else //furnace_lit_Id + else //lit_furnace_Id return &ms_pTileData->furnaceTile_iconFront_lit; } }; \ No newline at end of file diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/GrassTile_SPU.cpp b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/GrassTile_SPU.cpp index 833025ad..746682f4 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/GrassTile_SPU.cpp +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/GrassTile_SPU.cpp @@ -21,7 +21,7 @@ Icon_SPU *GrassTile_SPU::getTexture(ChunkRebuildData *level, int x, int y, int z if (face == Facing::UP) return &ms_pTileData->grass_iconTop; if (face == Facing::DOWN) return TileRef_SPU(dirt_Id)->getTexture(face); Material_SPU *above = level->getMaterial(x, y + 1, z); - if (above->getID() == Material_SPU::topSnow_Id || above->getID() == Material_SPU::snow_Id) + if (above->getID() == Material_SPU::snow_layer_Id || above->getID() == Material_SPU::snow_Id) return &ms_pTileData->grass_iconSnowSide; else return icon(); diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/HalfSlabTile_SPU.cpp b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/HalfSlabTile_SPU.cpp index 1dba9757..1cc89162 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/HalfSlabTile_SPU.cpp +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/HalfSlabTile_SPU.cpp @@ -71,7 +71,7 @@ bool HalfSlabTile_SPU::shouldRenderFace(ChunkRebuildData *level, int x, int y, i bool HalfSlabTile_SPU::isHalfSlab(int tileId) { - return tileId == Tile_SPU::stoneSlabHalf_Id || tileId == Tile_SPU::woodSlabHalf_Id; + return tileId == Tile_SPU::stone_slab_Id || tileId == Tile_SPU::wooden_slab_Id; } diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/LiquidTile_SPU.cpp b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/LiquidTile_SPU.cpp index 57b39c4d..a3f4bab6 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/LiquidTile_SPU.cpp +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/LiquidTile_SPU.cpp @@ -24,7 +24,7 @@ int LiquidTile_SPU::getColor(ChunkRebuildData *level, int x, int y, int z) int LiquidTile_SPU::getColor(ChunkRebuildData *level, int x, int y, int z, int d) { // MGH - TODO - if (getMaterial()->getID() == Material_SPU::water_Id) + if (getMaterial()->getID() == Material_SPU::flowing_water_Id) { // Biome b = level.getBiomeSource().getBiome(x, z); // return b.waterColor; @@ -62,16 +62,16 @@ Icon_SPU *LiquidTile_SPU::getTexture(int face, int data) { if (face == Facing::DOWN || face == Facing::UP) { - if(id == water_Id || id == calmWater_Id) + if(id == flowing_water_Id || id == water_Id) return &ms_pTileData->liquidTile_iconWaterStill; - else //(id == lava_Id || id == calmLava_Id) + else //(id == flowing_lava_Id || id == lava_Id) return &ms_pTileData->liquidTile_iconLavaStill; } else { - if(id == water_Id || id == calmWater_Id) + if(id == flowing_water_Id || id == water_Id) return &ms_pTileData->liquidTile_iconWaterFlow; - else //(id == lava_Id || id == calmLava_Id) + else //(id == flowing_lava_Id || id == lava_Id) return &ms_pTileData->liquidTile_iconLavaFlow; } } @@ -201,21 +201,21 @@ float LiquidTile_SPU::getBrightness(ChunkRebuildData *level, int x, int y, int z int LiquidTile_SPU::getRenderLayer() { - return getMaterial()->getID() == Material_SPU::water_Id ? 1 : 0; + return getMaterial()->getID() == Material_SPU::flowing_water_Id ? 1 : 0; } double LiquidTile_SPU::getSlopeAngle(ChunkRebuildData *level, int x, int y, int z, Material_SPU *m) { Vec3_SPU flow = Vec3_SPU(0,0,0); - if (m->getID() == Material_SPU::water_Id) + if (m->getID() == Material_SPU::flowing_water_Id) { - TileRef_SPU tRef(Tile_SPU::water_Id); + TileRef_SPU tRef(Tile_SPU::flowing_water_Id); flow = static_cast(tRef.getPtr())->getFlow(level, x, y, z); } - if (m->getID() == Material_SPU::lava_Id) + if (m->getID() == Material_SPU::flowing_lava_Id) { - TileRef_SPU tRef(Tile_SPU::lava_Id); + TileRef_SPU tRef(Tile_SPU::flowing_lava_Id); flow = static_cast(tRef.getPtr())->getFlow(level, x, y, z); } if (flow.x == 0 && flow.z == 0) return -1000; diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/Material_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/Material_SPU.h index e7cf34b8..180f4cdc 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/Material_SPU.h +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/Material_SPU.h @@ -10,11 +10,11 @@ public: static const int air_Id = 0; static const int grass_Id = 1; static const int dirt_Id = 2; - static const int wood_Id = 3; + static const int planks_Id = 3; static const int stone_Id = 4; static const int metal_Id = 5; - static const int water_Id = 6; - static const int lava_Id = 7; + static const int flowing_water_Id = 6; + static const int flowing_lava_Id = 7; static const int leaves_Id = 8; static const int plant_Id = 9; static const int replaceable_plant_Id = 10; @@ -27,7 +27,7 @@ public: static const int explosive_Id = 17; static const int coral_Id = 18; static const int ice_Id = 19; - static const int topSnow_Id = 20; + static const int snow_layer_Id = 20; static const int snow_Id = 21; static const int cactus_Id = 22; static const int clay_Id = 23; diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/MycelTile_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/MycelTile_SPU.h index 999bdf49..17adaea3 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/MycelTile_SPU.h +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/MycelTile_SPU.h @@ -17,7 +17,7 @@ public: if (face == Facing::UP) return &ms_pTileData->mycelTile_iconTop; if (face == Facing::DOWN) return TileRef_SPU(dirt_Id)->getTexture(face); Material_SPU *above = level->getMaterial(x, y + 1, z); - if (above->getID() == Material_SPU::topSnow_Id || above->getID() == Material_SPU::snow_Id) + if (above->getID() == Material_SPU::snow_layer_Id || above->getID() == Material_SPU::snow_Id) return &ms_pTileData->mycelTile_iconSnowSide; else return icon(); diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/PumpkinTile_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/PumpkinTile_SPU.h index 9e248e23..52ba3163 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/PumpkinTile_SPU.h +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/PumpkinTile_SPU.h @@ -17,7 +17,7 @@ public: if (face == Facing::DOWN) return &ms_pTileData->pumpkinTile_iconTop; Icon_SPU* iconFace = &ms_pTileData->pumpkinTile_iconFace; - if(id == litPumpkin_Id) + if(id == lit_pumpkin_Id) iconFace = &ms_pTileData->pumpkinTile_iconFaceLit; if (data == DIR_NORTH && face == Facing::NORTH) return iconFace; diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/RailTile_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/RailTile_SPU.h index 2f8639d4..279d51cf 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/RailTile_SPU.h +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/RailTile_SPU.h @@ -25,7 +25,7 @@ public: { bool usesDataBit = false; Icon_SPU* iconTurn = &ms_pTileData->railTile_iconTurn; - if(id == goldenRail_Id) + if(id == golden_rail_Id) { usesDataBit = true; iconTurn = &ms_pTileData->railTile_iconTurnGolden; @@ -33,7 +33,7 @@ public: if (usesDataBit) { -// if (id == Tile::goldenRail_Id) +// if (id == Tile::golden_rail_Id) // { if ((data & RAIL_DATA_BIT) == 0) { @@ -51,7 +51,7 @@ public: virtual int getRenderShape() { return Tile_SPU::SHAPE_RAIL; } bool isUsesDataBit() { - if(id == goldenRail_Id || id == detectorRail_Id) + if(id == golden_rail_Id || id == detector_rail_Id) return true; return false; } diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/RedStoneDustTile_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/RedStoneDustTile_SPU.h index 218cbd64..3b1e7006 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/RedStoneDustTile_SPU.h +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/RedStoneDustTile_SPU.h @@ -32,9 +32,9 @@ public: static bool shouldConnectTo(ChunkRebuildData *level, int x, int y, int z, int direction) { int t = level->getTile(x, y, z); - if (t == Tile_SPU::redStoneDust_Id) return true; + if (t == Tile_SPU::redstone_wire_Id) return true; if (t == 0) return false; - if (t == Tile_SPU::diode_off_Id || t == Tile_SPU::diode_on_Id) + if (t == Tile_SPU::unpowered_repeater_Id || t == Tile_SPU::powered_repeater_Id) { int data = level->getData(x, y, z); return direction == (data & DiodeTile_SPU::DIRECTION_MASK) || direction == Direction::DIRECTION_OPPOSITE[data & DiodeTile_SPU::DIRECTION_MASK]; diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/SignTile_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/SignTile_SPU.h index 74bdb95d..101a1f7c 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/SignTile_SPU.h +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/SignTile_SPU.h @@ -9,13 +9,13 @@ public: SignTile_SPU(int id) : EntityTile_SPU(id) {} bool onGround() { - if(id == wallSign_Id) + if(id == wall_standing_sign_Id) return false; - // sign_Id + // standing_sign_Id return true; } - Icon_SPU *getTexture(int face, int data){ return TileRef_SPU(wood_Id)->getTexture(face); } + Icon_SPU *getTexture(int face, int data){ return TileRef_SPU(planks_Id)->getTexture(face); } void updateShape(ChunkRebuildData *level, int x, int y, int z, int forceData = -1, TileEntity* forceEntity = nullptr) // 4J added forceData, forceEntity param { if (onGround()) return; diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/StairTile_SPU.cpp b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/StairTile_SPU.cpp index 5bdbdf4a..deb47953 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/StairTile_SPU.cpp +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/StairTile_SPU.cpp @@ -36,14 +36,14 @@ bool StairTile_SPU::isStairs(int id) { switch(id) { - case Tile_SPU::stairs_wood_Id: - case Tile_SPU::stairs_stone_Id: - case Tile_SPU::stairs_bricks_Id: - case Tile_SPU::stairs_stoneBrickSmooth_Id: - case Tile_SPU::stairs_netherBricks_Id: - case Tile_SPU::stairs_sandstone_Id: - case Tile_SPU::stairs_sprucewood_Id: - case Tile_SPU::stairs_birchwood_Id: + case Tile_SPU::oak_stairs_Id: + case Tile_SPU::stone_stairs_Id: + case Tile_SPU::brick_stairs_Id: + case Tile_SPU::stone_brick_stairsSmooth_Id: + case Tile_SPU::nether_brick_stairs_Id: + case Tile_SPU::sandstone_stairs_Id: + case Tile_SPU::spruce_stairs_Id: + case Tile_SPU::birch_stairs_Id: return true; default: return false; diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/StemTile_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/StemTile_SPU.h index 4923e862..ec86d220 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/StemTile_SPU.h +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/StemTile_SPU.h @@ -45,8 +45,8 @@ public: int getConnectDir(ChunkRebuildData *level, int x, int y, int z) { int fruitID = pumpkin_Id; - if(id == melonStem_Id) - fruitID = melon_Id; + if(id == melon_stem_Id) + fruitID = melon_block_Id; int d = level->getData(x, y, z); if (d < 7) return -1; diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/StoneMonsterTile_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/StoneMonsterTile_SPU.h index 75675eda..141d7547 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/StoneMonsterTile_SPU.h +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/StoneMonsterTile_SPU.h @@ -21,7 +21,7 @@ public: { if (data == HOST_COBBLE) { - return TileRef_SPU(stoneBrick_Id)->getTexture(face); + return TileRef_SPU(stonebrick_Id)->getTexture(face); } if (data == HOST_STONEBRICK) { diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/StoneSlabTile_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/StoneSlabTile_SPU.h index 1c0b2799..f34421b8 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/StoneSlabTile_SPU.h +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/StoneSlabTile_SPU.h @@ -37,19 +37,19 @@ public: return &ms_pTileData->stoneSlab_iconSide; break; case SAND_SLAB: - return TileRef_SPU(sandStone_Id)->getTexture(face); //Tile::sandStone->getTexture(face); + return TileRef_SPU(sandstone_Id)->getTexture(face); //Tile::sandStone->getTexture(face); case WOOD_SLAB: - return TileRef_SPU(wood_Id)->getTexture(face); //Tile::wood->getTexture(face); + return TileRef_SPU(planks_Id)->getTexture(face); //Tile::wood->getTexture(face); case COBBLESTONE_SLAB: - return TileRef_SPU(stoneBrick_Id)->getTexture(face); //Tile::stoneBrick->getTexture(face); + return TileRef_SPU(stonebrick_Id)->getTexture(face); //Tile::stoneBrick->getTexture(face); case BRICK_SLAB: - return TileRef_SPU(redBrick_Id)->getTexture(face); //Tile::redBrick->getTexture(face); + return TileRef_SPU(brick_block_Id)->getTexture(face); //Tile::redBrick->getTexture(face); case SMOOTHBRICK_SLAB: return TileRef_SPU(stoneBrickSmooth_Id)->getTexture(face); //Tile::stoneBrickSmooth->getTexture(face, SmoothStoneBrickTile::TYPE_DEFAULT); case NETHERBRICK_SLAB: - return TileRef_SPU(netherBrick_Id)->getTexture(Facing::UP); //Tile::netherBrick->getTexture(Facing::UP); + return TileRef_SPU(nether_brick_Id)->getTexture(Facing::UP); //Tile::netherBrick->getTexture(Facing::UP); case QUARTZ_SLAB: - return TileRef_SPU(quartzBlock_Id)->getTexture(face); //Tile::quartzBlock->getTexture(face); + return TileRef_SPU(quartz_block_Id)->getTexture(face); //Tile::quartzBlock->getTexture(face); } diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/ThinFenceTile_SPU.cpp b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/ThinFenceTile_SPU.cpp index 9e7d30de..09575957 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/ThinFenceTile_SPU.cpp +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/ThinFenceTile_SPU.cpp @@ -67,10 +67,10 @@ void ThinFenceTile_SPU::updateShape(ChunkRebuildData *level, int x, int y, int z Icon_SPU *ThinFenceTile_SPU::getEdgeTexture() { - if(id == Tile_SPU::ironFence_Id) - return &ms_pTileData->ironFence_EdgeTexture; - if(id == Tile_SPU::thinGlass_Id) - return &ms_pTileData->thinGlass_EdgeTexture; + if(id == Tile_SPU::iron_bars_Id) + return &ms_pTileData->iron_bars_EdgeTexture; + if(id == Tile_SPU::glass_pane_Id) + return &ms_pTileData->glass_pane_EdgeTexture; #ifndef SN_TARGET_PS3_SPU assert(0); #endif diff --git a/Minecraft.Client/Particle.cpp b/Minecraft.Client/Particle.cpp index 80dac72e..4d4b4654 100644 --- a/Minecraft.Client/Particle.cpp +++ b/Minecraft.Client/Particle.cpp @@ -1,10 +1,50 @@ #include "stdafx.h" #include "Particle.h" #include "Tesselator.h" +#include "../Minecraft.Client/Minecraft.h" +#include "../Minecraft.Client/MultiPlayerLevel.h" +#include "../Minecraft.Client/MultiPlayerLocalPlayer.h" +#include "../Minecraft.World/Level.h" +#include "../Minecraft.World/net.minecraft.world.level.dimension.h" #include "../Minecraft.World/Random.h" #include "../Minecraft.World/Mth.h" #include "../Minecraft.World/JavaMath.h" #include "../Minecraft.World/net.minecraft.world.h" +#include "ParticleUtils.h" + +static bool isKnownParticleLevel(Level *lev, Minecraft *mc) +{ + if (lev == nullptr || mc == nullptr) + return false; + + if (lev == mc->level || lev == mc->animateTickLevel || lev == mc->oldLevel) + return true; + + for (unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) + { + if (mc->localplayers[i] != nullptr && mc->localplayers[i]->level == lev) + return true; + } + + return false; +} + +static Level *safeParticleLevel(Level *level) +{ + Minecraft *mc = Minecraft::GetInstance(); + + if (level != nullptr && isReasonableLevelPointer(level) && isKnownParticleLevel(level, mc) && isReasonableDimensionPointer(level->dimension)) + { + return level; + } + + if (mc != nullptr && mc->level != nullptr && isReasonableLevelPointer(mc->level) && isReasonableDimensionPointer(mc->level->dimension)) + { + return static_cast(mc->level); + } + + return nullptr; +} /* protected int tex; @@ -42,15 +82,37 @@ void Particle::_init(Level *level, double x, double y, double z) texY = 0; } -Particle::Particle(Level *level, double x, double y, double z) : Entity(level, false) +Particle::Particle(Level *level, double x, double y, double z) : Entity(nullptr, false) { _init(level,x,y,z); + + Level *safeLevel = safeParticleLevel(level); + if (safeLevel != nullptr && isReasonableDimensionPointer(safeLevel->dimension)) + { + this->level = safeLevel; + dimension = safeLevel->dimension->id; + } + else + { + this->level = nullptr; + } } -Particle::Particle(Level *level, double x, double y, double z, double xa, double ya, double za) : Entity(level, false) +Particle::Particle(Level *level, double x, double y, double z, double xa, double ya, double za) : Entity(nullptr, false) { _init(level,x,y,z); + Level *safeLevel = safeParticleLevel(level); + if (safeLevel != nullptr && isReasonableDimensionPointer(safeLevel->dimension)) + { + this->level = safeLevel; + dimension = safeLevel->dimension->id; + } + else + { + this->level = nullptr; + } + xd = xa + static_cast(Math::random() * 2 - 1) * 0.4f; yd = ya + static_cast(Math::random() * 2 - 1) * 0.4f; zd = za + static_cast(Math::random() * 2 - 1) * 0.4f; diff --git a/Minecraft.Client/ParticleEngine.cpp b/Minecraft.Client/ParticleEngine.cpp index a5385347..a3553624 100644 --- a/Minecraft.Client/ParticleEngine.cpp +++ b/Minecraft.Client/ParticleEngine.cpp @@ -34,8 +34,11 @@ ParticleEngine::~ParticleEngine() void ParticleEngine::add(shared_ptr p) { + if (p == nullptr || p->level == nullptr || p->level->dimension == nullptr) return; + if (p->level != level) return; + int t = p->getParticleTexture(); - int l = p->level->dimension->id == 0 ? 0 : ( p->level->dimension->id == -1 ? 1 : 2); + int l = p->level->dimension->id == 0 ? 0 : ( p->level->dimension->id == -1 ? 1 : 2); int maxParticles; switch(p->GetType()) { @@ -68,6 +71,13 @@ void ParticleEngine::tick() for (unsigned int i = 0; i < particles[l][tt][list].size(); i++) { shared_ptr p = particles[l][tt][list][i]; + if (p == nullptr || p->level == nullptr || p->level != level || p->level->dimension == nullptr) + { + particles[l][tt][list][i] = particles[l][tt][list].back(); + particles[l][tt][list].pop_back(); + i--; + continue; + } p->tick(); if (p->removed) { @@ -87,6 +97,10 @@ void ParticleEngine::render(shared_ptr player, float a, int list) { return; } + if (level == nullptr || level->dimension == nullptr) + { + return; + } // 4J - change brought forward from 1.2.3 float xa = Camera::xa; @@ -194,19 +208,19 @@ void ParticleEngine::setLevel(Level *level) { this->level = level; // 4J - we've now got a set of particle vectors for each dimension, and only clearing them when its game over & the level is set to nullptr - if( level == nullptr ) - { - for( int l = 0; l < 3; l++ ) - { - for (int tt = 0; tt < TEXTURE_COUNT; tt++) - { - for( int list = 0; list < LIST_COUNT; list++ ) - { - particles[l][tt][list].clear(); - } - } - } - } + if (level == nullptr) + { + for (int l = 0; l < 3; l++) + { + for (int tt = 0; tt < TEXTURE_COUNT; tt++) + { + for (int list = 0; list < LIST_COUNT; list++) + { + particles[l][tt][list].clear(); + } + } + } + } } void ParticleEngine::destroy(int x, int y, int z, int tid, int data) diff --git a/Minecraft.Client/ParticleUtils.h b/Minecraft.Client/ParticleUtils.h new file mode 100644 index 00000000..2d97e593 --- /dev/null +++ b/Minecraft.Client/ParticleUtils.h @@ -0,0 +1,29 @@ +#pragma once + +class Level; +class Dimension; + +inline bool isReasonablePointer(const void *ptr) +{ + if (ptr == nullptr) + return false; + + unsigned long long addr = reinterpret_cast(ptr); + if (addr <= 0x10000ULL || addr > 0x00007FFFFFFFFFFFULL) + return false; + if ((addr & 0x7ULL) != 0ULL) + return false; + if ((addr & 0xFFFFFFFFULL) == 0ULL) + return false; + return true; +} + +inline bool isReasonableLevelPointer(Level *lev) +{ + return isReasonablePointer(lev); +} + +inline bool isReasonableDimensionPointer(Dimension *dim) +{ + return isReasonablePointer(dim); +} diff --git a/Minecraft.Client/PistonPieceRenderer.cpp b/Minecraft.Client/PistonPieceRenderer.cpp index 61b63e22..40b140e5 100644 --- a/Minecraft.Client/PistonPieceRenderer.cpp +++ b/Minecraft.Client/PistonPieceRenderer.cpp @@ -54,7 +54,18 @@ void PistonPieceRenderer::render(shared_ptr _entity, double x, doubl } else { - tileRenderer->tesselateInWorldNoCulling(tile, entity->x, entity->y, entity->z, entity->getData(), entity); + if (tile == Tile::slimeBlock) + { + tileRenderer->setFixedTexture(tile->getTexture(0, entity->getData())); + tileRenderer->fixedTextureAlpha = 0.35f; + tileRenderer->tesselateInWorldNoCulling(Tile::glass, entity->x, entity->y, entity->z, entity->getData(), entity); + tileRenderer->fixedTextureAlpha = 1.0f; + tileRenderer->clearFixedTexture(); + } + else + { + tileRenderer->tesselateInWorldNoCulling(tile, entity->x, entity->y, entity->z, entity->getData(), entity); + } } t->offset(0, 0, 0); t->end(); diff --git a/Minecraft.Client/PlayerConnection.cpp b/Minecraft.Client/PlayerConnection.cpp index f6c481a2..327738e1 100644 --- a/Minecraft.Client/PlayerConnection.cpp +++ b/Minecraft.Client/PlayerConnection.cpp @@ -799,7 +799,7 @@ skipUseItemOn: // beside a piston and then performing an action on the side of it facing a piston, the following line of code will send a TileUpdatePacket containing the change to pistonMovingPiece_Id // to the client, and this packet is received before the piston retract action happens - when the piston retract then occurs, it doesn't work properly because the piston tile // isn't what it is expecting. - if( level->getTile(x,y,z) != Tile::pistonMovingPiece_Id ) + if( level->getTile(x,y,z) != Tile::piston_extension_Id ) { player->connection->send(std::make_shared(x, y, z, level)); } @@ -2460,7 +2460,7 @@ void PlayerConnection::handleCustomPayload(shared_ptr custo // make sure the sent item is the currently carried item shared_ptr carried = player->inventory->getSelected(); - if (sentItem != nullptr && sentItem->id == Item::writingBook_Id && sentItem->id == carried->id) + if (sentItem != nullptr && sentItem->id == Item::writable_book_Id && sentItem->id == carried->id) { player->inventory->setItem(player->inventory->selected, sentItem); } @@ -2479,7 +2479,7 @@ void PlayerConnection::handleCustomPayload(shared_ptr custo // make sure the sent item is the currently carried item shared_ptr carried = player->inventory->getSelected(); - if (sentItem != nullptr && sentItem->id == Item::writingBook_Id && sentItem->id == carried->id) + if (sentItem != nullptr && sentItem->id == Item::writable_book_Id && sentItem->id == carried->id) { sentItem->setHoverName(sentItem->tag->getString(L"title")); sentItem->id = 387; @@ -2655,7 +2655,7 @@ void PlayerConnection::handleCraftItem(shared_ptr packet) player->drop(pTempItemInst); } } - else if (pTempItemInst->id == Item::fireworksCharge_Id || pTempItemInst->id == Item::fireworks_Id) + else if (pTempItemInst->id == Item::firework_charge_Id || pTempItemInst->id == Item::fireworks_Id) { CraftingMenu *menu = static_cast(player->containerMenu); player->openFireworks(menu->getX(), menu->getY(), menu->getZ() ); @@ -2745,16 +2745,16 @@ void PlayerConnection::handleCraftItem(shared_ptr packet) // handle achievements switch(pTempItemInst->id) { - case Tile::workBench_Id: player->awardStat(GenericStats::buildWorkbench(), GenericStats::param_buildWorkbench()); break; - case Item::pickAxe_wood_Id: player->awardStat(GenericStats::buildPickaxe(), GenericStats::param_buildPickaxe()); break; + case Tile::crafting_table_Id: player->awardStat(GenericStats::buildWorkbench(), GenericStats::param_buildWorkbench()); break; + case Item::wooden_pickaxe_Id: player->awardStat(GenericStats::buildPickaxe(), GenericStats::param_buildPickaxe()); break; case Tile::furnace_Id: player->awardStat(GenericStats::buildFurnace(), GenericStats::param_buildFurnace()); break; - //case Item::hoe_wood_Id: player->awardStat(GenericStats::buildHoe(), GenericStats::param_buildHoe()); break; + //case Item::wooden_hoe_Id: player->awardStat(GenericStats::buildHoe(), GenericStats::param_buildHoe()); break; case Item::bread_Id: player->awardStat(GenericStats::makeBread(), GenericStats::param_makeBread()); break; case Item::cake_Id: player->awardStat(GenericStats::bakeCake(), GenericStats::param_bakeCake()); break; - case Item::pickAxe_stone_Id: player->awardStat(GenericStats::buildBetterPickaxe(), GenericStats::param_buildBetterPickaxe()); break; - //case Item::sword_wood_Id: player->awardStat(GenericStats::buildSword(), GenericStats::param_buildSword()); break; + case Item::stone_pickaxe_Id: player->awardStat(GenericStats::buildBetterPickaxe(), GenericStats::param_buildBetterPickaxe()); break; + //case Item::wooden_sword_Id: player->awardStat(GenericStats::buildSword(), GenericStats::param_buildSword()); break; case Tile::dispenser_Id: player->awardStat(GenericStats::dispenseWithThis(), GenericStats::param_dispenseWithThis()); break; - case Tile::enchantTable_Id: player->awardStat(GenericStats::enchantments(), GenericStats::param_enchantments()); break; + case Tile::enchanting_table_Id: player->awardStat(GenericStats::enchantments(), GenericStats::param_enchantments()); break; case Tile::bookshelf_Id: player->awardStat(GenericStats::bookcase(), GenericStats::param_bookcase()); break; } switch (pTempItemInst->getItem()->getBaseItemType()) { diff --git a/Minecraft.Client/PlayerList.cpp b/Minecraft.Client/PlayerList.cpp index 04da1990..72ebc66b 100644 --- a/Minecraft.Client/PlayerList.cpp +++ b/Minecraft.Client/PlayerList.cpp @@ -218,7 +218,7 @@ bool PlayerList::placeNewPlayer(Connection *connection, shared_ptr int centreZC = 0; #endif // 4J Added - Give every player a map the first time they join a server - player->inventory->setItem( 9, std::make_shared(Item::emptyMap_Id, 1, level->getAuxValueForMap(player->getXuid(), 0, centreXC, centreZC, mapScale))); + player->inventory->setItem( 9, std::make_shared(Item::map_Id, 1, level->getAuxValueForMap(player->getXuid(), 0, centreXC, centreZC, mapScale))); Random* r = new Random(); player->enchantmentSeed = r->nextInt(1000000); //Randomise enchantment seed upon joining server if(app.getGameRuleDefinitions() != nullptr) diff --git a/Minecraft.Client/PreStitchedTextureMap.cpp b/Minecraft.Client/PreStitchedTextureMap.cpp index 6247483a..dac289c3 100644 --- a/Minecraft.Client/PreStitchedTextureMap.cpp +++ b/Minecraft.Client/PreStitchedTextureMap.cpp @@ -200,6 +200,8 @@ void PreStitchedTextureMap::stitch() void PreStitchedTextureMap::makeTextureAnimated(TexturePack *texturePack, StitchedTexture *tex) { + + if(!tex->hasOwnData()) { animatedTextures.push_back(tex); @@ -212,15 +214,18 @@ void PreStitchedTextureMap::makeTextureAnimated(TexturePack *texturePack, Stitch if(!animString.empty()) { + wstring filename = path + textureFileName + extension; // TODO: [EB] Put the frames into a proper object, not this inside out hack - vector *frames = TextureManager::getInstance()->createTextures(filename, m_mipMap); + vector *frames = TextureManager::getInstance()->createTextures(filename, m_mipMap, true); if (frames == nullptr || frames->empty()) { return; // Couldn't load a texture, skip it } + + Texture *first = frames->at(0); #ifndef _CONTENT_PACKAGE @@ -244,7 +249,7 @@ void PreStitchedTextureMap::makeTextureAnimated(TexturePack *texturePack, Stitch StitchedTexture *PreStitchedTextureMap::getTexture(const wstring &name) { #ifndef _CONTENT_PACKAGE - app.DebugPrintf("Not implemented!\n"); + app.DebugPrintf("Not implemented: getTexture('%ls')\n", name.c_str()); DEBUG_BREAK(); #endif return nullptr; @@ -259,7 +264,10 @@ void PreStitchedTextureMap::cycleAnimationFrames() { for(StitchedTexture* texture : animatedTextures) { - texture->cycleFrames(); + if (texture != nullptr && texture->getFrames() > 0) + { + texture->cycleFrames(); + } } } @@ -337,7 +345,7 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(0, 2, L"helmetIron") ADD_ICON(0, 3, L"helmetDiamond") ADD_ICON(0, 4, L"helmetGold") - ADD_ICON(0, 5, L"flintAndSteel") + ADD_ICON(0, 5, L"flint_and_steel") ADD_ICON(0, 6, L"flint") ADD_ICON(0, 7, L"coal") ADD_ICON(0, 8, L"string") @@ -405,11 +413,11 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(4, 2, L"swordIron") ADD_ICON(4, 3, L"swordDiamond") ADD_ICON(4, 4, L"swordGold") - ADD_ICON(4, 5, L"fishingRod_uncast") + ADD_ICON(4, 5, L"fishing_rod_uncast") ADD_ICON(4, 6, L"clock") ADD_ICON(4, 7, L"bowl") - ADD_ICON(4, 8, L"mushroomStew") - ADD_ICON(4, 9, L"yellowDust") + ADD_ICON(4, 8, L"mushroom_stew") + ADD_ICON(4, 9, L"glowstone_dust") ADD_ICON(4, 10, L"bucket") ADD_ICON(4, 11, L"bucketWater") ADD_ICON(4, 12, L"bucketLava") @@ -422,7 +430,7 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(5, 2, L"shovelIron") ADD_ICON(5, 3, L"shovelDiamond") ADD_ICON(5, 4, L"shovelGold") - ADD_ICON(5, 5, L"fishingRod_cast") + ADD_ICON(5, 5, L"fishing_rod_cast") ADD_ICON(5, 6, L"diode") ADD_ICON(5, 7, L"porkchopRaw") ADD_ICON(5, 8, L"porkchopCooked") @@ -440,13 +448,13 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(6, 3, L"pickaxeDiamond") ADD_ICON(6, 4, L"pickaxeGold") ADD_ICON(6, 5, L"bow_pull_0") - ADD_ICON(6, 6, L"carrotOnAStick") + ADD_ICON(6, 6, L"carrot_on_a_stick") ADD_ICON(6, 7, L"leather") ADD_ICON(6, 8, L"saddle") ADD_ICON(6, 9, L"beefRaw") ADD_ICON(6, 10, L"beefCooked") - ADD_ICON(6, 11, L"enderPearl") - ADD_ICON(6, 12, L"blazeRod") + ADD_ICON(6, 11, L"ender_pearl") + ADD_ICON(6, 12, L"blaze_rod") ADD_ICON(6, 13, L"melon") ADD_ICON(6, 14, L"dyePowder_green") ADD_ICON(6, 15, L"dyePowder_lime") @@ -457,13 +465,13 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(7, 3, L"hatchetDiamond") ADD_ICON(7, 4, L"hatchetGold") ADD_ICON(7, 5, L"bow_pull_1") - ADD_ICON(7, 6, L"potatoBaked") + ADD_ICON(7, 6, L"baked_potato") ADD_ICON(7, 7, L"potato") ADD_ICON(7, 8, L"carrots") ADD_ICON(7, 9, L"chickenRaw") ADD_ICON(7, 10, L"chickenCooked") - ADD_ICON(7, 11, L"ghastTear") - ADD_ICON(7, 12, L"goldNugget") + ADD_ICON(7, 11, L"ghast_tear") + ADD_ICON(7, 12, L"gold_nugget") ADD_ICON(7, 13, L"netherStalkSeeds") ADD_ICON(7, 14, L"dyePowder_brown") ADD_ICON(7, 15, L"dyePowder_yellow") @@ -474,12 +482,12 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(8, 3, L"hoeDiamond") ADD_ICON(8, 4, L"hoeGold") ADD_ICON(8, 5, L"bow_pull_2") - ADD_ICON(8, 6, L"potatoPoisonous") + ADD_ICON(8, 6, L"poisonous_potato") ADD_ICON(8, 7, L"minecart") ADD_ICON(8, 8, L"boat") - ADD_ICON(8, 9, L"speckledMelon") - ADD_ICON(8, 10, L"fermentedSpiderEye") - ADD_ICON(8, 11, L"spiderEye") + ADD_ICON(8, 9, L"speckled_melon") + ADD_ICON(8, 10, L"fermented_spider_eye") + ADD_ICON(8, 11, L"spider_eye") ADD_ICON(8, 12, L"potion") ADD_ICON(8, 12, L"glassBottle") // Same as potion ADD_ICON(8, 13, L"potion_contents") @@ -490,16 +498,16 @@ void PreStitchedTextureMap::loadUVs() //ADD_ICON(9, 1, L"unused") ADD_ICON(9, 2, L"iron_horse_armor") ADD_ICON(9, 3, L"diamond_horse_armor") - ADD_ICON(9, 4, L"gold_horse_armor") + ADD_ICON(9, 4, L"golden_horse_armor") ADD_ICON(9, 5, L"comparator") - ADD_ICON(9, 6, L"carrotGolden") - ADD_ICON(9, 7, L"minecart_chest") - ADD_ICON(9, 8, L"pumpkinPie") + ADD_ICON(9, 6, L"golden_carrot") + ADD_ICON(9, 7, L"chest_minecart") + ADD_ICON(9, 8, L"pumpkin_pie") ADD_ICON(9, 9, L"monsterPlacer") ADD_ICON(9, 10, L"potion_splash") - ADD_ICON(9, 11, L"eyeOfEnder") + ADD_ICON(9, 11, L"eye_of_ender") ADD_ICON(9, 12, L"cauldron") - ADD_ICON(9, 13, L"blazePowder") + ADD_ICON(9, 13, L"blaze_powder") ADD_ICON(9, 14, L"dyePowder_purple") ADD_ICON(9, 15, L"dyePowder_magenta") @@ -510,13 +518,13 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(10, 4, L"lead") ADD_ICON(10, 5, L"netherbrick") ADD_ICON(10, 6, L"clownfish") - ADD_ICON(10, 7, L"minecart_furnace") + ADD_ICON(10, 7, L"furnace_minecart") ADD_ICON(10, 8, L"charcoal") ADD_ICON(10, 9, L"monsterPlacer_overlay") ADD_ICON(10, 10, L"ruby") - ADD_ICON(10, 11, L"expBottle") - ADD_ICON(10, 12, L"brewingStand") - ADD_ICON(10, 13, L"magmaCream") + ADD_ICON(10, 11, L"experience_bottle") + ADD_ICON(10, 12, L"brewing_stand") + ADD_ICON(10, 13, L"magma_cream") ADD_ICON(10, 14, L"dyePowder_cyan") ADD_ICON(10, 15, L"dyePowder_orange") @@ -524,13 +532,13 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(11, 4, L"muttonRaw") ADD_ICON(11, 5, L"rabbitRaw") ADD_ICON(11, 6, L"pufferfish") - ADD_ICON(11, 7, L"minecart_hopper") + ADD_ICON(11, 7, L"hopper_minecart") ADD_ICON(11, 8, L"hopper") ADD_ICON(11, 9, L"nether_star") ADD_ICON(11, 10, L"emerald") - ADD_ICON(11, 11, L"writingBook") - ADD_ICON(11, 12, L"writtenBook") - ADD_ICON(11, 13, L"flowerPot") + ADD_ICON(11, 11, L"writable_book") + ADD_ICON(11, 12, L"written_book") + ADD_ICON(11, 13, L"flower_pot") ADD_ICON(11, 14, L"dyePowder_silver") ADD_ICON(11, 15, L"dyePowder_white") @@ -541,7 +549,7 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(12, 4, L"muttonCooked") ADD_ICON(12, 5, L"rabbitCooked") ADD_ICON(12, 6, L"salmonRaw") - ADD_ICON(12, 7, L"minecart_tnt") + ADD_ICON(12, 7, L"tnt_minecart") ADD_ICON(12, 8, L"armorStand") ADD_ICON(12, 9, L"fireworks") ADD_ICON(12, 10, L"fireworks_charge") @@ -549,14 +557,14 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(12, 12, L"netherquartz") ADD_ICON(12, 13, L"map_empty") ADD_ICON(12, 14, L"frame") - ADD_ICON(12, 15, L"enchantedBook") + ADD_ICON(12, 15, L"enchanted_book") ADD_ICON(13, 0, L"doorAcacia") ADD_ICON(13, 1, L"doorBirch") ADD_ICON(13, 2, L"doorDark") ADD_ICON(13, 3, L"doorJungle") ADD_ICON(13, 4, L"doorSpruce") - ADD_ICON(13, 5, L"rabbitStew") + ADD_ICON(13, 5, L"rabbit_stew") ADD_ICON(13, 6, L"salmonCooked") @@ -749,8 +757,8 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(4, 15, L"sapling_birch"); ADD_ICON(5, 0, L"torch_on"); - ADD_ICON(5, 1, L"door_wood_upper"); - ADD_ICON(5, 2, L"door_iron_upper"); + ADD_ICON(5, 1, L"wooden_door_upper"); + ADD_ICON(5, 2, L"iron_door_upper"); ADD_ICON(5, 3, L"ladder"); ADD_ICON(5, 4, L"trapdoor"); ADD_ICON(5, 5, L"iron_bars"); @@ -766,8 +774,8 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(5, 15, L"crops_7"); ADD_ICON(6, 0, L"lever"); - ADD_ICON(6, 1, L"door_wood_lower"); - ADD_ICON(6, 2, L"door_iron_lower"); + ADD_ICON(6, 1, L"wooden_door_lower"); + ADD_ICON(6, 2, L"iron_door_lower"); ADD_ICON(6, 3, L"redstone_torch_on"); ADD_ICON(6, 4, L"stonebrick_mossy"); ADD_ICON(6, 5, L"stonebrick_cracked"); @@ -1039,11 +1047,11 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(22, 15, L"red_sandstone_smooth"); - ADD_ICON(23, 0, L"door_acacia_upper"); - ADD_ICON(23, 1, L"door_birch_upper"); - ADD_ICON(23, 2, L"door_dark_upper"); - ADD_ICON(23, 3, L"door_jungle_upper"); - ADD_ICON(23, 4, L"door_spruce_upper"); + ADD_ICON(23, 0, L"acacia_door_upper"); + ADD_ICON(23, 1, L"birch_door_upper"); + ADD_ICON(23, 2, L"dark_oak_door_upper"); + ADD_ICON(23, 3, L"jungle_door_upper"); + ADD_ICON(23, 4, L"spruce_door_upper"); ADD_ICON(23, 13, L"sea_lantern"); ADD_ICON(22, 13, L"prismarine"); ADD_ICON(21, 13, L"prismarine_dark"); @@ -1054,11 +1062,11 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(23, 14, L"inverted_daylight_detector"); ADD_ICON(23, 15, L"iron_trapdoor"); - ADD_ICON(24, 0, L"door_acacia_lower"); - ADD_ICON(24, 1, L"door_birch_lower"); - ADD_ICON(24, 2, L"door_dark_lower"); - ADD_ICON(24, 3, L"door_jungle_lower"); - ADD_ICON(24, 4, L"door_spruce_lower"); + ADD_ICON(24, 0, L"acacia_door_lower"); + ADD_ICON(24, 1, L"birch_door_lower"); + ADD_ICON(24, 2, L"dark_oak_door_lower"); + ADD_ICON(24, 3, L"jungle_door_lower"); + ADD_ICON(24, 4, L"spruce_door_lower"); ADD_ICON(21, 1, L"tallgrass2_tall_grass_lower"); ADD_ICON(20, 1, L"tallgrass2_tall_grass_upper"); @@ -1070,6 +1078,10 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(20, 3, L"tallgrass2_rose_bush_upper"); ADD_ICON(21, 4, L"tallgrass2_lilac_lower"); ADD_ICON(20, 4, L"tallgrass2_lilac_upper"); + ADD_ICON(21, 6, L"tallgrass2_sunflower_lower"); + ADD_ICON(20, 6, L"tallgrass2_sunflower_upper"); + ADD_ICON(21, 7, L"tallgrass2_sunflower_head_front"); // dont ask me why these are flipped + ADD_ICON(20, 7, L"tallgrass2_sunflower_head_back"); // probably something to do with my slop code - Fireblade } } diff --git a/Minecraft.Client/ServerChunkCache.cpp b/Minecraft.Client/ServerChunkCache.cpp index 6262512a..ac73f0f0 100644 --- a/Minecraft.Client/ServerChunkCache.cpp +++ b/Minecraft.Client/ServerChunkCache.cpp @@ -325,7 +325,7 @@ void ServerChunkCache::updateOverwriteHellChunk(LevelChunk* origChunk, LevelChun for(int y=0;y<256;y++) { int playerTile = playerChunk->getTile(x,y,z); - if(playerTile == Tile::unbreakable_Id) // if the tile is still unbreakable, the player hasn't changed it, so we can replace with the source + if(playerTile == Tile::bedrock_Id) // if the tile is still unbreakable, the player hasn't changed it, so we can replace with the source playerChunk->setTileAndData(x, y, z, origChunk->getTile(x,y,z), origChunk->getData(x,y,z)); } } diff --git a/Minecraft.Client/ServerLevel.cpp b/Minecraft.Client/ServerLevel.cpp index a15e1af5..4f941aa6 100644 --- a/Minecraft.Client/ServerLevel.cpp +++ b/Minecraft.Client/ServerLevel.cpp @@ -77,12 +77,12 @@ void ServerLevel::staticCtor() RANDOM_BONUS_ITEMS = WeighedTreasureArray(20); RANDOM_BONUS_ITEMS[0] = new WeighedTreasure(Item::stick_Id, 0, 1, 3, 10); - RANDOM_BONUS_ITEMS[1] = new WeighedTreasure(Tile::wood_Id, 0, 1, 3, 10); - RANDOM_BONUS_ITEMS[2] = new WeighedTreasure(Tile::treeTrunk_Id, 0, 1, 3, 10); - RANDOM_BONUS_ITEMS[3] = new WeighedTreasure(Item::hatchet_stone_Id, 0, 1, 1, 3); - RANDOM_BONUS_ITEMS[4] = new WeighedTreasure(Item::hatchet_wood_Id, 0, 1, 1, 5); - RANDOM_BONUS_ITEMS[5] = new WeighedTreasure(Item::pickAxe_stone_Id, 0, 1, 1, 3); - RANDOM_BONUS_ITEMS[6] = new WeighedTreasure(Item::pickAxe_wood_Id, 0, 1, 1, 5); + RANDOM_BONUS_ITEMS[1] = new WeighedTreasure(Tile::planks_Id, 0, 1, 3, 10); + RANDOM_BONUS_ITEMS[2] = new WeighedTreasure(Tile::log_Id, 0, 1, 3, 10); + RANDOM_BONUS_ITEMS[3] = new WeighedTreasure(Item::stone_axe_Id, 0, 1, 1, 3); + RANDOM_BONUS_ITEMS[4] = new WeighedTreasure(Item::wooden_axe_Id, 0, 1, 1, 5); + RANDOM_BONUS_ITEMS[5] = new WeighedTreasure(Item::stone_pickaxe_Id, 0, 1, 1, 3); + RANDOM_BONUS_ITEMS[6] = new WeighedTreasure(Item::wooden_pickaxe_Id, 0, 1, 1, 5); RANDOM_BONUS_ITEMS[7] = new WeighedTreasure(Item::apple_Id, 0, 2, 3, 5); RANDOM_BONUS_ITEMS[8] = new WeighedTreasure(Item::bread_Id, 0, 2, 3, 3); // 4J-PB - new items @@ -90,12 +90,12 @@ void ServerLevel::staticCtor() RANDOM_BONUS_ITEMS[10] = new WeighedTreasure(Tile::sapling_Id, 1, 4, 4, 2); RANDOM_BONUS_ITEMS[11] = new WeighedTreasure(Tile::sapling_Id, 2, 4, 4, 2); RANDOM_BONUS_ITEMS[12] = new WeighedTreasure(Tile::sapling_Id, 3, 4, 4, 4); - RANDOM_BONUS_ITEMS[13] = new WeighedTreasure(Item::seeds_melon_Id, 0, 1, 2, 3); - RANDOM_BONUS_ITEMS[14] = new WeighedTreasure(Item::seeds_pumpkin_Id, 0, 1, 2, 3); + RANDOM_BONUS_ITEMS[13] = new WeighedTreasure(Item::melon_seeds_Id, 0, 1, 2, 3); + RANDOM_BONUS_ITEMS[14] = new WeighedTreasure(Item::pumpkin_seeds_Id, 0, 1, 2, 3); RANDOM_BONUS_ITEMS[15] = new WeighedTreasure(Tile::cactus_Id, 0, 1, 2, 3); - RANDOM_BONUS_ITEMS[16] = new WeighedTreasure(Item::dye_powder_Id, DyePowderItem::BROWN, 1, 2, 2); + RANDOM_BONUS_ITEMS[16] = new WeighedTreasure(Item::dye_Id, DyePowderItem::BROWN, 1, 2, 2); RANDOM_BONUS_ITEMS[17] = new WeighedTreasure(Item::potato_Id, 0, 1, 2, 3); - RANDOM_BONUS_ITEMS[18] = new WeighedTreasure(Item::carrots_Id, 0, 1, 2, 3); + RANDOM_BONUS_ITEMS[18] = new WeighedTreasure(Item::carrot_Id, 0, 1, 2, 3); RANDOM_BONUS_ITEMS[19] = new WeighedTreasure(Tile::mushroom_brown_Id, 0, 1, 2, 2); }; @@ -590,9 +590,9 @@ void ServerLevel::tickTiles() if (isRaining() && shouldSnow(x + xo, yy, z + zo)) { #if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) - if (!FourKitBridge::FireBlockForm(dimension->id, x + xo, yy, z + zo, Tile::topSnow_Id, 0)) + if (!FourKitBridge::FireBlockForm(dimension->id, x + xo, yy, z + zo, Tile::snow_layer_Id, 0)) #endif - setTileAndUpdate(x + xo, yy, z + zo, Tile::topSnow_Id); + setTileAndUpdate(x + xo, yy, z + zo, Tile::snow_layer_Id); } if (isRaining()) { @@ -892,7 +892,7 @@ bool ServerLevel::mayInteract(shared_ptr player, int xt, int yt, int zt, // We'll need to do this in a future update // 4J-PB - Let's allow water near the spawn point, but not lava - if(content!=Tile::lava_Id) + if(content!=Tile::flowing_lava_Id) { // allow this to be used return true; @@ -1646,13 +1646,13 @@ int ServerLevel::runUpdate(void* lpParam) if( m_updateTileCount[iLev] >= MAX_UPDATES ) break; // 4J Stu - Grass and Lava ticks currently take up the majority of all tile updates, so I am limiting them - if( (id == Tile::grass_Id && grassTicks >= MAX_GRASS_TICKS) || (id == Tile::calmLava_Id && lavaTicks >= MAX_LAVA_TICKS) ) continue; + if( (id == Tile::grass_Id && grassTicks >= MAX_GRASS_TICKS) || (id == Tile::lava_Id && lavaTicks >= MAX_LAVA_TICKS) ) continue; // 4J Stu - Added shouldTileTick as some tiles won't even do anything if they are set to tick and use up one of our updates if (Tile::tiles[id] != nullptr && Tile::tiles[id]->isTicking() && Tile::tiles[id]->shouldTileTick(m_level[iLev],x + (cx * 16), y, z + (cz * 16) ) ) { if(id == Tile::grass_Id) ++grassTicks; - else if(id == Tile::calmLava_Id) ++lavaTicks; + else if(id == Tile::lava_Id) ++lavaTicks; m_updateTileX[iLev][m_updateTileCount[iLev]] = x + (cx * 16); m_updateTileY[iLev][m_updateTileCount[iLev]] = y; m_updateTileZ[iLev][m_updateTileCount[iLev]] = z + (cz * 16); diff --git a/Minecraft.Client/ServerPlayer.cpp b/Minecraft.Client/ServerPlayer.cpp index 3cffcd5f..cd321df0 100644 --- a/Minecraft.Client/ServerPlayer.cpp +++ b/Minecraft.Client/ServerPlayer.cpp @@ -245,8 +245,8 @@ ServerPlayer::ServerPlayer(MinecraftServer *server, Level *level, const wstring& waterDepth = 0; int yw = yy2; while( ( yw < 128 ) && - (( level->getTile(xx2,yw,zz2) == Tile::water_Id ) || - ( level->getTile(xx2,yw,zz2) == Tile::calmWater_Id )) ) + (( level->getTile(xx2,yw,zz2) == Tile::flowing_water_Id ) || + ( level->getTile(xx2,yw,zz2) == Tile::water_Id )) ) { yw++; waterDepth++; @@ -1465,22 +1465,22 @@ bool ServerPlayer::openTrap(shared_ptr trap) return true; } -bool ServerPlayer::openBrewingStand(shared_ptr brewingStand) +bool ServerPlayer::openBrewingStand(shared_ptr brewing_stand) { if(containerMenu == inventoryMenu) { nextContainerCounter(); - containerMenu = new BrewingStandMenu(inventory, brewingStand); + containerMenu = new BrewingStandMenu(inventory, brewing_stand); containerMenu->containerId = containerCounter; containerMenu->addSlotListener(this); #if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) - if (FourKitBridge::FireInventoryOpen(entityId, ContainerOpenPacket::BREWING_STAND, brewingStand->getCustomName(), brewingStand->getContainerSize())) + if (FourKitBridge::FireInventoryOpen(entityId, ContainerOpenPacket::BREWING_STAND, brewing_stand->getCustomName(), brewing_stand->getContainerSize())) { doCloseContainer(); return true; } #endif - connection->send(std::make_shared(containerCounter, ContainerOpenPacket::BREWING_STAND, brewingStand->getCustomName(), brewingStand->getContainerSize(), brewingStand->hasCustomName())); + connection->send(std::make_shared(containerCounter, ContainerOpenPacket::BREWING_STAND, brewing_stand->getCustomName(), brewing_stand->getContainerSize(), brewing_stand->hasCustomName())); refreshContainer(containerMenu); } else diff --git a/Minecraft.Client/ServerPlayer.h b/Minecraft.Client/ServerPlayer.h index 12022b48..b14f5f0a 100644 --- a/Minecraft.Client/ServerPlayer.h +++ b/Minecraft.Client/ServerPlayer.h @@ -107,7 +107,7 @@ public: virtual bool openHopper(shared_ptr container); virtual bool openFurnace(shared_ptr furnace); // 4J added bool return virtual bool openTrap(shared_ptr trap); // 4J added bool return - virtual bool openBrewingStand(shared_ptr brewingStand); // 4J added bool return + virtual bool openBrewingStand(shared_ptr brewing_stand); // 4J added bool return virtual bool openBeacon(shared_ptr beacon); virtual bool openTrading(shared_ptr traderTarget, const wstring &name); // 4J added bool return virtual bool openHorseInventory(shared_ptr horse, shared_ptr container); diff --git a/Minecraft.Client/ServerPlayerGameMode.cpp b/Minecraft.Client/ServerPlayerGameMode.cpp index 35e75705..28a2a836 100644 --- a/Minecraft.Client/ServerPlayerGameMode.cpp +++ b/Minecraft.Client/ServerPlayerGameMode.cpp @@ -265,19 +265,19 @@ bool ServerPlayerGameMode::destroyBlock(int x, int y, int z) if (!EnchantmentHelper::hasSilkTouch(player)) { // (SYLV)todo: shouldnt we get these values from the actual blocks? - if (t == Tile::coalOre_Id) + if (t == Tile::coal_ore_Id) eventExp = Mth::nextInt(level->random, 0, 2); - else if (t == Tile::diamondOre_Id) + else if (t == Tile::diamond_ore_Id) eventExp = Mth::nextInt(level->random, 3, 7); - else if (t == Tile::emeraldOre_Id) + else if (t == Tile::emerald_ore_Id) eventExp = Mth::nextInt(level->random, 3, 7); - else if (t == Tile::lapisOre_Id) + else if (t == Tile::lapis_ore_Id) eventExp = Mth::nextInt(level->random, 2, 5); - else if (t == Tile::netherQuartz_Id) + else if (t == Tile::quartz_ore_Id) eventExp = Mth::nextInt(level->random, 2, 5); - else if (t == Tile::redStoneOre_Id || t == Tile::redStoneOre_lit_Id) + else if (t == Tile::redstone_ore_Id || t == Tile::lit_redstone_ore_Id) eventExp = 1 + level->random->nextInt(5); - else if (t == Tile::mobSpawner_Id) + else if (t == Tile::mob_spawner_Id) eventExp = 15 + level->random->nextInt(15) + level->random->nextInt(15); } } diff --git a/Minecraft.Client/StitchedTexture.cpp b/Minecraft.Client/StitchedTexture.cpp index 88ab3e56..049fb574 100644 --- a/Minecraft.Client/StitchedTexture.cpp +++ b/Minecraft.Client/StitchedTexture.cpp @@ -192,6 +192,11 @@ int StitchedTexture::getSourceHeight() const void StitchedTexture::cycleFrames() { + if (frames == nullptr || frames->empty()) + { + return; + } + if (frameOverride != nullptr) { pair current = frameOverride->at(frame); @@ -230,7 +235,7 @@ Texture *StitchedTexture::getSource() Texture *StitchedTexture::getFrame(int i) { - return frames->at(0); + return frames->at(i); } int StitchedTexture::getFrames() diff --git a/Minecraft.Client/SurvivalMode.cpp b/Minecraft.Client/SurvivalMode.cpp index 317af52d..e58ee42a 100644 --- a/Minecraft.Client/SurvivalMode.cpp +++ b/Minecraft.Client/SurvivalMode.cpp @@ -174,10 +174,10 @@ void SurvivalMode::initLevel(Level *level) shared_ptr SurvivalMode::createPlayer(Level *level) { shared_ptr player = GameMode::createPlayer(level); - // player.inventory.add(new ItemInstance(Item.pickAxe_diamond)); - // player.inventory.add(new ItemInstance(Item.hatchet_diamond)); + // player.inventory.add(new ItemInstance(Item.diamond_pickaxe)); + // player.inventory.add(new ItemInstance(Item.diamond_axe)); // player.inventory.add(new ItemInstance(Tile.torch, 64)); - // player.inventory.add(new ItemInstance(Item.porkChop_cooked, 4)); + // player.inventory.add(new ItemInstance(Item.cooked_porkchop, 4)); // player.inventory.add(new ItemInstance(Item.bow, 1)); // player.inventory.add(new ItemInstance(Item.arrow, 64)); return player; diff --git a/Minecraft.Client/TerrainParticle.cpp b/Minecraft.Client/TerrainParticle.cpp index 15a86465..ef10f8f9 100644 --- a/Minecraft.Client/TerrainParticle.cpp +++ b/Minecraft.Client/TerrainParticle.cpp @@ -8,6 +8,7 @@ TerrainParticle::TerrainParticle(Level *level, double x, double y, double z, double xa, double ya, double za, Tile *tile, int face, int data, Textures *textures) : Particle(level, x, y, z, xa, ya, za) { this->tile = tile; + if (tile == nullptr) return; // tu31 tutorial world fix this->setTex(textures, tile->getTexture(0, data)); // 4J - change brought forward from 1.8.2 to fix purple particles on door damage this->gravity = tile->gravity; rCol = gCol = bCol = 0.6f; @@ -16,6 +17,14 @@ TerrainParticle::TerrainParticle(Level *level, double x, double y, double z, dou shared_ptr TerrainParticle::init(int x, int y, int z, int data) // 4J - added data parameter { + if (tile == nullptr) return nullptr; // tu31 tutorial world fix + // double check particle texture cause sunflowers are dysfunctional for whatever reason + Icon *resolvedIcon = tile->getTexture(level, x, y, z, 0); + if (resolvedIcon != nullptr) + { + setTex(Minecraft::GetInstance()->textures, resolvedIcon); + } + if (tile == Tile::grass) return dynamic_pointer_cast( shared_from_this() ); int col = tile->getColor(level, x, y, z, data); // 4J - added data parameter rCol *= ((col >> 16) & 0xff) / 255.0f; @@ -26,6 +35,7 @@ shared_ptr TerrainParticle::init(int x, int y, int z, int data) shared_ptr TerrainParticle::init(int data) { + if (tile == nullptr) return nullptr; // tu31 tutorial world fix if (tile == Tile::grass) return dynamic_pointer_cast( shared_from_this() ); int col = tile->getColor(data); rCol *= ((col >> 16) & 0xff) / 255.0f; diff --git a/Minecraft.Client/TextureManager.cpp b/Minecraft.Client/TextureManager.cpp index 173f4578..428279f6 100644 --- a/Minecraft.Client/TextureManager.cpp +++ b/Minecraft.Client/TextureManager.cpp @@ -80,10 +80,13 @@ Stitcher *TextureManager::createStitcher(const wstring &name) return new Stitcher(name, maxTextureSize, maxTextureSize, true); } -vector *TextureManager::createTextures(const wstring &filename, bool mipmap) +vector *TextureManager::createTextures(const wstring &filename, bool mipmap, bool forceAnimation) { vector *result = new vector(); TexturePack *texturePack = Minecraft::GetInstance()->skins->getSelected(); + TexturePack *imagePack = texturePack; + + //try { int mode = Texture::TM_CONTAINER; // Most important -- so it doesn't get uploaded to videoram int clamp = Texture::WM_WRAP; // 4J Stu - Don't clamp as it causes issues with how we signal non-mipmmapped textures to the pixel shader //Texture::WM_CLAMP; @@ -95,9 +98,9 @@ vector *TextureManager::createTextures(const wstring &filename, bool wstring drive = L""; - if(texturePack->hasFile(L"res/" + filename,false)) + if(imagePack->hasFile(L"res/" + filename,false)) { - drive = texturePack->getPath(true); + drive = imagePack->getPath(true); } else { @@ -108,31 +111,39 @@ vector *TextureManager::createTextures(const wstring &filename, bool char *pchUsrDir = app.GetBDUsrDirPath(pchTextureName); wstring wstr (pchUsrDir, pchUsrDir+strlen(pchUsrDir)); drive= wstr + L"\\Common\\res\\TitleUpdate\\"; + imagePack = texturePack; } else #endif { - drive = Minecraft::GetInstance()->skins->getDefault()->getPath(true); + imagePack = Minecraft::GetInstance()->skins->getDefault(); + drive = imagePack->getPath(true); } } + + //BufferedImage *image = new BufferedImage(texturePack->getResource(L"/" + filename),false,true,drive); //ImageIO::read(texturePack->getResource(L"/" + filename)); - BufferedImage *image = texturePack->getImageResource(filename, false, true, drive); + BufferedImage *image = imagePack->getImageResource(filename, false, true, drive); MemSect(0); + + int height = image->getHeight(); int width = image->getWidth(); wstring texName = getTextureNameFromPath(filename); - if (isAnimation(filename, texturePack)) + if (forceAnimation || isAnimation(filename, texturePack)) { + // TODO: Read this information from the animation file later int frameWidth = width; int frameHeight = width; // This could end as 0 frames int frameCount = height / frameWidth; + for (int i = 0; i < frameCount; i++) { BufferedImage *subImage = image->getSubimage(0, frameHeight * i, frameWidth, frameHeight); @@ -140,6 +151,7 @@ vector *TextureManager::createTextures(const wstring &filename, bool delete subImage; result->push_back(texture); } + } else { @@ -147,6 +159,7 @@ vector *TextureManager::createTextures(const wstring &filename, bool if (width == height) { result->push_back(createTexture(texName, mode, width, height, clamp, format, minFilter, magFilter, mipmap || image->getData(1) != nullptr, image)); + } else { @@ -158,6 +171,8 @@ vector *TextureManager::createTextures(const wstring &filename, bool } delete image; + + //return result; //} catch (FileNotFoundException e) { @@ -176,9 +191,16 @@ wstring TextureManager::getTextureNameFromPath(const wstring &filename) bool TextureManager::isAnimation(const wstring &filename, TexturePack *texturePack) { - wstring dataFileName = L"/" + filename.substr(0, filename.find_last_of(L'.')) + L".txt"; - bool hasOriginalImage = texturePack->hasFile(L"/" + filename, false); - return Minecraft::GetInstance()->skins->getSelected()->hasFile(dataFileName, !hasOriginalImage); + File file(filename); + wstring textureName = file.getName(); + size_t extensionPos = textureName.find_last_of(L'.'); + if (extensionPos != wstring::npos) + { + textureName = textureName.substr(0, extensionPos); + } + + wstring path = filename.substr(0, filename.length() - file.getName().length()); + return !texturePack->getAnimationString(textureName, path, true).empty(); } Texture *TextureManager::createTexture(const wstring &name, int mode, int width, int height, int wrap, int format, int minFilter, int magFilter, bool mipmap, BufferedImage *image) diff --git a/Minecraft.Client/TextureManager.h b/Minecraft.Client/TextureManager.h index b1d71d2d..c256db1b 100644 --- a/Minecraft.Client/TextureManager.h +++ b/Minecraft.Client/TextureManager.h @@ -29,7 +29,7 @@ public: void registerTexture(Texture *texture); void unregisterTexture(const wstring &name, Texture *texture); Stitcher *createStitcher(const wstring &name); - vector *createTextures(const wstring &filename, bool mipmap); // 4J added mipmap param + vector *createTextures(const wstring &filename, bool mipmap, bool forceAnimation = false); // 4J added mipmap param private: wstring getTextureNameFromPath(const wstring &filename); diff --git a/Minecraft.Client/TextureMap.cpp b/Minecraft.Client/TextureMap.cpp index e329a532..561005cc 100644 --- a/Minecraft.Client/TextureMap.cpp +++ b/Minecraft.Client/TextureMap.cpp @@ -154,20 +154,12 @@ void TextureMap::stitch() { animatedTextures.push_back(stored); - wstring animationDefinitionFile = textureName + L".txt"; - TexturePack *texturePack = Minecraft::GetInstance()->skins->getSelected(); - bool requiresFallback = !texturePack->hasFile(L"\\" + textureName + L".png", false); - InputStream *fileStream = texturePack->getResource(L"\\" + path + animationDefinitionFile, requiresFallback); - - //Minecraft::getInstance()->getLogger().info("Found animation info for: " + animationDefinitionFile); -#ifndef _CONTENT_PACKAGE - wprintf(L"Found animation info for: %ls\n", animationDefinitionFile.c_str() ); -#endif - InputStreamReader isr(fileStream); - BufferedReader br(&isr); - stored->loadAnimationFrames(&br); - delete fileStream; + wstring animationString = texturePack->getAnimationString(textureName, path, true); + if (!animationString.empty()) + { + stored->loadAnimationFrames(animationString); + } } } delete areas; diff --git a/Minecraft.Client/TileRenderer.cpp b/Minecraft.Client/TileRenderer.cpp index 0dc19eb9..c6001c37 100644 --- a/Minecraft.Client/TileRenderer.cpp +++ b/Minecraft.Client/TileRenderer.cpp @@ -9,14 +9,25 @@ #include "../Minecraft.World/net.minecraft.world.level.material.h" #include "../Minecraft.World/net.minecraft.h" #include "../Minecraft.World/net.minecraft.world.h" +#include "../Minecraft.World/JavaMath.h" #include "Tesselator.h" #include "EntityTileRenderer.h" +#include "LevelRenderer.h" #include "Options.h" +#include "../Minecraft.World/TallGrass2.h" bool TileRenderer::fancy = true; const float smallUV = ( 1.0f / 16.0f ); +static inline void tessColor(Tesselator* t, float r, float g, float b, float a) +{ + if (a >= 0.999f) + t->color(r, g, b); + else + t->color(r, g, b, a); +} + void TileRenderer::_init() { fixedTexture = nullptr; @@ -41,6 +52,8 @@ void TileRenderer::_init() smoothShapeLighting = false; minecraft = Minecraft::GetInstance(); + fixedTextureAlpha = 1.0f; + xMin = 0; yMin = 0; zMin = 0; @@ -108,7 +121,7 @@ int TileRenderer::getLightColor( Tile *tt, LevelSource *level, int x, int y, int { // Don't use the cache for liquid tiles, as they are the only type that seem to have their own implementation of getLightColor that actually is important. // Without this we get patches of dark water where their lighting value is 0, it needs to pull in light from the tile above to work - if( ( tt->id >= Tile::water_Id ) && ( tt->id <= Tile::calmLava_Id ) ) return tt->getLightColor(level, x, y, z); + if( ( tt->id >= Tile::flowing_water_Id ) && ( tt->id <= Tile::lava_Id ) ) return tt->getLightColor(level, x, y, z); if( cache[id] & cache_getLightColor_valid ) return cache[id] & cache_getLightColor_mask; @@ -297,8 +310,8 @@ bool TileRenderer::tesselateInWorld( Tile* tt, int x, int y, int z, int forceDat // these block types can take advantage of a faster version of shouldRenderFace // there are others but this is an easy check which covers the majority // Note: This now covers rock, grass, dirt, stoneBrice, wood, sapling, unbreakable, sand, gravel, goldOre, ironOre, coalOre, treeTrunk - if( ( tt->id <= Tile::unbreakable_Id ) || - ( ( tt->id >= Tile::sand_Id ) && ( tt->id <= Tile::treeTrunk_Id ) ) ) + if( ( tt->id <= Tile::bedrock_Id ) || + ( ( tt->id >= Tile::sand_Id ) && ( tt->id <= Tile::log_Id ) ) ) { faceFlags = tt->getFaceFlags( level, x, y, z ); } @@ -336,6 +349,9 @@ bool TileRenderer::tesselateInWorld( Tile* tt, int x, int y, int z, int forceDat case Tile::SHAPE_CACTUS: retVal = tesselateCactusInWorld( tt, x, y, z ); break; + case Tile::SHAPE_SLIME: + retVal = tesselateSlimeBlockInWorld( tt, x, y, z ); + break; case Tile::SHAPE_CROSS_TEXTURE: retVal = tesselateCrossInWorld( tt, x, y, z ); break; @@ -2893,7 +2909,7 @@ bool TileRenderer::tesselateDustInWorld( Tile* tt, int x, int y, int z ) { const float yStretch = .35f / 16.0f; - if ( level->isSolidBlockingTile( x - 1, y, z ) && level->getTile( x - 1, y + 1, z ) == Tile::redStoneDust_Id ) + if ( level->isSolidBlockingTile( x - 1, y, z ) && level->getTile( x - 1, y + 1, z ) == Tile::redstone_wire_Id ) { t->color( br * red, br * green, br * blue ); t->vertexUV( ( float )( x + dustOffset ), ( float )( y + 1 + yStretch ), static_cast(z + 1), lineTexture->getU1(true), lineTexture->getV0(true) ); @@ -2907,7 +2923,7 @@ bool TileRenderer::tesselateDustInWorld( Tile* tt, int x, int y, int z ) t->vertexUV( ( float )( x + overlayOffset ), static_cast(y + 0), static_cast(z + 0), lineTextureOverlay->getU0(true), lineTextureOverlay->getV1(true) ); t->vertexUV( ( float )( x + overlayOffset ), ( float )( y + 1 + yStretch ), static_cast(z + 0), lineTextureOverlay->getU1(true), lineTextureOverlay->getV1(true) ); } - if ( level->isSolidBlockingTile( x + 1, y, z ) && level->getTile( x + 1, y + 1, z ) == Tile::redStoneDust_Id ) + if ( level->isSolidBlockingTile( x + 1, y, z ) && level->getTile( x + 1, y + 1, z ) == Tile::redstone_wire_Id ) { t->color( br * red, br * green, br * blue ); t->vertexUV( ( float )( x + 1 - dustOffset ), static_cast(y + 0), static_cast(z + 1), lineTexture->getU0(true), lineTexture->getV1(true) ); @@ -2921,7 +2937,7 @@ bool TileRenderer::tesselateDustInWorld( Tile* tt, int x, int y, int z ) t->vertexUV( ( float )( x + 1 - overlayOffset ), ( float )( y + 1 + yStretch ), static_cast(z + 0), lineTextureOverlay->getU1(true), lineTextureOverlay->getV0(true) ); t->vertexUV( ( float )( x + 1 - overlayOffset ), static_cast(y + 0), static_cast(z + 0), lineTextureOverlay->getU0(true), lineTextureOverlay->getV0(true) ); } - if ( level->isSolidBlockingTile( x, y, z - 1 ) && level->getTile( x, y + 1, z - 1 ) == Tile::redStoneDust_Id ) + if ( level->isSolidBlockingTile( x, y, z - 1 ) && level->getTile( x, y + 1, z - 1 ) == Tile::redstone_wire_Id ) { t->color( br * red, br * green, br * blue ); t->vertexUV( static_cast(x + 1), static_cast(y + 0), ( float )( z + dustOffset ), lineTexture->getU0(true), lineTexture->getV1(true) ); @@ -2935,7 +2951,7 @@ bool TileRenderer::tesselateDustInWorld( Tile* tt, int x, int y, int z ) t->vertexUV( static_cast(x + 0), ( float )( y + 1 + yStretch ), ( float )( z + overlayOffset ), lineTextureOverlay->getU1(true), lineTextureOverlay->getV0(true) ); t->vertexUV( static_cast(x + 0), static_cast(y + 0), ( float )( z + overlayOffset ), lineTextureOverlay->getU0(true), lineTextureOverlay->getV0(true) ); } - if ( level->isSolidBlockingTile( x, y, z + 1 ) && level->getTile( x, y + 1, z + 1 ) == Tile::redStoneDust_Id ) + if ( level->isSolidBlockingTile( x, y, z + 1 ) && level->getTile( x, y + 1, z + 1 ) == Tile::redstone_wire_Id ) { t->color( br * red, br * green, br * blue ); t->vertexUV( static_cast(x + 1), ( float )( y + 1 + yStretch ), ( float )( z + 1 - dustOffset ), lineTexture->getU1(true), lineTexture->getV0(true) ); @@ -4180,6 +4196,105 @@ bool TileRenderer::tesselateCrossInWorld( Tile* tt, int x, int y, int z ) zt += ((((seed >> 24) & 0xf) / 15.0f) - 0.5f) * 0.5f; } + if (tt == Tile::double_plant) + { + const int data = level->getData(x, y, z); + const bool isUpper = (data & TallGrass2::UPPER_BIT) != 0; + if (isUpper && level->getTile(x, y - 1, z) != Tile::double_plant_Id) + { + return true; + } + int lowerData = data; + if (isUpper && level->getTile(x, y - 1, z) == Tile::double_plant_Id) + { + lowerData = level->getData(x, y - 1, z); + } + const int variant = lowerData & ~TallGrass2::UPPER_BIT; + + if (isUpper && variant == TallGrass2::SUNFLOWER) + { + // cut off stem height (i think thats how it was in the original LCE?) + const int stemRenderData = (lowerData & ~TallGrass2::UPPER_BIT) | TallGrass2::UPPER_BIT; + tesselateCrossStemHeight(tt, stemRenderData, xt, yt, zt, 0.875f); + TallGrass2* tallGrass = static_cast(tt); + Icon* frontTex = tallGrass->getSunflowerHeadFrontIcon(); + Icon* backTex = tallGrass->getSunflowerHeadBackIcon(); + if (frontTex != nullptr && backTex != nullptr) + { + float fu0 = frontTex->getU0(true); + float fu1 = frontTex->getU1(true); + float fv0 = frontTex->getV0(true); + float fv1 = frontTex->getV1(true); + + float bu0 = backTex->getU0(true); + float bu1 = backTex->getU1(true); + float bv0 = backTex->getV0(true); + float bv1 = backTex->getV1(true); + + const float angle = 22.5f * (PI / 180.0f); + const float c = Mth::cos(angle); + const float s = Mth::sin(angle); + const float ox = xt + 0.5f; + const float oy = yt + 0.5f; + const float oz = zt + 0.5f; + + auto rotateZ = [&](float &px, float &py) + { + float dx = px - ox; + float dy = py - oy; + px = ox + (dx * c - dy * s); + py = oy + (dx * s + dy * c); + }; + + const float z0 = zt + (1.0f / 16.0f); + const float z1 = zt + (15.0f / 16.0f); + const float y0 = yt - (1.0f / 16.0f); + const float y1 = yt + (15.0f / 16.0f); + + const float xPlane = xt + (9.6f / 16.0f); + const float depth = 0.001f; + + float fx0 = xPlane + depth, fy0 = y1, fz0 = z0; + float fx1 = xPlane + depth, fy1 = y0, fz1 = z0; + float fx2 = xPlane + depth, fy2 = y0, fz2 = z1; + float fx3 = xPlane + depth, fy3 = y1, fz3 = z1; + rotateZ(fx0, fy0); + rotateZ(fx1, fy1); + rotateZ(fx2, fy2); + rotateZ(fx3, fy3); + + t->vertexUV(fx0, fy0, fz0, fu0, fv0); + t->vertexUV(fx1, fy1, fz1, fu0, fv1); + t->vertexUV(fx2, fy2, fz2, fu1, fv1); + t->vertexUV(fx3, fy3, fz3, fu1, fv0); + + float bx0 = xPlane - depth, by0 = y1, bz0 = z0; + float bx1 = xPlane - depth, by1 = y0, bz1 = z0; + float bx2 = xPlane - depth, by2 = y0, bz2 = z1; + float bx3 = xPlane - depth, by3 = y1, bz3 = z1; + rotateZ(bx0, by0); + rotateZ(bx1, by1); + rotateZ(bx2, by2); + rotateZ(bx3, by3); + + t->vertexUV(bx3, by3, bz3, bu0, bv0); + t->vertexUV(bx2, by2, bz2, bu0, bv1); + t->vertexUV(bx1, by1, bz1, bu1, bv1); + t->vertexUV(bx0, by0, bz0, bu1, bv0); + } + return true; + } + + int renderData = data; + if (isUpper) + { + renderData = (lowerData & ~TallGrass2::UPPER_BIT) | TallGrass2::UPPER_BIT; + } + + tesselateCrossTexture(tt, renderData, xt, yt, zt, 1); + return true; + } + tesselateCrossTexture( tt, level->getData( x, y, z ), xt, yt, zt, 1 ); return true; } @@ -4359,6 +4474,47 @@ void TileRenderer::tesselateCrossTexture( Tile* tt, int data, float x, float y, } +void TileRenderer::tesselateCrossStemHeight( Tile* tt, int data, float x, float y, float z, float height ) +{ + Tesselator* t = Tesselator::getInstance(); + + Icon *tex = getTexture(tt, 0, data); + + if (hasFixedTexture()) tex = fixedTexture; + float u0 = tex->getU0(true); + float v0 = tex->getV0(true); + float u1 = tex->getU1(true); + float v1 = tex->getV(height * SharedConstants::WORLD_RESOLUTION, true); + + float width = 0.45f; + float x0 = x + 0.5f - width; + float x1 = x + 0.5f + width; + float z0 = z + 0.5f - width; + float z1 = z + 0.5f + width; + + float topY = y + height; + + t->vertexUV( x0, topY, z0, u0, v0 ); + t->vertexUV( x0, y + 0, z0, u0, v1 ); + t->vertexUV( x1, y + 0, z1, u1, v1 ); + t->vertexUV( x1, topY, z1, u1, v0 ); + + t->vertexUV( x1, topY, z1, u0, v0 ); + t->vertexUV( x1, y + 0, z1, u0, v1 ); + t->vertexUV( x0, y + 0, z0, u1, v1 ); + t->vertexUV( x0, topY, z0, u1, v0 ); + + t->vertexUV( x0, topY, z1, u0, v0 ); + t->vertexUV( x0, y + 0, z1, u0, v1 ); + t->vertexUV( x1, y + 0, z0, u1, v1 ); + t->vertexUV( x1, topY, z0, u1, v0 ); + + t->vertexUV( x1, topY, z0, u0, v0 ); + t->vertexUV( x1, y + 0, z0, u0, v1 ); + t->vertexUV( x0, y + 0, z1, u1, v1 ); + t->vertexUV( x0, topY, z1, u1, v0 ); +} + void TileRenderer::tesselateStemTexture( Tile* tt, int data, float h, float x, float y, float z ) { Tesselator* t = Tesselator::getInstance(); @@ -6279,6 +6435,50 @@ bool TileRenderer::tesselateBlockInWorld( Tile* tt, int x, int y, int z, float r } +bool TileRenderer::tesselateSlimeBlockInWorld(Tile *tt, int x, int y, int z) +{ + setFixedTexture(getTexture(Tile::slimeBlock)); + setShape(0, 0, 0, 1, 1, 1); + + this->fixedTextureAlpha = 0.35f; + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_ALPHA_TEST); + glEnable(GL_BLEND); + + glDepthMask(false); + tesselateBlockInWorld(tt, x, y, z); + glDepthMask(true); + + glEnable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + + this->fixedTextureAlpha = 1.0f; + clearFixedTexture(); + + return true; +} + +bool TileRenderer::tesselateSlimeInnerInWorld(Tile *tt, int x, int y, int z) +{ + const float innerSizeStart = 3.0f / 16.0f; + const float innerSizeFinish = 13.0f / 16.0f; + setFixedTexture(getTexture(Tile::slimeBlock)); + setShape(innerSizeStart, innerSizeStart, innerSizeStart, innerSizeFinish, innerSizeFinish, innerSizeFinish); + this->fixedTextureAlpha = 0.18f; + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_ALPHA_TEST); + glEnable(GL_BLEND); + glDepthMask(false); + bool result = tesselateBlockInWorld(tt, x, y, z); + glDepthMask(true); + glEnable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + this->fixedTextureAlpha = 1.0f; + clearFixedTexture(); + return result; +} + bool TileRenderer::tesselateBeaconInWorld(Tile *tt, int x, int y, int z) { float obsHeight = 3.0f / 16.0f; @@ -6299,7 +6499,7 @@ bool TileRenderer::tesselateBeaconInWorld(Tile *tt, int x, int y, int z) noCulling = false; clearFixedTexture(); - + return true; } @@ -6572,8 +6772,8 @@ bool TileRenderer::tesselateFenceGateInWorld(FenceGateTile *tt, int x, int y, in float h20 = 5 / 16.0f; float h21 = 16 / 16.0f; - if (((direction == Direction::NORTH || direction == Direction::SOUTH) && level->getTile(x - 1, y, z) == Tile::cobbleWall_Id && level->getTile(x + 1, y, z) == Tile::cobbleWall_Id) - || ((direction == Direction::EAST || direction == Direction::WEST) && level->getTile(x, y, z - 1) == Tile::cobbleWall_Id && level->getTile(x, y, z + 1) == Tile::cobbleWall_Id)) + if (((direction == Direction::NORTH || direction == Direction::SOUTH) && level->getTile(x - 1, y, z) == Tile::cobblestone_wall_Id && level->getTile(x + 1, y, z) == Tile::cobblestone_wall_Id) + || ((direction == Direction::EAST || direction == Direction::WEST) && level->getTile(x, y, z - 1) == Tile::cobblestone_wall_Id && level->getTile(x, y, z + 1) == Tile::cobblestone_wall_Id)) { h00 -= 3.0f / 16.0f; h01 -= 3.0f / 16.0f; @@ -7285,16 +7485,16 @@ void TileRenderer::renderFaceDown( Tile* tt, double x, double y, double z, Icon } #endif - t->color( c1r, c1g, c1b ); + tessColor(t, c1r, c1g, c1b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc1 ); t->vertexUV( static_cast(x0), static_cast(y0), static_cast(z1), static_cast(u10), static_cast(v10) ); - t->color( c2r, c2g, c2b ); + tessColor(t, c2r, c2g, c2b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc2 ); t->vertexUV( static_cast(x0), static_cast(y0), static_cast(z0), ( float )( u00 ), ( float )( v00 ) ); - t->color( c3r, c3g, c3b ); + tessColor(t, c3r, c3g, c3b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc3 ); t->vertexUV( static_cast(x1), static_cast(y0), static_cast(z0), static_cast(u01), static_cast(v01) ); - t->color( c4r, c4g, c4b ); + tessColor(t, c4r, c4g, c4b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc4 ); t->vertexUV( static_cast(x1), static_cast(y0), static_cast(z1), ( float )( u11 ), ( float )( v11 ) ); } @@ -7397,16 +7597,16 @@ void TileRenderer::renderFaceUp( Tile* tt, double x, double y, double z, Icon *t } #endif - t->color( c1r, c1g, c1b ); + tessColor(t, c1r, c1g, c1b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc1 ); t->vertexUV( static_cast(x1), static_cast(y1), static_cast(z1), ( float )( u11 ), ( float )( v11 ) ); - t->color( c2r, c2g, c2b ); + tessColor(t, c2r, c2g, c2b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc2 ); t->vertexUV( static_cast(x1), static_cast(y1), static_cast(z0), ( float )( u01 ), ( float )( v01 ) ); - t->color( c3r, c3g, c3b ); + tessColor(t, c3r, c3g, c3b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc3 ); t->vertexUV( static_cast(x0), static_cast(y1), static_cast(z0), ( float )( u00 ), ( float )( v00 ) ); - t->color( c4r, c4g, c4b ); + tessColor(t, c4r, c4g, c4b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc4 ); t->vertexUV( static_cast(x0), static_cast(y1), static_cast(z1), ( float )( u10 ), ( float )( v10 ) ); } @@ -7516,16 +7716,16 @@ void TileRenderer::renderNorth( Tile* tt, double x, double y, double z, Icon *te } #endif - t->color( c1r, c1g, c1b ); + tessColor(t, c1r, c1g, c1b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc1 ); t->vertexUV( static_cast(x0), static_cast(y1), static_cast(z0), static_cast(u01), static_cast(v01) ); - t->color( c2r, c2g, c2b ); + tessColor(t, c2r, c2g, c2b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc2 ); t->vertexUV( static_cast(x1), static_cast(y1), static_cast(z0), static_cast(u00), static_cast(v00) ); - t->color( c3r, c3g, c3b ); + tessColor(t, c3r, c3g, c3b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc3 ); t->vertexUV( static_cast(x1), static_cast(y0), static_cast(z0), static_cast(u10), static_cast(v10) ); - t->color( c4r, c4g, c4b ); + tessColor(t, c4r, c4g, c4b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc4 ); t->vertexUV( static_cast(x0), static_cast(y0), static_cast(z0), static_cast(u11), static_cast(v11) ); } @@ -7635,16 +7835,16 @@ void TileRenderer::renderSouth( Tile* tt, double x, double y, double z, Icon *te } #endif - t->color( c1r, c1g, c1b ); + tessColor(t, c1r, c1g, c1b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc1 ); t->vertexUV( static_cast(x0), static_cast(y1), static_cast(z1), static_cast(u00), static_cast(v00) ); - t->color( c2r, c2g, c2b ); + tessColor(t, c2r, c2g, c2b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc2 ); t->vertexUV( static_cast(x0), static_cast(y0), static_cast(z1), static_cast(u10), static_cast(v10) ); - t->color( c3r, c3g, c3b ); + tessColor(t, c3r, c3g, c3b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc3 ); t->vertexUV( static_cast(x1), static_cast(y0), static_cast(z1), static_cast(u11), static_cast(v11) ); - t->color( c4r, c4g, c4b ); + tessColor(t, c4r, c4g, c4b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc4 ); t->vertexUV( static_cast(x1), static_cast(y1), static_cast(z1), static_cast(u01), static_cast(v01) ); } @@ -7753,16 +7953,16 @@ void TileRenderer::renderWest( Tile* tt, double x, double y, double z, Icon *tex } #endif - t->color( c1r, c1g, c1b ); + tessColor(t, c1r, c1g, c1b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc1 ); t->vertexUV( static_cast(x0), static_cast(y1), static_cast(z1), static_cast(u01), static_cast(v01) ); - t->color( c2r, c2g, c2b ); + tessColor(t, c2r, c2g, c2b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc2 ); t->vertexUV( static_cast(x0), static_cast(y1), static_cast(z0), static_cast(u00), static_cast(v00) ); - t->color( c3r, c3g, c3b ); + tessColor(t, c3r, c3g, c3b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc3 ); t->vertexUV( static_cast(x0), static_cast(y0), static_cast(z0), static_cast(u10), static_cast(v10) ); - t->color( c4r, c4g, c4b ); + tessColor(t, c4r, c4g, c4b, this->fixedTextureAlpha); if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc4 ); t->vertexUV( static_cast(x0), static_cast(y0), static_cast(z1), static_cast(u11), static_cast(v11) ); } @@ -8106,6 +8306,56 @@ void TileRenderer::renderTile( Tile* tile, int data, float brightness, float fAl tile->updateDefaultShape(); t->end(); } + else if (shape == Tile::SHAPE_SLIME) + { + tile->updateDefaultShape(); + glTranslatef(-0.5f, -0.5f, -0.5f); + + bool hadFixedTexture = hasFixedTexture(); + Icon *savedFixedTexture = fixedTexture; + + setFixedTexture(getTexture(Tile::slimeBlock)); + setShape(3.0f / 16.0f, 3.0f / 16.0f, 3.0f / 16.0f, 13.0f / 16.0f, 13.0f / 16.0f, 13.0f / 16.0f); + t->begin(); + t->normal(0.0f, -1.0f, 0.0f); + renderFaceDown(tile, 0, 0, 0, getTexture(tile, 0, data)); + t->normal(0.0f, 1.0f, 0.0f); + renderFaceUp(tile, 0, 0, 0, getTexture(tile, 1, data)); + t->normal(0.0f, 0.0f, -1.0f); + renderNorth(tile, 0, 0, 0, getTexture(tile, 2, data)); + t->normal(0.0f, 0.0f, 1.0f); + renderSouth(tile, 0, 0, 0, getTexture(tile, 3, data)); + t->normal(-1.0f, 0.0f, 0.0f); + renderWest(tile, 0, 0, 0, getTexture(tile, 4, data)); + t->normal(1.0f, 0.0f, 0.0f); + renderEast(tile, 0, 0, 0, getTexture(tile, 5, data)); + t->end(); + + setFixedTexture(getTexture(Tile::slimeBlock)); + setShape(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); + glColor4f(brightness, brightness, brightness, fAlpha * 0.5f); + t->begin(); + t->normal(0.0f, -1.0f, 0.0f); + renderFaceDown(tile, 0, 0, 0, getTexture(tile, 0, data)); + t->normal(0.0f, 1.0f, 0.0f); + renderFaceUp(tile, 0, 0, 0, getTexture(tile, 1, data)); + t->normal(0.0f, 0.0f, -1.0f); + renderNorth(tile, 0, 0, 0, getTexture(tile, 2, data)); + t->normal(0.0f, 0.0f, 1.0f); + renderSouth(tile, 0, 0, 0, getTexture(tile, 3, data)); + t->normal(-1.0f, 0.0f, 0.0f); + renderWest(tile, 0, 0, 0, getTexture(tile, 4, data)); + t->normal(1.0f, 0.0f, 0.0f); + renderEast(tile, 0, 0, 0, getTexture(tile, 5, data)); + t->end(); + + if (hadFixedTexture) + setFixedTexture(savedFixedTexture); + else + clearFixedTexture(); + + glColor4f(brightness, brightness, brightness, fAlpha); + } else if ( shape == Tile::SHAPE_CACTUS ) { tile->updateDefaultShape(); @@ -8557,6 +8807,7 @@ bool TileRenderer::canRender( int renderShape ) if ( renderShape == Tile::SHAPE_BLOCK ) return true; if ( renderShape == Tile::SHAPE_TREE ) return true; if ( renderShape == Tile::SHAPE_QUARTZ) return true; + if ( renderShape == Tile::SHAPE_SLIME ) return true; if ( renderShape == Tile::SHAPE_CACTUS ) return true; if ( renderShape == Tile::SHAPE_STAIRS ) return true; if ( renderShape == Tile::SHAPE_FENCE ) return true; diff --git a/Minecraft.Client/TileRenderer.h b/Minecraft.Client/TileRenderer.h index 817bbf48..5d2c53c6 100644 --- a/Minecraft.Client/TileRenderer.h +++ b/Minecraft.Client/TileRenderer.h @@ -12,6 +12,7 @@ class FenceGateTile; class BrewingStandTile; class CauldronTile; class EggTile; +class SlimeTile; class TheEndPortalFrameTile; class RepeaterTile; class ComparatorTile; @@ -39,6 +40,7 @@ class TileRenderer public : static bool fancy; bool setColor; + float fixedTextureAlpha; float tileShapeX0; float tileShapeX1; @@ -87,11 +89,14 @@ public: bool tesselateInWorld( Tile* tt, int x, int y, int z, int forceData = -1, shared_ptr< TileEntity > forceEntity = shared_ptr< TileEntity >() ); // 4J added forceData, forceEntity param + bool tesselateSlimeInnerInWorld(Tile *tt, int x, int y, int z); + private: bool tesselateAirPortalFrameInWorld(TheEndPortalFrameTile *tt, int x, int y, int z); bool tesselateBedInWorld( Tile* tt, int x, int y, int z ); bool tesselateBrewingStandInWorld(BrewingStandTile *tt, int x, int y, int z); bool tesselateCauldronInWorld(CauldronTile *tt, int x, int y, int z); + bool tesselateSlimeBlockInWorld(Tile *tt, int x, int y, int z); bool tesselateFlowerPotInWorld(FlowerPotTile *tt, int x, int y, int z); bool tesselateAnvilInWorld(AnvilTile *tt, int x, int y, int z); @@ -144,6 +149,7 @@ private: bool tesselateRowInWorld( Tile* tt, int x, int y, int z ); void tesselateTorch( Tile* tt, float x, float y, float z, float xxa, float zza, int data ); void tesselateCrossTexture( Tile* tt, int data, float x, float y, float z, float scale ); + void tesselateCrossStemHeight( Tile* tt, int data, float x, float y, float z, float height ); void tesselateStemTexture( Tile* tt, int data, float h, float x, float y, float z ); bool tesselateLilypadInWorld(Tile *tt, int x, int y, int z); void tesselateStemDirTexture( StemTile* tt, int data, int dir, float h, float x, float y, float z ); diff --git a/Minecraft.Client/TrackedEntity.cpp b/Minecraft.Client/TrackedEntity.cpp index cc82a737..82965bbd 100644 --- a/Minecraft.Client/TrackedEntity.cpp +++ b/Minecraft.Client/TrackedEntity.cpp @@ -841,7 +841,12 @@ shared_ptr TrackedEntity::getAddEntityPacket() app.DebugPrintf("eTYPE_ITEM_FRAME xyz %d,%d,%d\n",ix,iy,iz); } - shared_ptr packet = std::make_shared(e, AddEntityPacket::ITEM_FRAME, frame->dir, yRotp, xRotp, xp, yp, zp); + int data = frame->dir & 0xFF; + if (frame->placedByPlayer) + { + data |= 0x100; + } + shared_ptr packet = std::make_shared(e, AddEntityPacket::ITEM_FRAME, data, yRotp, xRotp, xp, yp, zp); packet->x = Mth::floor(frame->xTile * 32.0f); packet->y = Mth::floor(frame->yTile * 32.0f); packet->z = Mth::floor(frame->zTile * 32.0f); diff --git a/Minecraft.Client/Windows64/4JLibs b/Minecraft.Client/Windows64/4JLibs index 8fb036f6..8ad0c385 160000 --- a/Minecraft.Client/Windows64/4JLibs +++ b/Minecraft.Client/Windows64/4JLibs @@ -1 +1 @@ -Subproject commit 8fb036f6d6ca5aa5aa2e20633638d6232a58d508 +Subproject commit 8ad0c385ded218c3d02d9b6dcf86b657933a883b diff --git a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp index 8e28cb3d..a28a6091 100644 --- a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp +++ b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp @@ -430,6 +430,20 @@ void DefineActions(void) InputManager.SetGameJoypadMaps(MAP_STYLE_2,MINECRAFT_ACTION_DPAD_RIGHT, _360_JOY_BUTTON_DPAD_RIGHT); InputManager.SetGameJoypadMaps(MAP_STYLE_2,MINECRAFT_ACTION_DPAD_UP, _360_JOY_BUTTON_DPAD_UP); InputManager.SetGameJoypadMaps(MAP_STYLE_2,MINECRAFT_ACTION_DPAD_DOWN, _360_JOY_BUTTON_DPAD_DOWN); + + for (int pad = 0; pad < 4; pad++) + { + InputManager.AddMapButtonSwap(pad, 1, 0, _360_JOY_BUTTON_A, _360_JOY_BUTTON_B); + InputManager.AddMapButtonSwap(pad, 1, 1, _360_JOY_BUTTON_A, _360_JOY_BUTTON_B); + InputManager.AddMapButtonSwap(pad, 1, 2, _360_JOY_BUTTON_A, _360_JOY_BUTTON_B); + + if (pad == 0) + { + InputManager.AddMapButtonSwap(pad, 0, 0, _360_JOY_BUTTON_LTHUMB, _360_JOY_BUTTON_RTHUMB); + InputManager.AddMapButtonSwap(pad, 0, 1, _360_JOY_BUTTON_LTHUMB, _360_JOY_BUTTON_RTHUMB); + InputManager.AddMapButtonSwap(pad, 0, 2, _360_JOY_BUTTON_LTHUMB, _360_JOY_BUTTON_RTHUMB); + } + } } #if 0 @@ -1519,7 +1533,8 @@ static Minecraft* InitialiseMinecraftRuntime() return nullptr; app.InitGameSettings(); - app.InitialiseTips(); + app.InitialiseTips(); + ui.ReloadSkin(); return pMinecraft; } diff --git a/Minecraft.Client/Windows64Media/DLC/Skin Pack 1/Skins1_Sony.pck b/Minecraft.Client/Windows64Media/DLC/Skin Pack 1/Skins1_Sony.pck new file mode 100644 index 00000000..614dda0f Binary files /dev/null and b/Minecraft.Client/Windows64Media/DLC/Skin Pack 1/Skins1_Sony.pck differ diff --git a/Minecraft.Client/Windows64Media/DLC/Skin Pack 2/Skins2_Sony.pck b/Minecraft.Client/Windows64Media/DLC/Skin Pack 2/Skins2_Sony.pck new file mode 100644 index 00000000..689c1e77 Binary files /dev/null and b/Minecraft.Client/Windows64Media/DLC/Skin Pack 2/Skins2_Sony.pck differ diff --git a/Minecraft.Client/Windows64Media/DLC/Skin Pack 3/Skins3_Sony.pck b/Minecraft.Client/Windows64Media/DLC/Skin Pack 3/Skins3_Sony.pck new file mode 100644 index 00000000..9009460e Binary files /dev/null and b/Minecraft.Client/Windows64Media/DLC/Skin Pack 3/Skins3_Sony.pck differ diff --git a/Minecraft.Client/Windows64Media/DLC/Skin Pack 4/Skins4_XB1.pck b/Minecraft.Client/Windows64Media/DLC/Skin Pack 4/Skins4_XB1.pck index 435fb41d..450419fa 100644 Binary files a/Minecraft.Client/Windows64Media/DLC/Skin Pack 4/Skins4_XB1.pck and b/Minecraft.Client/Windows64Media/DLC/Skin Pack 4/Skins4_XB1.pck differ diff --git a/Minecraft.Client/Windows64Media/DLC/Skin Pack 5/SkinPack5.pck b/Minecraft.Client/Windows64Media/DLC/Skin Pack 5/SkinPack5.pck index 4cda4af5..4ddf51b1 100644 Binary files a/Minecraft.Client/Windows64Media/DLC/Skin Pack 5/SkinPack5.pck and b/Minecraft.Client/Windows64Media/DLC/Skin Pack 5/SkinPack5.pck differ diff --git a/Minecraft.Client/Windows64Media/DLC/Skin Pack 6/SkinPack6.pck b/Minecraft.Client/Windows64Media/DLC/Skin Pack 6/SkinPack6.pck index 03351d9c..3b64917e 100644 Binary files a/Minecraft.Client/Windows64Media/DLC/Skin Pack 6/SkinPack6.pck and b/Minecraft.Client/Windows64Media/DLC/Skin Pack 6/SkinPack6.pck differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/mob/minecart/inside.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/mob/minecart/inside.ogg new file mode 100644 index 00000000..92487c8c Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/mob/minecart/inside.ogg differ diff --git a/Minecraft.Client/Windows64Media/Sound/Minecraft/mob/minecart/rolling.ogg b/Minecraft.Client/Windows64Media/Sound/Minecraft/mob/minecart/rolling.ogg new file mode 100644 index 00000000..534618f3 Binary files /dev/null and b/Minecraft.Client/Windows64Media/Sound/Minecraft/mob/minecart/rolling.ogg differ diff --git a/Minecraft.Client/Windows64Media/Tutorial/Tutorial.mcs b/Minecraft.Client/Windows64Media/Tutorial/Tutorial.mcs index 99f9f5ca..6193e15a 100644 Binary files a/Minecraft.Client/Windows64Media/Tutorial/Tutorial.mcs and b/Minecraft.Client/Windows64Media/Tutorial/Tutorial.mcs differ diff --git a/Minecraft.Client/Windows64Media/Tutorial/Tutorial.pck b/Minecraft.Client/Windows64Media/Tutorial/Tutorial.pck index f05788b3..f3eb2b97 100644 Binary files a/Minecraft.Client/Windows64Media/Tutorial/Tutorial.pck and b/Minecraft.Client/Windows64Media/Tutorial/Tutorial.pck differ diff --git a/Minecraft.Client/Windows64Media/loc/stringsGeneric.xml b/Minecraft.Client/Windows64Media/loc/stringsGeneric.xml index 776c0a4a..c8e403ba 100644 --- a/Minecraft.Client/Windows64Media/loc/stringsGeneric.xml +++ b/Minecraft.Client/Windows64Media/loc/stringsGeneric.xml @@ -1,9577 +1,9667 @@ - - - New Downloadable Content is available! Access it from the Minecraft Store button on the Main Menu. - - - - You can change the look of your character with a Skin Pack from the Minecraft Store. Select 'Minecraft Store' on the Main Menu to see what's available. - - - - Alter the gamma settings to make the game brighter or darker. - - - - If you set the game difficulty to Peaceful, your health will automatically regenerate, and no monsters will come out at night! - - - - Feed a bone to a wolf to tame it. You can then make it sit or follow you. - - - - You can drop items when in the Inventory menu by moving the cursor off the menu and pressing{*CONTROLLER_VK_A*} - - - - Sleeping in a bed at night will fast forward the game to dawn, but all players in a multiplayer game need to sleep in beds at the same time. - - - - Harvest pork chops from pigs, and cook and eat them to regain health. - - - - Harvest leather from cows, and use it to make armor. - - - - If you have an empty bucket, you can fill it with milk from a cow, or water, or lava! - - - - Use a hoe to prepare areas of ground for planting. - - - - Spiders won't attack you during the day - unless you attack them. - - - - Digging soil or sand with a spade is faster than with your hand! - - - - Eating cooked pork chops gives more health than eating raw pork chops. - - - - Make some torches to light up areas at night. Monsters will avoid the areas around these torches. - - - - Get to destinations faster with a minecart and rail! - - - - Plant some saplings and they'll grow into trees. - - - - Pigmen won't attack you, unless you attack them. - - - - You can change your game spawn point and skip to dawn by sleeping in a bed. - - - - Hit those fireballs back at the Ghast! - - - - Building a portal will allow you to travel to another dimension - The Nether. - - - - Press{*CONTROLLER_VK_B*} to drop the item currently in your hand! - - - - Use the right tool for the job! - - - - If you can't find any coal for your torches, you can always make charcoal from trees in a furnace. - - - - Digging straight down or straight up is not a great idea. - - - - Bonemeal (crafted from a Skeleton bone) can be used as a fertilizer, and can make things grow instantly! - - - - Creepers explode when they get close to you! - - - - Obsidian is created when water hits a lava source block. - - - - Lava can take minutes to disappear COMPLETELY when the source block is removed. - - - - Cobblestone is resistant to Ghast fireballs, making it useful for guarding portals. - - - - Blocks that can be used as a light source will melt snow and ice. This includes torches, glowstone, and Jack-O-Lanterns. - - - - Take caution when building structures made of wool in open air, as lightning from thunderstorms can set wool on fire. - - - - A single bucket of lava can be used in a furnace to smelt 100 blocks. - - - - The instrument played by a note block depends on the material beneath it. - - - - Zombies and Skeletons can survive daylight if they are in water. - - - - Attacking a wolf will cause any wolves in the immediate vicinity to turn hostile and attack you. This trait is also shared by Zombie Pigmen. - - - - Wolves cannot enter the Nether. - - - - Wolves won't attack Creepers. - - - - Chickens lay an egg every 5 to 10 minutes. - - - - Obsidian can only be mined with a diamond pickaxe. - - - - Creepers are the easiest obtainable source of gunpowder. - - - - Placing two chests side by side will make one large chest. - - - - Tame wolves show their health with the position of their tail. Feed them meat to heal them. - - - - Cook cactus in a furnace to get green dye. - - - - Read the What's New section in the How To Play menus to see the latest update information about the game. - - - - Stackable fences are in the game now! - - - - Some animals will follow you if you have wheat in your hand. - - - - If an animal can't move more than 20 blocks in any direction, it won't despawn. - - - - Music by C418! - - - - Notch has over a million followers on twitter! - - - - Not all Swedish people have blonde hair. Some, like Jens from Mojang, even have ginger hair! - - - - There will be an update to this game eventually! - - - - Who is Notch? - - - - Mojang has more awards than staff! - - - - Some famous people play Minecraft! - - - - deadmau5 likes Minecraft! - - - - Do not look directly at the bugs. - - - - Creepers were born from a coding bug. - - - - Is it a chicken or is it a duck? - - - - Were you at Minecon? - - - - No-one at Mojang has ever seen junkboy's face. - - - - Did you know there's a Minecraft Wiki? - - - - Mojang's new office is cool! - - - - Minecon 2013 was in Orlando, Florida, USA! - - - - .party() was excellent! - - - - Always assume rumors are false, rather than assuming they're true! - - - - {*T3*}HOW TO PLAY : BASICS{*ETW*}{*B*}{*B*} -Minecraft is a game about placing blocks to build anything you can imagine. At night monsters come out, make sure to build a shelter before that happens.{*B*}{*B*} -Use{*CONTROLLER_ACTION_LOOK*} to look around.{*B*}{*B*} -Use{*CONTROLLER_ACTION_MOVE*} to move around.{*B*}{*B*} -Press{*CONTROLLER_ACTION_JUMP*} to jump.{*B*}{*B*} -Push{*CONTROLLER_ACTION_MOVE*} forward twice in rapid succession to sprint. While you hold {*CONTROLLER_ACTION_MOVE*} forward, the character will continue to sprint unless they run out of sprint time or the Food Bar has less than{*ICON_SHANK_03*}.{*B*}{*B*} -Hold{*CONTROLLER_ACTION_ACTION*} to mine and chop using your hand or whatever you are holding. You may need to craft a tool to mine some blocks.{*B*}{*B*} -If you are holding an item in your hand, use{*CONTROLLER_ACTION_USE*} to use that item, or press{*CONTROLLER_ACTION_DROP*} to drop that item. - - - - {*T3*}HOW TO PLAY : HUD{*ETW*}{*B*}{*B*} -The HUD shows information about your status; your health, your remaining oxygen when you are under water, your hunger level (you need to eat to replenish this), and your armor if you are wearing any. If you lose some health, but have a food bar with 9 or more{*ICON_SHANK_01*} in it, your health will automatically replenish. Eating food will replenish your food bar.{*B*} -The Experience Bar is also shown here, with a numeric value to show your Experience Level, and the bar indicating how many Experience Points are required to increase your Experience Level. Experience Points are gained by collecting the Experience Orbs dropped by mobs when they die, mining certain block types, breeding animals, fishing, and smelting ores in a furnace.{*B*}{*B*} -It also shows the items that are available to use. Use{*CONTROLLER_ACTION_LEFT_SCROLL*} and{*CONTROLLER_ACTION_RIGHT_SCROLL*} to change the item in your hand. - - - - {*T3*}HOW TO PLAY : INVENTORY{*ETW*}{*B*}{*B*} -Use{*CONTROLLER_ACTION_INVENTORY*} to view your inventory.{*B*}{*B*} -This screen shows items available for use in your hand, and all the other items that you are carrying. Your armor is also shown here.{*B*}{*B*} -Use{*CONTROLLER_MENU_NAVIGATE*} to move the pointer. Use{*CONTROLLER_VK_A*} to pick an item under the pointer. If there is more than one item here this will pick them all up, or you can use{*CONTROLLER_VK_X*} to pick up just half of them.{*B*}{*B*} -Move the item with the pointer over another space in the inventory and place it there using{*CONTROLLER_VK_A*}. With multiple items on the pointer, use{*CONTROLLER_VK_A*} to place them all, or{*CONTROLLER_VK_X*} to place just one.{*B*}{*B*} -If an item you are over is armor, you will be shown a tooltip to enable a quick move of this to the right armor slot in the inventory.{*B*}{*B*} -It is possible to change the color of your Leather Armor by dying it, you can do this in the inventory menu by holding the dye in your pointer, then pressing{*CONTROLLER_VK_X*} whilst the pointer is over the piece you wish to dye. - - - - - {*T3*}HOW TO PLAY : CHEST{*ETW*}{*B*}{*B*} -Once you have crafted a Chest, you can place this in the world and then use it with{*CONTROLLER_ACTION_USE*} to store items from your inventory.{*B*}{*B*} -Use the pointer to move items between your inventory and the chest.{*B*}{*B*} -Items in the chest will be stored there for you to swap back into your inventory again later. - - - - - {*T3*}HOW TO PLAY : LARGE CHEST{*ETW*}{*B*}{*B*} -Two chests placed next to each other will be combined to form a Large Chest. This can store even more items.{*B*}{*B*} -It is used in the same way as a normal chest. - - - - - {*T3*}HOW TO PLAY : CRAFTING{*ETW*}{*B*}{*B*} -In the Crafting interface, you can combine items from your inventory to create new types of items. Use{*CONTROLLER_ACTION_CRAFTING*} to open the crafting interface.{*B*}{*B*} -Scroll through the tabs at the top using{*CONTROLLER_VK_LB*} and{*CONTROLLER_VK_RB*} to select the type of item you wish to craft, then use{*CONTROLLER_MENU_NAVIGATE*} to select the item to craft.{*B*}{*B*} -The crafting area shows the items required to craft the new item. Press{*CONTROLLER_VK_A*} to craft the item and place it in your inventory. - - - - - {*T3*}HOW TO PLAY : CRAFTING TABLE{*ETW*}{*B*}{*B*} -You can craft larger items using a Crafting Table.{*B*}{*B*} -Place the table in the world and press{*CONTROLLER_ACTION_USE*} to use it.{*B*}{*B*} -Crafting on a table works in the same way as basic crafting, but you have a larger crafting area, and a more varied selection of items to craft. - - - - - {*T3*}HOW TO PLAY : FURNACE{*ETW*}{*B*}{*B*} -A Furnace allows you to change items by firing them. For example, you can turn iron ore into iron ingots in the furnace.{*B*}{*B*} -Place the furnace in the world and press{*CONTROLLER_ACTION_USE*} to use it.{*B*}{*B*} -You need to put some fuel into the bottom of the furnace, and the item to be fired in the top. The furnace will then fire up and start working.{*B*}{*B*} -When your items have been fired, you can move them from the output area into your inventory.{*B*}{*B*} -If an item you are over is an ingredient or fuel for the furnace, you will be shown tooltips to enable a quick move of this to the furnace. - - - - - {*T3*}HOW TO PLAY : DISPENSER{*ETW*}{*B*}{*B*} -A Dispenser is used to shoot out items. You will need to place a switch, for example a lever, next to the dispenser to trigger it.{*B*}{*B*} -To fill the dispenser with items press{*CONTROLLER_ACTION_USE*}, then move the items that you want to dispense from your inventory into the dispenser.{*B*}{*B*} -Now when you use the switch, the dispenser will shoot out an item. - - - - - {*T3*}HOW TO PLAY : BREWING{*ETW*}{*B*}{*B*} -Brewing potions requires a Brewing Stand, which can be built at a crafting table. Every potion starts off with a bottle of water, which is made by filling a Glass Bottle with water from a Cauldron, or a water source.{*B*} -A Brewing Stand has three slots for bottles, so can make three potions at the same time. One ingredient can be used over all three bottles, so always brew three potions at the same time to best use your resources.{*B*} -Putting a potion ingredient in the top position at the Brewing Stand will make a base potion after a short time. This doesn't have any effect by itself, but brewing another ingredient with this base potion will give you a potion with an effect.{*B*} -Once you have this potion you can add a third ingredient to make the effect last longer (using Redstone Dust), be more intense (using Glowstone Dust), or turn into a harmful potion (using a Fermented Spider Eye).{*B*} -You can also add gunpowder to any potion to turn it into a Splash Potion, which can then be thrown. The thrown Splash Potion will cause the potion effect to apply over the area it lands in.{*B*} - -The source ingredients for potions are :-{*B*}{*B*} -* {*T2*}Nether Wart{*ETW*}{*B*} -* {*T2*}Spider Eye{*ETW*}{*B*} -* {*T2*}Sugar{*ETW*}{*B*} -* {*T2*}Ghast Tear{*ETW*}{*B*} -* {*T2*}Blaze Powder{*ETW*}{*B*} -* {*T2*}Magma Cream{*ETW*}{*B*} -* {*T2*}Glistering Melon{*ETW*}{*B*} -* {*T2*}Redstone Dust{*ETW*}{*B*} -* {*T2*}Glowstone Dust{*ETW*}{*B*} -* {*T2*}Fermented Spider Eye{*ETW*}{*B*}{*B*} - -You'll need to experiment with combinations of ingredients in order to find out all the different potions you can make. - - - - - {*T3*}HOW TO PLAY : ENCHANTING{*ETW*}{*B*}{*B*} -The Experience Points collected when a mob dies, or when certain blocks are mined or smelted in a furnace, can be used to enchant some tools, weapons, armor and books.{*B*} -When a Sword, Bow, Axe, Pickaxe, Shovel, Armor or Book is placed in the slot below the book in the Enchantment Table, the three buttons to the right of the slot will display some enchantments and their Experience Levels costs.{*B*} -If you do not have enough Experience Levels to use some of these, the cost will appear in red, otherwise it will be shown in green.{*B*}{*B*} -The actual enchantment applied is randomly selected based on the cost displayed.{*B*}{*B*} -If the Enchantment Table is surrounded by Bookshelves (up to a maximum of 15 Bookshelves), with a one block gap between the Bookcase and the Enchantment Table, the potency of the enchantments will be increased, and arcane glyphs will be seen coming from the book on the Enchantment Table.{*B*}{*B*} -All the ingredients for an Enchantment Table can be found within the villages in a world, or by mining and cultivation of the world.{*B*}{*B*} -Enchanted Books are used at the Anvil to apply enchantments to items. This gives you more control over which enchantments you would like on your items.{*B*} - - - - - {*T3*}HOW TO PLAY : FARMING ANIMALS{*ETW*}{*B*}{*B*} -If you want to keep your animals in the one place, build a fenced area of less than 20x20 blocks and have your animals inside it. This ensures they will still be there when you come back to see them. - - - - - {*T3*}HOW TO PLAY : BREEDING ANIMALS{*ETW*}{*B*}{*B*} -The animals in Minecraft can breed, and will produce baby versions of themselves!{*B*} -To get the animals to breed, you will need to feed them with the right food to get them to go into 'Love Mode'.{*B*} -Feed Wheat to a cow, mooshroom or sheep, Carrots to a pig, Wheat Seeds or Nether Wart to a chicken, or any kind of meat to a wolf, and they'll start looking for another animal of the same species near them that is also in Love Mode.{*B*} -When two animals of the same species meet, and both are in Love Mode, they will kiss for a few seconds, and then a baby animal will appear. The baby animal will follow their parents for a while before growing into a full sized animal itself.{*B*} -After being in Love Mode, an animal will not be able to enter it again for about five minutes.{*B*} -There is a limit on the number of animals it is possible to have in a world, so you may find the animals don't breed when you have a lot of them. - - - - {*T3*}HOW TO PLAY : NETHER PORTAL{*ETW*}{*B*}{*B*} -A Nether Portal allows the player to travel between the Overworld and the Nether world. The Nether world can be used to fast-travel in the Overworld - traveling one block distance in the Nether is equivalent to traveling 3 blocks in the Overworld, so when you build a portal in the Nether world and exit through it, you will be 3 times further away from your entry point.{*B*}{*B*} -A minimum of 10 Obsidian blocks are required to build the portal, and the portal needs to be 5 blocks high by 4 blocks wide by 1 block deep. Once the portal frame is built, the space inside the frame needs to be set on fire to activate it. This can be done using the Flint and Steel item, or the Fire Charge item.{*B*}{*B*} -Examples of portal construction are shown in the picture to the right. - - - - - {*T3*}HOW TO PLAY : BANNING LEVELS{*ETW*}{*B*}{*B*} -If you find offensive content within a level you are playing, you can choose to add the level to your Banned Levels list. -If you would like to do this, bring up the Pause menu, then press{*CONTROLLER_VK_RB*} to select the Ban Level tooltip. -When you attempt to join this level in future, you will be notified that the level is in your Banned Levels list, and given the option to remove it from the list and continue into the level, or back out. - - - - {*T3*}HOW TO PLAY : HOST AND PLAYER OPTIONS{*ETW*}{*B*}{*B*} - -{*T1*}Game Options{*ETW*}{*B*} -When loading or creating a world, you can press the "More Options" button to enter a menu that allows more control over your game.{*B*}{*B*} - - {*T2*}Player vs Player{*ETW*}{*B*} - When enabled, players can inflict damage on other players. This option only affects Survival mode.{*B*}{*B*} - - {*T2*}Trust Players{*ETW*}{*B*} - When disabled, players joining the game are restricted in what they can do. They are not able to mine or use items, place blocks, use doors and switches, use containers, attack players or attack animals. You can change these options for a specific player using the in-game menu.{*B*}{*B*} - - {*T2*}Fire Spreads{*ETW*}{*B*} - When enabled, fire may spread to nearby flammable blocks. This option can also be changed from within the game.{*B*}{*B*} - - {*T2*}TNT Explodes{*ETW*}{*B*} - When enabled, TNT will explode when detonated. This option can also be changed from within the game.{*B*}{*B*} - - {*T2*}Host Privileges{*ETW*}{*B*} - When enabled, the host can toggle their ability to fly, disable exhaustion, and make themselves invisible from the in-game menu. {*DISABLES_ACHIEVEMENTS*}{*B*}{*B*} - - {*T2*}Daylight Cycle{*ETW*}{*B*} - When disabled, the time of day will not change.{*B*}{*B*} - - {*T2*}Keep Inventory{*ETW*}{*B*} - When enabled, players will keep their inventory when they die.{*B*}{*B*} - - {*T2*}Mob Spawning{*ETW*}{*B*} - When disabled, mobs will not spawn naturally.{*B*}{*B*} - - {*T2*}Mob Griefing{*ETW*}{*B*} - When disabled, prevents monsters and animals from changing blocks (for example, Creeper explosions won't destroy blocks and Sheep won't remove Grass) or picking up items.{*B*}{*B*} - - {*T2*}Mob Loot{*ETW*}{*B*} - When disabled, monsters and animals will not drop loot (for example, Creepers won't drop gunpowder).{*B*}{*B*} - - {*T2*}Tile Drops{*ETW*}{*B*} - When disabled, blocks will not drop items when destroyed (for example, Stone blocks won't drop Cobblestone).{*B*}{*B*} - - {*T2*}Natural Regeneration{*ETW*}{*B*} - When disabled, players will not regenerate health naturally.{*B*}{*B*} - -{*T1*}World Generation Options{*ETW*}{*B*} -When creating a new world there are some additional options.{*B*}{*B*} - - {*T2*}Generate Structures{*ETW*}{*B*} - When enabled, structures such as Villages and Strongholds will generate in the world.{*B*}{*B*} - - {*T2*}Superflat World{*ETW*}{*B*} - When enabled, a completely flat world will be generated in the Overworld and in the Nether.{*B*}{*B*} - - {*T2*}Bonus Chest{*ETW*}{*B*} - When enabled, a chest containing some useful items will be created near the player spawn point.{*B*}{*B*} - - {*T2*}Reset Nether{*ETW*}{*B*} - When enabled, the Nether will be re-generated. This is useful if you have an older save where Nether Fortresses were not present.{*B*}{*B*} - - {*T1*}In-Game Options{*ETW*}{*B*} - While in the game a number of options can be accessed by pressing {*BACK_BUTTON*} to bring up the in-game menu.{*B*}{*B*} - - {*T2*}Host Options{*ETW*}{*B*} - The host player, and any players set as moderators can access the "Host Option" menu. In this menu they can enable and disable fire spreading and TNT exploding.{*B*}{*B*} - -{*T1*}Player Options{*ETW*}{*B*} -To modify the privileges for a player, select their name and press{*CONTROLLER_VK_A*} to bring up the player privileges menu where you can use the following options.{*B*}{*B*} - - {*T2*}Can Build And Mine{*ETW*}{*B*} - This option is only available when "Trust Players" is turned off. When this option is enabled, the player is able to interact with the world as normal. When disabled the player will not be able to place or destroy blocks, or interact with many items and blocks.{*B*}{*B*} - - {*T2*}Can Use Doors and Switches{*ETW*}{*B*} - This option is only available when "Trust Players" is turned off. When this option is disabled, the player will not be able to use doors and switches.{*B*}{*B*} - - {*T2*}Can Open Containers{*ETW*}{*B*} - This option is only available when "Trust Players" is turned off. When this option is disabled, the player will not be able to open containers, such as chests.{*B*}{*B*} - - {*T2*}Can Attack Players{*ETW*}{*B*} - This option is only available when "Trust Players" is turned off. When this option is disabled the player will not be able to cause damage to other players.{*B*}{*B*} - - {*T2*}Can Attack Animals{*ETW*}{*B*} - This option is only available when "Trust Players" is turned off. When this option is disabled the player will not be able to cause damage to animals.{*B*}{*B*} - - {*T2*}Moderator{*ETW*}{*B*} - When this option is enabled, the player is able to change privileges for other players (except the host) if "Trust Players" is turned off, kick players and they can enable and disable fire spreading and TNT exploding.{*B*}{*B*} - - {*T2*}Kick Player{*ETW*}{*B*} - {*KICK_PLAYER_DESCRIPTION*}{*B*}{*B*} - -{*T1*}Host Player Options{*ETW*}{*B*} -If "Host Privileges" is enabled the host player can modify some privileges for themselves. To modify the privileges for a player, select their name and press{*CONTROLLER_VK_A*} to bring up the player privileges menu where you can use the following options.{*B*}{*B*} - - {*T2*}Can Fly{*ETW*}{*B*} - When this option is enabled, the player is able to fly. This option is only relevant to Survival mode, as flying is enabled for all players in Creative mode.{*B*}{*B*} - - {*T2*}Disable Exhaustion{*ETW*}{*B*} - This option only affects Survival mode. When enabled, physical activities (walking/sprinting/jumping etc.) do not decrease the food bar. However, if the player becomes injured, the food bar will slowly decrease while the player is healing.{*B*}{*B*} - - {*T2*}Invisible{*ETW*}{*B*} - When this option is enabled, the player is not visible to other players and is invulnerable.{*B*}{*B*} - - {*T2*}Can Teleport{*ETW*}{*B*} - This allows the player to move players or themselves to other players in the world. - - - - - Next Page - - - - Previous Page - - - - Basics - - - - HUD - - - - Inventory - - - - Chests - - - - Crafting - - - - Furnace - - - - Dispenser - - - - Farming Animals - - - - Breeding Animals - - - - Brewing - - - - Enchantment - - - - Nether Portal - - - - Multiplayer - - - - Sharing Screenshots - - - - Banning Levels - - - - Creative Mode - - - - Host and Player Options - - - - Trading - - - - Anvil - - - - The End - - - - {*T3*}HOW TO PLAY : THE END{*ETW*}{*B*}{*B*} -The End is another dimension in the game, which is reached through an active End Portal. The End Portal can be found in a Stronghold, which is deep underground in the Overworld.{*B*} -To activate the End Portal, you'll need to put an Eye of Ender into any End Portal Frame without one.{*B*} -Once the portal is active, jump in to it to go to The End.{*B*}{*B*} -In The End you will meet the Ender Dragon, a fierce and powerful enemy, along with many Enderman, so you will have to be well prepared for the battle before going there!{*B*}{*B*} -You'll find that there are Ender Crystals on top of eight Obsidian spikes that the Ender Dragon uses to heal itself, -so the first step in the battle is to destroy each of these.{*B*} -The first few can be reached with arrows, but the later ones are protected by an Iron Fence cage, and you will need to build up to them.{*B*}{*B*} -While you are doing this, the Ender Dragon will be attacking you by flying at you and spitting Ender acid balls!{*B*} -If you approach the Egg Podium in the centre of the spikes, the Ender Dragon will fly down and attack you and this is where you can really do some damage to it!{*B*} -Avoid the acid breath, and target the Ender Dragon's eyes for the best results. If possible, bring some friends in to The End to help you with the battle!{*B*}{*B*} -Once you are in The End, your friends will be able to see the location of the End Portal within the Stronghold on their maps, -so they can easily join you. - - - - - Sprint - - - - What's New - - - - {*T3*}Changes and Additions{*ETW*}{*B*}{*B*} -- Added new items - Hardened Clay, Stained Clay, Block of Coal, Hay Bale, Activator Rail, Block of Redstone, Daylight Sensor, Dropper, Hopper, Minecart with Hopper, Minecart with TNT, Redstone Comparator, Weighted Pressure Plate, Beacon, Trapped Chest, Firework Rocket, Firework Star, Nether Star, Lead, Horse Armor, Name Tag, Horse Spawn Egg{*B*} -- Added new Mobs - Wither, Wither Skeletons, Witches, Bats, Horses, Donkeys and Mules{*B*} -- Added new terrain generation features - Witch Huts.{*B*} -- Added Beacon interface.{*B*} -- Added Horse interface.{*B*} -- Added Hopper interface.{*B*} -- Added Fireworks - Fireworks interface is accessible from the Crafting Table when you have the ingredients to craft a Firework Star or Firework Rocket.{*B*} -- Added 'Adventure Mode' - You can only break blocks with the correct tools.{*B*} -- Added lots of new sounds.{*B*} -- Mobs, items and projectiles can now pass through portals.{*B*} -- Repeaters can now be locked by powering their sides with another Repeater.{*B*} -- Zombies and Skeletons can now spawn with different weapons and armor.{*B*} -- New death messages.{*B*} -- Name mobs with a Name Tag, and rename containers to change the title when the menu is open.{*B*} -- Bonemeal no longer instantly grows everything to full size, and instead randomly grows in stages.{*B*} -- A Redstone signal describing the contents of Chests, Brewing Stands, Dispensers and Jukeboxes can be detected by placing a Redstone Comparator directly against them.{*B*} -- Dispensers can face in any direction.{*B*} -- Eating a Golden Apple gives the player extra "absorption" health for a short period.{*B*} -- The longer you remain in an area the harder the monsters that spawn in that area will be.{*B*} - - - - - {*ETB*}Welcome back! You may not have noticed but your Minecraft has just been updated.{*B*}{*B*} -There are lots of new features for you and friends to play with so here’s just a few highlights. Have a read and then go and have fun!{*B*}{*B*} -{*T1*}New Items{*ETB*} - Hardened Clay, Stained Clay, Block of Coal, Hay Bale, Activator Rail, Block of Redstone, Daylight Sensor, Dropper, Hopper, Minecart with Hopper, Minecart with TNT, Redstone Comparator, Weighted Pressure Plate, Beacon, Trapped Chest, Firework Rocket, Firework Star, Nether Star, Lead, Horse Armor, Name Tag, Horse Spawn Egg{*B*}{*B*} -{*T1*}New Mobs{*ETB*} - Wither, Wither Skeletons, Witches, Bats, Horses, Donkeys and Mules{*B*}{*B*} -{*T1*}New Features{*ETB*} - Tame and ride a horse, craft fireworks and put on a show, name animals and monsters with a Name Tag, create more advanced Redstone circuits, and new Host Options to help control what guests to your world can do!{*B*}{*B*} -{*T1*}New Tutorial World{*ETB*} – Learn how to use the old and new features in the Tutorial World. See if you can find all the secret Music Discs hidden in the world!{*B*}{*B*} - - - - - Horses - - - - {*T3*}HOW TO PLAY : HORSES{*ETW*}{*B*}{*B*} -Horses and Donkeys are found mainly in open plains. Mules are the offspring of a Donkey and a Horse, but are infertile themselves.{*B*} -All adult Horses, Donkeys and Mules can be ridden. However only Horses can be armored, and only Mules and Donkeys may be equipped with saddlebags for transporting items.{*B*}{*B*} -Horses, Donkeys and Mules must be tamed before they can be used. A horse is tamed by attempting to ride it, and managing to stay on the horse while it attempts to throw the rider off.{*B*} -When Love Hearts appear around the horse, it is tame, and will no longer attempt to throw the player off. To steer a horse, the player must equip the horse with a Saddle.{*B*}{*B*} -Saddles can be bought from villagers or found inside Chests hidden in the world.{*B*} -Tame Donkeys and Mules can be given saddlebags by attaching a Chest. These saddlebags can then be accessed whilst riding or sneaking.{*B*}{*B*} -Horses and Donkeys (but not Mules) can be bred like other animals using Golden Apples or Golden Carrots.{*B*} -Foals will grow into adult horses over time, although feeding them Wheat or Hay will speed this up.{*B*} - - - - - Beacons - - - - {*T3*}HOW TO PLAY : BEACONS{*ETW*}{*B*}{*B*} -Active Beacons project a bright beam of light into the sky and grant powers to nearby players.{*B*} -They are crafted with Glass, Obsidian and Nether Stars, which can be obtained by defeating the Wither.{*B*}{*B*} -Beacons must be placed so that they are in sunlight during the day. Beacons must be placed on Pyramids of Iron, Gold, Emerald or Diamond.{*B*} -The material the Beacon is placed on has no effect on the power of the Beacon.{*B*}{*B*} -In the Beacon menu you can select one primary power for your Beacon. The more tiers your pyramid has the more powers you will have to choose from.{*B*} -A Beacon on a pyramid with at least four tiers also gives the option of either the Regeneration secondary power or a stronger primary power.{*B*}{*B*} -To set the powers of your Beacon you must sacrifice an Emerald, Diamond, Gold or Iron Ingot in the payment slot.{*B*} -Once set, the powers will emanate from the Beacon indefinitely.{*B*} - - - - - Fireworks - - - - {*T3*}HOW TO PLAY : FIREWORKS{*ETW*}{*B*}{*B*} -Fireworks are decorative items that can be launched by hand or from Dispensers. They are crafted using Paper, Gunpowder and optionally a number of Firework Stars.{*B*} -The colors, fade, shape, size, and effects (such as trails and twinkle) of Firework Stars can be customized by including additional ingredients when crafting.{*B*}{*B*} -To craft a Firework place Gunpowder and Paper in the 3x3 crafting grid that is shown above your inventory.{*B*} -You can optionally place multiple Firework Stars in the crafting grid to add them to the Firework.{*B*} -Filling more slots in the crafting grid with Gunpowder will increase the height at which all the Firework Stars will explode.{*B*}{*B*} -You can then take the crafted Firework out of the output slot.{*B*}{*B*} -Firework Stars can be crafted by placing Gunpowder and Dye into the crafting grid.{*B*} - - The Dye will set the color of the explosion of the Firework Star.{*B*} - - The shape of the Firework Star is set by adding either a Fire Charge, Gold Nugget, Feather or Mob Head.{*B*} - - A trail or a twinkle can be added using Diamonds or Glowstone Dust.{*B*}{*B*} -After a Firework Star has been crafted, you can set the fade color of the Firework Star by crafting it with Dye. - - - - - Hoppers - - - - {*T3*}HOW TO PLAY : HOPPERS{*ETW*}{*B*}{*B*} -Hoppers are used to insert or remove items from containers, and to automatically pick up items thrown into them.{*B*} -They can affect Brewing Stands, Chests, Dispensers, Droppers, Minecarts with Chests, Minecarts with Hoppers, as well as other Hoppers.{*B*}{*B*} -Hoppers will continuously attempt to suck items out of a suitable container placed above them. They will also attempt to insert stored items into an output container.{*B*} -If a Hopper is powered by Redstone it will become inactive and stop both sucking and inserting items.{*B*}{*B*} -A Hopper points in the direction it tries to output items. To make a Hopper point to a particular block, place the Hopper against that block whilst sneaking.{*B*} - - - - - Droppers - - - - {*T3*}HOW TO PLAY : DROPPERS{*ETW*}{*B*}{*B*} -When powered by Redstone, Droppers will drop a single random item contained within them onto the ground. Use {*CONTROLLER_ACTION_USE*} to open the Dropper and then you can load the Dropper with items from your inventory.{*B*} -If the Dropper is facing a Chest or another type of Container, the item will be placed into that instead. Long chains of Droppers can be constructed to transport items over a distance, but for this to work they will have to be alternately powered on and off. - - - - - Deals more damage than by hand. - - - - Used to dig dirt, grass, sand, gravel and snow faster than by hand. Shovels are required to dig snowballs. - - - - Required to mine stone-related blocks and ore. - - - - Used to chop wood-related blocks faster than by hand. - - - - Used to till dirt and grass blocks to prepare for crops. - - - - Wooden doors are activated by using, hitting them or with Redstone. - - - - Iron doors can only be opened by Redstone, buttons or switches. - - - - NOT USED - - - - NOT USED - - - - NOT USED - - - - NOT USED - - - - Gives the user 1 Armor when worn. - - - - Gives the user 3 Armor when worn. - - - - Gives the user 2 Armor when worn. - - - - Gives the user 1 Armor when worn. - - - - Gives the user 2 Armor when worn. - - - - Gives the user 5 Armor when worn. - - - - Gives the user 4 Armor when worn. - - - - Gives the user 1 Armor when worn. - - - - Gives the user 2 Armor when worn. - - - - Gives the user 6 Armor when worn. - - - - Gives the user 5 Armor when worn. - - - - Gives the user 2 Armor when worn. - - - - Gives the user 2 Armor when worn. - - - - Gives the user 5 Armor when worn. - - - - Gives the user 3 Armor when worn. - - - - Gives the user 1 Armor when worn. - - - - Gives the user 3 Armor when worn. - - - - Gives the user 8 Armor when worn. - - - - Gives the user 6 Armor when worn. - - - - Gives the user 3 Armor when worn. - - - - A shiny ingot which can be used to craft tools made from this material. Created by smelting ore in a furnace. - - - - Allows ingots, gems, or dyes to be crafted into placeable blocks. Can be used as an expensive building block or compact storage of the ore. - - - - Used to send an electrical charge when stepped on by a player, an animal, or a monster. Wooden Pressure Plates can also be activated by dropping something on them. - - - - Used for compact staircases. - - - - Used for making long staircases. Two slabs placed on top of each other will create a normal-sized double slab block. - - - - Used for making long staircases. Two slabs placed on top of each other will create a normal-sized double slab block. - - - - Used to create light. Torches also melt snow and ice. - - - - Used as a building material and can be crafted into many things. Can be crafted from any form of wood. - - - - Used as a building material. Is not influenced by gravity like normal Sand. - - - - Used as a building material. - - - - Used to craft torches, arrows, signs, ladders, fences and as handles for tools and weapons. - - - - Used to forward time from any time at night to morning if all the players in the world are in bed, and changes the spawn point of the player. -The colors of the bed are always the same, regardless of the colors of wool used. - - - - Allows you to craft a more varied selection of items than the normal crafting. - - - - Allows you to smelt ore, create charcoal and glass, and cook fish and porkchops. - - - - Stores blocks and items inside. Place two chests side by side to create a larger chest with double the capacity. - - - - Used as a barrier that cannot be jumped over. Counts as 1.5 blocks high for players, animals and monsters, but 1 block high for other blocks. - - - - Used to climb vertically. - - - - Activated by using, hitting them or with redstone. They function as normal doors, but are a one by one block and lay flat on the ground. - - - - Shows text entered by you or other players. - - - - Used to create brighter light than torches. Melts snow/ice and can be used underwater. - - - - Used to cause explosions. Activated after placing by igniting with Flint and Steel item, or with an electrical charge. - - - - Used to hold mushroom stew. You keep the bowl when the stew has been eaten. - - - - Used to hold and transport water, lava and milk. - - - - Used to hold and transport water. - - - - Used to hold and transport lava. - - - - Used to hold and transport milk. - - - - Used to create fire, ignite TNT, and open a portal once it has been built. - - - - Used to catch fish. - - - - Displays positions of the Sun and Moon. - - - - Points to your start point. - - - - Will create an image of an area explored while held. This can be used for path-finding. - - - - When used becomes a map of the part of the world that you are in, and gets filled in as you explore. - - - - Allows for ranged attacks by using arrows. - - - - Used as ammunition for bows. - - - - Dropped by the Wither, used in crafting Beacons. - - - - When activated, create colorful explosions. The color, effect, shape and fade are determined by the Firework Star used when the Firework is created. - - - - Used to determine the color, effect and shape of a Firework. - - - - Used in Redstone circuits to maintain, compare, or subtract signal strength, or to measure certain block states. - - - - Is a type of Minecart that acts as a moving TNT block. - - - - Is a block that outputs a Redstone signal based on sunlight (or lack of sunlight). - - - - Is a special type of Minecart that functions similarly to a Hopper. It will collect items lying on tracks and from containers above it. - - - - A special type of Armor that can be equipped to a horse. Provides 5 Armor. - - - - A special type of Armor that can be equipped to a horse. Provides 7 Armor. - - - - A special type of Armor that can be equipped to a horse. Provides 11 Armor. - - - - Used to leash mobs to the player or Fence posts. - - - - Used to name mobs in the world. - - - - Restores 2.5{*ICON_SHANK_01*}. - - - - Restores 1{*ICON_SHANK_01*}. Can be used 6 times. - - - - Restores 1{*ICON_SHANK_01*}. - - - - Restores 1{*ICON_SHANK_01*}. - - - - Restores 3{*ICON_SHANK_01*}. - - - - Restores 1{*ICON_SHANK_01*}, or can be cooked in a furnace. Eating this can cause you to be poisoned. - - - - Restores 3{*ICON_SHANK_01*}. Created by cooking raw chicken in a furnace. - - - - Restores 1.5{*ICON_SHANK_01*}, or can be cooked in a furnace. - - - - Restores 4{*ICON_SHANK_01*}. Created by cooking raw beef in a furnace. - - - - Restores 1.5{*ICON_SHANK_01*}, or can be cooked in a furnace. - - - - Restores 4{*ICON_SHANK_01*}. Created by cooking a raw porkchop in a furnace. - - - - Restores 1{*ICON_SHANK_01*}, or can be cooked in a furnace. Can be fed to an Ocelot to tame it. - - - - Restores 2.5{*ICON_SHANK_01*}. Created by cooking a raw fish in a furnace. - - - - Restores 2{*ICON_SHANK_01*}, and can be crafted into a golden apple. - - - - Restores 2{*ICON_SHANK_01*}, and regenerates health for 4 seconds. Crafted from an apple and gold nuggets. - - - - Restores 2{*ICON_SHANK_01*}. Eating this can cause you to be poisoned. - - - - Used in the cake recipe, and as an ingredient for brewing potions. - - - - Used to send an electrical charge by being turned on or off. Stays in the on or off state until pressed again. - - - - Constantly sends an electrical charge, or can be used as a receiver/transmitter when connected to the side of a block. -Can also be used for low-level lighting. - - - - Used in Redstone circuits as repeater, a delayer, and/or a diode. - - - - Used to send an electrical charge by being pressed. Stays activated for approximately a second before shutting off again. - - - - Used to hold and shoot out items in a random order when given a Redstone charge. - - - - Plays a note when triggered. Hit it to change the pitch of the note. Placing this on top of different blocks will change the type of instrument. - - - - Used to guide minecarts. - - - - When powered, accelerates minecarts that pass over it. When unpowered, causes minecarts to stop on it. - - - - Functions like a Pressure Plate (sends a Redstone signal when powered) but can only be activated by a Minecart. - - - - Used to transport you, an animal, or a monster along rails. - - - - Used to transport goods along rails. - - - - Will move along rails and can push other minecarts when coal is put in it. - - - - Used to travel in water more quickly than swimming. - - - - Collected from sheep, and can be colored with dyes. - - - - Used as a building material and can be colored with dyes. This recipe is not recommended because Wool can be easily obtained from Sheep. - - - - Used as a dye to create black wool. - - - - Used as a dye to create green wool. - - - - Used as a dye to create brown wool, as an ingredient in cookies, or to grow Cocoa Pods. - - - - Used as a dye to create silver wool. - - - - Used as a dye to create yellow wool. - - - - Used as a dye to create red wool. - - - - Used to instantly grow crops, trees, tall grass, huge mushrooms and flowers, and can be used in dye recipes. - - - - Used as a dye to create pink wool. - - - - Used as a dye to create orange wool. - - - - Used as a dye to create lime wool. - - - - Used as a dye to create gray wool. - - - - Used as a dye to create light gray wool. -(Note: light gray dye can also be made by combining gray dye with bone meal, letting you make four light gray dyes from every ink sac instead of three.) - - - - Used as a dye to create light blue wool. - - - - Used as a dye to create cyan wool. - - - - Used as a dye to create purple wool. - - - - Used as a dye to create magenta wool. - - - - Used as dye to create Blue Wool. - - - - Plays Music Discs. - - - - Use these to create very strong tools, weapons or armor. - - - - Used to create brighter light than torches. Melts snow/ice and can be used underwater. - - - - Used to create books and maps. - - - - Can be used to create bookshelves or enchanted to make Enchanted Books. - - - - Allows the creation of more powerful enchantments when placed around the Enchantment Table. - - - - Used as decoration. - - - - Can be mined with an iron pickaxe or better, then smelted in a furnace to produce gold ingots. - - - - Can be mined with a stone pickaxe or better, then smelted in a furnace to produce iron ingots. - - - - Can be mined with a pickaxe to collect coal. - - - - Can be mined with a stone pickaxe or better to collect lapis lazuli. - - - - Can be mined with an iron pickaxe or better to collect diamonds. - - - - Can be mined with an iron pickaxe or better to collect redstone dust. - - - - Can be mined with a pickaxe to collect cobblestone. - - - - Collected using a shovel. Can be used for construction. - - - - Can be planted and it will eventually grow into a tree. - - - - This cannot be broken. - - - - Sets fire to anything that touches it. Can be collected in a bucket. - - - - Collected using a shovel. Can be smelted into glass using the furnace. Is affected by gravity if there is no other tile underneath it. - - - - Collected using a shovel. Sometimes produces flint when dug up. Is affected by gravity if there is no other tile underneath it. - - - - Chopped using an axe, and can be crafted into planks or used as a fuel. - - - - Created in a furnace by smelting sand. Can be used for construction, but will break if you try to mine it. - - - - Mined from stone using a pickaxe. Can be used to construct a furnace or stone tools. - - - - Baked from clay in a furnace. - - - - Can be baked into bricks in a furnace. - - - - When broken drops clay balls which can be baked into bricks in a furnace. - - - - A compact way to store snowballs. - - - - Can be dug with a shovel to create snowballs. - - - - Sometimes produces wheat seeds when broken. - - - - Can be crafted into a dye. - - - - Can be crafted with a bowl to make stew. - - - - Can only be mined with a diamond pickaxe. Is produced by the meeting of water and still lava, and is used to build a portal. - - - - Spawns monsters into the world. - - - - Is placed on the ground to carry an electrical charge. When brewed with a potion it will increase the duration of the effect. - - - - When fully grown, crops can be harvested to collect wheat. - - - - Ground that has been prepared ready to plant seeds. - - - - Can be cooked in a furnace to create a green dye. - - - - Can be crafted to create sugar. - - - - Can be worn as a helmet or crafted with a torch to create a Jack-O-Lantern. It is also the main ingredient in Pumpkin Pie. - - - - Burns forever if set alight. - - - - Slows the movement of anything walking over it. - - - - Standing in the portal allows you to pass between the Overworld and the Nether. - - - - Used as a fuel in a furnace, or crafted to make a torch. - - - - Collected by killing a spider, and can be crafted into a Bow or Fishing Rod, or placed on the ground to create Tripwire. - - - - Collected by killing a chicken, and can be crafted into an arrow. - - - - Collected by killing a Creeper, and can be crafted into TNT or used as an ingredient for brewing potions. - - - - Can be planted in farmland to grow crops. Make sure there's enough light for the seeds to grow! - - - - Harvested from crops, and can be used to craft food items. - - - - Collected by digging gravel, and can be used to craft a flint and steel. - - - - When used on a pig it allows you to ride the pig. The pig can then be steered using a Carrot on a Stick. - - - - Collected by digging snow, and can be thrown. - - - - Collected by killing a cow, and can be crafted into armor or used to make Books. - - - - Collected by killing a Slime, and used as an ingredient for brewing potions or crafted to make Sticky Pistons. - - - - Dropped randomly by chickens, and can be crafted into food items. - - - - Collected by mining Glowstone, and can be crafted to make Glowstone blocks again or brewed with a potion to increase the potency of the effect. - - - - Collected by killing a Skeleton. Can be crafted into bone meal. Can be fed to a wolf to tame it. - - - - Collected by getting a Skeleton to kill a Creeper. Can be played in a jukebox. - - - - An invisible, but solid block. - - - - Extinguishes fire and helps crops grow. Can be collected in a bucket. - - - - When broken sometimes drops a sapling which can then be replanted to grow into a tree. - - - - Found in dungeons, can be used for construction and decoration. - - - - Used to obtain wool from sheep and harvest leaf blocks. - - - - When powered (using a button, a lever, a pressure plate, a redstone torch, or redstone with any one of these), a piston extends if it can and pushes blocks. - - - - When powered (using a button, a lever, a pressure plate, a redstone torch, or redstone with any one of these), a piston extends if it can and pushes blocks. When it retracts it pulls back the block touching the extended part of the piston. - - - - Made from Stone blocks, and commonly found in Strongholds. - - - - Used as a barrier, similar to fences. - - - - Similar to a door, but used primarily with fences. - - - - Can be crafted from Melon Slices. - - - - Transparent blocks that can be used as an alternative to Glass Blocks. - - - - Can be planted to grow pumpkins. - - - - Can be planted to grow melons. - - - - Dropped by Enderman when they die. When thrown, the player will be teleported to the position the Ender Pearl lands at, and will lose some health. - - - - A block of dirt with grass growing on top. Collected using a shovel. Can be used for construction. - - - - Can be used for construction and decoration. - - - - Slows movement when walking through it. Can be destroyed using shears to collect string. - - - - Spawns a Silverfish when destroyed. May also spawn Silverfish if nearby to another Silverfish being attacked. - - - - Grows over time when placed. Can be collected using shears. Can be climbed like a ladder. - - - - Slippery when walked on. Turns into water if above another block when destroyed. Melts if close enough to a light source or when placed in The Nether. - - - - Can be used as decoration. - - - - Used in potion brewing, and for locating Strongholds. Dropped by Blazes who tend to be found near or in Nether Fortresses. - - - - Used in potion brewing. Dropped by Ghasts when they die. - - - - Dropped by Zombie Pigmen when they die. Zombie Pigmen can be found in the Nether. Used as an ingredient for brewing potions. - - - - Used in potion brewing. This can be found naturally growing in Nether Fortresses. It can also be planted on Soul Sand. - - - - When used, can have various effects, depending on what it is used on. - - - - Can be filled with water, and used as the starting ingredient for a potion in the Brewing Stand. - - - - This is a poisonous food and brewing item. Dropped when a Spider or Cave Spider is killed by a player. - - - - Used in potion brewing, mainly to create potions with a negative effect. - - - - Used in potion brewing, or crafted with other items to make Eye of Ender or Magma Cream. - - - - Used in potion brewing. - - - - Used for making Potions and Splash Potions. - - - - Filled with water by rain or with a bucket of water, and can then be used to fill Glass Bottles with water. - - - - When thrown, will show the direction to an End Portal. When twelve of these are placed in the End Portal Frames, the End Portal will be activated. - - - - Used in potion brewing. - - - - Similar to Grass Blocks, but very good for growing mushrooms on. - - - - Floats on water, and can be walked on. - - - - Used to build Nether Fortresses. Immune to Ghast's fireballs. - - - - Used in Nether Fortresses. - - - - Found in Nether Fortresses, and will drop Nether Wart when broken. - - - - This allows players to enchant Swords, Pickaxes, Axes, Shovels, Bows and Armor, using the player's Experience Points. - - - - This can be activated using twelve Eye of Ender, and will allow the player to travel to The End dimension. - - - - Used to form an End Portal. - - - - A block type found in The End. It has a very high blast resistance, so is useful for building with. - - - - This block is created by the defeat of the Dragon in The End. - - - - When thrown, it drops Experience Orbs which increase your experience points when collected. - - - - Useful for setting things on fire, or for indiscriminately starting fires when fired from a Dispenser. - - - - These are similar to a display case, and will display the item or block placed in it. - - - - When thrown can spawn a creature of the type indicated. - - - - Used for making long staircases. Two slabs placed on top of each other will create a normal-sized double slab block. - - - - Used for making long staircases. Two slabs placed on top of each other will create a normal-sized double slab block. - - - - Created by smelting Netherrack in a furnace. Can be crafted into Nether Brick blocks. - - - - When powered they emit light. - - - - Can be farmed to collect Cocoa Beans. - - - - Mob Heads can be placed as a decoration, or worn as a mask in the helmet slot. - - - - Used to execute commands. - - - - Projects a beam of light into the sky and can provide Status Effects to nearby players. - - - - Stores blocks and items inside. Place two chest side by side to create a larger chest with double capacity. The trapped chest also creates a Redstone charge when opened. - - - - Provides a Redstone charge. The charge will be stronger if more items are on the plate. - - - - Provides a Redstone charge. The charge will be stronger if more items are on the plate. Requires more weight than the light plate. - - - - Used as a redstone power source. Can be crafted back into Redstone. - - - - Used to catch items or to transfer items into and out of containers. - - - - A type of rail that can enable or disable Minecarts with Hoppers and trigger Minecarts with TNT. - - - - Used to hold and drop items, or push items into another container, when given a Redstone charge. - - - - Colorful blocks crafted by dyeing Hardened clay. - - - - Can be fed to Horses, Donkeys or Mules to heal up to 10 Hearts. Speeds up the growth of foals. - - - - Created by smelting Clay in a furnace. - - - - Crafted from glass and a dye. - - - - Crafted from Stained Glass - - - - A compact way of storing Coal. Can be used as fuel in a Furnace. - - - - Squid - - - - Drops ink sacs when killed. - - - - Cow - - - - Drops leather when killed. Can also be milked with a bucket. - - - - Sheep - - - - Drops wool when sheared (if it has not already been sheared). Can be dyed to make its wool a different color. - - - - Chicken - - - - Drops feathers when killed, and also randomly lays eggs. - - - - Pig - - - - Drops porkchops when killed. Can be ridden by using a saddle. - - - - Wolf - - - - Docile until attacked, when they will attack you back. Can be tamed using bones which causes the wolf to follow you around and attack anything that attacks you. - - - - Creeper - - - - Explodes if you get too close! - - - - Skeleton - - - - Fires arrows at you. Drops arrows when killed. - - - - Spider - - - - Attacks you when you are close to it. Can climb walls. Drops string when killed. - - - - Zombie - - - - Attacks you when you are close to it. - - - - Zombie Pigman - - - - Initially docile, but will attack in groups if you attack one. - - - - Ghast - - - - Fires flaming balls at you that explode on contact. - - - - Slime - - - - Split into smaller Slimes when damaged. - - - - Enderman - - - - Will attack you if you look at it. Can also move blocks around. - - - - Silverfish - - - - Attracts nearby hidden Silverfish when attacked. Hides in stone blocks. - - - - Cave Spider - - - - Has a venomous bite. - - - - Mooshroom - - - - Makes mushroom stew when used with a bowl. Drops mushrooms and becomes a normal cow when sheared. - - - - Snow Golem - - - - The Snow Golem can be created by players using snow blocks and a pumpkin. They will throw snowballs at their creators enemies. - - - - Ender Dragon - - - - This is a large black dragon found in The End. - - - - Blaze - - - - These are enemies found in the Nether, mostly inside Nether Fortresses. They will drop Blaze Rods when killed. - - - - Magma Cube - - - - These can be found in The Nether. Similar to Slimes, they will break up into smaller versions when killed. - - - - Villager - - - - Ocelot - - - - These can be found in Jungles. They can be tamed by feeding them Raw Fish. You will need to let the Ocelot approach you though, since any sudden movements will scare it away. - - - - Iron Golem - - - - Appear in Villages to protect them, and can be created using Iron Blocks and Pumpkins. - - - - Bat - - - - These flying creatures are found in caverns or other large enclosed spaces. - - - - Witch - - - - These enemies can be found in swamps and attack you by throwing Potions. They drop Potions when killed. - - - - Horse - - - - These animals can be tamed and can then be ridden. - - - - Donkey - - - - These animals can be tamed and can then be ridden. They can have a chest attached. - - - - Mule - - - - Born when a Horse and a Donkey breed. These animals can be tamed and can then be ridden and carry chests. - - - - Zombie Horse - - - - Skeleton Horse - - - - Wither - - - - These are crafted from Wither Skulls and Soul Sand. They fire exploding skulls at you. - - - - Explosives Animator - - - - Concept Artist - - - - Number Crunching and Statistics - - - - Bully Coordinator - - - - Original Design and Code by - - - - Project Manager/Producer - - - - Rest of Mojang Office - - - - Lead Game Programmer Minecraft PC - - - - Ninja Coder - - - - CEO - - - - White Collar Worker - - - - Customer Support - - - - Office DJ - - - - Designer/Programmer Minecraft - Pocket Edition - - - - Developer - - - - Chief Architect - - - - Art Developer - - - - Game Crafter - - - - Director of Fun - - - - Music and Sounds - - - - Programming - - - - Art - - - - QA - - - - Executive Producer - - - - Lead Producer - - - - Producer - - - - Test Lead - - - - Lead Tester - - - - Design Team - - - - Development Team - - - - Release Management - - - - Director, XBLA Publishing - - - - Business Development - - - - Portfolio Director - - - - Product Manager - - - - Marketing - - - - Community Manager - - - - Europe Localization Team - - - - Redmond Localization Team - - - - Asia Localization Team - - - - User Research Team - - - - MGS Central Teams - - - - Milestone Acceptance Tester - - - - Special Thanks - - - - Test Manager - - - - Senior Test Lead - - - - SDET - - - - Project STE - - - - Additional STE - - - - Test Associates - - - - Jon KÃ¥gström - - - - Tobias Möllstam - - - - Risë Lugo - - - - Wooden Sword - - - - Stone Sword - - - - Iron Sword - - - - Diamond Sword - - - - Golden Sword - - - - Wooden Shovel - - - - Stone Shovel - - - - Iron Shovel - - - - Diamond Shovel - - - - Golden Shovel - - - - Wooden Pickaxe - - - - Stone Pickaxe - - - - Iron Pickaxe - - - - Diamond Pickaxe - - - - Golden Pickaxe - - - - Wooden Axe - - - - Stone Axe - - - - Iron Axe - - - - Diamond Axe - - - - Golden Axe - - - - Wooden Hoe - - - - Stone Hoe - - - - Iron Hoe - - - - Diamond Hoe - - - - Golden Hoe - - - - Oak Door - - - - Iron Door - - - - Chain Helmet - - - - Chain Chestplate - - - - Chain Leggings - - - - Chain Boots - - - - Leather Cap - - - - Iron Helmet - - - - Diamond Helmet - - - - Golden Helmet - - - - Leather Tunic - - - - Iron Chestplate - - - - Diamond Chestplate - - - - Golden Chestplate - - - - Leather Pants - - - - Iron Leggings - - - - Diamond Leggings - - - - Golden Leggings - - - - Leather Boots - - - - Iron Boots - - - - Diamond Boots - - - - Golden Boots - - - - Iron Ingot - - - - Gold Ingot - - - - Bucket - - - - Water Bucket - - - - Lava Bucket - - - - Flint and Steel - - - - Apple - - - - Bow - - - - Arrow - - - - Coal - - - - Charcoal - - - - Diamond - - - - Stick - - - - Bowl - - - - Mushroom Stew - - - - String - - - - Feather - - - - Gunpowder - - - - Seeds - - - - Wheat - - - - Bread - - - - Flint - - - - Raw Porkchop - - - - Cooked Porkchop - - - - Painting - - - - Golden Apple - - - - Sign - - - - Minecart - - - - Saddle - - - - Redstone - - - - Snowball - - - - Boat - - - - Leather - - - - Milk Bucket - - - - Brick - - - - Clay - - - - Sugar Canes - - - - Paper - - - - Book - - - - Slimeball - - - - Minecart with Chest - - - - Minecart with Furnace - - - - Egg - - - - Compass - - - - Fishing Rod - - - - Clock - - - - Glowstone Dust - - - - Raw Fish - - - - Cooked Fish - - - - Dye Powder - - - - Ink Sac - - - - Rose Red - - - - Cactus Green - - - - Cocoa Beans - - - - Lapis Lazuli - - - - Purple Dye - - - - Cyan Dye - - - - Light Gray Dye - - - - Gray Dye - - - - Pink Dye - - - - Lime Dye - - - - Dandelion Yellow - - - - Light Blue Dye - - - - Magenta Dye - - - - Orange Dye - - - - Bone Meal - - - - Bone - - - - Sugar - - - - Cake - - - - Bed - - - - Redstone Repeater - - - - Cookie - - - - Map - - - - Empty Map - - - - Music Disc - "13" - - - - Music Disc - "cat" - - - - Music Disc - "blocks" - - - - Music Disc - "chirp" - - - - Music Disc - "far" - - - - Music Disc - "mall" - - - - Music Disc - "mellohi" - - - - Music Disc - "stal" - - - - Music Disc - "strad" - - - - Music Disc - "ward" - - - - Music Disc - "11" - - - - Music Disc - "where are we now" - - - - Shears - - - - Pumpkin Seeds - - - - Melon Seeds - - - - Raw Chicken - - - - Cooked Chicken - - - - Raw Beef - - - - Steak - - - - Rotten Flesh - - - - Ender Pearl - - - - Melon Slice - - - - Blaze Rod - - - - Ghast Tear - - - - Gold Nugget - - - - Nether Wart - - - - {*splash*}{*prefix*}Potion {*postfix*} - - - - Glass Bottle - - - - Water Bottle - - - - Spider Eye - - - - Fermented Spider Eye - - - - Blaze Powder - - - - Magma Cream - - - - Brewing Stand - - - - Cauldron - - - - Eye of Ender - - - - Glistering Melon - - - - Bottle o' Enchanting - - - - Fire Charge - - - - Fire Charge (Charcoal) - - - - Fire Charge (Coal) - - - - Item Frame - - - - Spawn {*CREATURE*} - - - - Nether Brick - - - - Skull - - - - Skeleton Skull - - - - Wither Skeleton Skull - - - - Zombie Head - - - - Head - - - - %s's Head - - - - Creeper Head - - - - Nether Star - - - - Firework Rocket - - - - Firework Star - - - - Redstone Comparator - - - - Minecart with TNT - - - - Minecart with Hopper - - - - Iron Horse Armor - - - - Gold Horse Armor - - - - Diamond Horse Armor - - - - Lead - - - - Name Tag - - - - Stone - - - - Grass Block - - - - Dirt - - - - Cobblestone - - - - Oak Planks - - - - Spruce Planks - - - - Birch Planks - - - - Jungle Planks - - - - Planks (any type) - - - - Sapling - - - - Oak Sapling - - - - Spruce Sapling - - - - Birch Sapling - - - - Jungle Tree Sapling - - - - Bedrock - - - - Barrier - - - - Water - - - - Lava - - - - Sand - - - - Sandstone - - - - Gravel - - - - Gold Ore - - - - Iron Ore - - - - Coal Ore - - - - Wood - - - - Oak Wood - - - - Spruce Wood - - - - Birch Wood - - - - Jungle Wood - - - - Oak - - - - Spruce - - - - Birch - - - - Leaves - - - - Oak Leaves - - - - Spruce Leaves - - - - Birch Leaves - - - - Jungle Leaves - - - - Sponge - - - - Glass - - - - Wool - - - - Black Wool - - - - Red Wool - - - - Green Wool - - - - Brown Wool - - - - Blue Wool - - - - Purple Wool - - - - Cyan Wool - - - - Light Gray Wool - - - - Gray Wool - - - - Pink Wool - - - - Lime Wool - - - - Yellow Wool - - - - Light Blue Wool - - - - Magenta Wool - - - - Orange Wool - - - - White Wool - - - - Dandelion - - - - Poppy - - - - Mushroom - - - - Block of Gold - - - - A compact way of storing Gold. - - - - A compact way of storing Iron. - - - - Block of Iron - - - - Stone Slab - - - - Stone Slab - - - - Sandstone Slab - - - - Oak Wood Slab - - - - Cobblestone Slab - - - - Bricks Slab - - - - Stone Bricks Slab - - - - Oak Wood Slab - - - - Spruce Wood Slab - - - - Birch Wood Slab - - - - Jungle Wood Slab - - - - Nether Brick Slab - - - - Bricks - - - - TNT - - - - Bookshelf - - - - Moss Stone - - - - Obsidian - - - - Torch - - - - Torch (Coal) - - - - Torch (Charcoal) - - - - Fire - - - - Monster Spawner - - - - Oak Wood Stairs - - - - Chest - - - - Redstone Dust - - - - Diamond Ore - - - - Block of Diamond - - - - A compact way of storing Diamonds. - - - - Crafting Table - - - - Crops - - - - Farmland - - - - Furnace - - - - Sign - - - - Oak Door - - - - Ladder - - - - Rail - - - - Powered Rail - - - - Detector Rail - - - - Stone Stairs - - - - Lever - - - - Pressure Plate - - - - Iron Door - - - - Redstone Ore - - - - Redstone Torch - - - - Button - - - - Snow - - - - Ice - - - - Cactus - - - - Clay - - - - Sugar Cane - - - - Jukebox - - - - Oak Fence - - - - Pumpkin - - - - Jack-O-Lantern - - - - Netherrack - - - - Soul Sand - - - - Glowstone - - - - Portal - - - - Lapis Lazuli Ore - - - - Lapis Lazuli Block - - - - A compact way of storing Lapis Lazuli. - - - - Dispenser - - - - Note Block - - - - Cake - - - - Bed - - - - Web - - - - Tall Grass - - - - Dead Bush - - - - Diode - - - - Locked Chest - - - - Trapdoor - - - - Wool (any color) - - - - Piston - - - - Sticky Piston - - - - Silverfish Block - - - - Stone Bricks - - - - Mossy Stone Bricks - - - - Cracked Stone Bricks - - - - Chiseled Stone Bricks - - - - Mushroom - - - - Mushroom - - - - Iron Bars - - - - Glass Pane - - - - Melon - - - - Pumpkin Stem - - - - Melon Stem - - - - Vines - - - - Oak Fence Gate - - - - Brick Stairs - - - - Stone Brick Stairs - - - - Silverfish Stone - - - - Silverfish Cobblestone - - - - Silverfish Stone Brick - - - - Mycelium - - - - Lily Pad - - - - Nether Brick - - - - Nether Brick Fence - - - - Nether Brick Stairs - - - - Nether Wart - - - - Enchantment Table - - - - Brewing Stand - - - - Cauldron - - - - End Portal - - - - End Portal Frame - - - - End Stone - - - - Dragon Egg - - - - Shrub - - - - Fern - - - - Sandstone Stairs - - - - Spruce Wood Stairs - - - - Birch Wood Stairs - - - - Jungle Wood Stairs - - - - Redstone Lamp - - - - Cocoa - - - - Skull - - - - Command Block - - - - Beacon - - - - Trapped Chest - - - - Weighted Pressure Plate (Light) - - - - Weighted Pressure Plate (Heavy) - - - - Redstone Comparator - - - - Daylight Sensor - - - - Block of Redstone - - - - Hopper - - - - Activator Rail - - - - Dropper - - - - Stained Clay - - - - Hay Bale - - - - Hardened Clay - - - - Block of Coal - - - - Black Stained Clay - - - - Red Stained Clay - - - - Green Stained Clay - - - - Brown Stained Clay - - - - Blue Stained Clay - - - - Purple Stained Clay - - - - Cyan Stained Clay - - - - Light Gray Stained Clay - - - - Gray Stained Clay - - - - Pink Stained Clay - - - - Lime Stained Clay - - - - Yellow Stained Clay - - - - Light Blue Stained Clay - - - - Magenta Stained Clay - - - - Orange Stained Clay - - - - White Stained Clay - - - - Stained Glass - - - - Black Stained Glass - - - - Red Stained Glass - - - - Green Stained Glass - - - - Brown Stained Glass - - - - Blue Stained Glass - - - - Purple Stained Glass - - - - Cyan Stained Glass - - - - Light Gray Stained Glass - - - - Gray Stained Glass - - - - Pink Stained Glass - - - - Lime Stained Glass - - - - Yellow Stained Glass - - - - Light Blue Stained Glass - - - - Magenta Stained Glass - - - - Orange Stained Glass - - - - White Stained Glass - - - - Stained Glass Pane - - - - Black Stained Glass Pane - - - - Red Stained Glass Pane - - - - Green Stained Glass Pane - - - - Brown Stained Glass Pane - - - - Blue Stained Glass Pane - - - - Purple Stained Glass Pane - - - - Cyan Stained Glass Pane - - - - Light Gray Stained Glass Pane - - - - Gray Stained Glass Pane - - - - Pink Stained Glass Pane - - - - Lime Stained Glass Pane - - - - Yellow Stained Glass Pane - - - - Light Blue Stained Glass Pane - - - - Magenta Stained Glass Pane - - - - Orange Stained Glass Pane - - - - White Stained Glass Pane - - - - Small Ball - - - - Large Ball - - - - Star-shaped - - - - Creeper-shaped - - - - Burst - - - - Unknown Shape - - - - Black - - - - Red - - - - Green - - - - Brown - - - - Blue - - - - Purple - - - - Cyan - - - - Light Gray - - - - Gray - - - - Pink - - - - Lime - - - - Yellow - - - - Light Blue - - - - Magenta - - - - Orange - - - - White - - - - Custom - - - - Fade to - - - - Twinkle - - - - Trail - - - - Flight Duration: - - - - Current Controls - - - - Layout - - - - Move/Sprint - - - - Look - - - - Pause - - - - Jump - - - - Jump/Fly Up - - - - Inventory - - - - Cycle Held Item - - - - Action - - - - Use - - - - Crafting - - - - Drop - - - - Sneak - - - - Sneak/Fly Down - - - - Change Camera Mode - - - - Players/Invite - - - - Movement (When Flying) - - - - Layout 1 - - - - Layout 2 - - - - Layout 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {*B*}Press{*CONTROLLER_VK_A*} to continue. - - - - {*B*}Press{*CONTROLLER_VK_A*} to start the tutorial.{*B*} -Press{*CONTROLLER_VK_B*} if you think you are ready to play on your own. - - - - Minecraft is a game about placing blocks to build anything you can imagine. -At night monsters come out, make sure to build a shelter before that happens. - - - - Use{*CONTROLLER_ACTION_LOOK*} to look up, down and around. - - - - Use{*CONTROLLER_ACTION_MOVE*} to move around. - - - - To sprint, push{*CONTROLLER_ACTION_MOVE*} forward twice quickly. While you hold{*CONTROLLER_ACTION_MOVE*} forward, the character will continue to sprint unless they run out of sprint time or food. - - - - Press{*CONTROLLER_ACTION_JUMP*} to jump. - - - - Hold{*CONTROLLER_ACTION_ACTION*} to mine and chop using your hand or whatever you are holding. You may need to craft a tool to mine some blocks... - - - - Hold{*CONTROLLER_ACTION_ACTION*} to chop down 4 blocks of wood (tree trunks).{*B*}When a block breaks you can pick it up by standing near to the floating item that appears, causing it to appear in your inventory. - - - - Press{*CONTROLLER_ACTION_CRAFTING*} to open the crafting interface. - - - - As you collect and craft more items, your inventory will fill up.{*B*} -Press{*CONTROLLER_ACTION_INVENTORY*} to open the inventory. - - - - As you move around, mine and attack, you will deplete your food bar{*ICON_SHANK_01*}. Sprinting and sprint jumping use a lot more food than walking and jumping normally. - - - - If you lose some health, but have a food bar with 9 or more{*ICON_SHANK_01*} in it, your health will automatically replenish. Eating food will replenish your food bar. - - - - With a food item in your hand, hold{*CONTROLLER_ACTION_USE*} to eat it and replenish your food bar. You cannot eat if your food bar is full. - - - - Your food bar is low, and you have lost some health. Eat the steak in your inventory to replenish your food bar and start healing.{*ICON*}364{*/ICON*} - - - - The wood that you have collected can be crafted into planks. Open the crafting interface to craft them.{*PlanksIcon*} - - - - A lot of crafting can involve multiple steps. Now that you have some planks there are more items that you can craft. Create a crafting table.{*CraftingTableIcon*} - - - - To make collecting blocks faster you can build tools designed for the job. Some tools have a handle made of sticks. Craft some sticks now.{*SticksIcon*} - - - - Use{*CONTROLLER_ACTION_LEFT_SCROLL*} and{*CONTROLLER_ACTION_RIGHT_SCROLL*} to change the current held item. - - - - Use{*CONTROLLER_ACTION_USE*} to use items, interact with objects and place some items. Items that have been placed can be picked up again by mining them with the right tool. - - - - With the crafting table selected, point the crosshair where you want it and use{*CONTROLLER_ACTION_USE*} to place a crafting table. - - - - Point the crosshair at the crafting table and press{*CONTROLLER_ACTION_USE*} to open it. - - - - A shovel helps dig soft blocks, like dirt and snow, faster. As you collect more materials you can craft tools that work faster and last longer. Create a wooden shovel.{*WoodenShovelIcon*} - - - - An axe helps chop wood and wooden tiles, faster. As you collect more materials you can craft tools that work faster and last longer. Create a wooden axe.{*WoodenHatchetIcon*} - - - - A pickaxe helps dig hard blocks, like stone and ore, faster. As you collect more materials you can craft tools that work faster and last longer, and allow you to mine harder materials. Create a wooden pickaxe.{*WoodenPickaxeIcon*} - - - - Open the container - - - - Night time can approach quickly, and it is dangerous to be outside unprepared. You can craft armor and weapons, but it is sensible to have a safe shelter. - - - - Nearby there is an abandoned Miner's shelter that you can complete to be safe overnight. - - - - You will need to collect the resources to complete the shelter. Walls and roof can be made of any tile type, but you will want to create a door, some windows and lighting. - - - - Use your pickaxe to mine some stone blocks. Stone blocks will produce cobblestone when mined. If you collect 8 cobblestone blocks you can build a furnace. You may need to dig through some dirt to reach the stone, so use your shovel for this.{*StoneIcon*} - - - - You have collected enough cobblestone to build a furnace. Use your crafting table to create one. - - - - Use{*CONTROLLER_ACTION_USE*} to place the furnace in the world, and then open it. - - - - Use the furnace to create some charcoal. If you are waiting for it to finish how about using the time to collect more materials to finish the shelter? - - - - Use the furnace to create some glass. If you are waiting for it to finish how about using the time to collect more materials to finish the shelter? - - - - A good shelter will have a door so that you can easily go in and out without having to mine and replace the walls. Craft a wooden door now.{*WoodenDoorIcon*} - - - - Use{*CONTROLLER_ACTION_USE*} to place the door. You can use{*CONTROLLER_ACTION_USE*} to open and close a wooden door in the world. - - - - It can get very dark at night, so you will want some lighting inside your shelter so that you can see. Craft a torch now from sticks and charcoal using the crafting interface.{*TorchIcon*} - - - - You have completed the first part of the tutorial. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to continue with the tutorial.{*B*} -Press{*CONTROLLER_VK_B*} if you think you are ready to play on your own. - - - - This is your inventory. It shows items available for use in your hand, and all the other items that you are carrying. Your armor is also shown here. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to continue.{*B*} -Press{*CONTROLLER_VK_B*} if you already know how to use the inventory. - - - - Use{*CONTROLLER_MENU_NAVIGATE*} to move the pointer. Use{*CONTROLLER_VK_A*} to pick an item under the pointer. -If there is more than one item here this will pick them all up, or you can use{*CONTROLLER_VK_X*} to pick up just half of them. - - - - Move this item with the pointer over another space in the inventory and place it down using{*CONTROLLER_VK_A*}. -With multiple items on the pointer, use{*CONTROLLER_VK_A*} to place them all, or{*CONTROLLER_VK_X*} to place just one. - - - - If you move the pointer outside the edge of the interface with an item on the pointer, you can drop the item. - - - - If you want more information about an item, move the pointer over the item and press{*CONTROLLER_ACTION_MENU_PAGEDOWN*} . - - - - Press{*CONTROLLER_VK_B*} now to exit the inventory. - - - - This is the creative mode inventory. It shows items available for use in your hand, and all the other items that you can choose from. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to continue.{*B*} -Press{*CONTROLLER_VK_B*} if you already know how to use the creative mode inventory. - - - - Use{*CONTROLLER_MENU_NAVIGATE*} to move the pointer. -When on the item list, use{*CONTROLLER_VK_A*} to pick an item under the pointer, and use{*CONTROLLER_VK_Y*} to pick up a full stack of that item. - - - - The pointer will automatically move over a space in the use row. You can place it down using{*CONTROLLER_VK_A*}. Once you have placed the item, the pointer will return to the item list where you can select another item. - - - - If you move the pointer outside the edge of the interface with an item on the pointer, you can drop the item into the world. To clear all items in the quick select bar, press{*CONTROLLER_VK_X*}. - - - - Scroll through the Group Type tabs at the top using{*CONTROLLER_VK_LB*} and{*CONTROLLER_VK_RB*} to select the group type of the item you wish to pickup. - - - - If you want more information about an item, move the pointer over the item and press{*CONTROLLER_ACTION_MENU_PAGEDOWN*} . - - - - Press{*CONTROLLER_VK_B*} now to exit the creative mode inventory. - - - - This is the crafting interface. This interface allows you to combine the items you've collected to make new items. - - - - {*B*}Press{*CONTROLLER_VK_A*} to continue.{*B*} -Press{*CONTROLLER_VK_B*} if you already know how to craft. - - - - {*B*} -Press{*CONTROLLER_VK_X*} to show the item description. - - - - {*B*} -Press{*CONTROLLER_VK_X*} to show the ingredients required to make the current item. - - - - {*B*} -Press{*CONTROLLER_VK_X*} to show the inventory again. - - - - Scroll through the Group Type tabs at the top using{*CONTROLLER_VK_LB*} and{*CONTROLLER_VK_RB*} to select the group type of the item you wish to craft, then use{*CONTROLLER_MENU_NAVIGATE*} to select the item to craft. - - - - The crafting area shows the items you require in order to craft the new item. Press{*CONTROLLER_VK_A*} to craft the item and place it in your inventory. - - - - You can craft a larger selection of items using a crafting table. Crafting on a table works in the same way as basic crafting, but you have a larger crafting area allowing more combinations of ingredients. - - - - The bottom right part of the crafting interface shows your inventory. This area can also show a description of the currently selected item, and the ingredients required to craft it. - - - - The description of the currently selected item is now displayed. The description can give you an idea of what the item can be used for. - - - - The list of ingredients required to craft the selected item are now displayed. - - - - The wood that you have collected can be crafted into planks. Select the planks icon and press{*CONTROLLER_VK_A*} to create them.{*PlanksIcon*} - - - - Now you have built a crafting table you should place it in the world to enable you to build a larger selection of items.{*B*} -Press{*CONTROLLER_VK_B*} now to exit the crafting interface. - - - - Press{*CONTROLLER_VK_LB*} and{*CONTROLLER_VK_RB*} to change to the group type of the items you wish to craft. Select the tools group.{*ToolsIcon*} - - - - Press{*CONTROLLER_VK_LB*} and{*CONTROLLER_VK_RB*} to change to the group type of the items you wish to craft. Select the structures group.{*StructuresIcon*} - - - - Use{*CONTROLLER_MENU_NAVIGATE*} to change to the item you wish to craft. Some items have multiple versions depending on the materials used. Select the wooden shovel.{*WoodenShovelIcon*} - - - - A lot of crafting can involve multiple steps. Now that you have some planks there are more items that you can craft. Use{*CONTROLLER_MENU_NAVIGATE*} to change to the item you wish to craft. Select the crafting table.{*CraftingTableIcon*} - - - - With the tools you have built you are off to a great start, and are able to collect a variety of different materials more efficiently.{*B*} -Press{*CONTROLLER_VK_B*} now to exit the crafting interface. - - - - Some items can not be created using the crafting table, but require a furnace. Craft a furnace now.{*FurnaceIcon*} - - - - Place the furnace you have crafted in the world. You will want to put this inside your shelter.{*B*} -Press{*CONTROLLER_VK_B*} now to exit the crafting interface. - - - - This is the furnace interface. A furnace allows you to change items by firing them. For example, you can turn iron ore into iron ingots in the furnace. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to continue.{*B*} -Press{*CONTROLLER_VK_B*} if you already know how to use a furnace. - - - - You need to put some fuel into the bottom slot of the furnace, and the item to be changed in the top slot. The furnace will then fire up and start working, putting the result in the right-hand slot. - - - - Many wooden items can be used as fuels, but not everything burns for the same time. You may also discover other items in the world that can be used as a fuel. - - - - When your items have been fired, you can move them from the output area into your inventory. You should experiment with different ingredients to see what you can make. - - - - If you use wood as the ingredient then you can make charcoal. Put some fuel in the furnace and wood in the ingredient slot. It can take some time for the furnace to create the charcoal, so feel free to do something else and come back to check the progress. - - - - Charcoal can be used as a fuel, as well as being crafted into a torch with a stick. - - - - Placing sand in the ingredient slot allows you to make glass. Create some glass blocks to use as windows in your shelter. - - - - This is the brewing interface. You can use this to create potions that have a variety of different effects. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to continue.{*B*} -Press{*CONTROLLER_VK_B*} if you already know how to use the brewing stand. - - - - You brew potions by placing an ingredient in the top slot, and a potion or water bottle in the bottom slots (up to 3 can be brewed at one time). Once a valid combination is entered the brewing process will start and create the potion after a short time. - - - - All potions start with a Water Bottle. Most potions are created by first using a Nether Wart to make an Awkward Potion, and will require at least one more ingredient to make the final potion. - - - - Once you have a potion you can modify its effects. Adding Redstone Dust increases the duration of its effect and adding Glowstone Dust can make its effect more powerful. - - - - Adding Fermented Spider Eye corrupts the potion and can turn it into a potion with the opposite effect, and adding Gunpowder turns the potion into a Splash Potion which can be thrown to apply its affect to a nearby area. - - - - Create a Potion of Fire Resistance by first adding Nether Wart to a Water Bottle, and then adding Magma Cream. - - - - Press{*CONTROLLER_VK_B*} now to exit the brewing interface. - - - - In this area there is a Brewing Stand, a Cauldron and a chest full of items for brewing. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about brewing and potions.{*B*} -Press{*CONTROLLER_VK_B*} if you already know about brewing and potions. - - - - The first step in brewing a potion is to create a Water Bottle. Take a Glass Bottle from the chest. - - - - You can fill a glass bottle from a Cauldron that has water in it, or from a block of water. Fill your glass bottle now by pointing at a water source and pressing{*CONTROLLER_ACTION_USE*}. - - - - If a cauldron becomes empty, you can refill it with a Water Bucket. - - - - Use the Brewing Stand to create a Potion of Fire Resistance. You will need a Water Bottle, Nether Wart and Magma Cream. - - - - With a potion in your hand, hold{*CONTROLLER_ACTION_USE*} to use it. For a normal potion you will drink it and apply the effect to yourself, and for a Splash potion you will throw it and apply the effect to creatures near where it hits. -Splash potions can be created by adding gunpowder to normal potions. - - - - Use your Potion of Fire Resistance on yourself. - - - - Now that you are resistant to fire and lava, you should see if there are places you can get to that you couldn't before. - - - - This is the enchanting interface which you can use to add enchantments to weapons, armor and some tools. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about the enchanting interface.{*B*} -Press{*CONTROLLER_VK_B*} if you already know about the enchanting interface. - - - - To enchant an item, first place it in the enchanting slot. Weapons, armor and some tools can be enchanted to add special effects such as improved damage resistance or increasing the number of items produced when mining a block. - - - - When an item is placed in the enchanting slot, the buttons on the right will change to show a selection of random enchantments. - - - - The number on the button represents the cost in experience levels to apply that enchantment to the item. If you do not have a high enough level the button will be disabled. - - - - Select an enchantment and press{*CONTROLLER_VK_A*} to enchant the item. This will decrease your experience level by the cost of the enchantment. - - - - Although the enchantments are all random, some of the better enchantments are only available when you have a high experience level and have lots of bookcases around the Enchantment Table to increase its power. - - - - In this area there is an Enchantment Table and some other items to help you learn about enchanting. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about enchanting.{*B*} -Press{*CONTROLLER_VK_B*} if you already know about enchanting. - - - - Using an Enchantment Table allows you to add special effects such as increasing the number of items produced when mining a block, or improved damage resistance for weapons, armor and some tools. - - - - Placing bookcases around the Enchantment Table increases its power and allows access to higher level enchantments. - - - - Enchanting items costs Experience Levels, which can be built up by collecting Experience Orbs which are produced by killing monsters and animals, mining ores, breeding animals, fishing and smelting/cooking some things in a furnace. - - - - You can also build experience levels using a Bottle O' Enchanting, which, when thrown, creates Experience Orbs around where it lands. These orbs can then be collected. - - - - In the chests in this area you can find some enchanted items, Bottles O' Enchanting, and some items that have yet to be enchanted for you to experiment with at the Enchantment Table. - - - - You are now riding in a minecart. To exit the minecart, point the cursor at it and press{*CONTROLLER_ACTION_USE*} .{*MinecartIcon*} - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about minecarts.{*B*} -Press{*CONTROLLER_VK_B*} if you already know about minecarts. - - - - A minecart runs on rails. You can also craft a powered minecart with a furnace and a minecart with a chest in it.{*RailIcon*} - - - - You can also craft powered rails, which take power from redstone torches and circuits to accelerate the cart. These can be connected to switches, levers and pressure plates to make complex systems.{*PoweredRailIcon*} - - - - You are now sailing a boat. To exit the boat, point the cursor at it and press{*CONTROLLER_ACTION_USE*} .{*BoatIcon*} - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about boats.{*B*} -Press{*CONTROLLER_VK_B*} if you already know about boats. - - - - A boat allows you to travel quicker over water. You can steer it using{*CONTROLLER_ACTION_MOVE*} and{*CONTROLLER_ACTION_LOOK*}.{*BoatIcon*} - - - - You are now using a fishing rod. Press{*CONTROLLER_ACTION_USE*} to use it.{*FishingRodIcon*} - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about fishing.{*B*} -Press{*CONTROLLER_VK_B*} if you already know about fishing. - - - - Press{*CONTROLLER_ACTION_USE*} to cast your line and start fishing. Press{*CONTROLLER_ACTION_USE*} again to reel in the fishing line.{*FishingRodIcon*} - - - - If you wait until the float sinks below the surface of the water before reeling in you can catch a fish. Fish can be eaten raw, or cooked by a furnace, to restore health.{*FishIcon*} - - - - As with many other tools a fishing rod has a fixed number of uses. Those uses are not limited to catching fish though. You should experiment with it to see what else can be caught or activated...{*FishingRodIcon*} - - - - This is a bed. Press{*CONTROLLER_ACTION_USE*} while pointing at it at night to sleep through the night and awake in the morning.{*ICON*}355{*/ICON*} - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about beds.{*B*} -Press{*CONTROLLER_VK_B*} if you already know about beds. - - - - A bed should be placed in a safe, well-lit place so that monsters do not wake you in the middle of the night. Once you have used a bed, if you die you will respawn at that bed. -{*ICON*}355{*/ICON*} - - - - If there are other players in your game, everyone must be in a bed at the same time to be able to sleep. -{*ICON*}355{*/ICON*} - - - - In this area there are some simple Redstone and Piston circuits, and a chest with more items to extend these circuits. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about Redstone circuits and Pistons.{*B*} -Press{*CONTROLLER_VK_B*} if you already know about Redstone circuits and Pistons. - - - - Levers, Buttons, Pressure Plates and Redstone Torches can all provide power to circuits, either by directly attaching them to the item you want to activate or by connecting them with Redstone dust. - - - - The position and direction that you place a power source can change how it affects the surrounding blocks. For example a Redstone torch on the side of a block can be turned off if the block is powered by another source. - - - - Redstone dust is collected by mining redstone ore with a pickaxe made of Iron, Diamond or Gold. You can use it to carry power up to 15 blocks, and it can travel up or down one block in height. -{*ICON*}331{*/ICON*} - - - - Redstone repeaters can be used to extend the distance that the power is carried, or put a delay in a circuit. -{*ICON*}356{*/ICON*} - - - - When powered, a Piston will extend, pushing up to 12 blocks. When they retract, Sticky Pistons can pull back one block of most types. -{*ICON*}33{*/ICON*} - - - - In the chest in this area there are some components for making circuits with pistons. Try using or completing the circuits in this area, or put together your own. There are more examples outside the tutorial area. - - - - In this area there is a Portal to the Nether! - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about Portals and The Nether.{*B*} -Press{*CONTROLLER_VK_B*} if you already know about Portals and The Nether. - - - - Portals are created by placing Obsidian blocks into a frame four blocks wide and five blocks tall. The corner blocks are not required. - - - - To activate a Nether Portal, set fire to the Obsidian blocks inside the frame with a Flint and Steel. Portals can be deactivated if their frame is broken, an explosion happens nearby or a liquid flows through them. - - - - To use a Nether Portal, stand inside it. Your screen will go purple and a sound will play. After a few seconds you will be transported to another dimension. - - - - The Nether can be a dangerous place, full of lava, but can be useful to collect Netherrack which burns forever when lit, and Glowstone which produces light. - - - - The Nether world can be used to fast-travel in the Overworld - traveling one block distance in the Nether is equivalent to traveling 3 blocks in the Overworld. - - - - You are now in Creative mode. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about Creative mode.{*B*} -Press{*CONTROLLER_VK_B*} if you already know about Creative mode. - - - - When in Creative mode you have in infinite number of all available items and blocks, you can destroy blocks with one click without a tool, you are invulnerable and you can fly. - - - - Press{*CONTROLLER_ACTION_CRAFTING*} to open the creative inventory interface. - - - - Make your way to the opposite side of this hole to continue. - - - - You have now completed the Creative mode tutorial. - - - - In this area a farm has been set up. Farming enables you to create a renewable source of food and other items. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about farming.{*B*} -Press{*CONTROLLER_VK_B*} if you already know about farming. - - - - Wheat, Pumpkins and Melons are grown from seeds. Wheat seeds are collected by breaking Tall Grass or harvesting wheat, and Pumpkin and Melon seeds are crafted from Pumpkins and Melons respectively. - - - - Before planting seeds the dirt blocks need to be turned into Farmland by using a Hoe. A nearby source of water will help keep the Farmland hydrated and make the crops grow faster, as will keeping the area lit. - - - - Wheat goes through several stages when growing, and is ready to be harvested when it appears darker.{*ICON*}59:7{*/ICON*} - - - - Pumpkins and Melons also need a block next to where you planted the seed for the fruit to grow once the stem has fully grown. - - - - Sugarcane must be planted on a Grass, Dirt or Sand block that is right next to water block. Chopping a Sugarcane block will also drop all blocks that are above it.{*ICON*}83{*/ICON*} - - - - Cacti must be planted on Sand, and will grow up to three blocks high. Like Sugarcane, destroying the lowest block will also allow you to collect the blocks that are above it.{*ICON*}81{*/ICON*} - - - - Mushrooms should be planted in a dimly lit area, and will spread to nearby dimly lit blocks.{*ICON*}39{*/ICON*} - - - - Bonemeal can be used to grow crops to their fully grown state, or grow Mushrooms into Huge Mushrooms.{*ICON*}351:15{*/ICON*} - - - - You have now completed the farming tutorial. - - - - In this area animals have been penned in. You can breed animals to produce baby versions of themselves. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about animals and breeding.{*B*} -Press{*CONTROLLER_VK_B*} if you already know about animals and breeding. - - - - To get the animals to breed, you will need to feed them with the right food to get them to go into 'Love Mode'. - - - - Feed Wheat to a cow, mooshroom or sheep, Carrots to pigs, Wheat Seeds or Nether Wart to a chicken, or any kind of meat to a wolf, and they'll start looking for another animal of the same species near them that is also in Love Mode. - - - - When two animals of the same species meet, and both are in Love Mode, they will kiss for a few seconds, and then a baby animal will appear. The baby animal will follow their parents for a while before growing into a full sized animal itself. - - - - After being in Love Mode, an animal will not be able to enter it again for about five minutes. - - - - Some animals will follow you if you are holding their food in your hand. This makes it easier to group animals together to breed them.{*ICON*}296{*/ICON*} - - - - Wild wolves can be tamed by giving them bones. Once tamed Love Hearts will appear around them. Tamed wolves will follow the player and defend them if they haven't been commanded to sit. - - - - You have now completed the animal and breeding tutorial. - - - - In this area are some pumpkins and blocks to make a Snow Golem and an Iron Golem. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about Golems.{*B*} -Press{*CONTROLLER_VK_B*} if you already know about Golems. - - - - Golems are created by placing a pumpkin on top of a stack of blocks. - - - - Snow Golems are created with two Snow Blocks, one of top of the other, with a pumpkin on top. Snow Golems throw snowballs at your enemies. - - - - Iron Golems are created with four Iron Blocks in the pattern shown, with a pumpkin on top of the middle block. Iron Golems attack your enemies. - - - - Iron Golems also appear naturally to protect villages, and will attack you if you attack any villagers. - - - - You cannot leave this area until you have completed the tutorial. - - - - Different tools are better for different materials. You should use a shovel to mine soft materials like earth and sand. - - - - Different tools are better for different materials. You should use an axe to chop tree trunks. - - - - Different tools are better for different materials. You should use a pickaxe to mine stone and ore. You may need to make your pickaxe from better materials to get resources from some blocks. - - - - Certain tools are better for attacking enemies. Consider using a sword to attack. - - - - Hint: Hold {*CONTROLLER_ACTION_ACTION*}to mine and chop using your hand or whatever you are holding. You may need to craft a tool to mine some blocks... - - - - The tool you are using has become damaged. Every time you use a tool it becomes damaged, and will eventually break. The colored bar below the item in your inventory shows the current damage state. - - - - Hold{*CONTROLLER_ACTION_JUMP*} to swim up. - - - - In this area there is a minecart on a track. To enter the minecart, point the cursor at it and press{*CONTROLLER_ACTION_USE*}. Use{*CONTROLLER_ACTION_USE*} on the button to make the minecart move. - - - - In the chest beside the river there is a boat. To use the boat, point the cursor at water and press{*CONTROLLER_ACTION_USE*}. Use{*CONTROLLER_ACTION_USE*} while pointing at the boat to enter it. - - - - In the chest beside the pond there is a fishing rod. Take the fishing rod from the chest and select it as the current item in your hand to use it. - - - - This more advanced piston mechanism creates a self-repairing bridge! Push the button to activate, then investigate how the components interact to learn more. - - - - If you move the pointer outside of the interface while carrying an item, you can drop that item. - - - - You do not have all the ingredients required to make this item. The box on the bottom left shows the ingredients required to craft this. - - - - Congratulations, you have completed the tutorial. Time in the game is now passing normally, and you don't have long until night time and the monsters come out! Finish your shelter! - - - - {*EXIT_PICTURE*} When you are ready to explore further, there is a stairway in this area near the Miner's shelter that leads to a small castle. - - - - Reminder: - - - - - - - - New features have been added to the game in the latest version, including new areas in the tutorial world. - - - - {*B*}Press{*CONTROLLER_VK_A*} to play through the tutorial as normal.{*B*} -Press{*CONTROLLER_VK_B*} to skip the main tutorial. - - - - In this area you will find areas setup to help you learn about fishing, boats, pistons and redstone. - - - - Outside of this area you will find examples of buildings, farming, minecarts and tracks, enchanting, brewing, trading, smithing and more! - - - - Your food bar has depleted to a level where you will no longer heal. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about the food bar and eating food.{*B*} -Press{*CONTROLLER_VK_B*} if you already know about the food bar and eating food. - - - - This is the horse inventory interface. - - - - {*B*}Press{*CONTROLLER_VK_A*} to continue. -{*B*}Press{*CONTROLLER_VK_B*} if you already know how to use the horse inventory. - - - - The horse inventory allows you to transfer, or equip items to your Horse, Donkey or Mule. - - - - Saddle your Horse by placing a Saddle in the saddle slot. Horses can be given armor by placing Horse Armor in the armor slot. - - - - You can also transfer items between your own inventory and the saddlebags strapped to Donkeys and Mules in this menu. - - - - You have found a Horse. - - - - You have found a Donkey. - - - - You have found a Mule. - - - - {*B*}Press{*CONTROLLER_VK_A*} to learn more about Horses, Donkeys and Mules. -{*B*}Press{*CONTROLLER_VK_B*} if you already know about Horses, Donkeys and Mules. - - - - Horses and Donkeys are found mainly in open plains. Mules can be bred from a Donkey and a Horse, but are infertile themselves. - - - - All adult Horses, Donkeys and Mules can be ridden. However only Horses can be armored, and only Mules and Donkeys may be equipped with saddlebags for transporting items. - - - - Horses, Donkeys and Mules must be tamed before they can be used. A horse is tamed by attempting to ride it, and managing to stay on the horse while it attempts to throw the rider off. - - - - When tamed Love Hearts will appear around them and they will no longer buck the player off. - - - - Try to ride this horse now. Use {*CONTROLLER_ACTION_USE*} with no items or tools in your hand to mount it. - - - - To steer a horse they must then be equipped with a saddle, which can be bought from villagers or found inside chests hidden in the world. - - - - Tame Donkeys and Mules can be given saddlebags by attaching a chest. These bags can be accessed whilst riding or when sneaking. - - - - Horses and Donkeys (but not Mules) can be bred like other animals using Golden Apples or Golden Carrots. Foals will grow into adult horses over time, although feeding them wheat or hay will speed this up. - - - - You can try to tame the Horses and Donkeys here, and there are Saddles, Horse Armor and other useful items for Horses in chests around here too. - - - - This is the Beacon interface, which you can use to choose powers for your Beacon to grant. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to continue.{*B*} -Press{*CONTROLLER_VK_B*} if you already know how to use the Beacon interface. - - - - In the Beacon menu you can select 1 primary power for your Beacon. The more tiers your pyramid has the more powers you will have to choose from. - - - - A Beacon on a pyramid with at least 4 tiers grants an additional option of either the Regeneration secondary power or a stronger primary power. - - - - To set the powers of your Beacon you must sacrifice an Emerald, Diamond, Gold or Iron Ingot in the payment slot. Once set, the powers will emanate from the Beacon indefinitely. - - - - At the top of this pyramid there is an inactivate Beacon. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about Beacons.{*B*} -Press{*CONTROLLER_VK_B*} if you already know about Beacons. - - - - Active Beacons project a bright beam of light into the sky and grant powers to nearby players. They are crafted with Glass, Obsidian and Nether Stars, which can be obtained by defeating the Wither. - - - - Beacons must be placed so that they are in sunlight during the day. Beacons must be placed on Pyramids of Iron, Gold, Emerald or Diamond. However the choice of material has no effect on the power of the beacon. - - - - Try using the Beacon to set the powers it grants, you can use the Iron Ingots provided as the necessary payment. - - - - This room contains Hoppers - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about Hoppers.{*B*} -Press{*CONTROLLER_VK_B*} if you already know about Hoppers. - - - - Hoppers are used to insert or remove items from containers, and to automatically pick-up items thrown into them. - - - - They can affect Brewing Stands, Chests, Dispensers, Droppers, Minecarts with Chests, Minecarts with Hoppers, as well as other Hoppers. - - - - Hoppers will continuously attempt to suck items out of suitable container placed above them. It will also attempt to insert stored items into an output container. - - - - However if a Hopper is powered by Redstone it will become inactive and stop both sucking and inserting items. - - - - A Hopper points in the direction it tries to output items. To make a Hopper point to a particular block, place the Hopper against that block whilst sneaking. - - - - There are various useful Hopper layouts for you to see and experiment with in this room. - - - - This is the Firework interface, which you can use to craft Fireworks and Firework Stars. - - - - {*B*} -Press{*CONTROLLER_VK_A*} to continue.{*B*} -Press{*CONTROLLER_VK_B*} if you already know how to use the Firework interface. - - - - To craft a Firework, place Gunpowder and Paper in the 3x3 crafting grid that is shown above your inventory. - - - - You can optionally place multiple Firework Stars in the crafting grid to add them to the Firework. - - - - Filling more slots in the crafting grid with Gunpowder will increase the height at which all the Firework Stars will explode. - - - - You can then take the crafted Firework out of the output slot when you wish to craft it. - - - - Firework Stars can be crafted by placing Gunpowder and Dye into the crafting grid. - - - - The Dye will set the color of the explosion of the Firework Star. - - - - The shape of the Firework Star is set by adding either a Fire Charge, Gold Nugget, Feather or Mob Head. - - - - A trail or a twinkle can be added using Diamonds or Glowstone Dust. - - - - After a Firework Star has been crafted, you can set the fade color of the Firework Star by crafting it with Dye. - - - - Contained within the chests here there are various items used in the creation of FIREWORKS! - - - - {*B*} -Press{*CONTROLLER_VK_A*} to learn more about Fireworks. {*B*} -Press{*CONTROLLER_VK_B*} if you already know about Fireworks. - - - - Fireworks are decorative items that can be launched by hand or from Dispensers. They are crafted using Paper, Gunpowder and optionally a number of Firework Stars. - - - - The colors, fade, shape, size, and effects (such as trails and twinkles) of Firework Stars can be customized by including additional ingredients when crafting. - - - - Try crafting a Firework at the Crafting Table using an assortment of ingredients from the chests. - - - - Select - - - - Use - - - - Back - - - - Exit - - - - Cancel - - - - Cancel Join - - - - Refresh Online Games List - - - - Party Games - - - - All Games - - - - Change Group - - - - Show Inventory - - - - Show Description - - - - Show Ingredients - - - - Crafting - - - - Create - - - - Take/Place - - - - Take - - - - Take All - - - - Take Half - - - - Place - - - - Place All - - - - Place One - - - - Drop - - - - Drop All - - - - Drop One - - - - Swap - - - - Quick Move - - - - Clear Quick Select - - - - What's This? - - - - Share To Facebook - - - - Change Filter - - - - Send Friend Request - - - - Page Down - - - - Page Up - - - - Next - - - - Previous - - - - Kick Player - - - - Dye - - - - Mine - - - - Feed - - - - Tame - - - - Heal - - - - Sit - - - - Follow Me - - - - Eject - - - - Empty - - - - Saddle - - - - Place - - - - Hit - - - - Milk - - - - Collect - - - - Eat - - - - Sleep - - - - Wake Up - - - - Play - - - - Ride - - - - Sail - - - - Grow - - - - Swim Up - - - - Open - - - - Change Pitch - - - - Detonate - - - - Read - - - - Hang - - - - Throw - - - - Plant - - - - Till - - - - Harvest - - - - Continue - - - - Unlock Full Game - - - - Delete Save - - - - Delete - - - - Options - - - - Invite Friends - - - - Accept - - - - Shear - - - - Ban Level - - - - Select Skin - - - - Ignite - - - - Navigate - - - - Install Full Version - - - - Install Trial Version - - - - Install - - - - Reinstall - - - - Save Options - - - - Execute Command - - - - Creative - - - - Move Ingredient - - - - Move Fuel - - - - Move Tool - - - - Move Armor - - - - Move Weapon - - - - Equip - - - - Draw - - - - Release - - - - Privileges - - - - Block - - - - Page Up - - - - Page Down - - - - Love Mode - - - - Drink - - - - Rotate - - - - Hide - - - - Clear All Slots - - - - Mount - - - - Dismount - - - - Attach Chest - - - - Launch - - - - Leash - - - - Release - - - - Attach - - - - Name - - - - OK - - - - Cancel - - - - Minecraft Store - - - - Are you sure you want to leave your current game and join the new one? Any unsaved progress will be lost. - - - - Exit Game - - - - Save Game - - - - Exit Without Saving - - - - Are you sure you want to overwrite any previous save for this world with the current version of this world? - - - - Are you sure you want to exit without saving? You will lose all progress in this world! - - - - Start Game - - - - Damaged Save - - - - This save is corrupt or damaged. Would you like to delete it? - - - - Are you sure you want to exit to the main menu and disconnect all players from the game? Any unsaved progress will be lost. - - - - Exit and save - - - - Exit without saving - - - - Are you sure you want to exit to the main menu? Any unsaved progress will be lost. - - - - Are you sure you want to exit to the main menu? Your progress will be lost! - - - - Create New World - - - - Play Tutorial - - - - Tutorial - - - - Name Your World - - - - Enter a name for your world - - - - Input the seed for your world generation - - - - Load Saved World - - - - Press START to join game - - - - Exiting the game - - - - An error occurred. Exiting to the main menu. - - - - Connection failed - - - - Connection lost - - - - Connection to the server was lost. Exiting to the main menu. - - - - Disconnected by the server - - - - You were kicked from the game - - - - You were kicked from the game for flying - - - - Connection attempt took too long - - - - The server is full - - - - The host has exited the game. - - - - You cannot join this game as you are not friends with anybody in the game. - - - - You cannot join this game as you have previously been kicked by the host. - - - - You cannot join this game as the player you are trying to join is running an older version of the game. - - - - You cannot join this game as the player you are trying to join is running a newer version of the game. - - - - New World - - - - Award Unlocked! - - - - Hurray - you've been awarded a gamerpic featuring Steve from Minecraft! - - - - Hurray - you've been awarded a gamerpic featuring a Creeper! - - - - Unlock Full Game - - - - You're playing the trial game, but you'll need the full game to be able to save your game. -Would you like to unlock the full game now? - - - - Please wait - - - - No results - - - - Filter: - - - - Friends - - - - My Score - - - - Overall - - - - Entries: - - - - Rank - - - - Preparing to Save Level - - - - Preparing Chunks... - - - - Finalizing... - - - - Building Terrain - - - - Simulating world for a bit - - - - Initializing server - - - - Generating spawn area - - - - Loading spawn area - - - - Entering The Nether - - - - Leaving The Nether - - - - Respawning - - - - Generating level - - - - Loading level - - - - Saving players - - - - Connecting to host - - - - Downloading terrain - - - - Switching to offline game - - - - Please wait while the host saves the game - - - - Entering The END - - - - Leaving The END - - - - Finding Seed for the World Generator - - - - This bed is occupied - - - - You can only sleep at night - - - - %s is sleeping in a bed. To skip to dawn, all players need to sleep in beds at the same time. - - - - Your home bed was missing or obstructed - - - - You may not rest now, there are monsters nearby - - - - You are sleeping in a bed. To skip to dawn, all players need to sleep in beds at the same time. - - - - Tools and Weapons - - - - Weapons - - - - Food - - - - Structures - - - - Armor - - - - Mechanisms - - - - Transport - - - - Decorations - - - - Building Blocks - - - - Redstone & Transportation - - - - Miscellaneous - - - - Brewing - - - - Tools, Weapons & Armor - - - - Materials - - - - Signed out - - - - Difficulty - - - - Music - - - - Sound - - - - Gamma - - - - Game Sensitivity - - - - Interface Sensitivity - - - - Peaceful - - - - Easy - - - - Normal - - - - Hard - - - - In this mode, the player regains health over time, and there are no enemies in the environment. - - - - In this mode, enemies spawn in the environment, but will do less damage to the player than in the Normal mode. - - - - In this mode, enemies spawn in the environment and will do a standard amount of damage to the player. - - - - In this mode, enemies will spawn in the environment, and will do a great deal of damage to the player. Watch out for the Creepers too, since they are unlikely to cancel their exploding attack when you move away from them! - - - - Trial Timeout - - - - Game full - - - - Failed to join game as there are no spaces left - - - - Enter Sign Text - - - - Enter a line of text for your sign - - - - Enter Title - - - - Enter a title for your post - - - - Enter Caption - - - - Enter a caption for your post - - - - Enter Description - - - - Enter a description for your post - - - - Inventory - - - - Ingredients - - - - Brewing Stand - - - - Chest - - - - Enchant - - - - Furnace - - - - Ingredient - - - - Fuel - - - - Dispenser - - - - Horse - - - - Dropper - - - - Hopper - - - - Beacon - - - - Primary Power - - - - Secondary Power - - - - Minecart - - - - There are no downloadable content offers of this type available for this title at the moment. - - - - %s has joined the game. - - - - %s has left the game. - - - - %s was kicked from the game. - - - - Are you sure you want to delete this save game? - - - - Awaiting approval - - - - Censored - - - - Now playing: - - - - Reset Settings - - - - Are you sure you would like to reset your settings to their default values? - - - - Loading Error - - - - %s's Game - - - - Unknown host game - - - - Guest signed out - - - - A guest player has signed out causing all guest players to be removed from the game. - - - - Sign in - - - - You are not signed in. In order to play this game, you will need to be signed in. Do you want to sign in now? - - - - Multiplayer not allowed - - - - Failed to create game - - - - Auto Selected - - - - No Pack: Default Skins - - - - Favorite Skins - - - - Banned Level - - - - The game you are joining is in your banned level list. -If you choose to join this game, the level will be removed from your banned level list. - - - - Ban This Level? - - - - Are you sure you want to add this level to your banned level list? -Selecting OK will also exit this game. - - - - Remove from Banned List - - - - Autosave Interval - - - - Autosave Interval: OFF - - - - Mins - - - - Can't Place Here! - - - - Placing lava close to the level spawn point is not allowed due to the possibility of instant death for spawning players. - - - - Interface Opacity - - - - Preparing to Autosave Level - - - - HUD Size - - - - HUD Size (Splitscreen) - - - - Seed - - - - Unlock Skin Pack - - - - To use the skin you have selected, you need to unlock this skin pack. -Would you like to unlock this skin pack now? - - - - Unlock Texture Pack - - - - To use this texture pack for your world, you need to unlock it. -Would you like to unlock it now? - - - - Trial Texture Pack - - - - You are using a trial version of the texture pack. You will not be able to save this world unless you unlock the full version. -Would you like to unlock the full version of the texture pack? - - - - Texture Pack Not Present - - - - Unlock Full Version - - - - Download Trial Version - - - - Download Full Version - - - - This world uses a mash-up pack or texture pack you don't have! -Would you like to install the mash-up pack or texture pack now? - - - - Get Trial Version - - - - Get Full Version - - - - Kick player - - - - Are you sure you want to kick this player from the game? They will not be able to rejoin until you restart the world. - - - - Gamerpics Packs - - - - Themes - - - - Skins Packs - - - - Allow friends of friends - - - - You cannot join this game because it has been limited to players who are friends of the host. - - - - Can't Join Game - - - - Selected - - - - Selected skin: - - - - Corrupt Downloadable Content - - - - This downloadable content is corrupt and cannot be used. You need to delete it, then re-install it from the Minecraft Store menu. - - - - Some of your downloadable content is corrupt and cannot be used. You need to delete them, then re-install them from the Minecraft Store menu. - - - - Your game mode has been changed - - - - Rename Your World - - - - Enter the new name for your world - - - - Game Mode: Survival - - - - Game Mode: Creative - - - - Game Mode: Adventure - - - - Game Mode: Hardcore - - - - Survival - - - - Creative - - - - Adventure - - - - Hardcore - - - - Created in Survival Mode - - - - Created in Creative Mode - - - - Render Clouds - - - - What would you like to do with this save game? - - - - Rename Save - - - - Autosaving in %d... - - - - On - - - - Off - - - - Normal - - - - Superflat - - - - Enter a seed to generate the same terrain again. Leave blank for a random world. - - - - When enabled, the game will be an online game. - - - - When enabled, only invited players can join. - - - - When enabled, friends of people on your Friends List can join the game. - - - - When enabled, players can inflict damage on other players. Only affects Survival mode. - - - - When disabled, players joining the game cannot build or mine until authorised. - - - - When enabled, fire may spread to nearby flammable blocks. - - - - When enabled, TNT will explode when activated. - - - - When enabled, the Nether world will be re-generated. This is useful if you have an older save where Nether Fortresses were not present. - - - - When enabled, structures such as Villages and Strongholds will generate in the world. - - - - When enabled, a completely flat world will be generated in the Overworld and in the Nether. - - - - When enabled, a chest containing some useful items will be created near the player spawn point. - - - - When disabled, prevents monsters and animals from changing blocks (for example, Creeper explosions won't destroy blocks and Sheep won't remove Grass) or picking up items. - - - - When enabled, players will keep their inventory when they die. - - - - When disabled, mobs will not spawn naturally. - - - - When disabled, monsters and animals will not drop loot (for example, Creepers won't drop gunpowder). - - - - When disabled, blocks will not drop items when destroyed (for example, Stone blocks won't drop Cobblestone). - - - - When disabled, players will not regenerate health naturally. - - - - When disabled, the time of day will not change. - - - - Skin Packs - - - - Themes - - - - Gamerpics - - - - Avatar Items - - - - Texture Packs - - - - Mash-Up Packs - - - - {*PLAYER*} went up in flames - - - - {*PLAYER*} burned to death - - - - {*PLAYER*} tried to swim in lava - - - - {*PLAYER*} suffocated in a wall - - - - {*PLAYER*} drowned - - - - {*PLAYER*} starved to death - - - - {*PLAYER*} was pricked to death - - - - {*PLAYER*} hit the ground too hard - - - - {*PLAYER*} fell out of the world - - - - {*PLAYER*} died - - - - {*PLAYER*} blew up - - - - {*PLAYER*} was killed by magic - - - - {*PLAYER*} was killed by Ender Dragon breath - - - - {*PLAYER*} was slain by {*SOURCE*} - - - - {*PLAYER*} was slain by {*SOURCE*} - - - - {*PLAYER*} was shot by {*SOURCE*} - - - - {*PLAYER*} was fireballed by {*SOURCE*} - - - - {*PLAYER*} was pummeled by {*SOURCE*} - - - - {*PLAYER*} was killed by {*SOURCE*} using magic - - - - {*PLAYER*} fell off a ladder - - - - {*PLAYER*} fell off some vines - - - - {*PLAYER*} fell out of the water - - - - {*PLAYER*} fell from a high place - - - - {*PLAYER*} was doomed to fall by {*SOURCE*} - - - - {*PLAYER*} was doomed to fall by {*SOURCE*} - - - - {*PLAYER*} was doomed to fall by {*SOURCE*} using {*ITEM*} - - - - {*PLAYER*} fell too far and was finished by {*SOURCE*} - - - - {*PLAYER*} fell too far and was finished by {*SOURCE*} using {*ITEM*} - - - - {*PLAYER*} walked into fire whilst fighting {*SOURCE*} - - - - {*PLAYER*} was burnt to a crisp whilst fighting {*SOURCE*} - - - - {*PLAYER*} tried to swim in lava to escape {*SOURCE*} - - - - {*PLAYER*} drowned whilst trying to escape {*SOURCE*} - - - - {*PLAYER*} walked into a cactus whilst trying to escape {*SOURCE*} - - - - {*PLAYER*} was blown up by {*SOURCE*} - - - - {*PLAYER*} withered away - - - - {*PLAYER*} was slain by {*SOURCE*} using {*ITEM*} - - - - {*PLAYER*} was shot by {*SOURCE*} using {*ITEM*} - - - - {*PLAYER*} was fireballed by {*SOURCE*} using {*ITEM*} - - - - {*PLAYER*} was pummeled by {*SOURCE*} using {*ITEM*} - - - - {*PLAYER*} was killed by {*SOURCE*} using {*ITEM*} - - - - Bedrock Fog - - - - Display HUD - - - - Display Hand - - - - Death Messages - - - - dead. - - - - Animated Character - - - - Custom Skin Animation - - - - You can no longer mine or use items - - - - You can now mine and use items - - - - You can no longer place blocks - - - - You can now place blocks - - - - You can now use doors and switches - - - - You can no longer use doors and switches - - - - You can now use containers (e.g. chests) - - - - You can no longer use containers (e.g. chests) - - - - You can no longer attack mobs - - - - You can now attack mobs - - - - You can no longer attack players - - - - You can now attack players - - - - You can no longer attack animals - - - - You can now attack animals - - - - You are now a moderator - - - - You are no longer a moderator - - - - You can now fly - - - - You can no longer fly - - - - You will no longer get exhausted - - - - You will now get exhausted - - - - You are now invisible - - - - You are no longer invisible - - - - You are now invulnerable - - - - You are no longer invulnerable - - - - %d MSP - - - - Ender Dragon - - - - %s has entered The End - - - - %s has left The End - - - - -{*C3*}I see the player you mean.{*EF*}{*B*}{*B*} -{*C2*}{*PLAYER*}?{*EF*}{*B*}{*B*} -{*C3*}Yes. Take care. It has reached a higher level now. It can read our thoughts.{*EF*}{*B*}{*B*} -{*C2*}That doesn't matter. It thinks we are part of the game.{*EF*}{*B*}{*B*} -{*C3*}I like this player. It played well. It did not give up.{*EF*}{*B*}{*B*} -{*C2*}It is reading our thoughts as though they were words on a screen.{*EF*}{*B*}{*B*} -{*C3*}That is how it chooses to imagine many things, when it is deep in the dream of a game.{*EF*}{*B*}{*B*} -{*C2*}Words make a wonderful interface. Very flexible. And less terrifying than staring at the reality behind the screen.{*EF*}{*B*}{*B*} -{*C3*}They used to hear voices. Before players could read. Back in the days when those who did not play called the players witches, and warlocks. And players dreamed they flew through the air, on sticks powered by demons.{*EF*}{*B*}{*B*} -{*C2*}What did this player dream?{*EF*}{*B*}{*B*} -{*C3*}This player dreamed of sunlight and trees. Of fire and water. It dreamed it created. And it dreamed it destroyed. It dreamed it hunted, and was hunted. It dreamed of shelter.{*EF*}{*B*}{*B*} -{*C2*}Hah, the original interface. A million years old, and it still works. But what true structure did this player create, in the reality behind the screen?{*EF*}{*B*}{*B*} -{*C3*}It worked, with a million others, to sculpt a true world in a fold of the {*EF*}{*NOISE*}{*C3*}, and created a {*EF*}{*NOISE*}{*C3*} for {*EF*}{*NOISE*}{*C3*}, in the {*EF*}{*NOISE*}{*C3*}.{*EF*}{*B*}{*B*} -{*C2*}It cannot read that thought.{*EF*}{*B*}{*B*} -{*C3*}No. It has not yet achieved the highest level. That, it must achieve in the long dream of life, not the short dream of a game.{*EF*}{*B*}{*B*} -{*C2*}Does it know that we love it? That the universe is kind?{*EF*}{*B*}{*B*} -{*C3*}Sometimes, through the noise of its thoughts, it hears the universe, yes.{*EF*}{*B*}{*B*} -{*C2*}But there are times it is sad, in the long dream. It creates worlds that have no summer, and it shivers under a black sun, and it takes its sad creation for reality.{*EF*}{*B*}{*B*} -{*C3*}To cure it of sorrow would destroy it. The sorrow is part of its own private task. We cannot interfere.{*EF*}{*B*}{*B*} -{*C2*}Sometimes when they are deep in dreams, I want to tell them, they are building true worlds in reality. Sometimes I want to tell them of their importance to the universe. Sometimes, when they have not made a true connection in a while, I want to help them to speak the word they fear.{*EF*}{*B*}{*B*} -{*C3*}It reads our thoughts.{*EF*}{*B*}{*B*} -{*C2*}Sometimes I do not care. Sometimes I wish to tell them, this world you take for truth is merely {*EF*}{*NOISE*}{*C2*} and {*EF*}{*NOISE*}{*C2*}, I wish to tell them that they are {*EF*}{*NOISE*}{*C2*} in the {*EF*}{*NOISE*}{*C2*}. They see so little of reality, in their long dream.{*EF*}{*B*}{*B*} -{*C3*}And yet they play the game.{*EF*}{*B*}{*B*} -{*C2*}But it would be so easy to tell them...{*EF*}{*B*}{*B*} -{*C3*}Too strong for this dream. To tell them how to live is to prevent them living.{*EF*}{*B*}{*B*} -{*C2*}I will not tell the player how to live.{*EF*}{*B*}{*B*} -{*C3*}The player is growing restless.{*EF*}{*B*}{*B*} -{*C2*}I will tell the player a story.{*EF*}{*B*}{*B*} -{*C3*}But not the truth.{*EF*}{*B*}{*B*} -{*C2*}No. A story that contains the truth safely, in a cage of words. Not the naked truth that can burn over any distance.{*EF*}{*B*}{*B*} -{*C3*}Give it a body, again.{*EF*}{*B*}{*B*} -{*C2*}Yes. Player...{*EF*}{*B*}{*B*} -{*C3*}Use its name.{*EF*}{*B*}{*B*} -{*C2*}{*PLAYER*}. Player of games.{*EF*}{*B*}{*B*} -{*C3*}Good.{*EF*}{*B*}{*B*} - - - - - -{*C2*}Take a breath, now. Take another. Feel air in your lungs. Let your limbs return. Yes, move your fingers. Have a body again, under gravity, in air. Respawn in the long dream. There you are. Your body touching the universe again at every point, as though you were separate things. As though we were separate things.{*EF*}{*B*}{*B*} -{*C3*}Who are we? Once we were called the spirit of the mountain. Father sun, mother moon. Ancestral spirits, animal spirits. Jinn. Ghosts. The green man. Then gods, demons. Angels. Poltergeists. Aliens, extraterrestrials. Leptons, quarks. The words change. We do not change.{*EF*}{*B*}{*B*} -{*C2*}We are the universe. We are everything you think isn't you. You are looking at us now, through your skin and your eyes. And why does the universe touch your skin, and throw light on you? To see you, player. To know you. And to be known. I shall tell you a story.{*EF*}{*B*}{*B*} -{*C2*}Once upon a time, there was a player.{*EF*}{*B*}{*B*} -{*C3*}The player was you, {*PLAYER*}.{*EF*}{*B*}{*B*} -{*C2*}Sometimes it thought itself human, on the thin crust of a spinning globe of molten rock. The ball of molten rock circled a ball of blazing gas that was three hundred and thirty thousand times more massive than it. They were so far apart that light took eight minutes to cross the gap. The light was information from a star, and it could burn your skin from a hundred and fifty million kilometres away.{*EF*}{*B*}{*B*} -{*C2*}Sometimes the player dreamed it was a miner, on the surface of a world that was flat, and infinite. The sun was a square of white. The days were short; there was much to do; and death was a temporary inconvenience.{*EF*}{*B*}{*B*} -{*C3*}Sometimes the player dreamed it was lost in a story.{*EF*}{*B*}{*B*} -{*C2*}Sometimes the player dreamed it was other things, in other places. Sometimes these dreams were disturbing. Sometimes very beautiful indeed. Sometimes the player woke from one dream into another, then woke from that into a third.{*EF*}{*B*}{*B*} -{*C3*}Sometimes the player dreamed it watched words on a screen.{*EF*}{*B*}{*B*} -{*C2*}Let's go back.{*EF*}{*B*}{*B*} -{*C2*}The atoms of the player were scattered in the grass, in the rivers, in the air, in the ground. A woman gathered the atoms; she drank and ate and inhaled; and the woman assembled the player, in her body.{*EF*}{*B*}{*B*} -{*C2*}And the player awoke, from the warm, dark world of its mother's body, into the long dream.{*EF*}{*B*}{*B*} -{*C2*}And the player was a new story, never told before, written in letters of DNA. And the player was a new program, never run before, generated by a sourcecode a billion years old. And the player was a new human, never alive before, made from nothing but milk and love.{*EF*}{*B*}{*B*} -{*C3*}You are the player. The story. The program. The human. Made from nothing but milk and love.{*EF*}{*B*}{*B*} -{*C2*}Let's go further back.{*EF*}{*B*}{*B*} -{*C2*}The seven billion billion billion atoms of the player's body were created, long before this game, in the heart of a star. So the player, too, is information from a star. And the player moves through a story, which is a forest of information planted by a man called Julian, on a flat, infinite world created by a man called Markus, that exists inside a small, private world created by the player, who inhabits a universe created by...{*EF*}{*B*}{*B*} -{*C3*}Shush. Sometimes the player created a small, private world that was soft and warm and simple. Sometimes hard, and cold, and complicated. Sometimes it built a model of the universe in its head; flecks of energy, moving through vast empty spaces. Sometimes it called those flecks "electrons" and "protons".{*EF*}{*B*}{*B*} - - - - - -{*C2*}Sometimes it called them "planets" and "stars".{*EF*}{*B*}{*B*} -{*C2*}Sometimes it believed it was in a universe that was made of energy that was made of offs and ons; zeros and ones; lines of code. Sometimes it believed it was playing a game. Sometimes it believed it was reading words on a screen.{*EF*}{*B*}{*B*} -{*C3*}You are the player, reading words...{*EF*}{*B*}{*B*} -{*C2*}Shush... Sometimes the player read lines of code on a screen. Decoded them into words; decoded words into meaning; decoded meaning into feelings, emotions, theories, ideas, and the player started to breathe faster and deeper and realised it was alive, it was alive, those thousand deaths had not been real, the player was alive{*EF*}{*B*}{*B*} -{*C3*}You. You. You are alive.{*EF*}{*B*}{*B*} -{*C2*}and sometimes the player believed the universe had spoken to it through the sunlight that came through the shuffling leaves of the summer trees{*EF*}{*B*}{*B*} -{*C3*}and sometimes the player believed the universe had spoken to it through the light that fell from the crisp night sky of winter, where a fleck of light in the corner of the player's eye might be a star a million times as massive as the sun, boiling its planets to plasma in order to be visible for a moment to the player, walking home at the far side of the universe, suddenly smelling food, almost at the familiar door, about to dream again{*EF*}{*B*}{*B*} -{*C2*}and sometimes the player believed the universe had spoken to it through the zeros and ones, through the electricity of the world, through the scrolling words on a screen at the end of a dream{*EF*}{*B*}{*B*} -{*C3*}and the universe said I love you{*EF*}{*B*}{*B*} -{*C2*}and the universe said you have played the game well{*EF*}{*B*}{*B*} -{*C3*}and the universe said everything you need is within you{*EF*}{*B*}{*B*} -{*C2*}and the universe said you are stronger than you know{*EF*}{*B*}{*B*} -{*C3*}and the universe said you are the daylight{*EF*}{*B*}{*B*} -{*C2*}and the universe said you are the night{*EF*}{*B*}{*B*} -{*C3*}and the universe said the darkness you fight is within you{*EF*}{*B*}{*B*} -{*C2*}and the universe said the light you seek is within you{*EF*}{*B*}{*B*} -{*C3*}and the universe said you are not alone{*EF*}{*B*}{*B*} -{*C2*}and the universe said you are not separate from every other thing{*EF*}{*B*}{*B*} -{*C3*}and the universe said you are the universe tasting itself, talking to itself, reading its own code{*EF*}{*B*}{*B*} -{*C2*}and the universe said I love you because you are love.{*EF*}{*B*}{*B*} -{*C3*}And the game was over and the player woke up from the dream. And the player began a new dream. And the player dreamed again, dreamed better. And the player was the universe. And the player was love.{*EF*}{*B*}{*B*} -{*C3*}You are the player.{*EF*}{*B*}{*B*} -{*C2*}Wake up.{*EF*} - - - - - Reset Nether - - - - Are you sure you want to reset the Nether in this savegame to its default state? You will lose anything you have built in the Nether! - - - - Reset Nether - - - - Don't Reset Nether - - - - Can't shear this Mooshroom at the moment. The maximum number of Pigs, Sheep, Cows, Cats and Horses has been reached. - - - - Can't use Spawn Egg at the moment. The maximum number of Pigs, Sheep, Cows, Cats and Horses has been reached. - - - - Can't use Spawn Egg at the moment. The maximum number of Mooshrooms has been reached. - - - - Can't use Spawn Egg at the moment. The maximum number of Wolves in a world has been reached. - - - - Can't use Spawn Egg at the moment. The maximum number of Chickens in a world has been reached. - - - - Can't use Spawn Egg at the moment. The maximum number of Squid in a world has been reached. - - - - Can't use Spawn Egg at the moment. The maximum number of Bats in a world has been reached. - - - - Can't use Spawn Egg at the moment. The maximum number of enemies in a world has been reached. - - - - Can't use Spawn Egg at the moment. The maximum number of villagers in a world has been reached. - - - - The maximum number of Paintings/Item Frames in a world has been reached. - - - - You can't spawn enemies in Peaceful mode. - - - - This animal can't enter Love Mode. The maximum number of breeding Pigs, Sheep, Cows, Cats and Horses has been reached. - - - - This animal can't enter Love Mode. The maximum number of breeding Wolves has been reached. - - - - This animal can't enter Love Mode. The maximum number of breeding Chickens has been reached. - - - - This animal can't enter Love Mode. The maximum number of breeding horses has been reached. - - - - This animal can't enter Love Mode. The maximum number of breeding Mooshrooms has been reached. - - - - The maximum number of Boats in a world has been reached. - - - - The maximum number of Mob Heads in a world has been reached. - - - - Invert Look - - - - Southpaw - - - - You Died! - - - - Respawn - - - - Downloadable Content Offers - - - - Change Skin - - - - How To Play - - - - Controls - - - - Settings - - - - Languages - - - - Credits - - - - Reinstall Content - - - - Debug Settings - - - - Fire Spreads - - - - TNT Explodes - - - - Player vs Player - - - - Trust Players - - - - Host Privileges - - - - Generate Structures - - - - Superflat World - - - - Bonus Chest - - - - World Options - - - - Game Options - - - - Mob Griefing - - - - Keep Inventory - - - - Mob Spawning - - - - Mob Loot - - - - Tile Drops - - - - Natural Regeneration - - - - Daylight Cycle - - - - Can Build and Mine - - - - Can Use Doors and Switches - - - - Can Open Containers - - - - Can Attack Players - - - - Can Attack Animals - - - - Moderator - - - - Kick Player - - - - Can Fly - - - - Disable Exhaustion - - - - Invisible - - - - Host Options - - - - Players/Invite - - - - Online Game - - - - Invite Only - - - - More Options - - - - Load - - - - New World - - - - World Name - - - - Seed for the World Generator - - - - Leave blank for a random seed - - - - Players - - - - Join Game - - - - Start Game - - - - No Games Found - - - - Play Game - - - - Leaderboards - - - - Help & Options - - - - Unlock Full Game - - - - Resume Game - - - - Save Game - - - - Difficulty: - - - - Game Type: - - - - Structures: - - - - Level Type: - - - - PvP: - - - - Trust Players: - - - - TNT: - - - - Fire Spreads: - - - - Reinstall Theme - - - - Reinstall Gamerpic 1 - - - - Reinstall Gamerpic 2 - - - - Reinstall Avatar Item 1 - - - - Reinstall Avatar Item 2 - - - - Reinstall Avatar Item 3 - - - - Options - - - - Audio - - - - Control - - - - Graphics - - - - User Interface - - - - Reset to Defaults - - - - View Bobbing - - - - Hints - - - - In-Game Tooltips - - - - 2 Player Split-screen Vertical - - - - Done - - - - Edit sign message: - - - - Fill in the details to accompany your screenshot - - - - Caption - - - - Screenshot from in-game - - - - Edit sign message: - - - - The classic Minecraft textures, icons and user interface! - - - - Show all Mash-up Worlds - - - - No Effects - - - - Speed - - - - Slowness - - - - Haste - - - - Mining Fatigue - - - - Strength - - - - Weakness - - - - Instant Health - - - - Instant Damage - - - - Jump Boost - - - - Nausea - - - - Regeneration - - - - Resistance - - - - Fire Resistance - - - - Water Breathing - - - - Invisibility - - - - Blindness - - - - Night Vision - - - - Hunger - - - - Poison - - - - Wither - - - - Health Boost - - - - Absorption - - - - Saturation - - - - of Swiftness - - - - of Slowness - - - - of Haste - - - - of Dullness - - - - of Strength - - - - of Weakness - - - - of Healing - - - - of Harming - - - - of Leaping - - - - of Nausea - - - - of Regeneration - - - - of Resistance - - - - of Fire Resistance - - - - of Water Breathing - - - - of Invisibility - - - - of Blindness - - - - of Night Vision - - - - of Hunger - - - - of Poison - - - - of Decay - - - - of Health Boost - - - - of Absorption - - - - of Saturation - - - - - - - - - II - - - - III - - - - IV - - - - Splash - - - - Mundane - - - - Uninteresting - - - - Bland - - - - Clear - - - - Milky - - - - Diffuse - - - - Artless - - - - Thin - - - - Awkward - - - - Flat - - - - Bulky - - - - Bungling - - - - Buttered - - - - Smooth - - - - Suave - - - - Debonair - - - - Thick - - - - Elegant - - - - Fancy - - - - Charming - - - - Dashing - - - - Refined - - - - Cordial - - - - Sparkling - - - - Potent - - - - Foul - - - - Odorless - - - - Rank - - - - Harsh - - - - Acrid - - - - Gross - - - - Stinky - - - - Used as the base of all potions. Use in a brewing stand to create potions. - - - - Has no effects, can be used in a brewing stand to create potions by adding more ingredients. - - - - Increases affected players, animals and monsters movement speed, and players sprinting speed, jumping length and field of view. - - - - Reduces affected players, animals and monsters movement speed, and players sprinting speed, jumping length and field of view. - - - - Increase the damage caused by affected players and monsters when attacking. - - - - Reduces the damage cause by affected players and monsters when attacking. - - - - Instantly increases the affected players, animals and monsters health. - - - - Instantly reduces the affected players, animals and monsters health. - - - - Restores health to the affected players, animals and monsters over time. - - - - Makes the affected players, animals and monsters immune to damage from fire, lava, and ranged Blaze attacks. - - - - Reduces health of the affected players, animals and monsters over time. - - - - Allows affected players to breathe normally underwater. - - - - Increases the jump height of the affected player. - - - - When Applied: - - - - Horse Jump Strength - - - - Zombie Reinforcements - - - - Max Health - - - - Mob Follow Range - - - - Knockback Resistance - - - - Speed - - - - Attack Damage - - - - Sharpness - - - - Smite - - - - Bane of Arthropods - - - - Knockback - - - - Fire Aspect - - - - Protection - - - - Fire Protection - - - - Feather Falling - - - - Blast Protection - - - - Projectile Protection - - - - Respiration - - - - Aqua Affinity - - - - Depth Strider - - - - Efficiency - - - - Silk Touch - - - - Unbreaking - - - - Looting - - - - Fortune - - - - Power - - - - Flame - - - - Punch - - - - Infinity - - - - I - - - - II - - - - III - - - - IV - - - - V - - - - VI - - - - VII - - - - VIII - - - - IX - - - - X - - - - Can be mined with an Iron pickaxe or better to collect Emeralds. - - - - Similar to a Chest except that items placed in an Ender Chest are available in every one of the player's Ender Chests, even in different dimensions. - - - - Is activated when an entity passes through a connected Tripwire. - - - - Activates a connected Tripwire Hook when an entity passes through it. - - - - A compact way of storing Emeralds. - - - - A wall made of Cobblestone. - - - - Can be used to repair weapons, tools and armor. - - - - Smelted in a furnace to produce Nether Quartz. - - - - Used as a decoration. - - - - Can be traded with villagers. - - - - Used as a decoration. Flowers, Saplings, Cacti and Mushrooms can be planted in it. - - - - Restores 2{*ICON_SHANK_01*}, and can be crafted into a golden carrot. Can be planted in farmland. - - - - Restores 0.5{*ICON_SHANK_01*}, or can be cooked in a furnace. This can be planted in farmland. - - - - Restores 3{*ICON_SHANK_01*}. Created by cooking a potato in a furnace. - - - - Restores 1{*ICON_SHANK_01*}. Eating this can cause you to become poisoned. - - - - Restores 3{*ICON_SHANK_01*}. Crafted from a carrot and gold nuggets. - - - - Used to control a saddled pig when riding on it. - - - - Restores 4{*ICON_SHANK_01*}. - - - - Used with an Anvil to enchant weapons, tools or armor. - - - - Created by mining Nether Quartz Ore. Can be crafted into a Block of Quartz. - - - - Crafted from Wool. Used as a decoration. - - - - Emerald - - - - Flower Pot - - - - Carrot - - - - Potato - - - - Baked Potato - - - - Poisonous Potato - - - - Golden Carrot - - - - Carrot on a Stick - - - - Pumpkin Pie - - - - Enchanted Book - - - - Nether Quartz - - - - Emerald Ore - - - - Ender Chest - - - - Tripwire Hook - - - - Tripwire - - - - Block of Emerald - - - - Cobblestone Wall - - - - Mossy Cobblestone Wall - - - - Flower Pot - - - - Carrots - - - - Potatoes - - - - Anvil - - - - Anvil - - - - Slightly Damaged Anvil - - - - Very Damaged Anvil - - - - Nether Quartz Ore - - - - Block of Quartz - - - - Chiseled Quartz Block - - - - Pillar Quartz Block - - - - Quartz Stairs - - - - Carpet - - - - Black Carpet - - - - Red Carpet - - - - Green Carpet - - - - Brown Carpet - - - - Blue Carpet - - - - Purple Carpet - - - - Cyan Carpet - - - - Light Gray Carpet - - - - Gray Carpet - - - - Pink Carpet - - - - Lime Carpet - - - - Yellow Carpet - - - - Light Blue Carpet - - - - Magenta Carpet - - - - Orange Carpet - - - - White Carpet - - - - Chiseled Sandstone - - - - Smooth Sandstone - - - - {*PLAYER*} was killed trying to hurt {*SOURCE*} - - - - {*PLAYER*} was squashed by a falling Anvil. - - - - {*PLAYER*} was squashed by a falling block. - - - - Teleported {*PLAYER*} to {*DESTINATION*} - - - - {*PLAYER*} teleported you to their position - - - - {*PLAYER*} teleported to you - - - - Thorns - - - - Quartz Slab - - - - Makes dark areas appear as if in daylight, even under water. - - - - Makes affected players, animals and monsters invisible. - - - - Repair & Name - - - - Enchantment Cost: %d - - - - Too Expensive! - - - - Rename - - - - You have: - - - - Required Items For Trade - - - - {*VILLAGER_TYPE*} offers %s - - - - Repair - - - - Trade - - - - Dye collar - - - - - This is the Anvil interface, which you can use to rename, repair and apply enchantments to weapons, armor, or tools, at the cost of Experience Levels. - - - - - - {*B*} - Press{*CONTROLLER_VK_A*} to learn more about the Anvil interface.{*B*} - Press{*CONTROLLER_VK_B*} if you already know the Anvil interface. - - - - - - To begin working on an item, place it in the first input slot. - - - - - - When the correct raw material is placed in the second input slot (e.g. Iron Ingots for a damaged Iron Sword), the proposed repair appears in the output slot. - - - - - - Alternatively, a second identical item can be placed into the second slot to combine the two items. - - - - - - To enchant items on the Anvil, place an Enchanted Book in the second input slot. - - - - - - The number of Experience Levels that the work will cost is shown beneath the output. If you do not have enough Experience Levels, the repair cannot be completed. - - - - - - It is possible to rename the item by editing the name shown in the textbox. - - - - - - Picking up the repaired item will consume both items used by the Anvil and decrease your Experience Level by the given amount. - - - - - - In this area there is an Anvil and a Chest containing tools and weapons to work on. - - - - - - {*B*} - Press{*CONTROLLER_VK_A*} to learn more about the Anvil.{*B*} - Press{*CONTROLLER_VK_B*} if you already know about the Anvil. - - - - - - Using an Anvil, weapons and tools can be repaired to restore their durability, renamed, or enchanted with Enchanted Books. - - - - - - Enchanted Books can be found inside Chests within dungeons, or enchanted from normal Books at the Enchantment Table. - - - - - - Using the Anvil costs Experience Levels, and each use has a chance to damage the Anvil. - - - - - - The type of work to be done, value of the item, number of enchantments, and amount of prior work all affect the cost of repair. - - - - - - Renaming an item changes the displayed name for all players and permanently reduces the prior work cost. - - - - - - In the Chest in this area you will find damaged Pickaxes, raw materials, Bottles O' Enchanting, and Enchanted Books to experiment with. - - - - - - This is the trading interface which displays trades that can be made with a villager. - - - - - - {*B*} - Press{*CONTROLLER_VK_A*} to learn more about the trading interface.{*B*} - Press{*CONTROLLER_VK_B*} if you already know the trading interface. - - - - - - All trades that the villager is willing to make at the moment are displayed along the top. - - - - - - Trades will appear red and be unavailable if you do not have the required items. - - - - - - The amount and type of items you are giving to the villager are shown in the two boxes on the left. - - - - - - You can see the total number of the items required for the trade in the two boxes on the left. - - - - - - Press{*CONTROLLER_VK_A*} to trade the items the villager requires for the item on offer. - - - - - - In this area there is a villager and a Chest containing Paper to purchase items. - - - - - - {*B*} - Press{*CONTROLLER_VK_A*} to learn more about trading.{*B*} - Press{*CONTROLLER_VK_B*} if you already know about trading. - - - - - - Players can trade items from their inventory with villagers. - - - - - - The trades a villager is likely to offer depends on their profession. - - - - - - Performing a mix of trades will randomly add to or update the villager's available trades. - - - - - - Trades that have been used frequently may be removed temporarily, but the villager will always offer at least one trade. - - - - - - Take some Paper from the Chest and try trading with the villager here. - - - - - - In this area there are two Ender Chests. - - - - - - {*B*} - Press{*CONTROLLER_VK_A*} to learn more about Ender Chests.{*B*} - Press{*CONTROLLER_VK_B*} if you already know about Ender Chests. - - - - - - All Ender Chests in a world are linked, even across dimensions. Items placed into an Ender Chest are accessible in any other Ender Chest. - - - - - - However, the contents of the Ender Chests are different for each player. - - - - - - This allows players to store items in any Ender Chest, and retrieve them from other Ender Chests in different positions in the world. You can try this now by placing items in either Ender Chest. - - - - - Restores 2{*ICON_SHANK_01*}, regenerates health for 30 seconds, and grants fire resistance and damage resistance for 5 minutes. Crafted from an apple and gold blocks. - - - - Can Teleport - - - - Teleport - - - - Teleport To Player - - - - Teleport To Me - - - - Can Disable Exhaustion - - - - Can Become Invisible - - - - You can now enable invisibility - - - - You can no longer enable invisibility - - - - You can now enable flying - - - - You can no longer enable flying - - - - You can now disable exhaustion - - - - You can no longer disable exhaustion - - - - You can now teleport - - - - You can no longer teleport - - - - {*T3*}HOW TO PLAY : ANVIL{*ETW*}{*B*}{*B*} -Experience Levels can be used to repair, enchant or rename items with the Anvil.{*B*} -All items can be renamed, although only items with durability can be repaired or have enchantments from Enchanted Books applied to them.{*B*} -An item can be repaired by placing it in one of the input slots on the left, along with either some raw materials of the item, like Iron Ingots for an Iron Sword, or combined with another item of the same type.{*B*} -Combining items is more efficient when done with an Anvil, and additionally, if either of the items were enchanted, the finished product may have enchantments from either of the inputs.{*B*} -Enchanted Books can apply enchantments to items by combining them at an Anvil if the Book's enchantment is suitable. Enchanted Books can be found in Chests within dungeons, or enchanted from normal Books at the Enchantment Table.{*B*} -There is a chance that the Anvil will be damaged with each use and after enough punishment it will be destroyed.{*B*} - - - - - {*T3*}HOW TO PLAY : TRADING{*ETW*}{*B*}{*B*} -It is possible to trade items with villagers. Each villager has a profession; they can be Farmers, Butchers, Blacksmiths, Librarians or Priests, and this affects the type of items they might trade.{*B*} -You can find a list of all the trades a villager is offering in the trading menu. A villager may modify or add to its trades whenever a player trades with it, although a trade might become temporarily disabled if it is used too frequently.{*B*} -Trades usually involve buying or selling a number of items for emeralds.{*B*} -If you do not have the items required for a trade, the items are shown in red.{*B*} - - - - - {*T3*}HOW TO PLAY : ENDER CHEST {*ETW*}{*B*}{*B*} -All Ender Chests in a world are linked. Items placed into an Ender Chest are accessible in any other. However, the contents of the Ender Chests are different for each player. This allows players to store items in any Ender Chest, and retrieve them from other Ender Chests in different positions in the world. - - - - - Farmer - - - - Librarian - - - - Priest - - - - Blacksmith - - - - Butcher - - - - Found in villages, villagers will offer to sell items to the player depending on their profession. - - - - Large Chest - - - - - You can also create Enchanted Books at the Enchantment Table, which can be used later at the Anvil to apply their enchantment to an item. - - - - - - Tripwire Hooks will also provide constant power to a circuit while something is triggering the string between them. - - - - - - Once tamed, a wolf will always have its collar on. The color of their collar can be changed by dying it. - - - - - Carrots and Potatoes are farmed by planting Carrots or Potatoes, and are ready for harvesting when the vegetable is visible above the ground. - - - - - Additionally, pigs can be saddled and then ridden by players. They are controlled by tempting them with a Carrot on a Stick. - - - - - - If necessary you can slowly move your minecart along using {*CONTROLLER_ACTION_MOVE*}. This helps to start the minecart by getting it onto a powered rail. - - - - - You cannot join this game as split-screen is only supported when in High Definition mode. Sign out all other players if you wish to join. - - - - Cure - - - - Acacia Wood - - - - Dark Oak Wood - - - - Acacia Planks - - - - Dark Oak Planks - - - - Acacia Wood Stairs - - - - Dark Oak Wood Stairs - - - - Acacia Wood Slab - - - - Dark Oak Wood Slab - - - - Dark Oak Wood Slab - - - - Iron Trapdoor - - - - Spruce Door - - - - Birch Door - - - - Jungle Door - - - - Acacia Door - - - - Dark Oak Door - - - - Spruce Fence - - - - Birch Fence - - - - Jungle Fence - - - - Acacia Fence - - - - Dark Oak Fence - - - - Spruce Fence Gate - - - - Birch Fence Gate - - - - Jungle Fence Gate - - - - Acacia Fence Gate - - - - Dark Oak Fence Gate - - - - Spruce Door - - - - Birch Door - - - - Jungle Door - - - - Acacia Door - - - - Dark Oak Door - - - Armor Stand - - - - Can be equipped to display armor and other decorative items such as mob heads. - - - - Rabbit - - - - A harmless creature. May drop a rabbit hide or a rabbit's foot when killed. - - - - Rabbit Hide - - - - Used in crafting leather. - - - - Rabbit's Foot - - - - Used as an ingredient for brewing potions. - - - - Raw Rabbit - - - - Restores 0.5{*ICON_SHANK_01*}, or can be cooked in a furnace. - - - - Cooked Rabbit - - - - Restores 2.5{*ICON_SHANK_01*}. Used to cook up some rabbit stew. - - - - Raw Mutton - - - - Restores 1{*ICON_SHANK_01*}, or can be cooked in a furnace. - - - - Cooked Mutton - - - - Restores 3{*ICON_SHANK_01*}. Created by cooking raw mutton in a furnace. - - - - Acacia Sapling - - - - Dark Oak Sapling - - - - Acacia Leaves - - - - Dark Oak Leaves - - - - Red Sandstone - - - - Red Sandstone Stairs - - - - Prismarine Crystal - - - - Sea Lantern - - - - Exit Minecraft - - - - Prismarine - - - - Dark Prismarine - - - - Prismarine Bricks - - - - Prismarine Shard - - - - Rare decorative stone that can be found in Ocean Monuments. Can be crafted from Prismarine shards. - - - - A rarer form of Prismarine that can be found in Ocean Monuments. Can be crafted with Prismarine shards and an Ink Sac. - - - - Decorative Prismarine brick that can be found in Ocean Monuments. Can be crafted from Prismarine shards. - - - - Obtained from Sea Lanterns or by defeating Guardians and Elder Guardians. Can be used in crafting Sea Lanterns. - - - - Dropped by Guardians and Elder Guardians. Can be used in crafting Prismarine and Sea Lanterns. - - - - Rabbit Stew - - - - Tall Grass - - - - Large Fern - - - - Lilac - - - - Rose Bush - - - - Peony - - - - Packed Ice - - - - Sunflower - - - - A solid unmeltable block of ice that can have objects placed on it. - - - - Red colored Sandstone. It is not influenced by gravity like normal Sand. - - - - Underwater light sources that can be found in Ocean Monuments. Can be crafted from Prismarine shards and Prismarine crystals. - - - - Rare decorative stone that can be found in Ocean Monuments. Can be crafted from Prismarine shards. - - - - Double tall grass that can sometimes drop seeds. - - - - Chiseled Red Sandstone - - - - Smooth Red Sandstone - - - - Podzol - - - - Coarse Dirt - - - - Similar to Dirt Blocks, but very good for growing mushrooms on. - - - - A special type of dirt that does not grow grass. - - - - Granite - - - - Polished Granite - - - - Andesite - - - - Polished Andesite - - - - Diorite - - - - Polished Diorite - - - - Can be mined with a pickaxe to collect granite. - - - - Can be crafted from granite for a polished look. - - - - Can be mined with a pickaxe to collect andesite. - - - - Can be crafted from andesite for a polished look. - - - - Can be mined with a pickaxe to collect diorite. - - - - Can be crafted from diorite for a polished look. - - - - Red Sand - - - - Wet Sponge - - - - Can be dried in a furnace, allowing the sponge to be reused. - - - - Raw Salmon - - - - Cooked Salmon - - - - Clownfish - - - - Pufferfish - - - - Restores 1{*ICON_SHANK_01*}, or can be cooked in a furnace. Can be fed to an ocelot to tame it. - - - - Restores 3{*ICON_SHANK_01*}. Created by cooking a raw salmon in a furnace. - - - - Restores 0.5{*ICON_SHANK_01*}. - - - - Restores 0.5{*ICON_SHANK_01*} however it is poisonous. Can also be used as an ingredient in brewing potions. - - - - Blue Orchid - - - - Allium - - - - Azure Bluet - - - - Red Tulip - - - - Orange Tulip - - - - White Tulip - - - - Pink Tulip - - - - Oxeye Daisy - - - - A common red flower that can be used to craft red dye. - - - - A rare blue flower that can be used to craft light blue dye. - - - - A rare magenta flower that can be used to craft magenta dye. - - - - A small white flower that can be used to craft light gray dye. - - - - A small red flower that can be used to craft red dye. - - - - A small orange flower that can be used to craft orange dye. - - - - A small white flower that can be used to craft light gray dye. - - - - A small pink flower that can be used to craft pink dye. - - - - A common white and yellow flower that can be used to craft light gray dye. - - - - A tall yellow flower that can be used to craft yellow dye. - - - - A tall purple flower that can be used to craft magenta dye. - - - - A tall fern that can sometimes drop seeds. - - - - A tall red flower that can be used to craft red dye. - - - - A tall green and pink flower that can be used to craft pink dye. - - - - Endermite - - - - Guardian - - - - Elder Guardian - - - - Written Book - - - - A book signed by the author (cannot be written in). - - - - Book and Quill - - - - A Book that can be written in. - - - - Next Page - - - - Previous Page - - - - Add Page - - - - Exit Book - - - - Are you sure you want to exit this book and the changes you've made? - - - - Lure - - - - Luck of the Sea - - - Red Sandstone Slab - - - Elytra - - - Taking Inventory - Open your inventory. - - Getting Wood - Punch a tree until a block of wood pops out. - - Benchmarking - Craft a Workbench with four blocks of Wooden Planks. - - Time to Mine! - Use Planks and Sticks to make a Pickaxe. - - Hot Topic - Construct a Furnace out of eight Cobblestone blocks. - - Acquire Hardware - Smelt an Iron Ingot. - - Time to Farm! - Make a Hoe. - - Bake Bread - Turn Wheat into Bread. - - The Lie - Bake a Cake using: Wheat, Sugar, Milk and Eggs. - - Getting an Upgrade - Construct a better pickaxe. - - Delicious Fish - Catch and cook Fish! - - On A Rail - Travel by Minecart to a point at least 500m in a single direction from where you started. - - Time to Strike! - Use Planks and Sticks to make a Sword. - - Monster Hunter - Attack and destroy a monster. - - Cow Tipper - Harvest some leather. - - When Pigs Fly - Use a Saddle to ride a Pig, and then have the Pig get hurt from fall damage while riding it. - - Leader of the Pack - Befriend five Wolves. - - MOAR Tools - Construct one type of each tool. - - Dispense With This - Construct a dispenser. - - Into The Nether - Construct a Nether Portal. - - Pork Chop - Cook and eat a Pork Chop. - - Passing the Time - Play for 100 days. - - Archer - Kill a Creeper with Arrows. - - Sniper Duel - Kill a Skeleton with an Arrow from more than 50 meters. - - DIAMONDS! - Acquire diamonds with your iron tools. - - Return to Sender - Destroy a Ghast with a Fireball. - - Into Fire - Relieve a Blaze of its rod. - - Local Brewery - Brew a potion. - - The End? - Enter an End Portal. - - The End. - Kill the Enderdragon. - - Enchanter - Construct an Enchantment Table. - - Overkill - Deal nine hearts of damage in a single hit. - - Librarian - Build some Bookshelves to improve your Enchantment Table. - - Adventuring Time - Discover all biomes. - - Repopulation - Breed two Cows with Wheat. - - Diamonds to you! - Throw diamonds to another player. - - The Haggler - Mine or purchase 30 Emeralds. - - Pot Planter - Craft and place a Flower pot. - - It's a Sign! - Craft and place a sign. - - Iron Belly - Stop starvation using rotten flesh. - - Have a Shearful Day - Use Shears to obtain Wool from a Sheep. - - Rainbow Collection - Gather all 16 colors of Wool. - - Stayin' Frosty - Swim in Lava while having the Fire Resistance effect. - - Chestful of Cobblestone - Mine 1,728 Cobblestone and place it in a Chest. - - Renewable Energy - Smelt Wood Trunks using Charcoal to make more Charcoal. - - Music to my Ears - Play a Music Disc in a Jukebox. - - Body Guard - Create an Iron Golem. - - Iron Man - Wear a full suit of Iron Armor. - - Zombie Doctor - Cure a Zombie Villager. - - Lion Tamer - Tame an ocelot. - - Hold {*CONTROLLER_VK_Y*} to view - - Classic Crafting - - - Restores 5{*ICON_SHANK_01*}. - - + + + New Downloadable Content is available! Access it from the Minecraft Store button on the Main Menu. + + + + You can change the look of your character with a Skin Pack from the Minecraft Store. Select 'Minecraft Store' on the Main Menu to see what's available. + + + + Alter the gamma settings to make the game brighter or darker. + + + + If you set the game difficulty to Peaceful, your health will automatically regenerate, and no monsters will come out at night! + + + + Feed a bone to a wolf to tame it. You can then make it sit or follow you. + + + + You can drop items when in the Inventory menu by moving the cursor off the menu and pressing{*CONTROLLER_VK_A*} + + + + Sleeping in a bed at night will fast forward the game to dawn, but all players in a multiplayer game need to sleep in beds at the same time. + + + + Harvest pork chops from pigs, and cook and eat them to regain health. + + + + Harvest leather from cows, and use it to make armor. + + + + If you have an empty bucket, you can fill it with milk from a cow, or water, or lava! + + + + Use a hoe to prepare areas of ground for planting. + + + + Spiders won't attack you during the day - unless you attack them. + + + + Digging soil or sand with a spade is faster than with your hand! + + + + Eating cooked pork chops gives more health than eating raw pork chops. + + + + Make some torches to light up areas at night. Monsters will avoid the areas around these torches. + + + + Get to destinations faster with a minecart and rail! + + + + Plant some saplings and they'll grow into trees. + + + + Pigmen won't attack you, unless you attack them. + + + + You can change your game spawn point and skip to dawn by sleeping in a bed. + + + + Hit those fireballs back at the Ghast! + + + + Building a portal will allow you to travel to another dimension - The Nether. + + + + Press{*CONTROLLER_VK_B*} to drop the item currently in your hand! + + + + Use the right tool for the job! + + + + If you can't find any coal for your torches, you can always make charcoal from trees in a furnace. + + + + Digging straight down or straight up is not a great idea. + + + + Bonemeal (crafted from a Skeleton bone) can be used as a fertilizer, and can make things grow instantly! + + + + Creepers explode when they get close to you! + + + + Obsidian is created when water hits a lava source block. + + + + Lava can take minutes to disappear COMPLETELY when the source block is removed. + + + + Cobblestone is resistant to Ghast fireballs, making it useful for guarding portals. + + + + Blocks that can be used as a light source will melt snow and ice. This includes torches, glowstone, and Jack-O-Lanterns. + + + + Take caution when building structures made of wool in open air, as lightning from thunderstorms can set wool on fire. + + + + A single bucket of lava can be used in a furnace to smelt 100 blocks. + + + + The instrument played by a note block depends on the material beneath it. + + + + Zombies and Skeletons can survive daylight if they are in water. + + + + Attacking a wolf will cause any wolves in the immediate vicinity to turn hostile and attack you. This trait is also shared by Zombie Pigmen. + + + + Wolves cannot enter the Nether. + + + + Wolves won't attack Creepers. + + + + Chickens lay an egg every 5 to 10 minutes. + + + + Obsidian can only be mined with a diamond pickaxe. + + + + Creepers are the easiest obtainable source of gunpowder. + + + + Placing two chests side by side will make one large chest. + + + + Tame wolves show their health with the position of their tail. Feed them meat to heal them. + + + + Cook cactus in a furnace to get green dye. + + + + Read the What's New section in the How To Play menus to see the latest update information about the game. + + + + Stackable fences are in the game now! + + + + Some animals will follow you if you have wheat in your hand. + + + + If an animal can't move more than 20 blocks in any direction, it won't despawn. + + + + Music by C418! + + + + Notch has over a million followers on twitter! + + + + Not all Swedish people have blonde hair. Some, like Jens from Mojang, even have ginger hair! + + + + There will be an update to this game eventually! + + + + Who is Notch? + + + + Mojang has more awards than staff! + + + + Some famous people play Minecraft! + + + + deadmau5 likes Minecraft! + + + + Do not look directly at the bugs. + + + + Creepers were born from a coding bug. + + + + Is it a chicken or is it a duck? + + + + Were you at Minecon? + + + + No-one at Mojang has ever seen junkboy's face. + + + + Did you know there's a Minecraft Wiki? + + + + Mojang's new office is cool! + + + + Minecon 2013 was in Orlando, Florida, USA! + + + + .party() was excellent! + + + + Always assume rumors are false, rather than assuming they're true! + + + + {*T3*}HOW TO PLAY : BASICS{*ETW*}{*B*}{*B*} +Minecraft is a game about placing blocks to build anything you can imagine. At night monsters come out, make sure to build a shelter before that happens.{*B*}{*B*} +Use{*CONTROLLER_ACTION_LOOK*} to look around.{*B*}{*B*} +Use{*CONTROLLER_ACTION_MOVE*} to move around.{*B*}{*B*} +Press{*CONTROLLER_ACTION_JUMP*} to jump.{*B*}{*B*} +Push{*CONTROLLER_ACTION_MOVE*} forward twice in rapid succession to sprint. While you hold {*CONTROLLER_ACTION_MOVE*} forward, the character will continue to sprint unless they run out of sprint time or the Food Bar has less than{*ICON_SHANK_03*}.{*B*}{*B*} +Hold{*CONTROLLER_ACTION_ACTION*} to mine and chop using your hand or whatever you are holding. You may need to craft a tool to mine some blocks.{*B*}{*B*} +If you are holding an item in your hand, use{*CONTROLLER_ACTION_USE*} to use that item, or press{*CONTROLLER_ACTION_DROP*} to drop that item. + + + + {*T3*}HOW TO PLAY : HUD{*ETW*}{*B*}{*B*} +The HUD shows information about your status; your health, your remaining oxygen when you are under water, your hunger level (you need to eat to replenish this), and your armor if you are wearing any. If you lose some health, but have a food bar with 9 or more{*ICON_SHANK_01*} in it, your health will automatically replenish. Eating food will replenish your food bar.{*B*} +The Experience Bar is also shown here, with a numeric value to show your Experience Level, and the bar indicating how many Experience Points are required to increase your Experience Level. Experience Points are gained by collecting the Experience Orbs dropped by mobs when they die, mining certain block types, breeding animals, fishing, and smelting ores in a furnace.{*B*}{*B*} +It also shows the items that are available to use. Use{*CONTROLLER_ACTION_LEFT_SCROLL*} and{*CONTROLLER_ACTION_RIGHT_SCROLL*} to change the item in your hand. + + + + {*T3*}HOW TO PLAY : INVENTORY{*ETW*}{*B*}{*B*} +Use{*CONTROLLER_ACTION_INVENTORY*} to view your inventory.{*B*}{*B*} +This screen shows items available for use in your hand, and all the other items that you are carrying. Your armor is also shown here.{*B*}{*B*} +Use{*CONTROLLER_MENU_NAVIGATE*} to move the pointer. Use{*CONTROLLER_VK_A*} to pick an item under the pointer. If there is more than one item here this will pick them all up, or you can use{*CONTROLLER_VK_X*} to pick up just half of them.{*B*}{*B*} +Move the item with the pointer over another space in the inventory and place it there using{*CONTROLLER_VK_A*}. With multiple items on the pointer, use{*CONTROLLER_VK_A*} to place them all, or{*CONTROLLER_VK_X*} to place just one.{*B*}{*B*} +If an item you are over is armor, you will be shown a tooltip to enable a quick move of this to the right armor slot in the inventory.{*B*}{*B*} +It is possible to change the color of your Leather Armor by dying it, you can do this in the inventory menu by holding the dye in your pointer, then pressing{*CONTROLLER_VK_X*} whilst the pointer is over the piece you wish to dye. + + + + + {*T3*}HOW TO PLAY : CHEST{*ETW*}{*B*}{*B*} +Once you have crafted a Chest, you can place this in the world and then use it with{*CONTROLLER_ACTION_USE*} to store items from your inventory.{*B*}{*B*} +Use the pointer to move items between your inventory and the chest.{*B*}{*B*} +Items in the chest will be stored there for you to swap back into your inventory again later. + + + + + {*T3*}HOW TO PLAY : LARGE CHEST{*ETW*}{*B*}{*B*} +Two chests placed next to each other will be combined to form a Large Chest. This can store even more items.{*B*}{*B*} +It is used in the same way as a normal chest. + + + + + {*T3*}HOW TO PLAY : CRAFTING{*ETW*}{*B*}{*B*} +In the Crafting interface, you can combine items from your inventory to create new types of items. Use{*CONTROLLER_ACTION_CRAFTING*} to open the crafting interface.{*B*}{*B*} +Scroll through the tabs at the top using{*CONTROLLER_VK_LB*} and{*CONTROLLER_VK_RB*} to select the type of item you wish to craft, then use{*CONTROLLER_MENU_NAVIGATE*} to select the item to craft.{*B*}{*B*} +The crafting area shows the items required to craft the new item. Press{*CONTROLLER_VK_A*} to craft the item and place it in your inventory. + + + + + {*T3*}HOW TO PLAY : CRAFTING TABLE{*ETW*}{*B*}{*B*} +You can craft larger items using a Crafting Table.{*B*}{*B*} +Place the table in the world and press{*CONTROLLER_ACTION_USE*} to use it.{*B*}{*B*} +Crafting on a table works in the same way as basic crafting, but you have a larger crafting area, and a more varied selection of items to craft. + + + + + {*T3*}HOW TO PLAY : FURNACE{*ETW*}{*B*}{*B*} +A Furnace allows you to change items by firing them. For example, you can turn iron ore into iron ingots in the furnace.{*B*}{*B*} +Place the furnace in the world and press{*CONTROLLER_ACTION_USE*} to use it.{*B*}{*B*} +You need to put some fuel into the bottom of the furnace, and the item to be fired in the top. The furnace will then fire up and start working.{*B*}{*B*} +When your items have been fired, you can move them from the output area into your inventory.{*B*}{*B*} +If an item you are over is an ingredient or fuel for the furnace, you will be shown tooltips to enable a quick move of this to the furnace. + + + + + {*T3*}HOW TO PLAY : DISPENSER{*ETW*}{*B*}{*B*} +A Dispenser is used to shoot out items. You will need to place a switch, for example a lever, next to the dispenser to trigger it.{*B*}{*B*} +To fill the dispenser with items press{*CONTROLLER_ACTION_USE*}, then move the items that you want to dispense from your inventory into the dispenser.{*B*}{*B*} +Now when you use the switch, the dispenser will shoot out an item. + + + + + {*T3*}HOW TO PLAY : BREWING{*ETW*}{*B*}{*B*} +Brewing potions requires a Brewing Stand, which can be built at a crafting table. Every potion starts off with a bottle of water, which is made by filling a Glass Bottle with water from a Cauldron, or a water source.{*B*} +A Brewing Stand has three slots for bottles, so can make three potions at the same time. One ingredient can be used over all three bottles, so always brew three potions at the same time to best use your resources.{*B*} +Putting a potion ingredient in the top position at the Brewing Stand will make a base potion after a short time. This doesn't have any effect by itself, but brewing another ingredient with this base potion will give you a potion with an effect.{*B*} +Once you have this potion you can add a third ingredient to make the effect last longer (using Redstone Dust), be more intense (using Glowstone Dust), or turn into a harmful potion (using a Fermented Spider Eye).{*B*} +You can also add gunpowder to any potion to turn it into a Splash Potion, which can then be thrown. The thrown Splash Potion will cause the potion effect to apply over the area it lands in.{*B*} + +The source ingredients for potions are :-{*B*}{*B*} +* {*T2*}Nether Wart{*ETW*}{*B*} +* {*T2*}Spider Eye{*ETW*}{*B*} +* {*T2*}Sugar{*ETW*}{*B*} +* {*T2*}Ghast Tear{*ETW*}{*B*} +* {*T2*}Blaze Powder{*ETW*}{*B*} +* {*T2*}Magma Cream{*ETW*}{*B*} +* {*T2*}Glistering Melon{*ETW*}{*B*} +* {*T2*}Redstone Dust{*ETW*}{*B*} +* {*T2*}Glowstone Dust{*ETW*}{*B*} +* {*T2*}Fermented Spider Eye{*ETW*}{*B*}{*B*} + +You'll need to experiment with combinations of ingredients in order to find out all the different potions you can make. + + + + + {*T3*}HOW TO PLAY : ENCHANTING{*ETW*}{*B*}{*B*} +The Experience Points collected when a mob dies, or when certain blocks are mined or smelted in a furnace, can be used to enchant some tools, weapons, armor and books.{*B*} +When a Sword, Bow, Axe, Pickaxe, Shovel, Armor or Book is placed in the slot below the book in the Enchantment Table, the three buttons to the right of the slot will display some enchantments and their Experience Levels costs.{*B*} +If you do not have enough Experience Levels to use some of these, the cost will appear in red, otherwise it will be shown in green.{*B*}{*B*} +The actual enchantment applied is randomly selected based on the cost displayed.{*B*}{*B*} +If the Enchantment Table is surrounded by Bookshelves (up to a maximum of 15 Bookshelves), with a one block gap between the Bookcase and the Enchantment Table, the potency of the enchantments will be increased, and arcane glyphs will be seen coming from the book on the Enchantment Table.{*B*}{*B*} +All the ingredients for an Enchantment Table can be found within the villages in a world, or by mining and cultivation of the world.{*B*}{*B*} +Enchanted Books are used at the Anvil to apply enchantments to items. This gives you more control over which enchantments you would like on your items.{*B*} + + + + + {*T3*}HOW TO PLAY : FARMING ANIMALS{*ETW*}{*B*}{*B*} +If you want to keep your animals in the one place, build a fenced area of less than 20x20 blocks and have your animals inside it. This ensures they will still be there when you come back to see them. + + + + + {*T3*}HOW TO PLAY : BREEDING ANIMALS{*ETW*}{*B*}{*B*} +The animals in Minecraft can breed, and will produce baby versions of themselves!{*B*} +To get the animals to breed, you will need to feed them with the right food to get them to go into 'Love Mode'.{*B*} +Feed Wheat to a cow, mooshroom or sheep, Carrots to a pig, Wheat Seeds or Nether Wart to a chicken, or any kind of meat to a wolf, and they'll start looking for another animal of the same species near them that is also in Love Mode.{*B*} +When two animals of the same species meet, and both are in Love Mode, they will kiss for a few seconds, and then a baby animal will appear. The baby animal will follow their parents for a while before growing into a full sized animal itself.{*B*} +After being in Love Mode, an animal will not be able to enter it again for about five minutes.{*B*} +There is a limit on the number of animals it is possible to have in a world, so you may find the animals don't breed when you have a lot of them. + + + + {*T3*}HOW TO PLAY : NETHER PORTAL{*ETW*}{*B*}{*B*} +A Nether Portal allows the player to travel between the Overworld and the Nether world. The Nether world can be used to fast-travel in the Overworld - traveling one block distance in the Nether is equivalent to traveling 3 blocks in the Overworld, so when you build a portal in the Nether world and exit through it, you will be 3 times further away from your entry point.{*B*}{*B*} +A minimum of 10 Obsidian blocks are required to build the portal, and the portal needs to be 5 blocks high by 4 blocks wide by 1 block deep. Once the portal frame is built, the space inside the frame needs to be set on fire to activate it. This can be done using the Flint and Steel item, or the Fire Charge item.{*B*}{*B*} +Examples of portal construction are shown in the picture to the right. + + + + + {*T3*}HOW TO PLAY : BANNING LEVELS{*ETW*}{*B*}{*B*} +If you find offensive content within a level you are playing, you can choose to add the level to your Banned Levels list. +If you would like to do this, bring up the Pause menu, then press{*CONTROLLER_VK_RB*} to select the Ban Level tooltip. +When you attempt to join this level in future, you will be notified that the level is in your Banned Levels list, and given the option to remove it from the list and continue into the level, or back out. + + + + {*T3*}HOW TO PLAY : HOST AND PLAYER OPTIONS{*ETW*}{*B*}{*B*} + +{*T1*}Game Options{*ETW*}{*B*} +When loading or creating a world, you can press the "More Options" button to enter a menu that allows more control over your game.{*B*}{*B*} + + {*T2*}Player vs Player{*ETW*}{*B*} + When enabled, players can inflict damage on other players. This option only affects Survival mode.{*B*}{*B*} + + {*T2*}Trust Players{*ETW*}{*B*} + When disabled, players joining the game are restricted in what they can do. They are not able to mine or use items, place blocks, use doors and switches, use containers, attack players or attack animals. You can change these options for a specific player using the in-game menu.{*B*}{*B*} + + {*T2*}Fire Spreads{*ETW*}{*B*} + When enabled, fire may spread to nearby flammable blocks. This option can also be changed from within the game.{*B*}{*B*} + + {*T2*}TNT Explodes{*ETW*}{*B*} + When enabled, TNT will explode when detonated. This option can also be changed from within the game.{*B*}{*B*} + + {*T2*}Host Privileges{*ETW*}{*B*} + When enabled, the host can toggle their ability to fly, disable exhaustion, and make themselves invisible from the in-game menu. {*DISABLES_ACHIEVEMENTS*}{*B*}{*B*} + + {*T2*}Daylight Cycle{*ETW*}{*B*} + When disabled, the time of day will not change.{*B*}{*B*} + + {*T2*}Keep Inventory{*ETW*}{*B*} + When enabled, players will keep their inventory when they die.{*B*}{*B*} + + {*T2*}Mob Spawning{*ETW*}{*B*} + When disabled, mobs will not spawn naturally.{*B*}{*B*} + + {*T2*}Mob Griefing{*ETW*}{*B*} + When disabled, prevents monsters and animals from changing blocks (for example, Creeper explosions won't destroy blocks and Sheep won't remove Grass) or picking up items.{*B*}{*B*} + + {*T2*}Mob Loot{*ETW*}{*B*} + When disabled, monsters and animals will not drop loot (for example, Creepers won't drop gunpowder).{*B*}{*B*} + + {*T2*}Tile Drops{*ETW*}{*B*} + When disabled, blocks will not drop items when destroyed (for example, Stone blocks won't drop Cobblestone).{*B*}{*B*} + + {*T2*}Natural Regeneration{*ETW*}{*B*} + When disabled, players will not regenerate health naturally.{*B*}{*B*} + +{*T1*}World Generation Options{*ETW*}{*B*} +When creating a new world there are some additional options.{*B*}{*B*} + + {*T2*}Generate Structures{*ETW*}{*B*} + When enabled, structures such as Villages and Strongholds will generate in the world.{*B*}{*B*} + + {*T2*}Superflat World{*ETW*}{*B*} + When enabled, a completely flat world will be generated in the Overworld and in the Nether.{*B*}{*B*} + + {*T2*}Bonus Chest{*ETW*}{*B*} + When enabled, a chest containing some useful items will be created near the player spawn point.{*B*}{*B*} + + {*T2*}Reset Nether{*ETW*}{*B*} + When enabled, the Nether will be re-generated. This is useful if you have an older save where Nether Fortresses were not present.{*B*}{*B*} + + {*T1*}In-Game Options{*ETW*}{*B*} + While in the game a number of options can be accessed by pressing {*BACK_BUTTON*} to bring up the in-game menu.{*B*}{*B*} + + {*T2*}Host Options{*ETW*}{*B*} + The host player, and any players set as moderators can access the "Host Option" menu. In this menu they can enable and disable fire spreading and TNT exploding.{*B*}{*B*} + +{*T1*}Player Options{*ETW*}{*B*} +To modify the privileges for a player, select their name and press{*CONTROLLER_VK_A*} to bring up the player privileges menu where you can use the following options.{*B*}{*B*} + + {*T2*}Can Build And Mine{*ETW*}{*B*} + This option is only available when "Trust Players" is turned off. When this option is enabled, the player is able to interact with the world as normal. When disabled the player will not be able to place or destroy blocks, or interact with many items and blocks.{*B*}{*B*} + + {*T2*}Can Use Doors and Switches{*ETW*}{*B*} + This option is only available when "Trust Players" is turned off. When this option is disabled, the player will not be able to use doors and switches.{*B*}{*B*} + + {*T2*}Can Open Containers{*ETW*}{*B*} + This option is only available when "Trust Players" is turned off. When this option is disabled, the player will not be able to open containers, such as chests.{*B*}{*B*} + + {*T2*}Can Attack Players{*ETW*}{*B*} + This option is only available when "Trust Players" is turned off. When this option is disabled the player will not be able to cause damage to other players.{*B*}{*B*} + + {*T2*}Can Attack Animals{*ETW*}{*B*} + This option is only available when "Trust Players" is turned off. When this option is disabled the player will not be able to cause damage to animals.{*B*}{*B*} + + {*T2*}Moderator{*ETW*}{*B*} + When this option is enabled, the player is able to change privileges for other players (except the host) if "Trust Players" is turned off, kick players and they can enable and disable fire spreading and TNT exploding.{*B*}{*B*} + + {*T2*}Kick Player{*ETW*}{*B*} + {*KICK_PLAYER_DESCRIPTION*}{*B*}{*B*} + +{*T1*}Host Player Options{*ETW*}{*B*} +If "Host Privileges" is enabled the host player can modify some privileges for themselves. To modify the privileges for a player, select their name and press{*CONTROLLER_VK_A*} to bring up the player privileges menu where you can use the following options.{*B*}{*B*} + + {*T2*}Can Fly{*ETW*}{*B*} + When this option is enabled, the player is able to fly. This option is only relevant to Survival mode, as flying is enabled for all players in Creative mode.{*B*}{*B*} + + {*T2*}Disable Exhaustion{*ETW*}{*B*} + This option only affects Survival mode. When enabled, physical activities (walking/sprinting/jumping etc.) do not decrease the food bar. However, if the player becomes injured, the food bar will slowly decrease while the player is healing.{*B*}{*B*} + + {*T2*}Invisible{*ETW*}{*B*} + When this option is enabled, the player is not visible to other players and is invulnerable.{*B*}{*B*} + + {*T2*}Can Teleport{*ETW*}{*B*} + This allows the player to move players or themselves to other players in the world. + + + + + Next Page + + + + Previous Page + + + + Basics + + + + HUD + + + + Inventory + + + + Chests + + + + Crafting + + + + Furnace + + + + Dispenser + + + + Farming Animals + + + + Breeding Animals + + + + Brewing + + + + Enchantment + + + + Nether Portal + + + + Multiplayer + + + + Sharing Screenshots + + + + Banning Levels + + + + Creative Mode + + + + Host and Player Options + + + + Trading + + + + Anvil + + + + The End + + + + {*T3*}HOW TO PLAY : THE END{*ETW*}{*B*}{*B*} +The End is another dimension in the game, which is reached through an active End Portal. The End Portal can be found in a Stronghold, which is deep underground in the Overworld.{*B*} +To activate the End Portal, you'll need to put an Eye of Ender into any End Portal Frame without one.{*B*} +Once the portal is active, jump in to it to go to The End.{*B*}{*B*} +In The End you will meet the Ender Dragon, a fierce and powerful enemy, along with many Enderman, so you will have to be well prepared for the battle before going there!{*B*}{*B*} +You'll find that there are Ender Crystals on top of eight Obsidian spikes that the Ender Dragon uses to heal itself, +so the first step in the battle is to destroy each of these.{*B*} +The first few can be reached with arrows, but the later ones are protected by an Iron Fence cage, and you will need to build up to them.{*B*}{*B*} +While you are doing this, the Ender Dragon will be attacking you by flying at you and spitting Ender acid balls!{*B*} +If you approach the Egg Podium in the centre of the spikes, the Ender Dragon will fly down and attack you and this is where you can really do some damage to it!{*B*} +Avoid the acid breath, and target the Ender Dragon's eyes for the best results. If possible, bring some friends in to The End to help you with the battle!{*B*}{*B*} +Once you are in The End, your friends will be able to see the location of the End Portal within the Stronghold on their maps, +so they can easily join you. + + + + + Sprint + + + + What's New + + + + + {*T3*}Changes and Additions{*ETW*}{*B*} + {*T3*}neoLegacy v1.0.9b{*ETW*}{*B*}{*B*} + Additions{*B*} + - You can now copy and save various worlds on the LoadCreateJoin menu.{*B*}{*B*} + - Controller icons and in-game logos are now modifiable via a slider in 'User Interface' menu Changes{*B*}{*B*} + - Skin Select menu has been updated in order to achieve parity with TU36+{*B*}{*B*} + - Controls menu has been updated.{*B*}{*B*} + - Tutorial world has been updated to version TU31.{*B*}{*B*} + - Settings menus are now wider to match the ones from TU31{*B*}{*B*} + - In-game music now fades when leaving / joining a world.{*B*}{*B*} + - World size is now displayed correctly on the worlds-list menu.{*B*}{*B*} + - The LoadCreateJoin menu no longer features an infinite spinner object.{*B*}{*B*} + + + + + + Welcome back! You may not have noticed, but your Minecraft has just been updated. + {*T3*}neoLegacy v1.0.9b{*ETW*} + Additions + - You can now copy and save various worlds on the LoadCreateJoin menu. + - Controller icons and in-game logos are now modifiable via a slider in 'User Interface' menu. + Changes + - Skin Select menu has been updated in order to achieve parity with TU36+ + - Controls menu has been updated. + - Tutorial world has been updated to version TU31. + - Settings menus are now wider to match the ones from TU31+ + Bug Fixes + - In-game music now fades when leaving / joining a world. + - World size is now displayed correctly on the worlds-list menu. + - The LoadCreateJoin menu no longer features an infinite spinner object. + + + + + Horses + + + + {*T3*}HOW TO PLAY : HORSES{*ETW*}{*B*}{*B*} +Horses and Donkeys are found mainly in open plains. Mules are the offspring of a Donkey and a Horse, but are infertile themselves.{*B*} +All adult Horses, Donkeys and Mules can be ridden. However only Horses can be armored, and only Mules and Donkeys may be equipped with saddlebags for transporting items.{*B*}{*B*} +Horses, Donkeys and Mules must be tamed before they can be used. A horse is tamed by attempting to ride it, and managing to stay on the horse while it attempts to throw the rider off.{*B*} +When Love Hearts appear around the horse, it is tame, and will no longer attempt to throw the player off. To steer a horse, the player must equip the horse with a Saddle.{*B*}{*B*} +Saddles can be bought from villagers or found inside Chests hidden in the world.{*B*} +Tame Donkeys and Mules can be given saddlebags by attaching a Chest. These saddlebags can then be accessed whilst riding or sneaking.{*B*}{*B*} +Horses and Donkeys (but not Mules) can be bred like other animals using Golden Apples or Golden Carrots.{*B*} +Foals will grow into adult horses over time, although feeding them Wheat or Hay will speed this up.{*B*} + + + + + Beacons + + + + {*T3*}HOW TO PLAY : BEACONS{*ETW*}{*B*}{*B*} +Active Beacons project a bright beam of light into the sky and grant powers to nearby players.{*B*} +They are crafted with Glass, Obsidian and Nether Stars, which can be obtained by defeating the Wither.{*B*}{*B*} +Beacons must be placed so that they are in sunlight during the day. Beacons must be placed on Pyramids of Iron, Gold, Emerald or Diamond.{*B*} +The material the Beacon is placed on has no effect on the power of the Beacon.{*B*}{*B*} +In the Beacon menu you can select one primary power for your Beacon. The more tiers your pyramid has the more powers you will have to choose from.{*B*} +A Beacon on a pyramid with at least four tiers also gives the option of either the Regeneration secondary power or a stronger primary power.{*B*}{*B*} +To set the powers of your Beacon you must sacrifice an Emerald, Diamond, Gold or Iron Ingot in the payment slot.{*B*} +Once set, the powers will emanate from the Beacon indefinitely.{*B*} + + + + + Fireworks + + + + {*T3*}HOW TO PLAY : FIREWORKS{*ETW*}{*B*}{*B*} +Fireworks are decorative items that can be launched by hand or from Dispensers. They are crafted using Paper, Gunpowder and optionally a number of Firework Stars.{*B*} +The colors, fade, shape, size, and effects (such as trails and twinkle) of Firework Stars can be customized by including additional ingredients when crafting.{*B*}{*B*} +To craft a Firework place Gunpowder and Paper in the 3x3 crafting grid that is shown above your inventory.{*B*} +You can optionally place multiple Firework Stars in the crafting grid to add them to the Firework.{*B*} +Filling more slots in the crafting grid with Gunpowder will increase the height at which all the Firework Stars will explode.{*B*}{*B*} +You can then take the crafted Firework out of the output slot.{*B*}{*B*} +Firework Stars can be crafted by placing Gunpowder and Dye into the crafting grid.{*B*} + - The Dye will set the color of the explosion of the Firework Star.{*B*} + - The shape of the Firework Star is set by adding either a Fire Charge, Gold Nugget, Feather or Mob Head.{*B*} + - A trail or a twinkle can be added using Diamonds or Glowstone Dust.{*B*}{*B*} +After a Firework Star has been crafted, you can set the fade color of the Firework Star by crafting it with Dye. + + + + + Hoppers + + + + {*T3*}HOW TO PLAY : HOPPERS{*ETW*}{*B*}{*B*} +Hoppers are used to insert or remove items from containers, and to automatically pick up items thrown into them.{*B*} +They can affect Brewing Stands, Chests, Dispensers, Droppers, Minecarts with Chests, Minecarts with Hoppers, as well as other Hoppers.{*B*}{*B*} +Hoppers will continuously attempt to suck items out of a suitable container placed above them. They will also attempt to insert stored items into an output container.{*B*} +If a Hopper is powered by Redstone it will become inactive and stop both sucking and inserting items.{*B*}{*B*} +A Hopper points in the direction it tries to output items. To make a Hopper point to a particular block, place the Hopper against that block whilst sneaking.{*B*} + + + + + Droppers + + + + {*T3*}HOW TO PLAY : DROPPERS{*ETW*}{*B*}{*B*} +When powered by Redstone, Droppers will drop a single random item contained within them onto the ground. Use {*CONTROLLER_ACTION_USE*} to open the Dropper and then you can load the Dropper with items from your inventory.{*B*} +If the Dropper is facing a Chest or another type of Container, the item will be placed into that instead. Long chains of Droppers can be constructed to transport items over a distance, but for this to work they will have to be alternately powered on and off. + + + + + Deals more damage than by hand. + + + + Used to dig dirt, grass, sand, gravel and snow faster than by hand. Shovels are required to dig snowballs. + + + + Required to mine stone-related blocks and ore. + + + + Used to chop wood-related blocks faster than by hand. + + + + Used to till dirt and grass blocks to prepare for crops. + + + + Wooden doors are activated by using, hitting them or with Redstone. + + + + Iron doors can only be opened by Redstone, buttons or switches. + + + + NOT USED + + + + NOT USED + + + + NOT USED + + + + NOT USED + + + + Gives the user 1 Armor when worn. + + + + Gives the user 3 Armor when worn. + + + + Gives the user 2 Armor when worn. + + + + Gives the user 1 Armor when worn. + + + + Gives the user 2 Armor when worn. + + + + Gives the user 5 Armor when worn. + + + + Gives the user 4 Armor when worn. + + + + Gives the user 1 Armor when worn. + + + + Gives the user 2 Armor when worn. + + + + Gives the user 6 Armor when worn. + + + + Gives the user 5 Armor when worn. + + + + Gives the user 2 Armor when worn. + + + + Gives the user 2 Armor when worn. + + + + Gives the user 5 Armor when worn. + + + + Gives the user 3 Armor when worn. + + + + Gives the user 1 Armor when worn. + + + + Gives the user 3 Armor when worn. + + + + Gives the user 8 Armor when worn. + + + + Gives the user 6 Armor when worn. + + + + Gives the user 3 Armor when worn. + + + + A shiny ingot which can be used to craft tools made from this material. Created by smelting ore in a furnace. + + + + Allows ingots, gems, or dyes to be crafted into placeable blocks. Can be used as an expensive building block or compact storage of the ore. + + + + Used to send an electrical charge when stepped on by a player, an animal, or a monster. Wooden Pressure Plates can also be activated by dropping something on them. + + + + Used for compact staircases. + + + + Used for making long staircases. Two slabs placed on top of each other will create a normal-sized double slab block. + + + + Used for making long staircases. Two slabs placed on top of each other will create a normal-sized double slab block. + + + + Used to create light. Torches also melt snow and ice. + + + + Used as a building material and can be crafted into many things. Can be crafted from any form of wood. + + + + Used as a building material. Is not influenced by gravity like normal Sand. + + + + Used as a building material. + + + + Used to craft torches, arrows, signs, ladders, fences and as handles for tools and weapons. + + + + Used to forward time from any time at night to morning if all the players in the world are in bed, and changes the spawn point of the player. +The colors of the bed are always the same, regardless of the colors of wool used. + + + + Allows you to craft a more varied selection of items than the normal crafting. + + + + Allows you to smelt ore, create charcoal and glass, and cook fish and porkchops. + + + + Stores blocks and items inside. Place two chests side by side to create a larger chest with double the capacity. + + + + Used as a barrier that cannot be jumped over. Counts as 1.5 blocks high for players, animals and monsters, but 1 block high for other blocks. + + + + Used to climb vertically. + + + + Activated by using, hitting them or with redstone. They function as normal doors, but are a one by one block and lay flat on the ground. + + + + Shows text entered by you or other players. + + + + Used to create brighter light than torches. Melts snow/ice and can be used underwater. + + + + Used to cause explosions. Activated after placing by igniting with Flint and Steel item, or with an electrical charge. + + + + Used to hold mushroom stew. You keep the bowl when the stew has been eaten. + + + + Used to hold and transport water, lava and milk. + + + + Used to hold and transport water. + + + + Used to hold and transport lava. + + + + Used to hold and transport milk. + + + + Used to create fire, ignite TNT, and open a portal once it has been built. + + + + Used to catch fish. + + + + Displays positions of the Sun and Moon. + + + + Points to your start point. + + + + Will create an image of an area explored while held. This can be used for path-finding. + + + + When used becomes a map of the part of the world that you are in, and gets filled in as you explore. + + + + Allows for ranged attacks by using arrows. + + + + Used as ammunition for bows. + + + + Dropped by the Wither, used in crafting Beacons. + + + + When activated, create colorful explosions. The color, effect, shape and fade are determined by the Firework Star used when the Firework is created. + + + + Used to determine the color, effect and shape of a Firework. + + + + Used in Redstone circuits to maintain, compare, or subtract signal strength, or to measure certain block states. + + + + Is a type of Minecart that acts as a moving TNT block. + + + + Is a block that outputs a Redstone signal based on sunlight (or lack of sunlight). + + + + Is a special type of Minecart that functions similarly to a Hopper. It will collect items lying on tracks and from containers above it. + + + + A special type of Armor that can be equipped to a horse. Provides 5 Armor. + + + + A special type of Armor that can be equipped to a horse. Provides 7 Armor. + + + + A special type of Armor that can be equipped to a horse. Provides 11 Armor. + + + + Used to leash mobs to the player or Fence posts. + + + + Used to name mobs in the world. + + + + Restores 2.5{*ICON_SHANK_01*}. + + + + Restores 1{*ICON_SHANK_01*}. Can be used 6 times. + + + + Restores 1{*ICON_SHANK_01*}. + + + + Restores 1{*ICON_SHANK_01*}. + + + + Restores 3{*ICON_SHANK_01*}. + + + + Restores 1{*ICON_SHANK_01*}, or can be cooked in a furnace. Eating this can cause you to be poisoned. + + + + Restores 3{*ICON_SHANK_01*}. Created by cooking raw chicken in a furnace. + + + + Restores 1.5{*ICON_SHANK_01*}, or can be cooked in a furnace. + + + + Restores 4{*ICON_SHANK_01*}. Created by cooking raw beef in a furnace. + + + + Restores 1.5{*ICON_SHANK_01*}, or can be cooked in a furnace. + + + + Restores 4{*ICON_SHANK_01*}. Created by cooking a raw porkchop in a furnace. + + + + Restores 1{*ICON_SHANK_01*}, or can be cooked in a furnace. Can be fed to an Ocelot to tame it. + + + + Restores 2.5{*ICON_SHANK_01*}. Created by cooking a raw fish in a furnace. + + + + Restores 2{*ICON_SHANK_01*}, and can be crafted into a golden apple. + + + + Restores 2{*ICON_SHANK_01*}, and regenerates health for 4 seconds. Crafted from an apple and gold nuggets. + + + + Restores 2{*ICON_SHANK_01*}. Eating this can cause you to be poisoned. + + + + Used in the cake recipe, and as an ingredient for brewing potions. + + + + Used to send an electrical charge by being turned on or off. Stays in the on or off state until pressed again. + + + + Constantly sends an electrical charge, or can be used as a receiver/transmitter when connected to the side of a block. +Can also be used for low-level lighting. + + + + Used in Redstone circuits as repeater, a delayer, and/or a diode. + + + + Used to send an electrical charge by being pressed. Stays activated for approximately a second before shutting off again. + + + + Used to hold and shoot out items in a random order when given a Redstone charge. + + + + Plays a note when triggered. Hit it to change the pitch of the note. Placing this on top of different blocks will change the type of instrument. + + + + Used to guide minecarts. + + + + When powered, accelerates minecarts that pass over it. When unpowered, causes minecarts to stop on it. + + + + Functions like a Pressure Plate (sends a Redstone signal when powered) but can only be activated by a Minecart. + + + + Used to transport you, an animal, or a monster along rails. + + + + Used to transport goods along rails. + + + + Will move along rails and can push other minecarts when coal is put in it. + + + + Used to travel in water more quickly than swimming. + + + + Collected from sheep, and can be colored with dyes. + + + + Used as a building material and can be colored with dyes. This recipe is not recommended because Wool can be easily obtained from Sheep. + + + + Used as a dye to create black wool. + + + + Used as a dye to create green wool. + + + + Used as a dye to create brown wool, as an ingredient in cookies, or to grow Cocoa Pods. + + + + Used as a dye to create silver wool. + + + + Used as a dye to create yellow wool. + + + + Used as a dye to create red wool. + + + + Used to instantly grow crops, trees, tall grass, huge mushrooms and flowers, and can be used in dye recipes. + + + + Used as a dye to create pink wool. + + + + Used as a dye to create orange wool. + + + + Used as a dye to create lime wool. + + + + Used as a dye to create gray wool. + + + + Used as a dye to create light gray wool. +(Note: light gray dye can also be made by combining gray dye with bone meal, letting you make four light gray dyes from every ink sac instead of three.) + + + + Used as a dye to create light blue wool. + + + + Used as a dye to create cyan wool. + + + + Used as a dye to create purple wool. + + + + Used as a dye to create magenta wool. + + + + Used as dye to create Blue Wool. + + + + Plays Music Discs. + + + + Use these to create very strong tools, weapons or armor. + + + + Used to create brighter light than torches. Melts snow/ice and can be used underwater. + + + + Used to create books and maps. + + + + Can be used to create bookshelves or enchanted to make Enchanted Books. + + + + Allows the creation of more powerful enchantments when placed around the Enchantment Table. + + + + Used as decoration. + + + + Can be mined with an iron pickaxe or better, then smelted in a furnace to produce gold ingots. + + + + Can be mined with a stone pickaxe or better, then smelted in a furnace to produce iron ingots. + + + + Can be mined with a pickaxe to collect coal. + + + + Can be mined with a stone pickaxe or better to collect lapis lazuli. + + + + Can be mined with an iron pickaxe or better to collect diamonds. + + + + Can be mined with an iron pickaxe or better to collect redstone dust. + + + + Can be mined with a pickaxe to collect cobblestone. + + + + Causes players and mobs to bounce when they jump on it. + + + + Collected using a shovel. Can be used for construction. + + + + Can be planted and it will eventually grow into a tree. + + + + This cannot be broken. + + + + Sets fire to anything that touches it. Can be collected in a bucket. + + + + Collected using a shovel. Can be smelted into glass using the furnace. Is affected by gravity if there is no other tile underneath it. + + + + Collected using a shovel. Sometimes produces flint when dug up. Is affected by gravity if there is no other tile underneath it. + + + + Chopped using an axe, and can be crafted into planks or used as a fuel. + + + + Created in a furnace by smelting sand. Can be used for construction, but will break if you try to mine it. + + + + Mined from stone using a pickaxe. Can be used to construct a furnace or stone tools. + + + + Baked from clay in a furnace. + + + + Can be baked into bricks in a furnace. + + + + When broken drops clay balls which can be baked into bricks in a furnace. + + + + A compact way to store snowballs. + + + + Can be dug with a shovel to create snowballs. + + + + Sometimes produces wheat seeds when broken. + + + + Can be crafted into a dye. + + + + Can be crafted with a bowl to make stew. + + + + Can only be mined with a diamond pickaxe. Is produced by the meeting of water and still lava, and is used to build a portal. + + + + Spawns monsters into the world. + + + + Is placed on the ground to carry an electrical charge. When brewed with a potion it will increase the duration of the effect. + + + + When fully grown, crops can be harvested to collect wheat. + + + + Ground that has been prepared ready to plant seeds. + + + + Can be cooked in a furnace to create a green dye. + + + + Can be crafted to create sugar. + + + + Can be worn as a helmet or crafted with a torch to create a Jack-O-Lantern. It is also the main ingredient in Pumpkin Pie. + + + + Burns forever if set alight. + + + + Slows the movement of anything walking over it. + + + + Standing in the portal allows you to pass between the Overworld and the Nether. + + + + Used as a fuel in a furnace, or crafted to make a torch. + + + + Collected by killing a spider, and can be crafted into a Bow or Fishing Rod, or placed on the ground to create Tripwire. + + + + Collected by killing a chicken, and can be crafted into an arrow. + + + + Collected by killing a Creeper, and can be crafted into TNT or used as an ingredient for brewing potions. + + + + Can be planted in farmland to grow crops. Make sure there's enough light for the seeds to grow! + + + + Harvested from crops, and can be used to craft food items. + + + + Collected by digging gravel, and can be used to craft a flint and steel. + + + + When used on a pig it allows you to ride the pig. The pig can then be steered using a Carrot on a Stick. + + + + Collected by digging snow, and can be thrown. + + + + Collected by killing a cow, and can be crafted into armor or used to make Books. + + + + Collected by killing a Slime, and used as an ingredient for brewing potions or crafted to make Sticky Pistons. + + + + Dropped randomly by chickens, and can be crafted into food items. + + + + Collected by mining Glowstone, and can be crafted to make Glowstone blocks again or brewed with a potion to increase the potency of the effect. + + + + Collected by killing a Skeleton. Can be crafted into bone meal. Can be fed to a wolf to tame it. + + + + Collected by getting a Skeleton to kill a Creeper. Can be played in a jukebox. + + + + An invisible, but solid block. + + + + Extinguishes fire and helps crops grow. Can be collected in a bucket. + + + + When broken sometimes drops a sapling which can then be replanted to grow into a tree. + + + + Found in dungeons, can be used for construction and decoration. + + + + Used to obtain wool from sheep and harvest leaf blocks. + + + + When powered (using a button, a lever, a pressure plate, a redstone torch, or redstone with any one of these), a piston extends if it can and pushes blocks. + + + + When powered (using a button, a lever, a pressure plate, a redstone torch, or redstone with any one of these), a piston extends if it can and pushes blocks. When it retracts it pulls back the block touching the extended part of the piston. + + + + Made from Stone blocks, and commonly found in Strongholds. + + + + Used as a barrier, similar to fences. + + + + Similar to a door, but used primarily with fences. + + + + Can be crafted from Melon Slices. + + + + Transparent blocks that can be used as an alternative to Glass Blocks. + + + + Can be planted to grow pumpkins. + + + + Can be planted to grow melons. + + + + Dropped by Enderman when they die. When thrown, the player will be teleported to the position the Ender Pearl lands at, and will lose some health. + + + + A block of dirt with grass growing on top. Collected using a shovel. Can be used for construction. + + + + Can be used for construction and decoration. + + + + Slows movement when walking through it. Can be destroyed using shears to collect string. + + + + Spawns a Silverfish when destroyed. May also spawn Silverfish if nearby to another Silverfish being attacked. + + + + Grows over time when placed. Can be collected using shears. Can be climbed like a ladder. + + + + Slippery when walked on. Turns into water if above another block when destroyed. Melts if close enough to a light source or when placed in The Nether. + + + + Can be used as decoration. + + + + Used in potion brewing, and for locating Strongholds. Dropped by Blazes who tend to be found near or in Nether Fortresses. + + + + Used in potion brewing. Dropped by Ghasts when they die. + + + + Dropped by Zombie Pigmen when they die. Zombie Pigmen can be found in the Nether. Used as an ingredient for brewing potions. + + + + Used in potion brewing. This can be found naturally growing in Nether Fortresses. It can also be planted on Soul Sand. + + + + When used, can have various effects, depending on what it is used on. + + + + Can be filled with water, and used as the starting ingredient for a potion in the Brewing Stand. + + + + This is a poisonous food and brewing item. Dropped when a Spider or Cave Spider is killed by a player. + + + + Used in potion brewing, mainly to create potions with a negative effect. + + + + Used in potion brewing, or crafted with other items to make Eye of Ender or Magma Cream. + + + + Used in potion brewing. + + + + Used for making Potions and Splash Potions. + + + + Filled with water by rain or with a bucket of water, and can then be used to fill Glass Bottles with water. + + + + When thrown, will show the direction to an End Portal. When twelve of these are placed in the End Portal Frames, the End Portal will be activated. + + + + Used in potion brewing. + + + + Similar to Grass Blocks, but very good for growing mushrooms on. + + + + Floats on water, and can be walked on. + + + + Used to build Nether Fortresses. Immune to Ghast's fireballs. + + + + Used in Nether Fortresses. + + + + Found in Nether Fortresses, and will drop Nether Wart when broken. + + + + This allows players to enchant Swords, Pickaxes, Axes, Shovels, Bows and Armor, using the player's Experience Points. + + + + This can be activated using twelve Eye of Ender, and will allow the player to travel to The End dimension. + + + + Used to form an End Portal. + + + + A block type found in The End. It has a very high blast resistance, so is useful for building with. + + + + This block is created by the defeat of the Dragon in The End. + + + + When thrown, it drops Experience Orbs which increase your experience points when collected. + + + + Useful for setting things on fire, or for indiscriminately starting fires when fired from a Dispenser. + + + + These are similar to a display case, and will display the item or block placed in it. + + + + When thrown can spawn a creature of the type indicated. + + + + Used for making long staircases. Two slabs placed on top of each other will create a normal-sized double slab block. + + + + Used for making long staircases. Two slabs placed on top of each other will create a normal-sized double slab block. + + + + Created by smelting Netherrack in a furnace. Can be crafted into Nether Brick blocks. + + + + When powered they emit light. + + + + Can be farmed to collect Cocoa Beans. + + + + Mob Heads can be placed as a decoration, or worn as a mask in the helmet slot. + + + + Used to execute commands. + + + + Projects a beam of light into the sky and can provide Status Effects to nearby players. + + + + Stores blocks and items inside. Place two chest side by side to create a larger chest with double capacity. The trapped chest also creates a Redstone charge when opened. + + + + Provides a Redstone charge. The charge will be stronger if more items are on the plate. + + + + Provides a Redstone charge. The charge will be stronger if more items are on the plate. Requires more weight than the light plate. + + + + Used as a redstone power source. Can be crafted back into Redstone. + + + + Used to catch items or to transfer items into and out of containers. + + + + A type of rail that can enable or disable Minecarts with Hoppers and trigger Minecarts with TNT. + + + + Used to hold and drop items, or push items into another container, when given a Redstone charge. + + + + Colorful blocks crafted by dyeing Hardened clay. + + + + Can be fed to Horses, Donkeys or Mules to heal up to 10 Hearts. Speeds up the growth of foals. + + + + Created by smelting Clay in a furnace. + + + + Crafted from glass and a dye. + + + + Crafted from Stained Glass + + + + A compact way of storing Coal. Can be used as fuel in a Furnace. + + + + Squid + + + + Drops ink sacs when killed. + + + + Cow + + + + Drops leather when killed. Can also be milked with a bucket. + + + + Sheep + + + + Drops wool when sheared (if it has not already been sheared). Can be dyed to make its wool a different color. + + + + Chicken + + + + Drops feathers when killed, and also randomly lays eggs. + + + + Pig + + + + Drops porkchops when killed. Can be ridden by using a saddle. + + + + Wolf + + + + Docile until attacked, when they will attack you back. Can be tamed using bones which causes the wolf to follow you around and attack anything that attacks you. + + + + Creeper + + + + Explodes if you get too close! + + + + Skeleton + + + + Fires arrows at you. Drops arrows when killed. + + + + Spider + + + + Attacks you when you are close to it. Can climb walls. Drops string when killed. + + + + Zombie + + + + Attacks you when you are close to it. + + + + Zombie Pigman + + + + Initially docile, but will attack in groups if you attack one. + + + + Ghast + + + + Fires flaming balls at you that explode on contact. + + + + Slime + + + + Split into smaller Slimes when damaged. + + + + Enderman + + + + Will attack you if you look at it. Can also move blocks around. + + + + Silverfish + + + + Attracts nearby hidden Silverfish when attacked. Hides in stone blocks. + + + + Cave Spider + + + + Has a venomous bite. + + + + Mooshroom + + + + Makes mushroom stew when used with a bowl. Drops mushrooms and becomes a normal cow when sheared. + + + + Snow Golem + + + + The Snow Golem can be created by players using snow blocks and a pumpkin. They will throw snowballs at their creators enemies. + + + + Ender Dragon + + + + This is a large black dragon found in The End. + + + + Blaze + + + + These are enemies found in the Nether, mostly inside Nether Fortresses. They will drop Blaze Rods when killed. + + + + Magma Cube + + + + These can be found in The Nether. Similar to Slimes, they will break up into smaller versions when killed. + + + + Villager + + + + Ocelot + + + + These can be found in Jungles. They can be tamed by feeding them Raw Fish. You will need to let the Ocelot approach you though, since any sudden movements will scare it away. + + + + Iron Golem + + + + Appear in Villages to protect them, and can be created using Iron Blocks and Pumpkins. + + + + Bat + + + + These flying creatures are found in caverns or other large enclosed spaces. + + + + Witch + + + + These enemies can be found in swamps and attack you by throwing Potions. They drop Potions when killed. + + + + Horse + + + + These animals can be tamed and can then be ridden. + + + + Donkey + + + + These animals can be tamed and can then be ridden. They can have a chest attached. + + + + Mule + + + + Born when a Horse and a Donkey breed. These animals can be tamed and can then be ridden and carry chests. + + + + Zombie Horse + + + + Skeleton Horse + + + + Wither + + + + These are crafted from Wither Skulls and Soul Sand. They fire exploding skulls at you. + + + + Explosives Animator + + + + Concept Artist + + + + Number Crunching and Statistics + + + + Bully Coordinator + + + + Original Design and Code by + + + + Project Manager/Producer + + + + Rest of Mojang Office + + + + Lead Game Programmer Minecraft PC + + + + Ninja Coder + + + + CEO + + + + White Collar Worker + + + + Customer Support + + + + Office DJ + + + + Designer/Programmer Minecraft - Pocket Edition + + + + Developer + + + + Chief Architect + + + + Art Developer + + + + Game Crafter + + + + Director of Fun + + + + Music and Sounds + + + + Programming + + + + Art + + + + QA + + + + Executive Producer + + + + Lead Producer + + + + Producer + + + + Test Lead + + + + Lead Tester + + + + Design Team + + + + Development Team + + + + Release Management + + + + Director, XBLA Publishing + + + + Business Development + + + + Portfolio Director + + + + Product Manager + + + + Marketing + + + + Community Manager + + + + Europe Localization Team + + + + Redmond Localization Team + + + + Asia Localization Team + + + + User Research Team + + + + MGS Central Teams + + + + Milestone Acceptance Tester + + + + Special Thanks + + + + Test Manager + + + + Senior Test Lead + + + + SDET + + + + Project STE + + + + Additional STE + + + + Test Associates + + + + Jon KÃ¥gström + + + + Tobias Möllstam + + + + Risë Lugo + + + + Wooden Sword + + + + Stone Sword + + + + Iron Sword + + + + Diamond Sword + + + + Golden Sword + + + + Wooden Shovel + + + + Stone Shovel + + + + Iron Shovel + + + + Diamond Shovel + + + + Golden Shovel + + + + Wooden Pickaxe + + + + Stone Pickaxe + + + + Iron Pickaxe + + + + Diamond Pickaxe + + + + Golden Pickaxe + + + + Wooden Axe + + + + Stone Axe + + + + Iron Axe + + + + Diamond Axe + + + + Golden Axe + + + + Wooden Hoe + + + + Stone Hoe + + + + Iron Hoe + + + + Diamond Hoe + + + + Golden Hoe + + + + Oak Door + + + + Iron Door + + + + Chain Helmet + + + + Chain Chestplate + + + + Chain Leggings + + + + Chain Boots + + + + Leather Cap + + + + Iron Helmet + + + + Diamond Helmet + + + + Golden Helmet + + + + Leather Tunic + + + + Iron Chestplate + + + + Diamond Chestplate + + + + Golden Chestplate + + + + Leather Pants + + + + Iron Leggings + + + + Diamond Leggings + + + + Golden Leggings + + + + Leather Boots + + + + Iron Boots + + + + Diamond Boots + + + + Golden Boots + + + + Iron Ingot + + + + Gold Ingot + + + + Bucket + + + + Water Bucket + + + + Lava Bucket + + + + Flint and Steel + + + + Apple + + + + Bow + + + + Arrow + + + + Coal + + + + Charcoal + + + + Diamond + + + + Stick + + + + Bowl + + + + Mushroom Stew + + + + String + + + + Feather + + + + Gunpowder + + + + Seeds + + + + Wheat + + + + Bread + + + + Flint + + + + Raw Porkchop + + + + Cooked Porkchop + + + + Painting + + + + Golden Apple + + + + Sign + + + + Minecart + + + + Saddle + + + + Redstone + + + + Snowball + + + + Boat + + + + Leather + + + + Milk Bucket + + + + Brick + + + + Clay + + + + Sugar Canes + + + + Paper + + + + Book + + + + Slimeball + + + + Minecart with Chest + + + + Minecart with Furnace + + + + Egg + + + + Compass + + + + Fishing Rod + + + + Clock + + + + Glowstone Dust + + + + Raw Fish + + + + Cooked Fish + + + + Dye Powder + + + + Ink Sac + + + + Rose Red + + + + Cactus Green + + + + Cocoa Beans + + + + Lapis Lazuli + + + + Purple Dye + + + + Cyan Dye + + + + Light Gray Dye + + + + Gray Dye + + + + Pink Dye + + + + Lime Dye + + + + Dandelion Yellow + + + + Light Blue Dye + + + + Magenta Dye + + + + Orange Dye + + + + Bone Meal + + + + Bone + + + + Sugar + + + + Cake + + + + Bed + + + + Redstone Repeater + + + + Cookie + + + + Map + + + + Empty Map + + + + Music Disc - "13" + + + + Music Disc - "cat" + + + + Music Disc - "blocks" + + + + Music Disc - "chirp" + + + + Music Disc - "far" + + + + Music Disc - "mall" + + + + Music Disc - "mellohi" + + + + Music Disc - "stal" + + + + Music Disc - "strad" + + + + Music Disc - "ward" + + + + Music Disc - "11" + + + + Music Disc - "where are we now" + + + + Shears + + + + Pumpkin Seeds + + + + Melon Seeds + + + + Raw Chicken + + + + Cooked Chicken + + + + Raw Beef + + + + Steak + + + + Rotten Flesh + + + + Ender Pearl + + + + Melon Slice + + + + Blaze Rod + + + + Ghast Tear + + + + Gold Nugget + + + + Nether Wart + + + + {*splash*}{*prefix*}Potion {*postfix*} + + + + Glass Bottle + + + + Water Bottle + + + + Spider Eye + + + + Fermented Spider Eye + + + + Blaze Powder + + + + Magma Cream + + + + Brewing Stand + + + + Cauldron + + + + Eye of Ender + + + + Glistering Melon + + + + Bottle o' Enchanting + + + + Fire Charge + + + + Fire Charge (Charcoal) + + + + Fire Charge (Coal) + + + + Item Frame + + + + Spawn {*CREATURE*} + + + + Nether Brick + + + + Skull + + + + Skeleton Skull + + + + Wither Skeleton Skull + + + + Zombie Head + + + + Head + + + + %s's Head + + + + Creeper Head + + + + Nether Star + + + + Firework Rocket + + + + Firework Star + + + + Redstone Comparator + + + + Minecart with TNT + + + + Minecart with Hopper + + + + Iron Horse Armor + + + + Gold Horse Armor + + + + Diamond Horse Armor + + + + Lead + + + + Name Tag + + + + Stone + + + + Slime Block + + + + Grass Block + + + + Dirt + + + + Cobblestone + + + + Oak Planks + + + + Spruce Planks + + + + Birch Planks + + + + Jungle Planks + + + + Planks (any type) + + + + Sapling + + + + Oak Sapling + + + + Spruce Sapling + + + + Birch Sapling + + + + Jungle Tree Sapling + + + + Bedrock + + + + Barrier + + + + Water + + + + Lava + + + + Sand + + + + Sandstone + + + + Gravel + + + + Gold Ore + + + + Iron Ore + + + + Coal Ore + + + + Wood + + + + Oak Wood + + + + Spruce Wood + + + + Birch Wood + + + + Jungle Wood + + + + Oak + + + + Spruce + + + + Birch + + + + Leaves + + + + Oak Leaves + + + + Spruce Leaves + + + + Birch Leaves + + + + Jungle Leaves + + + + Sponge + + + + Glass + + + + Wool + + + + Black Wool + + + + Red Wool + + + + Green Wool + + + + Brown Wool + + + + Blue Wool + + + + Purple Wool + + + + Cyan Wool + + + + Light Gray Wool + + + + Gray Wool + + + + Pink Wool + + + + Lime Wool + + + + Yellow Wool + + + + Light Blue Wool + + + + Magenta Wool + + + + Orange Wool + + + + White Wool + + + + Dandelion + + + + Poppy + + + + Mushroom + + + + Block of Gold + + + + A compact way of storing Gold. + + + + A compact way of storing Iron. + + + + Block of Iron + + + + Stone Slab + + + + Stone Slab + + + + Sandstone Slab + + + + Oak Wood Slab + + + + Cobblestone Slab + + + + Bricks Slab + + + + Stone Bricks Slab + + + + Oak Wood Slab + + + + Spruce Wood Slab + + + + Birch Wood Slab + + + + Jungle Wood Slab + + + + Nether Brick Slab + + + + Bricks + + + + TNT + + + + Bookshelf + + + + Moss Stone + + + + Obsidian + + + + Torch + + + + Torch (Coal) + + + + Torch (Charcoal) + + + + Fire + + + + Monster Spawner + + + + Oak Wood Stairs + + + + Chest + + + + Redstone Dust + + + + Diamond Ore + + + + Block of Diamond + + + + A compact way of storing Diamonds. + + + + Crafting Table + + + + Crops + + + + Farmland + + + + Furnace + + + + Sign + + + + Oak Door + + + + Ladder + + + + Rail + + + + Powered Rail + + + + Detector Rail + + + + Stone Stairs + + + + Lever + + + + Pressure Plate + + + + Iron Door + + + + Redstone Ore + + + + Redstone Torch + + + + Button + + + + Snow + + + + Ice + + + + Cactus + + + + Clay + + + + Sugar Cane + + + + Jukebox + + + + Oak Fence + + + + Pumpkin + + + + Jack-O-Lantern + + + + Netherrack + + + + Soul Sand + + + + Glowstone + + + + Portal + + + + Lapis Lazuli Ore + + + + Lapis Lazuli Block + + + + A compact way of storing Lapis Lazuli. + + + + Dispenser + + + + Note Block + + + + Cake + + + + Bed + + + + Web + + + + Tall Grass + + + + Dead Bush + + + + Diode + + + + Locked Chest + + + + Trapdoor + + + + Wool (any color) + + + + Piston + + + + Sticky Piston + + + + Silverfish Block + + + + Stone Bricks + + + + Mossy Stone Bricks + + + + Cracked Stone Bricks + + + + Chiseled Stone Bricks + + + + Mushroom + + + + Mushroom + + + + Iron Bars + + + + Glass Pane + + + + Melon + + + + Pumpkin Stem + + + + Melon Stem + + + + Vines + + + + Oak Fence Gate + + + + Brick Stairs + + + + Stone Brick Stairs + + + + Silverfish Stone + + + + Silverfish Cobblestone + + + + Silverfish Stone Brick + + + + Mycelium + + + + Lily Pad + + + + Nether Brick + + + + Nether Brick Fence + + + + Nether Brick Stairs + + + + Nether Wart + + + + Enchantment Table + + + + Brewing Stand + + + + Cauldron + + + + End Portal + + + + End Portal Frame + + + + End Stone + + + + Dragon Egg + + + + Shrub + + + + Fern + + + + Sandstone Stairs + + + + Spruce Wood Stairs + + + + Birch Wood Stairs + + + + Jungle Wood Stairs + + + + Redstone Lamp + + + + Cocoa + + + + Skull + + + + Command Block + + + + Beacon + + + + Trapped Chest + + + + Weighted Pressure Plate (Light) + + + + Weighted Pressure Plate (Heavy) + + + + Redstone Comparator + + + + Daylight Sensor + + + + Block of Redstone + + + + Hopper + + + + Activator Rail + + + + Dropper + + + + Stained Clay + + + + Hay Bale + + + + Hardened Clay + + + + Block of Coal + + + + Black Stained Clay + + + + Red Stained Clay + + + + Green Stained Clay + + + + Brown Stained Clay + + + + Blue Stained Clay + + + + Purple Stained Clay + + + + Cyan Stained Clay + + + + Light Gray Stained Clay + + + + Gray Stained Clay + + + + Pink Stained Clay + + + + Lime Stained Clay + + + + Yellow Stained Clay + + + + Light Blue Stained Clay + + + + Magenta Stained Clay + + + + Orange Stained Clay + + + + White Stained Clay + + + + Stained Glass + + + + Black Stained Glass + + + + Red Stained Glass + + + + Green Stained Glass + + + + Brown Stained Glass + + + + Blue Stained Glass + + + + Purple Stained Glass + + + + Cyan Stained Glass + + + + Light Gray Stained Glass + + + + Gray Stained Glass + + + + Pink Stained Glass + + + + Lime Stained Glass + + + + Yellow Stained Glass + + + + Light Blue Stained Glass + + + + Magenta Stained Glass + + + + Orange Stained Glass + + + + White Stained Glass + + + + Stained Glass Pane + + + + Black Stained Glass Pane + + + + Red Stained Glass Pane + + + + Green Stained Glass Pane + + + + Brown Stained Glass Pane + + + + Blue Stained Glass Pane + + + + Purple Stained Glass Pane + + + + Cyan Stained Glass Pane + + + + Light Gray Stained Glass Pane + + + + Gray Stained Glass Pane + + + + Pink Stained Glass Pane + + + + Lime Stained Glass Pane + + + + Yellow Stained Glass Pane + + + + Light Blue Stained Glass Pane + + + + Magenta Stained Glass Pane + + + + Orange Stained Glass Pane + + + + White Stained Glass Pane + + + + Small Ball + + + + Large Ball + + + + Star-shaped + + + + Creeper-shaped + + + + Burst + + + + Unknown Shape + + + + Black + + + + Red + + + + Green + + + + Brown + + + + Blue + + + + Purple + + + + Cyan + + + + Light Gray + + + + Gray + + + + Pink + + + + Lime + + + + Yellow + + + + Light Blue + + + + Magenta + + + + Orange + + + + White + + + + Custom + + + + Fade to + + + + Twinkle + + + + Trail + + + + Flight Duration: + + + + Current Controls + + + + Layout + + + + Move/Sprint + + + + Look + + + + Pause + + + + Jump + + + + Jump/Fly Up + + + + Inventory + + + + Cycle Held Item + + + + Action + + + + Use + + + + Crafting + + + + Drop + + + + Sneak + + + + Sneak/Fly Down + + + + Change Camera Mode + + + + Players/Invite + + + + Movement (When Flying) + + + + Layout 1 + + + + Layout 2 + + + + Layout 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {*B*}Press{*CONTROLLER_VK_A*} to continue. + + + + {*B*}Press{*CONTROLLER_VK_A*} to start the tutorial.{*B*} +Press{*CONTROLLER_VK_B*} if you think you are ready to play on your own. + + + + Minecraft is a game about placing blocks to build anything you can imagine. +At night monsters come out, make sure to build a shelter before that happens. + + + + Use{*CONTROLLER_ACTION_LOOK*} to look up, down and around. + + + + Use{*CONTROLLER_ACTION_MOVE*} to move around. + + + + To sprint, push{*CONTROLLER_ACTION_MOVE*} forward twice quickly. While you hold{*CONTROLLER_ACTION_MOVE*} forward, the character will continue to sprint unless they run out of sprint time or food. + + + + Press{*CONTROLLER_ACTION_JUMP*} to jump. + + + + Hold{*CONTROLLER_ACTION_ACTION*} to mine and chop using your hand or whatever you are holding. You may need to craft a tool to mine some blocks... + + + + Hold{*CONTROLLER_ACTION_ACTION*} to chop down 4 blocks of wood (tree trunks).{*B*}When a block breaks you can pick it up by standing near to the floating item that appears, causing it to appear in your inventory. + + + + Press{*CONTROLLER_ACTION_CRAFTING*} to open the crafting interface. + + + + As you collect and craft more items, your inventory will fill up.{*B*} +Press{*CONTROLLER_ACTION_INVENTORY*} to open the inventory. + + + + As you move around, mine and attack, you will deplete your food bar{*ICON_SHANK_01*}. Sprinting and sprint jumping use a lot more food than walking and jumping normally. + + + + If you lose some health, but have a food bar with 9 or more{*ICON_SHANK_01*} in it, your health will automatically replenish. Eating food will replenish your food bar. + + + + With a food item in your hand, hold{*CONTROLLER_ACTION_USE*} to eat it and replenish your food bar. You cannot eat if your food bar is full. + + + + Your food bar is low, and you have lost some health. Eat the steak in your inventory to replenish your food bar and start healing.{*ICON*}364{*/ICON*} + + + + The wood that you have collected can be crafted into planks. Open the crafting interface to craft them.{*PlanksIcon*} + + + + A lot of crafting can involve multiple steps. Now that you have some planks there are more items that you can craft. Create a crafting table.{*CraftingTableIcon*} + + + + To make collecting blocks faster you can build tools designed for the job. Some tools have a handle made of sticks. Craft some sticks now.{*SticksIcon*} + + + + Use{*CONTROLLER_ACTION_LEFT_SCROLL*} and{*CONTROLLER_ACTION_RIGHT_SCROLL*} to change the current held item. + + + + Use{*CONTROLLER_ACTION_USE*} to use items, interact with objects and place some items. Items that have been placed can be picked up again by mining them with the right tool. + + + + With the crafting table selected, point the crosshair where you want it and use{*CONTROLLER_ACTION_USE*} to place a crafting table. + + + + Point the crosshair at the crafting table and press{*CONTROLLER_ACTION_USE*} to open it. + + + + A shovel helps dig soft blocks, like dirt and snow, faster. As you collect more materials you can craft tools that work faster and last longer. Create a wooden shovel.{*WoodenShovelIcon*} + + + + An axe helps chop wood and wooden tiles, faster. As you collect more materials you can craft tools that work faster and last longer. Create a wooden axe.{*WoodenHatchetIcon*} + + + + A pickaxe helps dig hard blocks, like stone and ore, faster. As you collect more materials you can craft tools that work faster and last longer, and allow you to mine harder materials. Create a wooden pickaxe.{*WoodenPickaxeIcon*} + + + + Open the container + + + + Night time can approach quickly, and it is dangerous to be outside unprepared. You can craft armor and weapons, but it is sensible to have a safe shelter. + + + + Nearby there is an abandoned Miner's shelter that you can complete to be safe overnight. + + + + You will need to collect the resources to complete the shelter. Walls and roof can be made of any tile type, but you will want to create a door, some windows and lighting. + + + + Use your pickaxe to mine some stone blocks. Stone blocks will produce cobblestone when mined. If you collect 8 cobblestone blocks you can build a furnace. You may need to dig through some dirt to reach the stone, so use your shovel for this.{*StoneIcon*} + + + + You have collected enough cobblestone to build a furnace. Use your crafting table to create one. + + + + Use{*CONTROLLER_ACTION_USE*} to place the furnace in the world, and then open it. + + + + Use the furnace to create some charcoal. If you are waiting for it to finish how about using the time to collect more materials to finish the shelter? + + + + Use the furnace to create some glass. If you are waiting for it to finish how about using the time to collect more materials to finish the shelter? + + + + A good shelter will have a door so that you can easily go in and out without having to mine and replace the walls. Craft a wooden door now.{*WoodenDoorIcon*} + + + + Use{*CONTROLLER_ACTION_USE*} to place the door. You can use{*CONTROLLER_ACTION_USE*} to open and close a wooden door in the world. + + + + It can get very dark at night, so you will want some lighting inside your shelter so that you can see. Craft a torch now from sticks and charcoal using the crafting interface.{*TorchIcon*} + + + + You have completed the first part of the tutorial. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to continue with the tutorial.{*B*} +Press{*CONTROLLER_VK_B*} if you think you are ready to play on your own. + + + + This is your inventory. It shows items available for use in your hand, and all the other items that you are carrying. Your armor is also shown here. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to continue.{*B*} +Press{*CONTROLLER_VK_B*} if you already know how to use the inventory. + + + + Use{*CONTROLLER_MENU_NAVIGATE*} to move the pointer. Use{*CONTROLLER_VK_A*} to pick an item under the pointer. +If there is more than one item here this will pick them all up, or you can use{*CONTROLLER_VK_X*} to pick up just half of them. + + + + Move this item with the pointer over another space in the inventory and place it down using{*CONTROLLER_VK_A*}. +With multiple items on the pointer, use{*CONTROLLER_VK_A*} to place them all, or{*CONTROLLER_VK_X*} to place just one. + + + + If you move the pointer outside the edge of the interface with an item on the pointer, you can drop the item. + + + + If you want more information about an item, move the pointer over the item and press{*CONTROLLER_ACTION_MENU_PAGEDOWN*} . + + + + Press{*CONTROLLER_VK_B*} now to exit the inventory. + + + + This is the creative mode inventory. It shows items available for use in your hand, and all the other items that you can choose from. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to continue.{*B*} +Press{*CONTROLLER_VK_B*} if you already know how to use the creative mode inventory. + + + + Use{*CONTROLLER_MENU_NAVIGATE*} to move the pointer. +When on the item list, use{*CONTROLLER_VK_A*} to pick an item under the pointer, and use{*CONTROLLER_VK_Y*} to pick up a full stack of that item. + + + + The pointer will automatically move over a space in the use row. You can place it down using{*CONTROLLER_VK_A*}. Once you have placed the item, the pointer will return to the item list where you can select another item. + + + + If you move the pointer outside the edge of the interface with an item on the pointer, you can drop the item into the world. To clear all items in the quick select bar, press{*CONTROLLER_VK_X*}. + + + + Scroll through the Group Type tabs at the top using{*CONTROLLER_VK_LB*} and{*CONTROLLER_VK_RB*} to select the group type of the item you wish to pickup. + + + + If you want more information about an item, move the pointer over the item and press{*CONTROLLER_ACTION_MENU_PAGEDOWN*} . + + + + Press{*CONTROLLER_VK_B*} now to exit the creative mode inventory. + + + + This is the crafting interface. This interface allows you to combine the items you've collected to make new items. + + + + {*B*}Press{*CONTROLLER_VK_A*} to continue.{*B*} +Press{*CONTROLLER_VK_B*} if you already know how to craft. + + + + {*B*} +Press{*CONTROLLER_VK_X*} to show the item description. + + + + {*B*} +Press{*CONTROLLER_VK_X*} to show the ingredients required to make the current item. + + + + {*B*} +Press{*CONTROLLER_VK_X*} to show the inventory again. + + + + Scroll through the Group Type tabs at the top using{*CONTROLLER_VK_LB*} and{*CONTROLLER_VK_RB*} to select the group type of the item you wish to craft, then use{*CONTROLLER_MENU_NAVIGATE*} to select the item to craft. + + + + The crafting area shows the items you require in order to craft the new item. Press{*CONTROLLER_VK_A*} to craft the item and place it in your inventory. + + + + You can craft a larger selection of items using a crafting table. Crafting on a table works in the same way as basic crafting, but you have a larger crafting area allowing more combinations of ingredients. + + + + The bottom right part of the crafting interface shows your inventory. This area can also show a description of the currently selected item, and the ingredients required to craft it. + + + + The description of the currently selected item is now displayed. The description can give you an idea of what the item can be used for. + + + + The list of ingredients required to craft the selected item are now displayed. + + + + The wood that you have collected can be crafted into planks. Select the planks icon and press{*CONTROLLER_VK_A*} to create them.{*PlanksIcon*} + + + + Now you have built a crafting table you should place it in the world to enable you to build a larger selection of items.{*B*} +Press{*CONTROLLER_VK_B*} now to exit the crafting interface. + + + + Press{*CONTROLLER_VK_LB*} and{*CONTROLLER_VK_RB*} to change to the group type of the items you wish to craft. Select the tools group.{*ToolsIcon*} + + + + Press{*CONTROLLER_VK_LB*} and{*CONTROLLER_VK_RB*} to change to the group type of the items you wish to craft. Select the structures group.{*StructuresIcon*} + + + + Use{*CONTROLLER_MENU_NAVIGATE*} to change to the item you wish to craft. Some items have multiple versions depending on the materials used. Select the wooden shovel.{*WoodenShovelIcon*} + + + + A lot of crafting can involve multiple steps. Now that you have some planks there are more items that you can craft. Use{*CONTROLLER_MENU_NAVIGATE*} to change to the item you wish to craft. Select the crafting table.{*CraftingTableIcon*} + + + + With the tools you have built you are off to a great start, and are able to collect a variety of different materials more efficiently.{*B*} +Press{*CONTROLLER_VK_B*} now to exit the crafting interface. + + + + Some items can not be created using the crafting table, but require a furnace. Craft a furnace now.{*FurnaceIcon*} + + + + Place the furnace you have crafted in the world. You will want to put this inside your shelter.{*B*} +Press{*CONTROLLER_VK_B*} now to exit the crafting interface. + + + + This is the furnace interface. A furnace allows you to change items by firing them. For example, you can turn iron ore into iron ingots in the furnace. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to continue.{*B*} +Press{*CONTROLLER_VK_B*} if you already know how to use a furnace. + + + + You need to put some fuel into the bottom slot of the furnace, and the item to be changed in the top slot. The furnace will then fire up and start working, putting the result in the right-hand slot. + + + + Many wooden items can be used as fuels, but not everything burns for the same time. You may also discover other items in the world that can be used as a fuel. + + + + When your items have been fired, you can move them from the output area into your inventory. You should experiment with different ingredients to see what you can make. + + + + If you use wood as the ingredient then you can make charcoal. Put some fuel in the furnace and wood in the ingredient slot. It can take some time for the furnace to create the charcoal, so feel free to do something else and come back to check the progress. + + + + Charcoal can be used as a fuel, as well as being crafted into a torch with a stick. + + + + Placing sand in the ingredient slot allows you to make glass. Create some glass blocks to use as windows in your shelter. + + + + This is the brewing interface. You can use this to create potions that have a variety of different effects. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to continue.{*B*} +Press{*CONTROLLER_VK_B*} if you already know how to use the brewing stand. + + + + You brew potions by placing an ingredient in the top slot, and a potion or water bottle in the bottom slots (up to 3 can be brewed at one time). Once a valid combination is entered the brewing process will start and create the potion after a short time. + + + + All potions start with a Water Bottle. Most potions are created by first using a Nether Wart to make an Awkward Potion, and will require at least one more ingredient to make the final potion. + + + + Once you have a potion you can modify its effects. Adding Redstone Dust increases the duration of its effect and adding Glowstone Dust can make its effect more powerful. + + + + Adding Fermented Spider Eye corrupts the potion and can turn it into a potion with the opposite effect, and adding Gunpowder turns the potion into a Splash Potion which can be thrown to apply its affect to a nearby area. + + + + Create a Potion of Fire Resistance by first adding Nether Wart to a Water Bottle, and then adding Magma Cream. + + + + Press{*CONTROLLER_VK_B*} now to exit the brewing interface. + + + + In this area there is a Brewing Stand, a Cauldron and a chest full of items for brewing. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about brewing and potions.{*B*} +Press{*CONTROLLER_VK_B*} if you already know about brewing and potions. + + + + The first step in brewing a potion is to create a Water Bottle. Take a Glass Bottle from the chest. + + + + You can fill a glass bottle from a Cauldron that has water in it, or from a block of water. Fill your glass bottle now by pointing at a water source and pressing{*CONTROLLER_ACTION_USE*}. + + + + If a cauldron becomes empty, you can refill it with a Water Bucket. + + + + Use the Brewing Stand to create a Potion of Fire Resistance. You will need a Water Bottle, Nether Wart and Magma Cream. + + + + With a potion in your hand, hold{*CONTROLLER_ACTION_USE*} to use it. For a normal potion you will drink it and apply the effect to yourself, and for a Splash potion you will throw it and apply the effect to creatures near where it hits. +Splash potions can be created by adding gunpowder to normal potions. + + + + Use your Potion of Fire Resistance on yourself. + + + + Now that you are resistant to fire and lava, you should see if there are places you can get to that you couldn't before. + + + + This is the enchanting interface which you can use to add enchantments to weapons, armor and some tools. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about the enchanting interface.{*B*} +Press{*CONTROLLER_VK_B*} if you already know about the enchanting interface. + + + + To enchant an item, first place it in the enchanting slot. Weapons, armor and some tools can be enchanted to add special effects such as improved damage resistance or increasing the number of items produced when mining a block. + + + + When an item is placed in the enchanting slot, the buttons on the right will change to show a selection of random enchantments. + + + + The number on the button represents the cost in experience levels to apply that enchantment to the item. If you do not have a high enough level the button will be disabled. + + + + Select an enchantment and press{*CONTROLLER_VK_A*} to enchant the item. This will decrease your experience level by the cost of the enchantment. + + + + Although the enchantments are all random, some of the better enchantments are only available when you have a high experience level and have lots of bookcases around the Enchantment Table to increase its power. + + + + In this area there is an Enchantment Table and some other items to help you learn about enchanting. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about enchanting.{*B*} +Press{*CONTROLLER_VK_B*} if you already know about enchanting. + + + + Using an Enchantment Table allows you to add special effects such as increasing the number of items produced when mining a block, or improved damage resistance for weapons, armor and some tools. + + + + Placing bookcases around the Enchantment Table increases its power and allows access to higher level enchantments. + + + + Enchanting items costs Experience Levels, which can be built up by collecting Experience Orbs which are produced by killing monsters and animals, mining ores, breeding animals, fishing and smelting/cooking some things in a furnace. + + + + You can also build experience levels using a Bottle O' Enchanting, which, when thrown, creates Experience Orbs around where it lands. These orbs can then be collected. + + + + In the chests in this area you can find some enchanted items, Bottles O' Enchanting, and some items that have yet to be enchanted for you to experiment with at the Enchantment Table. + + + + You are now riding in a minecart. To exit the minecart, point the cursor at it and press{*CONTROLLER_ACTION_USE*} .{*MinecartIcon*} + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about minecarts.{*B*} +Press{*CONTROLLER_VK_B*} if you already know about minecarts. + + + + A minecart runs on rails. You can also craft a powered minecart with a furnace and a minecart with a chest in it.{*RailIcon*} + + + + You can also craft powered rails, which take power from redstone torches and circuits to accelerate the cart. These can be connected to switches, levers and pressure plates to make complex systems.{*PoweredRailIcon*} + + + + You are now sailing a boat. To exit the boat, point the cursor at it and press{*CONTROLLER_ACTION_USE*} .{*BoatIcon*} + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about boats.{*B*} +Press{*CONTROLLER_VK_B*} if you already know about boats. + + + + A boat allows you to travel quicker over water. You can steer it using{*CONTROLLER_ACTION_MOVE*} and{*CONTROLLER_ACTION_LOOK*}.{*BoatIcon*} + + + + You are now using a fishing rod. Press{*CONTROLLER_ACTION_USE*} to use it.{*FishingRodIcon*} + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about fishing.{*B*} +Press{*CONTROLLER_VK_B*} if you already know about fishing. + + + + Press{*CONTROLLER_ACTION_USE*} to cast your line and start fishing. Press{*CONTROLLER_ACTION_USE*} again to reel in the fishing line.{*FishingRodIcon*} + + + + If you wait until the float sinks below the surface of the water before reeling in you can catch a fish. Fish can be eaten raw, or cooked by a furnace, to restore health.{*FishIcon*} + + + + As with many other tools a fishing rod has a fixed number of uses. Those uses are not limited to catching fish though. You should experiment with it to see what else can be caught or activated...{*FishingRodIcon*} + + + + This is a bed. Press{*CONTROLLER_ACTION_USE*} while pointing at it at night to sleep through the night and awake in the morning.{*ICON*}355{*/ICON*} + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about beds.{*B*} +Press{*CONTROLLER_VK_B*} if you already know about beds. + + + + A bed should be placed in a safe, well-lit place so that monsters do not wake you in the middle of the night. Once you have used a bed, if you die you will respawn at that bed. +{*ICON*}355{*/ICON*} + + + + If there are other players in your game, everyone must be in a bed at the same time to be able to sleep. +{*ICON*}355{*/ICON*} + + + + In this area there are some simple Redstone and Piston circuits, and a chest with more items to extend these circuits. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about Redstone circuits and Pistons.{*B*} +Press{*CONTROLLER_VK_B*} if you already know about Redstone circuits and Pistons. + + + + Levers, Buttons, Pressure Plates and Redstone Torches can all provide power to circuits, either by directly attaching them to the item you want to activate or by connecting them with Redstone dust. + + + + The position and direction that you place a power source can change how it affects the surrounding blocks. For example a Redstone torch on the side of a block can be turned off if the block is powered by another source. + + + + Redstone dust is collected by mining redstone ore with a pickaxe made of Iron, Diamond or Gold. You can use it to carry power up to 15 blocks, and it can travel up or down one block in height. +{*ICON*}331{*/ICON*} + + + + Redstone repeaters can be used to extend the distance that the power is carried, or put a delay in a circuit. +{*ICON*}356{*/ICON*} + + + + When powered, a Piston will extend, pushing up to 12 blocks. When they retract, Sticky Pistons can pull back one block of most types. +{*ICON*}33{*/ICON*} + + + + In the chest in this area there are some components for making circuits with pistons. Try using or completing the circuits in this area, or put together your own. There are more examples outside the tutorial area. + + + + In this area there is a Portal to the Nether! + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about Portals and The Nether.{*B*} +Press{*CONTROLLER_VK_B*} if you already know about Portals and The Nether. + + + + Portals are created by placing Obsidian blocks into a frame four blocks wide and five blocks tall. The corner blocks are not required. + + + + To activate a Nether Portal, set fire to the Obsidian blocks inside the frame with a Flint and Steel. Portals can be deactivated if their frame is broken, an explosion happens nearby or a liquid flows through them. + + + + To use a Nether Portal, stand inside it. Your screen will go purple and a sound will play. After a few seconds you will be transported to another dimension. + + + + The Nether can be a dangerous place, full of lava, but can be useful to collect Netherrack which burns forever when lit, and Glowstone which produces light. + + + + The Nether world can be used to fast-travel in the Overworld - traveling one block distance in the Nether is equivalent to traveling 3 blocks in the Overworld. + + + + You are now in Creative mode. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about Creative mode.{*B*} +Press{*CONTROLLER_VK_B*} if you already know about Creative mode. + + + + When in Creative mode you have in infinite number of all available items and blocks, you can destroy blocks with one click without a tool, you are invulnerable and you can fly. + + + + Press{*CONTROLLER_ACTION_CRAFTING*} to open the creative inventory interface. + + + + Make your way to the opposite side of this hole to continue. + + + + You have now completed the Creative mode tutorial. + + + + In this area a farm has been set up. Farming enables you to create a renewable source of food and other items. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about farming.{*B*} +Press{*CONTROLLER_VK_B*} if you already know about farming. + + + + Wheat, Pumpkins and Melons are grown from seeds. Wheat seeds are collected by breaking Tall Grass or harvesting wheat, and Pumpkin and Melon seeds are crafted from Pumpkins and Melons respectively. + + + + Before planting seeds the dirt blocks need to be turned into Farmland by using a Hoe. A nearby source of water will help keep the Farmland hydrated and make the crops grow faster, as will keeping the area lit. + + + + Wheat goes through several stages when growing, and is ready to be harvested when it appears darker.{*ICON*}59:7{*/ICON*} + + + + Pumpkins and Melons also need a block next to where you planted the seed for the fruit to grow once the stem has fully grown. + + + + Sugarcane must be planted on a Grass, Dirt or Sand block that is right next to water block. Chopping a Sugarcane block will also drop all blocks that are above it.{*ICON*}83{*/ICON*} + + + + Cacti must be planted on Sand, and will grow up to three blocks high. Like Sugarcane, destroying the lowest block will also allow you to collect the blocks that are above it.{*ICON*}81{*/ICON*} + + + + Mushrooms should be planted in a dimly lit area, and will spread to nearby dimly lit blocks.{*ICON*}39{*/ICON*} + + + + Bonemeal can be used to grow crops to their fully grown state, or grow Mushrooms into Huge Mushrooms.{*ICON*}351:15{*/ICON*} + + + + You have now completed the farming tutorial. + + + + In this area animals have been penned in. You can breed animals to produce baby versions of themselves. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about animals and breeding.{*B*} +Press{*CONTROLLER_VK_B*} if you already know about animals and breeding. + + + + To get the animals to breed, you will need to feed them with the right food to get them to go into 'Love Mode'. + + + + Feed Wheat to a cow, mooshroom or sheep, Carrots to pigs, Wheat Seeds or Nether Wart to a chicken, or any kind of meat to a wolf, and they'll start looking for another animal of the same species near them that is also in Love Mode. + + + + When two animals of the same species meet, and both are in Love Mode, they will kiss for a few seconds, and then a baby animal will appear. The baby animal will follow their parents for a while before growing into a full sized animal itself. + + + + After being in Love Mode, an animal will not be able to enter it again for about five minutes. + + + + Some animals will follow you if you are holding their food in your hand. This makes it easier to group animals together to breed them.{*ICON*}296{*/ICON*} + + + + Wild wolves can be tamed by giving them bones. Once tamed Love Hearts will appear around them. Tamed wolves will follow the player and defend them if they haven't been commanded to sit. + + + + You have now completed the animal and breeding tutorial. + + + + In this area are some pumpkins and blocks to make a Snow Golem and an Iron Golem. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about Golems.{*B*} +Press{*CONTROLLER_VK_B*} if you already know about Golems. + + + + Golems are created by placing a pumpkin on top of a stack of blocks. + + + + Snow Golems are created with two Snow Blocks, one of top of the other, with a pumpkin on top. Snow Golems throw snowballs at your enemies. + + + + Iron Golems are created with four Iron Blocks in the pattern shown, with a pumpkin on top of the middle block. Iron Golems attack your enemies. + + + + Iron Golems also appear naturally to protect villages, and will attack you if you attack any villagers. + + + + You cannot leave this area until you have completed the tutorial. + + + + Different tools are better for different materials. You should use a shovel to mine soft materials like earth and sand. + + + + Different tools are better for different materials. You should use an axe to chop tree trunks. + + + + Different tools are better for different materials. You should use a pickaxe to mine stone and ore. You may need to make your pickaxe from better materials to get resources from some blocks. + + + + Certain tools are better for attacking enemies. Consider using a sword to attack. + + + + Hint: Hold {*CONTROLLER_ACTION_ACTION*}to mine and chop using your hand or whatever you are holding. You may need to craft a tool to mine some blocks... + + + + The tool you are using has become damaged. Every time you use a tool it becomes damaged, and will eventually break. The colored bar below the item in your inventory shows the current damage state. + + + + Hold{*CONTROLLER_ACTION_JUMP*} to swim up. + + + + In this area there is a minecart on a track. To enter the minecart, point the cursor at it and press{*CONTROLLER_ACTION_USE*}. Use{*CONTROLLER_ACTION_USE*} on the button to make the minecart move. + + + + In the chest beside the river there is a boat. To use the boat, point the cursor at water and press{*CONTROLLER_ACTION_USE*}. Use{*CONTROLLER_ACTION_USE*} while pointing at the boat to enter it. + + + + In the chest beside the pond there is a fishing rod. Take the fishing rod from the chest and select it as the current item in your hand to use it. + + + + This more advanced piston mechanism creates a self-repairing bridge! Push the button to activate, then investigate how the components interact to learn more. + + + + If you move the pointer outside of the interface while carrying an item, you can drop that item. + + + + You do not have all the ingredients required to make this item. The box on the bottom left shows the ingredients required to craft this. + + + + Congratulations, you have completed the tutorial. Time in the game is now passing normally, and you don't have long until night time and the monsters come out! Finish your shelter! + + + + {*EXIT_PICTURE*} When you are ready to explore further, there is a stairway in this area near the Miner's shelter that leads to a small castle. + + + + Reminder: + + + + + + + + New features have been added to the game in the latest version, including new areas in the tutorial world. + + + + {*B*}Press{*CONTROLLER_VK_A*} to play through the tutorial as normal.{*B*} +Press{*CONTROLLER_VK_B*} to skip the main tutorial. + + + + In this area you will find areas setup to help you learn about fishing, boats, pistons and redstone. + + + + Outside of this area you will find examples of buildings, farming, minecarts and tracks, enchanting, brewing, trading, smithing and more! + + + + Your food bar has depleted to a level where you will no longer heal. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about the food bar and eating food.{*B*} +Press{*CONTROLLER_VK_B*} if you already know about the food bar and eating food. + + + + This is the horse inventory interface. + + + + {*B*}Press{*CONTROLLER_VK_A*} to continue. +{*B*}Press{*CONTROLLER_VK_B*} if you already know how to use the horse inventory. + + + + The horse inventory allows you to transfer, or equip items to your Horse, Donkey or Mule. + + + + Saddle your Horse by placing a Saddle in the saddle slot. Horses can be given armor by placing Horse Armor in the armor slot. + + + + You can also transfer items between your own inventory and the saddlebags strapped to Donkeys and Mules in this menu. + + + + You have found a Horse. + + + + You have found a Donkey. + + + + You have found a Mule. + + + + {*B*}Press{*CONTROLLER_VK_A*} to learn more about Horses, Donkeys and Mules. +{*B*}Press{*CONTROLLER_VK_B*} if you already know about Horses, Donkeys and Mules. + + + + Horses and Donkeys are found mainly in open plains. Mules can be bred from a Donkey and a Horse, but are infertile themselves. + + + + All adult Horses, Donkeys and Mules can be ridden. However only Horses can be armored, and only Mules and Donkeys may be equipped with saddlebags for transporting items. + + + + Horses, Donkeys and Mules must be tamed before they can be used. A horse is tamed by attempting to ride it, and managing to stay on the horse while it attempts to throw the rider off. + + + + When tamed Love Hearts will appear around them and they will no longer buck the player off. + + + + Try to ride this horse now. Use {*CONTROLLER_ACTION_USE*} with no items or tools in your hand to mount it. + + + + To steer a horse they must then be equipped with a saddle, which can be bought from villagers or found inside chests hidden in the world. + + + + Tame Donkeys and Mules can be given saddlebags by attaching a chest. These bags can be accessed whilst riding or when sneaking. + + + + Horses and Donkeys (but not Mules) can be bred like other animals using Golden Apples or Golden Carrots. Foals will grow into adult horses over time, although feeding them wheat or hay will speed this up. + + + + You can try to tame the Horses and Donkeys here, and there are Saddles, Horse Armor and other useful items for Horses in chests around here too. + + + + This is the Beacon interface, which you can use to choose powers for your Beacon to grant. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to continue.{*B*} +Press{*CONTROLLER_VK_B*} if you already know how to use the Beacon interface. + + + + In the Beacon menu you can select 1 primary power for your Beacon. The more tiers your pyramid has the more powers you will have to choose from. + + + + A Beacon on a pyramid with at least 4 tiers grants an additional option of either the Regeneration secondary power or a stronger primary power. + + + + To set the powers of your Beacon you must sacrifice an Emerald, Diamond, Gold or Iron Ingot in the payment slot. Once set, the powers will emanate from the Beacon indefinitely. + + + + At the top of this pyramid there is an inactivate Beacon. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about Beacons.{*B*} +Press{*CONTROLLER_VK_B*} if you already know about Beacons. + + + + Active Beacons project a bright beam of light into the sky and grant powers to nearby players. They are crafted with Glass, Obsidian and Nether Stars, which can be obtained by defeating the Wither. + + + + Beacons must be placed so that they are in sunlight during the day. Beacons must be placed on Pyramids of Iron, Gold, Emerald or Diamond. However the choice of material has no effect on the power of the beacon. + + + + Try using the Beacon to set the powers it grants, you can use the Iron Ingots provided as the necessary payment. + + + + This room contains Hoppers + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about Hoppers.{*B*} +Press{*CONTROLLER_VK_B*} if you already know about Hoppers. + + + + Hoppers are used to insert or remove items from containers, and to automatically pick-up items thrown into them. + + + + They can affect Brewing Stands, Chests, Dispensers, Droppers, Minecarts with Chests, Minecarts with Hoppers, as well as other Hoppers. + + + + Hoppers will continuously attempt to suck items out of suitable container placed above them. It will also attempt to insert stored items into an output container. + + + + However if a Hopper is powered by Redstone it will become inactive and stop both sucking and inserting items. + + + + A Hopper points in the direction it tries to output items. To make a Hopper point to a particular block, place the Hopper against that block whilst sneaking. + + + + There are various useful Hopper layouts for you to see and experiment with in this room. + + + + This is the Firework interface, which you can use to craft Fireworks and Firework Stars. + + + + {*B*} +Press{*CONTROLLER_VK_A*} to continue.{*B*} +Press{*CONTROLLER_VK_B*} if you already know how to use the Firework interface. + + + + To craft a Firework, place Gunpowder and Paper in the 3x3 crafting grid that is shown above your inventory. + + + + You can optionally place multiple Firework Stars in the crafting grid to add them to the Firework. + + + + Filling more slots in the crafting grid with Gunpowder will increase the height at which all the Firework Stars will explode. + + + + You can then take the crafted Firework out of the output slot when you wish to craft it. + + + + Firework Stars can be crafted by placing Gunpowder and Dye into the crafting grid. + + + + The Dye will set the color of the explosion of the Firework Star. + + + + The shape of the Firework Star is set by adding either a Fire Charge, Gold Nugget, Feather or Mob Head. + + + + A trail or a twinkle can be added using Diamonds or Glowstone Dust. + + + + After a Firework Star has been crafted, you can set the fade color of the Firework Star by crafting it with Dye. + + + + Contained within the chests here there are various items used in the creation of FIREWORKS! + + + + {*B*} +Press{*CONTROLLER_VK_A*} to learn more about Fireworks. {*B*} +Press{*CONTROLLER_VK_B*} if you already know about Fireworks. + + + + Fireworks are decorative items that can be launched by hand or from Dispensers. They are crafted using Paper, Gunpowder and optionally a number of Firework Stars. + + + + The colors, fade, shape, size, and effects (such as trails and twinkles) of Firework Stars can be customized by including additional ingredients when crafting. + + + + Try crafting a Firework at the Crafting Table using an assortment of ingredients from the chests. + + + + Select + + + + Use + + + + Back + + + + Exit + + + + Cancel + + + + Cancel Join + + + + Refresh Online Games List + + + + Party Games + + + + All Games + + + + Change Group + + + + Show Inventory + + + + Show Description + + + + Show Ingredients + + + + Crafting + + + + Create + + + + Take/Place + + + + Take + + + + Take All + + + + Take Half + + + + Place + + + + Place All + + + + Place One + + + + Drop + + + + Drop All + + + + Drop One + + + + Swap + + + + Quick Move + + + + Clear Quick Select + + + + What's This? + + + + Share To Facebook + + + + Change Filter + + + + Send Friend Request + + + + Page Down + + + + Page Up + + + + Next + + + + Previous + + + + Kick Player + + + + Dye + + + + Mine + + + + Feed + + + + Tame + + + + Heal + + + + Sit + + + + Follow Me + + + + Eject + + + + Empty + + + + Saddle + + + + Place + + + + Hit + + + + Milk + + + + Collect + + + + Eat + + + + Sleep + + + + Wake Up + + + + Play + + + + Ride + + + + Sail + + + + Grow + + + + Swim Up + + + + Open + + + + Change Pitch + + + + Detonate + + + + Read + + + + Hang + + + + Throw + + + + Plant + + + + Till + + + + Harvest + + + + Continue + + + + Unlock Full Game + + + + Delete Save + + + + Delete + + + + Options + + + + Invite Friends + + + + Accept + + + + Shear + + + + Ban Level + + + + Select Skin + + + + Ignite + + + + Navigate + + + + Install Full Version + + + + Install Trial Version + + + + Install + + + + Reinstall + + + + Save Options + + + + Execute Command + + + + Creative + + + + Move Ingredient + + + + Move Fuel + + + + Move Tool + + + + Move Armor + + + + Move Weapon + + + + Equip + + + + Draw + + + + Release + + + + Privileges + + + + Block + + + + Page Up + + + + Page Down + + + + Love Mode + + + + Drink + + + + Rotate + + + + Hide + + + + Clear All Slots + + + + Mount + + + + Dismount + + + + Attach Chest + + + + Launch + + + + Leash + + + + Release + + + + Attach + + + + Name + + + + OK + + + + Cancel + + + + Minecraft Store + + + + Are you sure you want to leave your current game and join the new one? Any unsaved progress will be lost. + + + + Exit Game + + + + Save Game + + + + Exit Without Saving + + + + Are you sure you want to overwrite any previous save for this world with the current version of this world? + + + + Are you sure you want to exit without saving? You will lose all progress in this world! + + + + Start Game + + + + Damaged Save + + + + This save is corrupt or damaged. Would you like to delete it? + + + + Are you sure you want to exit to the main menu and disconnect all players from the game? Any unsaved progress will be lost. + + + + Exit and save + + + + Exit without saving + + + + Are you sure you want to exit to the main menu? Any unsaved progress will be lost. + + + + Are you sure you want to exit to the main menu? Your progress will be lost! + + + + Create New World + + + + Play Tutorial + + + + Tutorial + + + + Name Your World + + + + Enter a name for your world + + + + Input the seed for your world generation + + + + Load Saved World + + + + Press START to join game + + + + Exiting the game + + + + An error occurred. Exiting to the main menu. + + + + Connection failed + + + + Connection lost + + + + Connection to the server was lost. Exiting to the main menu. + + + + Disconnected by the server + + + + You were kicked from the game + + + + You were kicked from the game for flying + + + + Connection attempt took too long + + + + The server is full + + + + The host has exited the game. + + + + You cannot join this game as you are not friends with anybody in the game. + + + + You cannot join this game as you have previously been kicked by the host. + + + + You cannot join this game as the player you are trying to join is running an older version of the game. + + + + You cannot join this game as the player you are trying to join is running a newer version of the game. + + + + New World + + + + Award Unlocked! + + + + Hurray - you've been awarded a gamerpic featuring Steve from Minecraft! + + + + Hurray - you've been awarded a gamerpic featuring a Creeper! + + + + Unlock Full Game + + + + You're playing the trial game, but you'll need the full game to be able to save your game. +Would you like to unlock the full game now? + + + + Please wait + + + + No results + + + + Filter: + + + + Friends + + + + My Score + + + + Overall + + + + Entries: + + + + Rank + + + + Preparing to Save Level + + + + Preparing Chunks... + + + + Finalizing... + + + + Building Terrain + + + + Simulating world for a bit + + + + Initializing server + + + + Generating spawn area + + + + Loading spawn area + + + + Entering The Nether + + + + Leaving The Nether + + + + Respawning + + + + Generating level + + + + Loading level + + + + Saving players + + + + Connecting to host + + + + Downloading terrain + + + + Switching to offline game + + + + Please wait while the host saves the game + + + + Entering The END + + + + Leaving The END + + + + Finding Seed for the World Generator + + + + This bed is occupied + + + + You can only sleep at night + + + + %s is sleeping in a bed. To skip to dawn, all players need to sleep in beds at the same time. + + + + Your home bed was missing or obstructed + + + + You may not rest now, there are monsters nearby + + + + You are sleeping in a bed. To skip to dawn, all players need to sleep in beds at the same time. + + + + Tools and Weapons + + + + Weapons + + + + Food + + + + Structures + + + + Armor + + + + Mechanisms + + + + Transport + + + + Decorations + + + + Building Blocks + + + + Redstone & Transportation + + + + Miscellaneous + + + + Brewing + + + + Tools, Weapons & Armor + + + + Materials + + + + Signed out + + + + Difficulty + + + + Control Type + + + + Music + + + + Sound + + + + Gamma + + + + Game Sensitivity + + + + Interface Sensitivity + + + + Peaceful + + + + Easy + + + + Normal + + + + Hard + + + + Keyboard & Mouse + + + + Xbox One + + + + Xbox 360 + + + + PlayStation Vita + + + + PlayStation 3 + + + + PlayStation 4 + + + + Wii U + + + + Nintendo Switch + + + + In this mode, the player regains health over time, and there are no enemies in the environment. + + + + In this mode, enemies spawn in the environment, but will do less damage to the player than in the Normal mode. + + + + In this mode, enemies spawn in the environment and will do a standard amount of damage to the player. + + + + In this mode, enemies will spawn in the environment, and will do a great deal of damage to the player. Watch out for the Creepers too, since they are unlikely to cancel their exploding attack when you move away from them! + + + + Trial Timeout + + + + Game full + + + + Failed to join game as there are no spaces left + + + + Enter Sign Text + + + + Enter a line of text for your sign + + + + Enter Title + + + + Enter a title for your post + + + + Enter Caption + + + + Enter a caption for your post + + + + Enter Description + + + + Enter a description for your post + + + + Inventory + + + + Ingredients + + + + Brewing Stand + + + + Chest + + + + Enchant + + + + Furnace + + + + Ingredient + + + + Fuel + + + + Dispenser + + + + Horse + + + + Dropper + + + + Hopper + + + + Beacon + + + + Primary Power + + + + Secondary Power + + + + Minecart + + + + There are no downloadable content offers of this type available for this title at the moment. + + + + %s has joined the game. + + + + %s has left the game. + + + + %s was kicked from the game. + + + + Are you sure you want to delete this save game? + + + + Awaiting approval + + + + Censored + + + + Now playing: + + + + Reset Settings + + + + Are you sure you would like to reset your settings to their default values? + + + + Loading Error + + + + %s's Game + + + + Unknown host game + + + + Guest signed out + + + + A guest player has signed out causing all guest players to be removed from the game. + + + + Sign in + + + + You are not signed in. In order to play this game, you will need to be signed in. Do you want to sign in now? + + + + Multiplayer not allowed + + + + Failed to create game + + + + Auto Selected + + + + No Pack: Default Skins + + + + Favorite Skins + + + + Banned Level + + + + The game you are joining is in your banned level list. +If you choose to join this game, the level will be removed from your banned level list. + + + + Ban This Level? + + + + Are you sure you want to add this level to your banned level list? +Selecting OK will also exit this game. + + + + Remove from Banned List + + + + Autosave Interval + + + + Autosave Interval: OFF + + + + Mins + + + + Can't Place Here! + + + + Placing lava close to the level spawn point is not allowed due to the possibility of instant death for spawning players. + + + + Interface Opacity + + + + Preparing to Autosave Level + + + + HUD Size + + + + HUD Size (Splitscreen) + + + + Seed + + + + Unlock Skin Pack + + + + To use the skin you have selected, you need to unlock this skin pack. +Would you like to unlock this skin pack now? + + + + Unlock Texture Pack + + + + To use this texture pack for your world, you need to unlock it. +Would you like to unlock it now? + + + + Trial Texture Pack + + + + You are using a trial version of the texture pack. You will not be able to save this world unless you unlock the full version. +Would you like to unlock the full version of the texture pack? + + + + Texture Pack Not Present + + + + Unlock Full Version + + + + Download Trial Version + + + + Download Full Version + + + + This world uses a mash-up pack or texture pack you don't have! +Would you like to install the mash-up pack or texture pack now? + + + + Get Trial Version + + + + Get Full Version + + + + Kick player + + + + Are you sure you want to kick this player from the game? They will not be able to rejoin until you restart the world. + + + + Gamerpics Packs + + + + Themes + + + + Skins Packs + + + + Allow friends of friends + + + + You cannot join this game because it has been limited to players who are friends of the host. + + + + Can't Join Game + + + + Selected + + + + Selected skin: + + + + Corrupt Downloadable Content + + + + This downloadable content is corrupt and cannot be used. You need to delete it, then re-install it from the Minecraft Store menu. + + + + Some of your downloadable content is corrupt and cannot be used. You need to delete them, then re-install them from the Minecraft Store menu. + + + + Your game mode has been changed + + + + Rename Your World + + + + Enter the new name for your world + + + + Game Mode: Survival + + + + Game Mode: Creative + + + + Game Mode: Adventure + + + + Game Mode: Hardcore + + + + Survival + + + + Creative + + + + Adventure + + + + Hardcore + + + + Created in Survival Mode + + + + Created in Creative Mode + + + + Render Clouds + + + + Cave Sounds + + + + Minecart Sounds + + + + What would you like to do with this save game? + + + + Rename Save + + + + Autosaving in %d... + + + + On + + + + Off + + + + Normal + + + + Superflat + + + + Enter a seed to generate the same terrain again. Leave blank for a random world. + + + + When enabled, the game will be an online game. + + + + When enabled, only invited players can join. + + + + When enabled, friends of people on your Friends List can join the game. + + + + When enabled, players can inflict damage on other players. Only affects Survival mode. + + + + When disabled, players joining the game cannot build or mine until authorised. + + + + When enabled, fire may spread to nearby flammable blocks. + + + + When enabled, TNT will explode when activated. + + + + When enabled, the Nether world will be re-generated. This is useful if you have an older save where Nether Fortresses were not present. + + + + When enabled, structures such as Villages and Strongholds will generate in the world. + + + + When enabled, a completely flat world will be generated in the Overworld and in the Nether. + + + + When enabled, a chest containing some useful items will be created near the player spawn point. + + + + When disabled, prevents monsters and animals from changing blocks (for example, Creeper explosions won't destroy blocks and Sheep won't remove Grass) or picking up items. + + + + When enabled, players will keep their inventory when they die. + + + + When disabled, mobs will not spawn naturally. + + + + When disabled, monsters and animals will not drop loot (for example, Creepers won't drop gunpowder). + + + + When disabled, blocks will not drop items when destroyed (for example, Stone blocks won't drop Cobblestone). + + + + When disabled, players will not regenerate health naturally. + + + + When disabled, the time of day will not change. + + + + Skin Packs + + + + Themes + + + + Gamerpics + + + + Avatar Items + + + + Texture Packs + + + + Mash-Up Packs + + + + {*PLAYER*} went up in flames + + + + {*PLAYER*} burned to death + + + + {*PLAYER*} tried to swim in lava + + + + {*PLAYER*} suffocated in a wall + + + + {*PLAYER*} drowned + + + + {*PLAYER*} starved to death + + + + {*PLAYER*} was pricked to death + + + + {*PLAYER*} hit the ground too hard + + + + {*PLAYER*} fell out of the world + + + + {*PLAYER*} died + + + + {*PLAYER*} blew up + + + + {*PLAYER*} was killed by magic + + + + {*PLAYER*} was killed by Ender Dragon breath + + + + {*PLAYER*} was slain by {*SOURCE*} + + + + {*PLAYER*} was slain by {*SOURCE*} + + + + {*PLAYER*} was shot by {*SOURCE*} + + + + {*PLAYER*} was fireballed by {*SOURCE*} + + + + {*PLAYER*} was pummeled by {*SOURCE*} + + + + {*PLAYER*} was killed by {*SOURCE*} using magic + + + + {*PLAYER*} fell off a ladder + + + + {*PLAYER*} fell off some vines + + + + {*PLAYER*} fell out of the water + + + + {*PLAYER*} fell from a high place + + + + {*PLAYER*} was doomed to fall by {*SOURCE*} + + + + {*PLAYER*} was doomed to fall by {*SOURCE*} + + + + {*PLAYER*} was doomed to fall by {*SOURCE*} using {*ITEM*} + + + + {*PLAYER*} fell too far and was finished by {*SOURCE*} + + + + {*PLAYER*} fell too far and was finished by {*SOURCE*} using {*ITEM*} + + + + {*PLAYER*} walked into fire whilst fighting {*SOURCE*} + + + + {*PLAYER*} was burnt to a crisp whilst fighting {*SOURCE*} + + + + {*PLAYER*} tried to swim in lava to escape {*SOURCE*} + + + + {*PLAYER*} drowned whilst trying to escape {*SOURCE*} + + + + {*PLAYER*} walked into a cactus whilst trying to escape {*SOURCE*} + + + + {*PLAYER*} was blown up by {*SOURCE*} + + + + {*PLAYER*} withered away + + + + {*PLAYER*} was slain by {*SOURCE*} using {*ITEM*} + + + + {*PLAYER*} was shot by {*SOURCE*} using {*ITEM*} + + + + {*PLAYER*} was fireballed by {*SOURCE*} using {*ITEM*} + + + + {*PLAYER*} was pummeled by {*SOURCE*} using {*ITEM*} + + + + {*PLAYER*} was killed by {*SOURCE*} using {*ITEM*} + + + + Bedrock Fog + + + + Display HUD + + + + Display Hand + + + + Death Messages + + + + dead. + + + + Animated Character + + + + Custom Skin Animation + + + + You can no longer mine or use items + + + + You can now mine and use items + + + + You can no longer place blocks + + + + You can now place blocks + + + + You can now use doors and switches + + + + You can no longer use doors and switches + + + + You can now use containers (e.g. chests) + + + + You can no longer use containers (e.g. chests) + + + + You can no longer attack mobs + + + + You can now attack mobs + + + + You can no longer attack players + + + + You can now attack players + + + + You can no longer attack animals + + + + You can now attack animals + + + + You are now a moderator + + + + You are no longer a moderator + + + + You can now fly + + + + You can no longer fly + + + + You will no longer get exhausted + + + + You will now get exhausted + + + + You are now invisible + + + + You are no longer invisible + + + + You are now invulnerable + + + + You are no longer invulnerable + + + + %d MSP + + + + Ender Dragon + + + + %s has entered The End + + + + %s has left The End + + + + +{*C3*}I see the player you mean.{*EF*}{*B*}{*B*} +{*C2*}{*PLAYER*}?{*EF*}{*B*}{*B*} +{*C3*}Yes. Take care. It has reached a higher level now. It can read our thoughts.{*EF*}{*B*}{*B*} +{*C2*}That doesn't matter. It thinks we are part of the game.{*EF*}{*B*}{*B*} +{*C3*}I like this player. It played well. It did not give up.{*EF*}{*B*}{*B*} +{*C2*}It is reading our thoughts as though they were words on a screen.{*EF*}{*B*}{*B*} +{*C3*}That is how it chooses to imagine many things, when it is deep in the dream of a game.{*EF*}{*B*}{*B*} +{*C2*}Words make a wonderful interface. Very flexible. And less terrifying than staring at the reality behind the screen.{*EF*}{*B*}{*B*} +{*C3*}They used to hear voices. Before players could read. Back in the days when those who did not play called the players witches, and warlocks. And players dreamed they flew through the air, on sticks powered by demons.{*EF*}{*B*}{*B*} +{*C2*}What did this player dream?{*EF*}{*B*}{*B*} +{*C3*}This player dreamed of sunlight and trees. Of fire and water. It dreamed it created. And it dreamed it destroyed. It dreamed it hunted, and was hunted. It dreamed of shelter.{*EF*}{*B*}{*B*} +{*C2*}Hah, the original interface. A million years old, and it still works. But what true structure did this player create, in the reality behind the screen?{*EF*}{*B*}{*B*} +{*C3*}It worked, with a million others, to sculpt a true world in a fold of the {*EF*}{*NOISE*}{*C3*}, and created a {*EF*}{*NOISE*}{*C3*} for {*EF*}{*NOISE*}{*C3*}, in the {*EF*}{*NOISE*}{*C3*}.{*EF*}{*B*}{*B*} +{*C2*}It cannot read that thought.{*EF*}{*B*}{*B*} +{*C3*}No. It has not yet achieved the highest level. That, it must achieve in the long dream of life, not the short dream of a game.{*EF*}{*B*}{*B*} +{*C2*}Does it know that we love it? That the universe is kind?{*EF*}{*B*}{*B*} +{*C3*}Sometimes, through the noise of its thoughts, it hears the universe, yes.{*EF*}{*B*}{*B*} +{*C2*}But there are times it is sad, in the long dream. It creates worlds that have no summer, and it shivers under a black sun, and it takes its sad creation for reality.{*EF*}{*B*}{*B*} +{*C3*}To cure it of sorrow would destroy it. The sorrow is part of its own private task. We cannot interfere.{*EF*}{*B*}{*B*} +{*C2*}Sometimes when they are deep in dreams, I want to tell them, they are building true worlds in reality. Sometimes I want to tell them of their importance to the universe. Sometimes, when they have not made a true connection in a while, I want to help them to speak the word they fear.{*EF*}{*B*}{*B*} +{*C3*}It reads our thoughts.{*EF*}{*B*}{*B*} +{*C2*}Sometimes I do not care. Sometimes I wish to tell them, this world you take for truth is merely {*EF*}{*NOISE*}{*C2*} and {*EF*}{*NOISE*}{*C2*}, I wish to tell them that they are {*EF*}{*NOISE*}{*C2*} in the {*EF*}{*NOISE*}{*C2*}. They see so little of reality, in their long dream.{*EF*}{*B*}{*B*} +{*C3*}And yet they play the game.{*EF*}{*B*}{*B*} +{*C2*}But it would be so easy to tell them...{*EF*}{*B*}{*B*} +{*C3*}Too strong for this dream. To tell them how to live is to prevent them living.{*EF*}{*B*}{*B*} +{*C2*}I will not tell the player how to live.{*EF*}{*B*}{*B*} +{*C3*}The player is growing restless.{*EF*}{*B*}{*B*} +{*C2*}I will tell the player a story.{*EF*}{*B*}{*B*} +{*C3*}But not the truth.{*EF*}{*B*}{*B*} +{*C2*}No. A story that contains the truth safely, in a cage of words. Not the naked truth that can burn over any distance.{*EF*}{*B*}{*B*} +{*C3*}Give it a body, again.{*EF*}{*B*}{*B*} +{*C2*}Yes. Player...{*EF*}{*B*}{*B*} +{*C3*}Use its name.{*EF*}{*B*}{*B*} +{*C2*}{*PLAYER*}. Player of games.{*EF*}{*B*}{*B*} +{*C3*}Good.{*EF*}{*B*}{*B*} + + + + + +{*C2*}Take a breath, now. Take another. Feel air in your lungs. Let your limbs return. Yes, move your fingers. Have a body again, under gravity, in air. Respawn in the long dream. There you are. Your body touching the universe again at every point, as though you were separate things. As though we were separate things.{*EF*}{*B*}{*B*} +{*C3*}Who are we? Once we were called the spirit of the mountain. Father sun, mother moon. Ancestral spirits, animal spirits. Jinn. Ghosts. The green man. Then gods, demons. Angels. Poltergeists. Aliens, extraterrestrials. Leptons, quarks. The words change. We do not change.{*EF*}{*B*}{*B*} +{*C2*}We are the universe. We are everything you think isn't you. You are looking at us now, through your skin and your eyes. And why does the universe touch your skin, and throw light on you? To see you, player. To know you. And to be known. I shall tell you a story.{*EF*}{*B*}{*B*} +{*C2*}Once upon a time, there was a player.{*EF*}{*B*}{*B*} +{*C3*}The player was you, {*PLAYER*}.{*EF*}{*B*}{*B*} +{*C2*}Sometimes it thought itself human, on the thin crust of a spinning globe of molten rock. The ball of molten rock circled a ball of blazing gas that was three hundred and thirty thousand times more massive than it. They were so far apart that light took eight minutes to cross the gap. The light was information from a star, and it could burn your skin from a hundred and fifty million kilometres away.{*EF*}{*B*}{*B*} +{*C2*}Sometimes the player dreamed it was a miner, on the surface of a world that was flat, and infinite. The sun was a square of white. The days were short; there was much to do; and death was a temporary inconvenience.{*EF*}{*B*}{*B*} +{*C3*}Sometimes the player dreamed it was lost in a story.{*EF*}{*B*}{*B*} +{*C2*}Sometimes the player dreamed it was other things, in other places. Sometimes these dreams were disturbing. Sometimes very beautiful indeed. Sometimes the player woke from one dream into another, then woke from that into a third.{*EF*}{*B*}{*B*} +{*C3*}Sometimes the player dreamed it watched words on a screen.{*EF*}{*B*}{*B*} +{*C2*}Let's go back.{*EF*}{*B*}{*B*} +{*C2*}The atoms of the player were scattered in the grass, in the rivers, in the air, in the ground. A woman gathered the atoms; she drank and ate and inhaled; and the woman assembled the player, in her body.{*EF*}{*B*}{*B*} +{*C2*}And the player awoke, from the warm, dark world of its mother's body, into the long dream.{*EF*}{*B*}{*B*} +{*C2*}And the player was a new story, never told before, written in letters of DNA. And the player was a new program, never run before, generated by a sourcecode a billion years old. And the player was a new human, never alive before, made from nothing but milk and love.{*EF*}{*B*}{*B*} +{*C3*}You are the player. The story. The program. The human. Made from nothing but milk and love.{*EF*}{*B*}{*B*} +{*C2*}Let's go further back.{*EF*}{*B*}{*B*} +{*C2*}The seven billion billion billion atoms of the player's body were created, long before this game, in the heart of a star. So the player, too, is information from a star. And the player moves through a story, which is a forest of information planted by a man called Julian, on a flat, infinite world created by a man called Markus, that exists inside a small, private world created by the player, who inhabits a universe created by...{*EF*}{*B*}{*B*} +{*C3*}Shush. Sometimes the player created a small, private world that was soft and warm and simple. Sometimes hard, and cold, and complicated. Sometimes it built a model of the universe in its head; flecks of energy, moving through vast empty spaces. Sometimes it called those flecks "electrons" and "protons".{*EF*}{*B*}{*B*} + + + + + +{*C2*}Sometimes it called them "planets" and "stars".{*EF*}{*B*}{*B*} +{*C2*}Sometimes it believed it was in a universe that was made of energy that was made of offs and ons; zeros and ones; lines of code. Sometimes it believed it was playing a game. Sometimes it believed it was reading words on a screen.{*EF*}{*B*}{*B*} +{*C3*}You are the player, reading words...{*EF*}{*B*}{*B*} +{*C2*}Shush... Sometimes the player read lines of code on a screen. Decoded them into words; decoded words into meaning; decoded meaning into feelings, emotions, theories, ideas, and the player started to breathe faster and deeper and realised it was alive, it was alive, those thousand deaths had not been real, the player was alive{*EF*}{*B*}{*B*} +{*C3*}You. You. You are alive.{*EF*}{*B*}{*B*} +{*C2*}and sometimes the player believed the universe had spoken to it through the sunlight that came through the shuffling leaves of the summer trees{*EF*}{*B*}{*B*} +{*C3*}and sometimes the player believed the universe had spoken to it through the light that fell from the crisp night sky of winter, where a fleck of light in the corner of the player's eye might be a star a million times as massive as the sun, boiling its planets to plasma in order to be visible for a moment to the player, walking home at the far side of the universe, suddenly smelling food, almost at the familiar door, about to dream again{*EF*}{*B*}{*B*} +{*C2*}and sometimes the player believed the universe had spoken to it through the zeros and ones, through the electricity of the world, through the scrolling words on a screen at the end of a dream{*EF*}{*B*}{*B*} +{*C3*}and the universe said I love you{*EF*}{*B*}{*B*} +{*C2*}and the universe said you have played the game well{*EF*}{*B*}{*B*} +{*C3*}and the universe said everything you need is within you{*EF*}{*B*}{*B*} +{*C2*}and the universe said you are stronger than you know{*EF*}{*B*}{*B*} +{*C3*}and the universe said you are the daylight{*EF*}{*B*}{*B*} +{*C2*}and the universe said you are the night{*EF*}{*B*}{*B*} +{*C3*}and the universe said the darkness you fight is within you{*EF*}{*B*}{*B*} +{*C2*}and the universe said the light you seek is within you{*EF*}{*B*}{*B*} +{*C3*}and the universe said you are not alone{*EF*}{*B*}{*B*} +{*C2*}and the universe said you are not separate from every other thing{*EF*}{*B*}{*B*} +{*C3*}and the universe said you are the universe tasting itself, talking to itself, reading its own code{*EF*}{*B*}{*B*} +{*C2*}and the universe said I love you because you are love.{*EF*}{*B*}{*B*} +{*C3*}And the game was over and the player woke up from the dream. And the player began a new dream. And the player dreamed again, dreamed better. And the player was the universe. And the player was love.{*EF*}{*B*}{*B*} +{*C3*}You are the player.{*EF*}{*B*}{*B*} +{*C2*}Wake up.{*EF*} + + + + + Reset Nether + + + + Are you sure you want to reset the Nether in this savegame to its default state? You will lose anything you have built in the Nether! + + + + Reset Nether + + + + Don't Reset Nether + + + + Can't shear this Mooshroom at the moment. The maximum number of Pigs, Sheep, Cows, Cats and Horses has been reached. + + + + Can't use Spawn Egg at the moment. The maximum number of Pigs, Sheep, Cows, Cats and Horses has been reached. + + + + Can't use Spawn Egg at the moment. The maximum number of Mooshrooms has been reached. + + + + Can't use Spawn Egg at the moment. The maximum number of Wolves in a world has been reached. + + + + Can't use Spawn Egg at the moment. The maximum number of Chickens in a world has been reached. + + + + Can't use Spawn Egg at the moment. The maximum number of Squid in a world has been reached. + + + + Can't use Spawn Egg at the moment. The maximum number of Bats in a world has been reached. + + + + Can't use Spawn Egg at the moment. The maximum number of enemies in a world has been reached. + + + + Can't use Spawn Egg at the moment. The maximum number of villagers in a world has been reached. + + + + The maximum number of Paintings/Item Frames in a world has been reached. + + + + You can't spawn enemies in Peaceful mode. + + + + This animal can't enter Love Mode. The maximum number of breeding Pigs, Sheep, Cows, Cats and Horses has been reached. + + + + This animal can't enter Love Mode. The maximum number of breeding Wolves has been reached. + + + + This animal can't enter Love Mode. The maximum number of breeding Chickens has been reached. + + + + This animal can't enter Love Mode. The maximum number of breeding horses has been reached. + + + + This animal can't enter Love Mode. The maximum number of breeding Mooshrooms has been reached. + + + + The maximum number of Boats in a world has been reached. + + + + The maximum number of Mob Heads in a world has been reached. + + + + Invert Look + + + + Southpaw + + + + You Died! + + + + Respawn + + + + Downloadable Content Offers + + + + Change Skin + + + + How To Play + + + + Controls + + + + Settings + + + + Languages + + + + Credits + + + + Reinstall Content + + + + Debug Settings + + + + Fire Spreads + + + + TNT Explodes + + + + Player vs Player + + + + Trust Players + + + + Host Privileges + + + + Generate Structures + + + + Superflat World + + + + Bonus Chest + + + + World Options + + + + Game Options + + + + Mob Griefing + + + + Keep Inventory + + + + Mob Spawning + + + + Mob Loot + + + + Tile Drops + + + + Natural Regeneration + + + + Daylight Cycle + + + + Can Build and Mine + + + + Can Use Doors and Switches + + + + Can Open Containers + + + + Can Attack Players + + + + Can Attack Animals + + + + Moderator + + + + Kick Player + + + + Can Fly + + + + Disable Exhaustion + + + + Invisible + + + + Host Options + + + + Players/Invite + + + + Online Game + + + + Invite Only + + + + More Options + + + + Load + + + + New World + + + + World Name + + + + Seed for the World Generator + + + + Leave blank for a random seed + + + + Players + + + + Join Game + + + + Start Game + + + + No Games Found + + + + Play Game + + + + Leaderboards + + + + Help & Options + + + + Unlock Full Game + + + + Resume Game + + + + Save Game + + + + Difficulty: + + + + Game Type: + + + + Structures: + + + + Level Type: + + + + PvP: + + + + Trust Players: + + + + TNT: + + + + Fire Spreads: + + + + Reinstall Theme + + + + Reinstall Gamerpic 1 + + + + Reinstall Gamerpic 2 + + + + Reinstall Avatar Item 1 + + + + Reinstall Avatar Item 2 + + + + Reinstall Avatar Item 3 + + + + Game Options + + + + Audio + + + + Control + + + + Graphics + + + + User Interface + + + + Reset to Defaults + + + + View Bobbing + + + + Hints + + + + In-Game Tooltips + + + + Vertical Splitscreen + + + + Done + + + + Edit sign message: + + + + Fill in the details to accompany your screenshot + + + + Caption + + + + Screenshot from in-game + + + + Edit sign message: + + + + The classic Minecraft textures, icons and user interface! + + + + Show all Mash-up Worlds + + + + No Effects + + + + Speed + + + + Slowness + + + + Haste + + + + Mining Fatigue + + + + Strength + + + + Weakness + + + + Instant Health + + + + Instant Damage + + + + Jump Boost + + + + Nausea + + + + Regeneration + + + + Resistance + + + + Fire Resistance + + + + Water Breathing + + + + Invisibility + + + + Blindness + + + + Night Vision + + + + Hunger + + + + Poison + + + + Wither + + + + Health Boost + + + + Absorption + + + + Saturation + + + + of Swiftness + + + + of Slowness + + + + of Haste + + + + of Dullness + + + + of Strength + + + + of Weakness + + + + of Healing + + + + of Harming + + + + of Leaping + + + + of Nausea + + + + of Regeneration + + + + of Resistance + + + + of Fire Resistance + + + + of Water Breathing + + + + of Invisibility + + + + of Blindness + + + + of Night Vision + + + + of Hunger + + + + of Poison + + + + of Decay + + + + of Health Boost + + + + of Absorption + + + + of Saturation + + + + + + + + + II + + + + III + + + + IV + + + + Splash + + + + Mundane + + + + Uninteresting + + + + Bland + + + + Clear + + + + Milky + + + + Diffuse + + + + Artless + + + + Thin + + + + Awkward + + + + Flat + + + + Bulky + + + + Bungling + + + + Buttered + + + + Smooth + + + + Suave + + + + Debonair + + + + Thick + + + + Elegant + + + + Fancy + + + + Charming + + + + Dashing + + + + Refined + + + + Cordial + + + + Sparkling + + + + Potent + + + + Foul + + + + Odorless + + + + Rank + + + + Harsh + + + + Acrid + + + + Gross + + + + Stinky + + + + Used as the base of all potions. Use in a brewing stand to create potions. + + + + Has no effects, can be used in a brewing stand to create potions by adding more ingredients. + + + + Increases affected players, animals and monsters movement speed, and players sprinting speed, jumping length and field of view. + + + + Reduces affected players, animals and monsters movement speed, and players sprinting speed, jumping length and field of view. + + + + Increase the damage caused by affected players and monsters when attacking. + + + + Reduces the damage cause by affected players and monsters when attacking. + + + + Instantly increases the affected players, animals and monsters health. + + + + Instantly reduces the affected players, animals and monsters health. + + + + Restores health to the affected players, animals and monsters over time. + + + + Makes the affected players, animals and monsters immune to damage from fire, lava, and ranged Blaze attacks. + + + + Reduces health of the affected players, animals and monsters over time. + + + + Allows affected players to breathe normally underwater. + + + + Increases the jump height of the affected player. + + + + When Applied: + + + + Horse Jump Strength + + + + Zombie Reinforcements + + + + Max Health + + + + Mob Follow Range + + + + Knockback Resistance + + + + Speed + + + + Attack Damage + + + + Sharpness + + + + Smite + + + + Bane of Arthropods + + + + Knockback + + + + Fire Aspect + + + + Protection + + + + Fire Protection + + + + Feather Falling + + + + Blast Protection + + + + Projectile Protection + + + + Respiration + + + + Aqua Affinity + + + + Depth Strider + + + + Efficiency + + + + Silk Touch + + + + Unbreaking + + + + Looting + + + + Fortune + + + + Power + + + + Flame + + + + Punch + + + + Infinity + + + + I + + + + II + + + + III + + + + IV + + + + V + + + + VI + + + + VII + + + + VIII + + + + IX + + + + X + + + + Can be mined with an Iron pickaxe or better to collect Emeralds. + + + + Similar to a Chest except that items placed in an Ender Chest are available in every one of the player's Ender Chests, even in different dimensions. + + + + Is activated when an entity passes through a connected Tripwire. + + + + Activates a connected Tripwire Hook when an entity passes through it. + + + + A compact way of storing Emeralds. + + + + A wall made of Cobblestone. + + + + Can be used to repair weapons, tools and armor. + + + + Smelted in a furnace to produce Nether Quartz. + + + + Used as a decoration. + + + + Can be traded with villagers. + + + + Used as a decoration. Flowers, Saplings, Cacti and Mushrooms can be planted in it. + + + + Restores 2{*ICON_SHANK_01*}, and can be crafted into a golden carrot. Can be planted in farmland. + + + + Restores 0.5{*ICON_SHANK_01*}, or can be cooked in a furnace. This can be planted in farmland. + + + + Restores 3{*ICON_SHANK_01*}. Created by cooking a potato in a furnace. + + + + Restores 1{*ICON_SHANK_01*}. Eating this can cause you to become poisoned. + + + + Restores 3{*ICON_SHANK_01*}. Crafted from a carrot and gold nuggets. + + + + Used to control a saddled pig when riding on it. + + + + Restores 4{*ICON_SHANK_01*}. + + + + Used with an Anvil to enchant weapons, tools or armor. + + + + Created by mining Nether Quartz Ore. Can be crafted into a Block of Quartz. + + + + Crafted from Wool. Used as a decoration. + + + + Emerald + + + + Flower Pot + + + + Carrot + + + + Potato + + + + Baked Potato + + + + Poisonous Potato + + + + Golden Carrot + + + + Carrot on a Stick + + + + Pumpkin Pie + + + + Enchanted Book + + + + Nether Quartz + + + + Emerald Ore + + + + Ender Chest + + + + Tripwire Hook + + + + Tripwire + + + + Block of Emerald + + + + Cobblestone Wall + + + + Mossy Cobblestone Wall + + + + Flower Pot + + + + Carrots + + + + Potatoes + + + + Anvil + + + + Anvil + + + + Slightly Damaged Anvil + + + + Very Damaged Anvil + + + + Nether Quartz Ore + + + + Block of Quartz + + + + Chiseled Quartz Block + + + + Pillar Quartz Block + + + + Quartz Stairs + + + + Carpet + + + + Black Carpet + + + + Red Carpet + + + + Green Carpet + + + + Brown Carpet + + + + Blue Carpet + + + + Purple Carpet + + + + Cyan Carpet + + + + Light Gray Carpet + + + + Gray Carpet + + + + Pink Carpet + + + + Lime Carpet + + + + Yellow Carpet + + + + Light Blue Carpet + + + + Magenta Carpet + + + + Orange Carpet + + + + White Carpet + + + + Chiseled Sandstone + + + + Smooth Sandstone + + + + {*PLAYER*} was killed trying to hurt {*SOURCE*} + + + + {*PLAYER*} was squashed by a falling Anvil. + + + + {*PLAYER*} was squashed by a falling block. + + + + Teleported {*PLAYER*} to {*DESTINATION*} + + + + {*PLAYER*} teleported you to their position + + + + {*PLAYER*} teleported to you + + + + Thorns + + + + Quartz Slab + + + + Makes dark areas appear as if in daylight, even under water. + + + + Makes affected players, animals and monsters invisible. + + + + Repair & Name + + + + Enchantment Cost: %d + + + + Too Expensive! + + + + Rename + + + + You have: + + + + Required Items For Trade + + + + {*VILLAGER_TYPE*} offers %s + + + + Repair + + + + Trade + + + + Dye collar + + + + + This is the Anvil interface, which you can use to rename, repair and apply enchantments to weapons, armor, or tools, at the cost of Experience Levels. + + + + + + {*B*} + Press{*CONTROLLER_VK_A*} to learn more about the Anvil interface.{*B*} + Press{*CONTROLLER_VK_B*} if you already know the Anvil interface. + + + + + + To begin working on an item, place it in the first input slot. + + + + + + When the correct raw material is placed in the second input slot (e.g. Iron Ingots for a damaged Iron Sword), the proposed repair appears in the output slot. + + + + + + Alternatively, a second identical item can be placed into the second slot to combine the two items. + + + + + + To enchant items on the Anvil, place an Enchanted Book in the second input slot. + + + + + + The number of Experience Levels that the work will cost is shown beneath the output. If you do not have enough Experience Levels, the repair cannot be completed. + + + + + + It is possible to rename the item by editing the name shown in the textbox. + + + + + + Picking up the repaired item will consume both items used by the Anvil and decrease your Experience Level by the given amount. + + + + + + In this area there is an Anvil and a Chest containing tools and weapons to work on. + + + + + + {*B*} + Press{*CONTROLLER_VK_A*} to learn more about the Anvil.{*B*} + Press{*CONTROLLER_VK_B*} if you already know about the Anvil. + + + + + + Using an Anvil, weapons and tools can be repaired to restore their durability, renamed, or enchanted with Enchanted Books. + + + + + + Enchanted Books can be found inside Chests within dungeons, or enchanted from normal Books at the Enchantment Table. + + + + + + Using the Anvil costs Experience Levels, and each use has a chance to damage the Anvil. + + + + + + The type of work to be done, value of the item, number of enchantments, and amount of prior work all affect the cost of repair. + + + + + + Renaming an item changes the displayed name for all players and permanently reduces the prior work cost. + + + + + + In the Chest in this area you will find damaged Pickaxes, raw materials, Bottles O' Enchanting, and Enchanted Books to experiment with. + + + + + + This is the trading interface which displays trades that can be made with a villager. + + + + + + {*B*} + Press{*CONTROLLER_VK_A*} to learn more about the trading interface.{*B*} + Press{*CONTROLLER_VK_B*} if you already know the trading interface. + + + + + + All trades that the villager is willing to make at the moment are displayed along the top. + + + + + + Trades will appear red and be unavailable if you do not have the required items. + + + + + + The amount and type of items you are giving to the villager are shown in the two boxes on the left. + + + + + + You can see the total number of the items required for the trade in the two boxes on the left. + + + + + + Press{*CONTROLLER_VK_A*} to trade the items the villager requires for the item on offer. + + + + + + In this area there is a villager and a Chest containing Paper to purchase items. + + + + + + {*B*} + Press{*CONTROLLER_VK_A*} to learn more about trading.{*B*} + Press{*CONTROLLER_VK_B*} if you already know about trading. + + + + + + Players can trade items from their inventory with villagers. + + + + + + The trades a villager is likely to offer depends on their profession. + + + + + + Performing a mix of trades will randomly add to or update the villager's available trades. + + + + + + Trades that have been used frequently may be removed temporarily, but the villager will always offer at least one trade. + + + + + + Take some Paper from the Chest and try trading with the villager here. + + + + + + In this area there are two Ender Chests. + + + + + + {*B*} + Press{*CONTROLLER_VK_A*} to learn more about Ender Chests.{*B*} + Press{*CONTROLLER_VK_B*} if you already know about Ender Chests. + + + + + + All Ender Chests in a world are linked, even across dimensions. Items placed into an Ender Chest are accessible in any other Ender Chest. + + + + + + However, the contents of the Ender Chests are different for each player. + + + + + + This allows players to store items in any Ender Chest, and retrieve them from other Ender Chests in different positions in the world. You can try this now by placing items in either Ender Chest. + + + + + Restores 2{*ICON_SHANK_01*}, regenerates health for 30 seconds, and grants fire resistance and damage resistance for 5 minutes. Crafted from an apple and gold blocks. + + + + Can Teleport + + + + Teleport + + + + Teleport To Player + + + + Teleport To Me + + + + Can Disable Exhaustion + + + + Can Become Invisible + + + + You can now enable invisibility + + + + You can no longer enable invisibility + + + + You can now enable flying + + + + You can no longer enable flying + + + + You can now disable exhaustion + + + + You can no longer disable exhaustion + + + + You can now teleport + + + + You can no longer teleport + + + + {*T3*}HOW TO PLAY : ANVIL{*ETW*}{*B*}{*B*} +Experience Levels can be used to repair, enchant or rename items with the Anvil.{*B*} +All items can be renamed, although only items with durability can be repaired or have enchantments from Enchanted Books applied to them.{*B*} +An item can be repaired by placing it in one of the input slots on the left, along with either some raw materials of the item, like Iron Ingots for an Iron Sword, or combined with another item of the same type.{*B*} +Combining items is more efficient when done with an Anvil, and additionally, if either of the items were enchanted, the finished product may have enchantments from either of the inputs.{*B*} +Enchanted Books can apply enchantments to items by combining them at an Anvil if the Book's enchantment is suitable. Enchanted Books can be found in Chests within dungeons, or enchanted from normal Books at the Enchantment Table.{*B*} +There is a chance that the Anvil will be damaged with each use and after enough punishment it will be destroyed.{*B*} + + + + + {*T3*}HOW TO PLAY : TRADING{*ETW*}{*B*}{*B*} +It is possible to trade items with villagers. Each villager has a profession; they can be Farmers, Butchers, Blacksmiths, Librarians or Priests, and this affects the type of items they might trade.{*B*} +You can find a list of all the trades a villager is offering in the trading menu. A villager may modify or add to its trades whenever a player trades with it, although a trade might become temporarily disabled if it is used too frequently.{*B*} +Trades usually involve buying or selling a number of items for emeralds.{*B*} +If you do not have the items required for a trade, the items are shown in red.{*B*} + + + + + {*T3*}HOW TO PLAY : ENDER CHEST {*ETW*}{*B*}{*B*} +All Ender Chests in a world are linked. Items placed into an Ender Chest are accessible in any other. However, the contents of the Ender Chests are different for each player. This allows players to store items in any Ender Chest, and retrieve them from other Ender Chests in different positions in the world. + + + + + Farmer + + + + Librarian + + + + Priest + + + + Blacksmith + + + + Butcher + + + + Found in villages, villagers will offer to sell items to the player depending on their profession. + + + + Large Chest + + + + + You can also create Enchanted Books at the Enchantment Table, which can be used later at the Anvil to apply their enchantment to an item. + + + + + + Tripwire Hooks will also provide constant power to a circuit while something is triggering the string between them. + + + + + + Once tamed, a wolf will always have its collar on. The color of their collar can be changed by dying it. + + + + + Carrots and Potatoes are farmed by planting Carrots or Potatoes, and are ready for harvesting when the vegetable is visible above the ground. + + + + + Additionally, pigs can be saddled and then ridden by players. They are controlled by tempting them with a Carrot on a Stick. + + + + + + If necessary you can slowly move your minecart along using {*CONTROLLER_ACTION_MOVE*}. This helps to start the minecart by getting it onto a powered rail. + + + + + You cannot join this game as split-screen is only supported when in High Definition mode. Sign out all other players if you wish to join. + + + + Cure + + + + Acacia Wood + + + + Dark Oak Wood + + + + Acacia Planks + + + + Dark Oak Planks + + + + Acacia Wood Stairs + + + + Dark Oak Wood Stairs + + + + Acacia Wood Slab + + + + Dark Oak Wood Slab + + + + Dark Oak Wood Slab + + + + Iron Trapdoor + + + + Spruce Door + + + + Birch Door + + + + Jungle Door + + + + Acacia Door + + + + Dark Oak Door + + + + Spruce Fence + + + + Birch Fence + + + + Jungle Fence + + + + Acacia Fence + + + + Dark Oak Fence + + + + Spruce Fence Gate + + + + Birch Fence Gate + + + + Jungle Fence Gate + + + + Acacia Fence Gate + + + + Dark Oak Fence Gate + + + + Spruce Door + + + + Birch Door + + + + Jungle Door + + + + Acacia Door + + + + Dark Oak Door + + + Armor Stand + + + + Can be equipped to display armor and other decorative items such as mob heads. + + + + Rabbit + + + + A harmless creature. May drop a rabbit hide or a rabbit's foot when killed. + + + + Rabbit Hide + + + + Used in crafting leather. + + + + Rabbit's Foot + + + + Used as an ingredient for brewing potions. + + + + Raw Rabbit + + + + Restores 0.5{*ICON_SHANK_01*}, or can be cooked in a furnace. + + + + Cooked Rabbit + + + + Restores 2.5{*ICON_SHANK_01*}. Used to cook up some rabbit stew. + + + + Raw Mutton + + + + Restores 1{*ICON_SHANK_01*}, or can be cooked in a furnace. + + + + Cooked Mutton + + + + Restores 3{*ICON_SHANK_01*}. Created by cooking raw mutton in a furnace. + + + + Acacia Sapling + + + + Dark Oak Sapling + + + + Acacia Leaves + + + + Dark Oak Leaves + + + + Red Sandstone + + + + Red Sandstone Stairs + + + + Prismarine Crystal + + + + Sea Lantern + + + + Exit Minecraft + + + + Prismarine + + + + Dark Prismarine + + + + Prismarine Bricks + + + + Prismarine Shard + + + + Rare decorative stone that can be found in Ocean Monuments. Can be crafted from Prismarine shards. + + + + A rarer form of Prismarine that can be found in Ocean Monuments. Can be crafted with Prismarine shards and an Ink Sac. + + + + Decorative Prismarine brick that can be found in Ocean Monuments. Can be crafted from Prismarine shards. + + + + Obtained from Sea Lanterns or by defeating Guardians and Elder Guardians. Can be used in crafting Sea Lanterns. + + + + Dropped by Guardians and Elder Guardians. Can be used in crafting Prismarine and Sea Lanterns. + + + + Rabbit Stew + + + + Tall Grass + + + + Large Fern + + + + Lilac + + + + Rose Bush + + + + Peony + + + + Packed Ice + + + + Sunflower + + + + A solid unmeltable block of ice that can have objects placed on it. + + + + Red colored Sandstone. It is not influenced by gravity like normal Sand. + + + + Underwater light sources that can be found in Ocean Monuments. Can be crafted from Prismarine shards and Prismarine crystals. + + + + Rare decorative stone that can be found in Ocean Monuments. Can be crafted from Prismarine shards. + + + + Double tall grass that can sometimes drop seeds. + + + + Chiseled Red Sandstone + + + + Smooth Red Sandstone + + + + Podzol + + + + Coarse Dirt + + + + Similar to Dirt Blocks, but very good for growing mushrooms on. + + + + A special type of dirt that does not grow grass. + + + + Granite + + + + Polished Granite + + + + Andesite + + + + Polished Andesite + + + + Diorite + + + + Polished Diorite + + + + Can be mined with a pickaxe to collect granite. + + + + Can be crafted from granite for a polished look. + + + + Can be mined with a pickaxe to collect andesite. + + + + Can be crafted from andesite for a polished look. + + + + Can be mined with a pickaxe to collect diorite. + + + + Can be crafted from diorite for a polished look. + + + + Red Sand + + + + Wet Sponge + + + + Can be dried in a furnace, allowing the sponge to be reused. + + + + Raw Salmon + + + + Cooked Salmon + + + + Clownfish + + + + Pufferfish + + + + Restores 1{*ICON_SHANK_01*}, or can be cooked in a furnace. Can be fed to an ocelot to tame it. + + + + Restores 3{*ICON_SHANK_01*}. Created by cooking a raw salmon in a furnace. + + + + Restores 0.5{*ICON_SHANK_01*}. + + + + Restores 0.5{*ICON_SHANK_01*} however it is poisonous. Can also be used as an ingredient in brewing potions. + + + + Blue Orchid + + + + Allium + + + + Azure Bluet + + + + Red Tulip + + + + Orange Tulip + + + + White Tulip + + + + Pink Tulip + + + + Oxeye Daisy + + + + A common red flower that can be used to craft red dye. + + + + A rare blue flower that can be used to craft light blue dye. + + + + A rare magenta flower that can be used to craft magenta dye. + + + + A small white flower that can be used to craft light gray dye. + + + + A small red flower that can be used to craft red dye. + + + + A small orange flower that can be used to craft orange dye. + + + + A small white flower that can be used to craft light gray dye. + + + + A small pink flower that can be used to craft pink dye. + + + + A common white and yellow flower that can be used to craft light gray dye. + + + + A tall yellow flower that can be used to craft yellow dye. + + + + A tall purple flower that can be used to craft magenta dye. + + + + A tall fern that can sometimes drop seeds. + + + + A tall red flower that can be used to craft red dye. + + + + A tall green and pink flower that can be used to craft pink dye. + + + + Endermite + + + + Guardian + + + + Elder Guardian + + + + Written Book + + + + A book signed by the author (cannot be written in). + + + + Book and Quill + + + + A Book that can be written in. + + + + Next Page + + + + Previous Page + + + + Add Page + + + + Exit Book + + + + Are you sure you want to exit this book and the changes you've made? + + + + Lure + + + + Luck of the Sea + + + Red Sandstone Slab + + + Elytra + + + Taking Inventory + Open your inventory. + + Getting Wood + Punch a tree until a block of wood pops out. + + Benchmarking + Craft a Workbench with four blocks of Wooden Planks. + + Time to Mine! + Use Planks and Sticks to make a Pickaxe. + + Hot Topic + Construct a Furnace out of eight Cobblestone blocks. + + Acquire Hardware + Smelt an Iron Ingot. + + Time to Farm! + Make a Hoe. + + Bake Bread + Turn Wheat into Bread. + + The Lie + Bake a Cake using: Wheat, Sugar, Milk and Eggs. + + Getting an Upgrade + Construct a better pickaxe. + + Delicious Fish + Catch and cook Fish! + + On A Rail + Travel by Minecart to a point at least 500m in a single direction from where you started. + + Time to Strike! + Use Planks and Sticks to make a Sword. + + Monster Hunter + Attack and destroy a monster. + + Cow Tipper + Harvest some leather. + + When Pigs Fly + Use a Saddle to ride a Pig, and then have the Pig get hurt from fall damage while riding it. + + Leader of the Pack + Befriend five Wolves. + + MOAR Tools + Construct one type of each tool. + + Dispense With This + Construct a dispenser. + + Into The Nether + Construct a Nether Portal. + + Pork Chop + Cook and eat a Pork Chop. + + Passing the Time + Play for 100 days. + + Archer + Kill a Creeper with Arrows. + + Sniper Duel + Kill a Skeleton with an Arrow from more than 50 meters. + + DIAMONDS! + Acquire diamonds with your iron tools. + + Return to Sender + Destroy a Ghast with a Fireball. + + Into Fire + Relieve a Blaze of its rod. + + Local Brewery + Brew a potion. + + The End? + Enter an End Portal. + + The End. + Kill the Enderdragon. + + Enchanter + Construct an Enchantment Table. + + Overkill + Deal nine hearts of damage in a single hit. + + Librarian + Build some Bookshelves to improve your Enchantment Table. + + Adventuring Time + Discover all biomes. + + Repopulation + Breed two Cows with Wheat. + + Diamonds to you! + Throw diamonds to another player. + + The Haggler + Mine or purchase 30 Emeralds. + + Pot Planter + Craft and place a Flower pot. + + It's a Sign! + Craft and place a sign. + + Iron Belly + Stop starvation using rotten flesh. + + Have a Shearful Day + Use Shears to obtain Wool from a Sheep. + + Rainbow Collection + Gather all 16 colors of Wool. + + Stayin' Frosty + Swim in Lava while having the Fire Resistance effect. + + Chestful of Cobblestone + Mine 1,728 Cobblestone and place it in a Chest. + + Renewable Energy + Smelt Wood Trunks using Charcoal to make more Charcoal. + + Music to my Ears + Play a Music Disc in a Jukebox. + + Body Guard + Create an Iron Golem. + + Iron Man + Wear a full suit of Iron Armor. + + Zombie Doctor + Cure a Zombie Villager. + + Lion Tamer + Tame an ocelot. + + Hold {*CONTROLLER_VK_Y*} to view + + Classic Crafting + + + Restores 5{*ICON_SHANK_01*}. + + + + Safe Sprint] + + + + Swap + + + + Copy Save + + + + Are you sure you want to copy this save game? + + + + Copying Save + + + + Texture Pack + + + + Skin Pack + + + + Add Favorite + + + + Remove Favorite + + diff --git a/Minecraft.Client/Windows64Media/old_strings.h b/Minecraft.Client/Windows64Media/old_strings.h index f87d6e69..de893827 100644 --- a/Minecraft.Client/Windows64Media/old_strings.h +++ b/Minecraft.Client/Windows64Media/old_strings.h @@ -2482,3 +2482,5 @@ #define IDS_RICHPRESENCESTATE_BREWING 2284 #define IDS_RICHPRESENCESTATE_ANVIL 2285 #define IDS_RICHPRESENCESTATE_TRADING 2286 +#define IDS_SAFE_SPRINT 2288 +#define IDS_SWAP 2289 diff --git a/Minecraft.Client/cmake/sources/Windows.cmake b/Minecraft.Client/cmake/sources/Windows.cmake index 5f29fb52..a01142d6 100644 --- a/Minecraft.Client/cmake/sources/Windows.cmake +++ b/Minecraft.Client/cmake/sources/Windows.cmake @@ -181,6 +181,8 @@ set(_MINECRAFT_CLIENT_WINDOWS_COMMON_UI_SCENES_FRONTEND_MENU_SCREENS "${CMAKE_CURRENT_SOURCE_DIR}/Common/UI/UIScene_SaveMessage.h" "${CMAKE_CURRENT_SOURCE_DIR}/Common/UI/UIScene_TrialExitUpsell.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Common/UI/UIScene_TrialExitUpsell.h" + "${CMAKE_CURRENT_SOURCE_DIR}/Common/UI/UIControl_MultiList.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/Common/UI/UIControl_MultiList.h" ) source_group("Common/UI/Scenes/Frontend Menu screens" FILES ${_MINECRAFT_CLIENT_WINDOWS_COMMON_UI_SCENES_FRONTEND_MENU_SCREENS}) @@ -201,8 +203,6 @@ set(_MINECRAFT_CLIENT_WINDOWS_COMMON_UI_SCENES_HELP__OPTIONS "${CMAKE_CURRENT_SOURCE_DIR}/Common/UI/UIScene_ReinstallMenu.h" "${CMAKE_CURRENT_SOURCE_DIR}/Common/UI/UIScene_SettingsAudioMenu.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Common/UI/UIScene_SettingsAudioMenu.h" - "${CMAKE_CURRENT_SOURCE_DIR}/Common/UI/UIScene_SettingsControlMenu.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/Common/UI/UIScene_SettingsControlMenu.h" "${CMAKE_CURRENT_SOURCE_DIR}/Common/UI/UIScene_SettingsGraphicsMenu.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Common/UI/UIScene_SettingsGraphicsMenu.h" "${CMAKE_CURRENT_SOURCE_DIR}/Common/UI/UIScene_SettingsMenu.cpp" diff --git a/Minecraft.Server/cmake/sources/Common.cmake b/Minecraft.Server/cmake/sources/Common.cmake index de12229c..1dd26941 100644 --- a/Minecraft.Server/cmake/sources/Common.cmake +++ b/Minecraft.Server/cmake/sources/Common.cmake @@ -158,6 +158,7 @@ set(_MINECRAFT_SERVER_COMMON_ROOT "${_MS_SRC}/../Minecraft.Client/Common/UI/UIControl_Book.cpp" "${_MS_SRC}/../Minecraft.Client/Common/UI/UIControl_Button.cpp" "${_MS_SRC}/../Minecraft.Client/Common/UI/UIControl_ButtonList.cpp" + "${_MS_SRC}/../Minecraft.Client/Common/UI/UIControl_MultiList.cpp" "${_MS_SRC}/../Minecraft.Client/Common/UI/UIControl_CheckBox.cpp" "${_MS_SRC}/../Minecraft.Client/Common/UI/UIControl_Cursor.cpp" "${_MS_SRC}/../Minecraft.Client/Common/UI/UIControl_DLCList.cpp" @@ -236,7 +237,6 @@ set(_MINECRAFT_SERVER_COMMON_ROOT "${_MS_SRC}/../Minecraft.Client/Common/UI/UIScene_ReinstallMenu.cpp" "${_MS_SRC}/../Minecraft.Client/Common/UI/UIScene_SaveMessage.cpp" "${_MS_SRC}/../Minecraft.Client/Common/UI/UIScene_SettingsAudioMenu.cpp" - "${_MS_SRC}/../Minecraft.Client/Common/UI/UIScene_SettingsControlMenu.cpp" "${_MS_SRC}/../Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.cpp" "${_MS_SRC}/../Minecraft.Client/Common/UI/UIScene_SettingsMenu.cpp" "${_MS_SRC}/../Minecraft.Client/Common/UI/UIScene_SettingsOptionsMenu.cpp" diff --git a/Minecraft.World/AbstractTreeFeature.h b/Minecraft.World/AbstractTreeFeature.h index 37703e55..e6d37e10 100644 --- a/Minecraft.World/AbstractTreeFeature.h +++ b/Minecraft.World/AbstractTreeFeature.h @@ -15,11 +15,11 @@ public: return tile == 0 || tile == Tile::leaves_Id || tile == Tile::leaves2_Id - || tile == Tile::treeTrunk_Id - || tile == Tile::tree2Trunk_Id + || tile == Tile::log_Id + || tile == Tile::log2_Id || tile == Tile::vine_Id || tile == Tile::tallgrass_Id - || tile == Tile::flower_Id; + || tile == Tile::yellow_flower_Id; } void setDirtAt(Level* level, int x, int y, int z) diff --git a/Minecraft.World/Achievements.cpp b/Minecraft.World/Achievements.cpp index c130c032..6773678c 100644 --- a/Minecraft.World/Achievements.cpp +++ b/Minecraft.World/Achievements.cpp @@ -38,7 +38,7 @@ Achievement *Achievements::snipeSkeleton = nullptr; Achievement *Achievements::diamonds = nullptr; //Achievement *Achievements::portal = nullptr; Achievement *Achievements::ghast = nullptr; -Achievement *Achievements::blazeRod = nullptr; +Achievement *Achievements::blaze_rod = nullptr; Achievement *Achievements::potion = nullptr; Achievement *Achievements::theEnd = nullptr; Achievement *Achievements::winGame = nullptr; @@ -92,16 +92,16 @@ void Achievements::staticCtor() Achievements::openInventory = (new Achievement(eAward_TakingInventory, L"openInventory", 0, 0, Item::book, nullptr, "001", IDS_ACHIEVE_NAME_TAKING_INVENTORY, IDS_ACHIEVE_DESC_TAKING_INVENTORY))->setAwardLocallyOnly()->postConstruct(); Achievements::mineWood = (new Achievement(eAward_GettingWood, L"mineWood", 2, 1, Tile::treeTrunk, (Achievement *) openInventory, "002", IDS_ACHIEVE_NAME_GETTING_WOOD, IDS_ACHIEVE_DESC_GETTING_WOOD))->postConstruct(); Achievements::buildWorkbench = (new Achievement(eAward_Benchmarking, L"buildWorkBench", 4, -1, Tile::workBench, (Achievement *) mineWood, "003", IDS_ACHIEVE_NAME_BENCHMARKING, IDS_ACHIEVE_DESC_BENCHMARKING))->postConstruct(); - Achievements::buildPickaxe = (new Achievement(eAward_TimeToMine, L"buildPickaxe", 4, 2, Item::pickAxe_wood, (Achievement *) buildWorkbench, "004", IDS_ACHIEVE_NAME_TIME_TO_MINE, IDS_ACHIEVE_DESC_TIME_TO_MINE))->postConstruct(); + Achievements::buildPickaxe = (new Achievement(eAward_TimeToMine, L"buildPickaxe", 4, 2, Item::wooden_pickaxe, (Achievement *) buildWorkbench, "004", IDS_ACHIEVE_NAME_TIME_TO_MINE, IDS_ACHIEVE_DESC_TIME_TO_MINE))->postConstruct(); Achievements::buildFurnace = (new Achievement(eAward_HotTopic, L"buildFurnace", 3, 4, Tile::furnace_lit, (Achievement *) buildPickaxe, "005", IDS_ACHIEVE_NAME_HOT_TOPIC, IDS_ACHIEVE_DESC_HOT_TOPIC))->postConstruct(); - Achievements::acquireIron = (new Achievement(eAward_AquireHardware, L"acquireIron", 1, 4, Item::ironIngot, (Achievement *) buildFurnace, "006", IDS_ACHIEVE_NAME_ACQUIRE_HARDWARE, IDS_ACHIEVE_DESC_ACQUIRE_HARDWARE))->postConstruct(); - Achievements::buildHoe = (new Achievement(eAward_TimeToFarm, L"buildHoe", 2, -3, Item::hoe_wood, (Achievement *) buildWorkbench, "007", IDS_ACHIEVE_NAME_TIME_TO_FARM, IDS_ACHIEVE_DESC_TIME_TO_FARM))->postConstruct(); + Achievements::acquireIron = (new Achievement(eAward_AquireHardware, L"acquireIron", 1, 4, Item::iron_ingot, (Achievement *) buildFurnace, "006", IDS_ACHIEVE_NAME_ACQUIRE_HARDWARE, IDS_ACHIEVE_DESC_ACQUIRE_HARDWARE))->postConstruct(); + Achievements::buildHoe = (new Achievement(eAward_TimeToFarm, L"buildHoe", 2, -3, Item::wooden_hoe, (Achievement *) buildWorkbench, "007", IDS_ACHIEVE_NAME_TIME_TO_FARM, IDS_ACHIEVE_DESC_TIME_TO_FARM))->postConstruct(); Achievements::makeBread = (new Achievement(eAward_BakeBread, L"makeBread", -1, -3, Item::bread, (Achievement *) buildHoe, "008", IDS_ACHIEVE_NAME_BAKE_BREAD, IDS_ACHIEVE_DESC_BAKE_BREAD))->postConstruct(); Achievements::bakeCake = (new Achievement(eAward_TheLie, L"bakeCake", 0, -5, Item::cake, (Achievement *) buildHoe, "009", IDS_ACHIEVE_NAME_THE_LIE, IDS_ACHIEVE_DESC_THE_LIE))->postConstruct(); - Achievements::buildBetterPickaxe = (new Achievement(eAward_GettingAnUpgrade, L"buildBetterPickaxe", 6, 2, Item::pickAxe_stone, (Achievement *) buildPickaxe, "010", IDS_ACHIEVE_NAME_GETTING_AN_UPGRADE, IDS_ACHIEVE_DESC_GETTING_AN_UPGRADE))->postConstruct(); - Achievements::cookFish = (new Achievement(eAward_DeliciousFish, L"cookFish", 2, 6, Item::fish_cooked, (Achievement *) buildFurnace, "011", IDS_ACHIEVE_NAME_DELICIOUS_FISH, IDS_ACHIEVE_DESC_DELICIOUS_FISH))->postConstruct(); + Achievements::buildBetterPickaxe = (new Achievement(eAward_GettingAnUpgrade, L"buildBetterPickaxe", 6, 2, Item::stone_pickaxe, (Achievement *) buildPickaxe, "010", IDS_ACHIEVE_NAME_GETTING_AN_UPGRADE, IDS_ACHIEVE_DESC_GETTING_AN_UPGRADE))->postConstruct(); + Achievements::cookFish = (new Achievement(eAward_DeliciousFish, L"cookFish", 2, 6, Item::cooked_fish, (Achievement *) buildFurnace, "011", IDS_ACHIEVE_NAME_DELICIOUS_FISH, IDS_ACHIEVE_DESC_DELICIOUS_FISH))->postConstruct(); Achievements::onARail = (new Achievement(eAward_OnARail, L"onARail", 2, 3, Tile::rail, (Achievement *) acquireIron, "012", IDS_ACHIEVE_NAME_ON_A_RAIL, IDS_ACHIEVE_DESC_ON_A_RAIL))->setGolden()->postConstruct(); - Achievements::buildSword = (new Achievement(eAward_TimeToStrike, L"buildSword", 6, -1, Item::sword_wood, (Achievement *) buildWorkbench, "013", IDS_ACHIEVE_NAME_TIME_TO_STRIKE, IDS_ACHIEVE_DESC_TIME_TO_STRIKE))->postConstruct(); + Achievements::buildSword = (new Achievement(eAward_TimeToStrike, L"buildSword", 6, -1, Item::wooden_sword, (Achievement *) buildWorkbench, "013", IDS_ACHIEVE_NAME_TIME_TO_STRIKE, IDS_ACHIEVE_DESC_TIME_TO_STRIKE))->postConstruct(); Achievements::killEnemy = (new Achievement(eAward_MonsterHunter, L"killEnemy", 8, -1, Item::bone, (Achievement *) buildSword, "014", IDS_ACHIEVE_NAME_MONSTER_HUNTER, IDS_ACHIEVE_DESC_MONSTER_HUNTER))->postConstruct(); Achievements::killCow = (new Achievement(eAward_CowTipper, L"killCow", 7, -3, Item::leather, (Achievement *) buildSword, "015", IDS_ACHIEVE_NAME_COW_TIPPER, IDS_ACHIEVE_DESC_COW_TIPPER))->postConstruct(); Achievements::flyPig = (new Achievement(eAward_WhenPigsFly, L"flyPig", 8, -4, Item::saddle, (Achievement *) killCow, "016", IDS_ACHIEVE_NAME_WHEN_PIGS_FLY, IDS_ACHIEVE_DESC_WHEN_PIGS_FLY))->setGolden()->postConstruct(); @@ -138,18 +138,18 @@ void Achievements::staticCtor() // 4J Stu - These added in 1.0.1, but do not map to any Xbox achievements Achievements::diamonds = (new Achievement(eAward_diamonds, L"diamonds", -1, 5, Item::diamond, (Achievement *) acquireIron, "022", IDS_ACHIEVE_NAME_DIAMONDS, IDS_ACHIEVE_DESC_DIAMONDS) )->postConstruct(); //Achievements::portal = (new Achievement(eAward_portal, L"portal", -1, 7, Tile::obsidian, (Achievement *)diamonds) )->postConstruct(); - Achievements::ghast = (new Achievement(eAward_ghast, L"ghast", -4, 8, Item::ghastTear, (Achievement *)ghast, "023", IDS_ACHIEVE_NAME_GHAST, IDS_ACHIEVE_DESC_GHAST) )->setGolden()->postConstruct(); - Achievements::blazeRod = (new Achievement(eAward_blazeRod, L"blazeRod", 0, 9, Item::blazeRod, (Achievement *)blazeRod, "024", IDS_ACHIEVE_NAME_BLAZEROD, IDS_ACHIEVE_DESC_BLAZEROD) )->postConstruct(); + Achievements::ghast = (new Achievement(eAward_ghast, L"ghast", -4, 8, Item::ghast_tear, (Achievement *)ghast, "023", IDS_ACHIEVE_NAME_GHAST, IDS_ACHIEVE_DESC_GHAST) )->setGolden()->postConstruct(); + Achievements::blaze_rod = (new Achievement(eAward_blazeRod, L"blaze_rod", 0, 9, Item::blaze_rod, (Achievement *)blaze_rod, "024", IDS_ACHIEVE_NAME_BLAZEROD, IDS_ACHIEVE_DESC_BLAZEROD) )->postConstruct(); Achievements::potion = (new Achievement(eAward_potion, L"potion", 2, 8, Item::potion, (Achievement *)potion, "025", IDS_ACHIEVE_NAME_POTION, IDS_ACHIEVE_DESC_POTION) )->postConstruct(); - Achievements::theEnd = (new Achievement(eAward_theEnd, L"theEnd", 3, 10, Item::eyeOfEnder, (Achievement *)theEnd, "026", IDS_ACHIEVE_NAME_THE_END, IDS_ACHIEVE_DESC_THE_END) )->setGolden()->postConstruct(); + Achievements::theEnd = (new Achievement(eAward_theEnd, L"theEnd", 3, 10, Item::eye_of_ender, (Achievement *)theEnd, "026", IDS_ACHIEVE_NAME_THE_END, IDS_ACHIEVE_DESC_THE_END) )->setGolden()->postConstruct(); Achievements::winGame = (new Achievement(eAward_winGame, L"theEnd2", 4, 13, Tile::dragonEgg, (Achievement *)winGame, "027", IDS_ACHIEVE_NAME_WINGAME, IDS_ACHIEVE_DESC_WINGAME) )->setGolden()->postConstruct(); Achievements::enchantments = (new Achievement(eAward_enchantments, L"enchantments", -4, 4, Tile::enchantTable, (Achievement *)enchantments, "028", IDS_ACHIEVE_NAME_ENCHANTMENTS, IDS_ACHIEVE_DESC_ENCHANTMENTS) )->postConstruct(); - // Achievements::overkill = (new Achievement(eAward_overkill, L"overkill", -4, 1, Item::sword_diamond, (Achievement *)enchantments) )->setGolden()->postConstruct(); + // Achievements::overkill = (new Achievement(eAward_overkill, L"overkill", -4, 1, Item::diamond_sword, (Achievement *)enchantments) )->setGolden()->postConstruct(); // Achievements::bookcase = (new Achievement(eAward_bookcase, L"bookcase", -3, 6, Tile::bookshelf, (Achievement *)enchantments) )->postConstruct(); #endif - Achievements::overkill = (new Achievement(eAward_overkill, L"overkill", -4,1, Item::sword_diamond, (Achievement *)enchantments, "029", IDS_ACHIEVE_NAME_OVERKILL, IDS_ACHIEVE_DESC_OVERKILL) )->setGolden()->postConstruct(); + Achievements::overkill = (new Achievement(eAward_overkill, L"overkill", -4,1, Item::diamond_sword, (Achievement *)enchantments, "029", IDS_ACHIEVE_NAME_OVERKILL, IDS_ACHIEVE_DESC_OVERKILL) )->setGolden()->postConstruct(); Achievements::bookcase = (new Achievement(eAward_bookcase, L"bookcase", -3,6, Tile::bookshelf, (Achievement *)enchantments, "030", IDS_ACHIEVE_NAME_BOOKCASE, IDS_ACHIEVE_DESC_BOOKCASE) )->postConstruct(); Achievements::adventuringTime = (new Achievement(eAward_adventuringTime, L"adventuringTime", 0,0, Tile::bookshelf, (Achievement*) nullptr, "031", IDS_ACHIEVE_NAME_ADVENTURING_TIME, IDS_ACHIEVE_DESC_ADVENTURING_TIME) )->setAwardLocallyOnly()->postConstruct(); diff --git a/Minecraft.World/Achievements.h b/Minecraft.World/Achievements.h index f2ff0e73..31e8b47a 100644 --- a/Minecraft.World/Achievements.h +++ b/Minecraft.World/Achievements.h @@ -42,7 +42,7 @@ public: static Achievement *diamonds; //static Achievement *portal; //4J-JEV: Whats this? static Achievement *ghast; - static Achievement *blazeRod; + static Achievement *blaze_rod; static Achievement *potion; static Achievement *theEnd; static Achievement *winGame; diff --git a/Minecraft.World/AddPaintingPacket.cpp b/Minecraft.World/AddPaintingPacket.cpp index f574cbf2..1b3ec14b 100644 --- a/Minecraft.World/AddPaintingPacket.cpp +++ b/Minecraft.World/AddPaintingPacket.cpp @@ -15,6 +15,7 @@ AddPaintingPacket::AddPaintingPacket() z = 0; dir = 0; motive = L""; + placedByPlayer = false; } AddPaintingPacket::AddPaintingPacket(shared_ptr e) @@ -25,6 +26,7 @@ AddPaintingPacket::AddPaintingPacket(shared_ptr e) z = e->zTile; dir = e->dir; motive = e->motive->name; + placedByPlayer = e->placedByPlayer; } void AddPaintingPacket::read(DataInputStream *dis) //throws IOException @@ -35,6 +37,7 @@ void AddPaintingPacket::read(DataInputStream *dis) //throws IOException y = dis->readInt(); z = dis->readInt(); dir = dis->readInt(); + placedByPlayer = dis->readByte() != 0; } void AddPaintingPacket::write(DataOutputStream *dos) //throws IOException @@ -45,6 +48,7 @@ void AddPaintingPacket::write(DataOutputStream *dos) //throws IOException dos->writeInt(y); dos->writeInt(z); dos->writeInt(dir); + dos->writeByte(placedByPlayer ? 1 : 0); } void AddPaintingPacket::handle(PacketListener *listener) @@ -54,5 +58,5 @@ void AddPaintingPacket::handle(PacketListener *listener) int AddPaintingPacket::getEstimatedSize() { - return 24; + return 25; } diff --git a/Minecraft.World/AddPaintingPacket.h b/Minecraft.World/AddPaintingPacket.h index a50c1b77..e42c4863 100644 --- a/Minecraft.World/AddPaintingPacket.h +++ b/Minecraft.World/AddPaintingPacket.h @@ -12,6 +12,7 @@ public: int x, y, z; int dir; wstring motive; + bool placedByPlayer; public: AddPaintingPacket(); diff --git a/Minecraft.World/AgableMob.cpp b/Minecraft.World/AgableMob.cpp index 892a14e5..1f587745 100644 --- a/Minecraft.World/AgableMob.cpp +++ b/Minecraft.World/AgableMob.cpp @@ -17,7 +17,7 @@ bool AgableMob::mobInteract(shared_ptr player) { shared_ptr item = player->inventory->getSelected(); - if (item != nullptr && item->id == Item::spawnEgg_Id) + if (item != nullptr && item->id == Item::spawn_egg_Id) { if (!level->isClientSide) { diff --git a/Minecraft.World/AnvilMenu.cpp b/Minecraft.World/AnvilMenu.cpp index 78d72daf..1affd424 100644 --- a/Minecraft.World/AnvilMenu.cpp +++ b/Minecraft.World/AnvilMenu.cpp @@ -78,7 +78,7 @@ void AnvilMenu::createResult() if (addition != nullptr) { - usingBook = addition->id == Item::enchantedBook_Id && Item::enchantedBook->getEnchantments(addition)->size() > 0; + usingBook = addition->id == Item::enchanted_book_Id && Item::enchanted_book->getEnchantments(addition)->size() > 0; if (result->isDamageableItem() && Item::items[result->id]->isValidRepairItem(input, addition)) { @@ -147,7 +147,7 @@ void AnvilMenu::createResult() int extra = level - current; bool compatible = enchantment->canEnchant(input); - if (player->abilities.instabuild || input->id == EnchantedBookItem::enchantedBook_Id) compatible = true; + if (player->abilities.instabuild || input->id == EnchantedBookItem::enchanted_book_Id) compatible = true; for (auto& it2 : *enchantments) { diff --git a/Minecraft.World/ArmorDyeRecipe.cpp b/Minecraft.World/ArmorDyeRecipe.cpp index d4581182..fa2568c7 100644 --- a/Minecraft.World/ArmorDyeRecipe.cpp +++ b/Minecraft.World/ArmorDyeRecipe.cpp @@ -27,7 +27,7 @@ bool ArmorDyeRecipe::matches(shared_ptr craftSlots, Level *le return false; } } - else if (item->id == Item::dye_powder_Id) + else if (item->id == Item::dye_Id) { dyes.push_back(item); } @@ -83,7 +83,7 @@ shared_ptr ArmorDyeRecipe::assembleDyedArmor(shared_ptrid == Item::dye_powder_Id) + else if (item->id == Item::dye_Id) { int tileData = ColoredTile::getTileDataForItemAuxValue(item->getAuxValue()); int red = static_cast(Sheep::COLOR[tileData][0] * 0xFF); diff --git a/Minecraft.World/ArmorItem.cpp b/Minecraft.World/ArmorItem.cpp index 1850c202..e92c6695 100644 --- a/Minecraft.World/ArmorItem.cpp +++ b/Minecraft.World/ArmorItem.cpp @@ -107,15 +107,15 @@ int _ArmorMaterial::getTierItemId() const } else if (this == CHAIN) { - return Item::ironIngot_Id; + return Item::iron_ingot_Id; } else if (this == GOLD) { - return Item::goldIngot_Id; + return Item::gold_ingot_Id; } else if (this == IRON) { - return Item::ironIngot_Id; + return Item::iron_ingot_Id; } else if (this == DIAMOND) { @@ -289,13 +289,13 @@ Icon *ArmorItem::getEmptyIcon(int slot) switch (slot) { case 0: - return Item::helmet_diamond->iconEmpty; + return Item::diamond_helmet->iconEmpty; case 1: - return Item::chestplate_diamond->iconEmpty; + return Item::diamond_chestplate->iconEmpty; case 2: - return Item::leggings_diamond->iconEmpty; + return Item::diamond_leggings->iconEmpty; case 3: - return Item::boots_diamond->iconEmpty; + return Item::diamond_boots->iconEmpty; } return nullptr; diff --git a/Minecraft.World/ArmorRecipes.cpp b/Minecraft.World/ArmorRecipes.cpp index 0717e694..07fae9cd 100644 --- a/Minecraft.World/ArmorRecipes.cpp +++ b/Minecraft.World/ArmorRecipes.cpp @@ -30,11 +30,11 @@ wstring ArmorRecipes::shapes[][4] = /* ArmorRecipes::map[5] = { - {Item::leather, Tile::fire, Item::ironIngot, Item::diamond, Item::goldIngot}, - {Item::helmet_cloth, Item::helmet_chain, Item::helmet_iron, Item::helmet_diamond, Item::helmet_gold}, - {Item::chestplate_cloth, Item::chestplate_chain, Item::chestplate_iron, Item::chestplate_diamond, Item::chestplate_gold}, - {Item::leggings_cloth, Item::leggings_chain, Item::leggings_iron, Item::leggings_diamond, Item::leggings_gold}, - {Item::boots_cloth, Item::boots_chain, Item::boots_iron, Item::boots_diamond, Item::boots_gold}, + {Item::leather, Tile::fire, Item::iron_ingot, Item::diamond, Item::gold_ingot}, + {Item::helmet_cloth, Item::chainmail_helmet, Item::iron_helmet, Item::diamond_helmet, Item::golden_helmet}, + {Item::chestplate_cloth, Item::chainmail_chestplate, Item::iron_chestplate, Item::diamond_chestplate, Item::golden_chestplate}, + {Item::leggings_cloth, Item::chainmail_leggings, Item::iron_leggings, Item::diamond_leggings, Item::golden_leggings}, + {Item::boots_cloth, Item::chainmail_boots, Item::iron_boots, Item::diamond_boots, Item::golden_boots}, }; */ @@ -45,33 +45,33 @@ void ArmorRecipes::_init() // 4J-PB - removing the chain armour, since we show all possible recipes in the xbox game, and it's not one you can make ADD_OBJECT(map[0],Item::leather); // ADD_OBJECT(map[0],Tile::fire); - ADD_OBJECT(map[0],Item::ironIngot); + ADD_OBJECT(map[0],Item::iron_ingot); ADD_OBJECT(map[0],Item::diamond); - ADD_OBJECT(map[0],Item::goldIngot); + ADD_OBJECT(map[0],Item::gold_ingot); - ADD_OBJECT(map[1],Item::helmet_leather); -// ADD_OBJECT(map[1],Item::helmet_chain); - ADD_OBJECT(map[1],Item::helmet_iron); - ADD_OBJECT(map[1],Item::helmet_diamond); - ADD_OBJECT(map[1],Item::helmet_gold); + ADD_OBJECT(map[1],Item::leather_helmet); +// ADD_OBJECT(map[1],Item::chainmail_helmet); + ADD_OBJECT(map[1],Item::iron_helmet); + ADD_OBJECT(map[1],Item::diamond_helmet); + ADD_OBJECT(map[1],Item::golden_helmet); - ADD_OBJECT(map[2],Item::chestplate_leather); -// ADD_OBJECT(map[2],Item::chestplate_chain); - ADD_OBJECT(map[2],Item::chestplate_iron); - ADD_OBJECT(map[2],Item::chestplate_diamond); - ADD_OBJECT(map[2],Item::chestplate_gold); + ADD_OBJECT(map[2],Item::leather_chestplate); +// ADD_OBJECT(map[2],Item::chainmail_chestplate); + ADD_OBJECT(map[2],Item::iron_chestplate); + ADD_OBJECT(map[2],Item::diamond_chestplate); + ADD_OBJECT(map[2],Item::golden_chestplate); - ADD_OBJECT(map[3],Item::leggings_leather); -// ADD_OBJECT(map[3],Item::leggings_chain); - ADD_OBJECT(map[3],Item::leggings_iron); - ADD_OBJECT(map[3],Item::leggings_diamond); - ADD_OBJECT(map[3],Item::leggings_gold); + ADD_OBJECT(map[3],Item::leather_leggings); +// ADD_OBJECT(map[3],Item::chainmail_leggings); + ADD_OBJECT(map[3],Item::iron_leggings); + ADD_OBJECT(map[3],Item::diamond_leggings); + ADD_OBJECT(map[3],Item::golden_leggings); - ADD_OBJECT(map[4],Item::boots_leather); -// ADD_OBJECT(map[4],Item::boots_chain); - ADD_OBJECT(map[4],Item::boots_iron); - ADD_OBJECT(map[4],Item::boots_diamond); - ADD_OBJECT(map[4],Item::boots_gold); + ADD_OBJECT(map[4],Item::leather_boots); +// ADD_OBJECT(map[4],Item::chainmail_boots); + ADD_OBJECT(map[4],Item::iron_boots); + ADD_OBJECT(map[4],Item::diamond_boots); + ADD_OBJECT(map[4],Item::golden_boots); } // 4J-PB added for quick equip in the inventory @@ -79,37 +79,37 @@ ArmorRecipes::_eArmorType ArmorRecipes::GetArmorType(int iId) { switch(iId) { - case Item::helmet_leather_Id: - case Item::helmet_chain_Id: - case Item::helmet_iron_Id: - case Item::helmet_diamond_Id: - case Item::helmet_gold_Id: + case Item::leather_helmet_Id: + case Item::chainmail_helmet_Id: + case Item::iron_helmet_Id: + case Item::diamond_helmet_Id: + case Item::golden_helmet_Id: return eArmorType_Helmet; break; - case Item::chestplate_leather_Id: - case Item::chestplate_chain_Id: - case Item::chestplate_iron_Id: - case Item::chestplate_diamond_Id: - case Item::chestplate_gold_Id: + case Item::leather_chestplate_Id: + case Item::chainmail_chestplate_Id: + case Item::iron_chestplate_Id: + case Item::diamond_chestplate_Id: + case Item::golden_chestplate_Id: case Item::elytra_Id: return eArmorType_Chestplate; break; - case Item::leggings_leather_Id: - case Item::leggings_chain_Id: - case Item::leggings_iron_Id: - case Item::leggings_diamond_Id: - case Item::leggings_gold_Id: + case Item::leather_leggings_Id: + case Item::chainmail_leggings_Id: + case Item::iron_leggings_Id: + case Item::diamond_leggings_Id: + case Item::golden_leggings_Id: return eArmorType_Leggings; break; - case Item::boots_leather_Id: - case Item::boots_chain_Id: - case Item::boots_iron_Id: - case Item::boots_diamond_Id: - case Item::boots_gold_Id: + case Item::leather_boots_Id: + case Item::chainmail_boots_Id: + case Item::iron_boots_Id: + case Item::diamond_boots_Id: + case Item::golden_boots_Id: return eArmorType_Boots; break; } diff --git a/Minecraft.World/ArrayWithLength.h b/Minecraft.World/ArrayWithLength.h index ab491aa8..414129bb 100644 --- a/Minecraft.World/ArrayWithLength.h +++ b/Minecraft.World/ArrayWithLength.h @@ -10,8 +10,26 @@ template class arrayWithLength public: T *data; unsigned int length; - arrayWithLength() { data = nullptr; length = 0; } - arrayWithLength(unsigned int elements, bool bClearArray=true) { assert(elements!=0); data = new T[elements]; if(bClearArray){ memset( data,0,sizeof(T)*elements); } this->length = elements; } + + arrayWithLength() { + data = nullptr; + length = 0; + + } + arrayWithLength(unsigned int elements, bool bClearArray=true) { + if (elements == 0) { + data = nullptr; + length = 0; + return; + } + data = new T[elements]; + + if(bClearArray) + { + memset(data, 0, sizeof(T) * elements); + } + this->length = elements; + } // 4J Stu Added this ctor so I static init arrays in the Item derivation tree arrayWithLength( T data[], unsigned int elements) { this->data = data; this->length = elements; } diff --git a/Minecraft.World/BarrierTile.cpp b/Minecraft.World/BarrierTile.cpp index 64a6287f..a41158a7 100644 --- a/Minecraft.World/BarrierTile.cpp +++ b/Minecraft.World/BarrierTile.cpp @@ -3,6 +3,7 @@ BarrierTile::BarrierTile(int id, Material *material, bool allowSame) : HalfTransparentTile(id, L"barrier", material, allowSame) { + setLightBlock(0); } int BarrierTile::getResourceCount(Random *random) diff --git a/Minecraft.World/BaseEntityTile.cpp b/Minecraft.World/BaseEntityTile.cpp index 7dc06f77..5c8e86ea 100644 --- a/Minecraft.World/BaseEntityTile.cpp +++ b/Minecraft.World/BaseEntityTile.cpp @@ -6,6 +6,7 @@ BaseEntityTile::BaseEntityTile(int id, Material *material, bool isSolidRender /*= true*/) : Tile(id, material, isSolidRender) { + setLightBlock(0); _isEntityTile = true; } diff --git a/Minecraft.World/BasePressurePlateTile.cpp b/Minecraft.World/BasePressurePlateTile.cpp index cd4c821c..2a47c965 100644 --- a/Minecraft.World/BasePressurePlateTile.cpp +++ b/Minecraft.World/BasePressurePlateTile.cpp @@ -11,11 +11,38 @@ BasePressurePlateTile::BasePressurePlateTile(int id, const wstring &tex, Materia { texture = tex; setTicking(true); + setLightBlock(0); // 4J Stu - Move this to derived classes //updateShape(getDataForSignal(Redstone::SIGNAL_MAX)); } +void BasePressurePlateTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int BasePressurePlateTile::defaultBlockState() +{ + return 0; +} + +int BasePressurePlateTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState BasePressurePlateTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState BasePressurePlateTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + void BasePressurePlateTile::updateShape(LevelSource *level, int x, int y, int z, int forceData, shared_ptr forceEntity) { updateShape(level->getData(x, y, z)); diff --git a/Minecraft.World/BasePressurePlateTile.h b/Minecraft.World/BasePressurePlateTile.h index c0870dab..b094263b 100644 --- a/Minecraft.World/BasePressurePlateTile.h +++ b/Minecraft.World/BasePressurePlateTile.h @@ -12,6 +12,11 @@ protected: public: virtual void updateShape(LevelSource *level, int x, int y, int z, int forceData = -1, shared_ptr forceEntity = shared_ptr()); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); protected: virtual void updateShape(int data); diff --git a/Minecraft.World/BaseRailTile.cpp b/Minecraft.World/BaseRailTile.cpp index 0494e266..bcafc7d0 100644 --- a/Minecraft.World/BaseRailTile.cpp +++ b/Minecraft.World/BaseRailTile.cpp @@ -32,6 +32,36 @@ BaseRailTile::Rail::Rail(Level *level, int x, int y, int z) } } +void BaseRailTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int BaseRailTile::defaultBlockState() +{ + return 0; +} + +int BaseRailTile::convertBlockStateToLegacyData(BlockState *state) +{ + if (!state) return 0; + int mask = RAIL_DIRECTION_MASK | (usesDataBit ? RAIL_DATA_BIT : 0); + return state->value & mask; +} + +Tile::BlockState BaseRailTile::getBlockState(int data) +{ + int mask = RAIL_DIRECTION_MASK | (usesDataBit ? RAIL_DATA_BIT : 0); + return Tile::BlockState(data & mask); +} + +Tile::BlockState BaseRailTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + int mask = RAIL_DIRECTION_MASK | (usesDataBit ? RAIL_DATA_BIT : 0); + return Tile::BlockState(level->getData(x, y, z) & mask); +} + BaseRailTile::Rail::~Rail() { for( size_t i = 0; i < connections.size(); i++ ) @@ -351,7 +381,7 @@ bool BaseRailTile::isRail(Level *level, int x, int y, int z) bool BaseRailTile::isRail(int id) { - return id == Tile::rail_Id || id == Tile::goldenRail_Id || id == Tile::detectorRail_Id || id == Tile::activatorRail_Id; + return id == Tile::rail_Id || id == Tile::golden_rail_Id || id == Tile::detector_rail_Id || id == Tile::activator_rail_Id; } BaseRailTile::BaseRailTile(int id, bool usesDataBit) : Tile(id, Material::decoration, isSolidRender()) diff --git a/Minecraft.World/BaseRailTile.h b/Minecraft.World/BaseRailTile.h index 105ddfde..2e8f639e 100644 --- a/Minecraft.World/BaseRailTile.h +++ b/Minecraft.World/BaseRailTile.h @@ -65,6 +65,11 @@ protected: BaseRailTile(int id, bool usesDataBit); public: using Tile::getResourceCount; + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); bool isUsesDataBit(); virtual AABB *getAABB(Level *level, int x, int y, int z); diff --git a/Minecraft.World/BasicTree.cpp b/Minecraft.World/BasicTree.cpp index fc08a5f7..60fe5f08 100644 --- a/Minecraft.World/BasicTree.cpp +++ b/Minecraft.World/BasicTree.cpp @@ -342,18 +342,18 @@ void BasicTree::makeTrunk() int z = origin[2]; int startCoord[] = { x, startY, z }; int endCoord[] = { x, topY, z }; - limb(startCoord, endCoord, Tile::treeTrunk_Id); + limb(startCoord, endCoord, Tile::log_Id); if (trunkWidth == 2) { startCoord[0] += 1; endCoord[0] += 1; - limb(startCoord, endCoord, Tile::treeTrunk_Id); + limb(startCoord, endCoord, Tile::log_Id); startCoord[2] += 1; endCoord[2] += 1; - limb(startCoord, endCoord, Tile::treeTrunk_Id); + limb(startCoord, endCoord, Tile::log_Id); startCoord[0] += -1; endCoord[0] += -1; - limb(startCoord, endCoord, Tile::treeTrunk_Id); + limb(startCoord, endCoord, Tile::log_Id); } } @@ -373,7 +373,7 @@ void BasicTree::makeBranches() int localY = baseCoord[1] - origin[1]; if (trimBranches(localY)) { - limb(baseCoord, endCoord, Tile::treeTrunk_Id); + limb(baseCoord, endCoord, Tile::log_Id); } idx++; } diff --git a/Minecraft.World/BasicTypeContainers.cpp b/Minecraft.World/BasicTypeContainers.cpp index ba2359d8..7850d7f4 100644 --- a/Minecraft.World/BasicTypeContainers.cpp +++ b/Minecraft.World/BasicTypeContainers.cpp @@ -16,7 +16,7 @@ const double Double::MAX_VALUE = DBL_MAX; const double Double::MIN_NORMAL = DBL_MIN; -int Integer::parseInt(wstring &str, int radix /* = 10*/) +int Integer::parseInt(const wstring &str, int radix /* = 10*/) { return wcstol( str.c_str(), nullptr, radix ); } \ No newline at end of file diff --git a/Minecraft.World/BasicTypeContainers.h b/Minecraft.World/BasicTypeContainers.h index d2936ebe..656847a8 100644 --- a/Minecraft.World/BasicTypeContainers.h +++ b/Minecraft.World/BasicTypeContainers.h @@ -19,7 +19,7 @@ class Integer { public: static const int MAX_VALUE = INT_MAX; - static int parseInt(wstring &str, int radix = 10); + static int parseInt(const wstring &str, int radix = 10); }; class Float diff --git a/Minecraft.World/BeaconMenu.cpp b/Minecraft.World/BeaconMenu.cpp index f88ded24..ab63639e 100644 --- a/Minecraft.World/BeaconMenu.cpp +++ b/Minecraft.World/BeaconMenu.cpp @@ -152,7 +152,7 @@ bool BeaconMenu::PaymentSlot::mayPlace(shared_ptr item) { if (item != nullptr) { - return (item->id == Item::emerald_Id || item->id == Item::diamond_Id || item->id == Item::goldIngot_Id || item->id == Item::ironIngot_Id); + return (item->id == Item::emerald_Id || item->id == Item::diamond_Id || item->id == Item::gold_ingot_Id || item->id == Item::iron_ingot_Id); } return false; } diff --git a/Minecraft.World/BeaconTileEntity.cpp b/Minecraft.World/BeaconTileEntity.cpp index 633930f4..5207fe28 100644 --- a/Minecraft.World/BeaconTileEntity.cpp +++ b/Minecraft.World/BeaconTileEntity.cpp @@ -131,7 +131,7 @@ void BeaconTileEntity::updateShape() for (int lz = z - step; lz <= z + step; lz++) { int tile = level->getTile(lx, ly, lz); - if (tile != Tile::emeraldBlock_Id && tile != Tile::goldBlock_Id && tile != Tile::diamondBlock_Id && tile != Tile::ironBlock_Id) + if (tile != Tile::emerald_block_Id && tile != Tile::gold_block_Id && tile != Tile::diamond_block_Id && tile != Tile::iron_block_Id) { isOk = false; break; @@ -373,5 +373,5 @@ void BeaconTileEntity::stopOpen() bool BeaconTileEntity::canPlaceItem(int slot, shared_ptr item) { - return (item->id == Item::emerald_Id || item->id == Item::diamond_Id || item->id == Item::goldIngot_Id || item->id == Item::ironIngot_Id); + return (item->id == Item::emerald_Id || item->id == Item::diamond_Id || item->id == Item::gold_ingot_Id || item->id == Item::iron_ingot_Id); } \ No newline at end of file diff --git a/Minecraft.World/BedTile.cpp b/Minecraft.World/BedTile.cpp index 5597f740..542e1419 100644 --- a/Minecraft.World/BedTile.cpp +++ b/Minecraft.World/BedTile.cpp @@ -21,6 +21,32 @@ BedTile::BedTile(int id) : DirectionalTile(id, Material::cloth, isSolidRender()) iconTop = nullptr; } +void BedTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int BedTile::defaultBlockState() +{ + return 0; +} + +int BedTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState BedTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState BedTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + // 4J Added override void BedTile::updateDefaultShape() { diff --git a/Minecraft.World/BedTile.h b/Minecraft.World/BedTile.h index 0e54ba36..1216f9cd 100644 --- a/Minecraft.World/BedTile.h +++ b/Minecraft.World/BedTile.h @@ -23,6 +23,11 @@ public: static int HEAD_DIRECTION_OFFSETS[4][2]; BedTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void updateDefaultShape(); virtual bool TestUse(Level *level, int x, int y, int z, shared_ptr player); diff --git a/Minecraft.World/Biome.cpp b/Minecraft.World/Biome.cpp index f35769db..efd6014d 100644 --- a/Minecraft.World/Biome.cpp +++ b/Minecraft.World/Biome.cpp @@ -109,9 +109,10 @@ void Biome::staticCtor() Biome::smallerExtremeHills = (new ExtremeHillsBiome(20))->setColor(0x72789a)->setName(L"Extreme Hills Edge")->setDepthAndScale(0.2f, 0.8f)->setTemperatureAndDownfall(0.2f, 0.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHillsEdge, eMinecraftColour_Foliage_ExtremeHillsEdge, eMinecraftColour_Water_ExtremeHillsEdge,eMinecraftColour_Sky_ExtremeHillsEdge); Biome::jungle = (new JungleBiome(21, false))->setColor(0x537b09)->setName(L"Jungle")->setLeafColor(0x537b09)->setTemperatureAndDownfall(1.2f, 0.9f)->setDepthAndScale(0.2f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Jungle, eMinecraftColour_Foliage_Jungle, eMinecraftColour_Water_Jungle,eMinecraftColour_Sky_Jungle); Biome::jungleHills = (new JungleBiome(22, false))->setColor(0x2c4205)->setName(L"Jungle Hills")->setLeafColor(0x537b09)->setTemperatureAndDownfall(1.2f, 0.9f)->setDepthAndScale(1.8f, 0.5f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_JungleHills, eMinecraftColour_Foliage_JungleHills, eMinecraftColour_Water_JungleHills,eMinecraftColour_Sky_JungleHills); - Biome::jungleEdge = (new JungleBiome(23, true))->setColor(0x6458135)->setName(L"Jungle Edge")->setLeafColor(0x5470985)->setTemperatureAndDownfall(0.95F, 0.8F); + Biome::jungleEdge = (new JungleBiome(23, true))->setColor(0x628b17)->setName(L"Jungle Edge")->setLeafColor(0x537b09)->setTemperatureAndDownfall(0.95F, 0.8F)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Jungle, eMinecraftColour_Foliage_Jungle, eMinecraftColour_Water_JungleEdge,eMinecraftColour_Sky_JungleEdge); Biome::deepOcean= (new OceanBiome(24))->setName(L"Deep Ocean")->setDepthAndScale(-1.8,0.1f)->setColor(0x000070)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Ocean, eMinecraftColour_Foliage_Ocean, eMinecraftColour_Water_Ocean,eMinecraftColour_Sky_Ocean);; //public static final BiomeGenBase stoneBeach = (new BiomeGenStoneBeach(25)).setColor(10658436).setBiomeName("Stone Beach").setTemperatureRainfall(0.2F, 0.3F).setHeight(height_RockyWaters); + Biome::stoneBeach = (new StoneBeachBiome(25))->setColor(0xa2a284)->setName(L"Stone Beach")->setTemperatureAndDownfall(0.2f, 0.3f)->setDepthAndScale(0.1f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Beach, eMinecraftColour_Foliage_Beach, eMinecraftColour_Water_Beach, eMinecraftColour_Sky_Beach); Biome::coldBeach = (new BeachBiome(26))->setColor(0xFAF0C0)->setName(L"Cold Beach")->setTemperatureAndDownfall(0.05F, 0.3F)->setDepthAndScale(0.0F, 0.025F)->setSnowCovered()->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_IcePlains, eMinecraftColour_Foliage_IcePlains, eMinecraftColour_Water_IcePlains, eMinecraftColour_Sky_IcePlains); Biome::birchForest=(new ForestBiome(27, 2))->setColor(0x307444)->setName(L"Birch Forest")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Forest, eMinecraftColour_Foliage_Birch, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest); Biome::birchForestHills=(new ForestBiome(28, 2))->setColor(0x1f5f32)->setName(L"Birch Forest Hills")->setDepthAndScale(0.45f, 0.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ForestHills, eMinecraftColour_Foliage_Birch, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_ForestHills); @@ -137,7 +138,7 @@ void Biome::staticCtor() Biome::swamplandM = (new SwampBiome(134))->setColor(0x07F9B2)->setName(L"Swampland M")->setLeafColor(0x8BAF48)->setDepthAndScale(-0.1f, 0.3f)->setTemperatureAndDownfall(0.8f, 0.9f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Swampland, eMinecraftColour_Foliage_Swampland, eMinecraftColour_Water_Swampland,eMinecraftColour_Sky_Swampland); Biome::iceSpikes = (new IceBiome(140,true))->setColor(0xffffff)->setName(L"Ice Spikes")->setSnowCovered()->setTemperatureAndDownfall(0, 0.5f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_IcePlains, eMinecraftColour_Foliage_IcePlains, eMinecraftColour_Water_IcePlains,eMinecraftColour_Sky_IcePlains); Biome::jungleM = (new JungleBiome(149, false))->setColor(0x537b09)->setName(L"Jungle M")->setLeafColor(0x537b09)->setTemperatureAndDownfall(1.2f, 0.9f)->setDepthAndScale(0.2f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Jungle, eMinecraftColour_Foliage_Jungle, eMinecraftColour_Water_Jungle,eMinecraftColour_Sky_Jungle); - Biome::jungleEdgeM = (new JungleBiome(151, true))->setColor(0x6458135)->setName(L"Jungle Edge M")->setLeafColor(0x5470985)->setTemperatureAndDownfall(0.95F, 0.8F); + Biome::jungleEdgeM = (new JungleBiome(151, true))->setColor(0x628b17)->setName(L"Jungle Edge M")->setLeafColor(0x537b09)->setTemperatureAndDownfall(0.95F, 0.8F)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Jungle, eMinecraftColour_Foliage_Jungle, eMinecraftColour_Water_JungleEdge, eMinecraftColour_Sky_JungleEdge); Biome::birchForestM=(new ForestBiome::MutatedBirchForestBiome(155, biomes[27]))->setColor(0x47875a)->setName(L"Birch Forest M")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Forest, eMinecraftColour_Foliage_Birch, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest); Biome::birchForestHillsM=(new ForestBiome::MutatedBirchForestBiome(156, biomes[28]))->setColor(0x47875a)->setName(L"Birch Forest Hills M")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ForestHills, eMinecraftColour_Foliage_Birch, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_ForestHills); Biome::roofedForestM=(new ForestBiome::MutatedForestBiome(157, biomes[29]))->setColor(0x177a35)->setName(L"Roofed Forest M")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_RoofedForest, eMinecraftColour_Foliage_RoofedForest, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest); @@ -410,7 +411,7 @@ void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlock if (y <= 1 + random->nextInt(2)) { - chunkBlocks[index] = static_cast(Tile::unbreakable_Id); + chunkBlocks[index] = static_cast(Tile::bedrock_Id); continue; } @@ -444,7 +445,7 @@ void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlock if (this->getTemperature(x, y, z) < 0.15f) topState = static_cast(Tile::ice_Id); else - topState = static_cast(Tile::calmWater_Id); + topState = static_cast(Tile::water_Id); topStateData = 0; } @@ -482,7 +483,7 @@ void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlock } else { - fillerState = static_cast(Tile::sandStone_Id); + fillerState = static_cast(Tile::sandstone_Id); fillerStateData = 0; } } @@ -542,9 +543,9 @@ Feature *Biome::getFlowerFeature(Random *random, int x, int y, int z) if (random->nextInt(3) > 0) { - return new FlowerFeature(Tile::flower_Id); + return new FlowerFeature(Tile::yellow_flower_Id); } - return new FlowerFeature(Tile::rose_Id); + return new FlowerFeature(Tile::red_flower_Id); } int Biome::getRandomDoublePlantType(Random *random) diff --git a/Minecraft.World/BiomeDecorator.cpp b/Minecraft.World/BiomeDecorator.cpp index f6577572..4f586d57 100644 --- a/Minecraft.World/BiomeDecorator.cpp +++ b/Minecraft.World/BiomeDecorator.cpp @@ -49,19 +49,19 @@ void BiomeDecorator::_init() gravelFeature = new SandFeature(6, Tile::gravel_Id); dirtOreFeature = new OreFeature(Tile::dirt_Id, 32); gravelOreFeature = new OreFeature(Tile::gravel_Id, 32); - coalOreFeature = new OreFeature(Tile::coalOre_Id, 16); - ironOreFeature = new OreFeature(Tile::ironOre_Id, 8); - goldOreFeature = new OreFeature(Tile::goldOre_Id, 8); - redStoneOreFeature = new OreFeature(Tile::redStoneOre_Id, 7); - diamondOreFeature = new OreFeature(Tile::diamondOre_Id, 7); - lapisOreFeature = new OreFeature(Tile::lapisOre_Id, 6); + coalOreFeature = new OreFeature(Tile::coal_ore_Id, 16); + ironOreFeature = new OreFeature(Tile::iron_ore_Id, 8); + goldOreFeature = new OreFeature(Tile::gold_ore_Id, 8); + redStoneOreFeature = new OreFeature(Tile::redstone_ore_Id, 7); + diamondOreFeature = new OreFeature(Tile::diamond_ore_Id, 7); + lapisOreFeature = new OreFeature(Tile::lapis_ore_Id, 6); graniteOreFeature = new OreFeature(Tile::stone_Id, StoneTile::GRANITE, 33); dioriteOreFeature = new OreFeature(Tile::stone_Id, StoneTile::DIORITE, 33); andesiteOreFeature = new OreFeature(Tile::stone_Id, StoneTile::ANDESITE, 33); - yellowFlowerFeature = new FlowerFeature(Tile::flower_Id); - roseFlowerFeature = new FlowerFeature(Tile::rose_Id); + yellowFlowerFeature = new FlowerFeature(Tile::yellow_flower_Id); + roseFlowerFeature = new FlowerFeature(Tile::red_flower_Id); brownMushroomFeature = new FlowerFeature(Tile::mushroom_brown_Id); redMushroomFeature = new FlowerFeature(Tile::mushroom_red_Id); hugeMushroomFeature = new HugeMushroomFeature(); @@ -69,14 +69,14 @@ void BiomeDecorator::_init() cactusFeature = new CactusFeature(); waterlilyFeature = new WaterlilyFeature(); - blueOrchidFeature = new FlowerFeature(Tile::rose_Id, Rose::BLUE_ORCHID); - alliumFeature = new FlowerFeature(Tile::rose_Id, Rose::ALLIUM); - azureBluetFeature = new FlowerFeature(Tile::rose_Id, Rose::AZURE_BLUET); - oxeyeDaisyFeature = new FlowerFeature(Tile::rose_Id, Rose::OXEYE_DAISY); - tulipRedFeature = new FlowerFeature(Tile::rose_Id, Rose::RED_TULIP); - tulipOrangeFeature = new FlowerFeature(Tile::rose_Id, Rose::ORANGE_TULIP); - tulipWhiteFeature = new FlowerFeature(Tile::rose_Id, Rose::WHITE_TULIP); - tulipPinkFeature = new FlowerFeature(Tile::rose_Id, Rose::PINK_TULIP); + blueOrchidFeature = new FlowerFeature(Tile::red_flower_Id, Rose::BLUE_ORCHID); + alliumFeature = new FlowerFeature(Tile::red_flower_Id, Rose::ALLIUM); + azureBluetFeature = new FlowerFeature(Tile::red_flower_Id, Rose::AZURE_BLUET); + oxeyeDaisyFeature = new FlowerFeature(Tile::red_flower_Id, Rose::OXEYE_DAISY); + tulipRedFeature = new FlowerFeature(Tile::red_flower_Id, Rose::RED_TULIP); + tulipOrangeFeature = new FlowerFeature(Tile::red_flower_Id, Rose::ORANGE_TULIP); + tulipWhiteFeature = new FlowerFeature(Tile::red_flower_Id, Rose::WHITE_TULIP); + tulipPinkFeature = new FlowerFeature(Tile::red_flower_Id, Rose::PINK_TULIP); doublePlantFeature = new DoublePlantFeature(false); @@ -241,7 +241,7 @@ void BiomeDecorator::decorate() PIXBeginNamedEvent(0,"Decorate bush/waterlily/mushroom/reeds/pumpkins/cactuses"); DeadBushFeature *deadBushFeature = nullptr; - if(deadBushCount > 0) deadBushFeature = new DeadBushFeature(Tile::deadBush_Id); + if(deadBushCount > 0) deadBushFeature = new DeadBushFeature(Tile::deadbush_Id); for (int i = 0; i < deadBushCount; i++) { int x = xo + random->nextInt(16) + 8; @@ -335,7 +335,7 @@ void BiomeDecorator::decorate() if( liquids ) { - SpringFeature *waterSpringFeature = new SpringFeature(Tile::water_Id); + SpringFeature *waterSpringFeature = new SpringFeature(Tile::flowing_water_Id); for (int i = 0; i < 50; i++) { int x = xo + random->nextInt(16) + 8; @@ -345,7 +345,7 @@ void BiomeDecorator::decorate() } delete waterSpringFeature; - SpringFeature *lavaSpringFeature = new SpringFeature(Tile::lava_Id); + SpringFeature *lavaSpringFeature = new SpringFeature(Tile::flowing_lava_Id); for (int i = 0; i < 20; i++) { int x = xo + random->nextInt(16) + 8; diff --git a/Minecraft.World/BiomeEdgeLayer.cpp b/Minecraft.World/BiomeEdgeLayer.cpp index 97e7024a..2ad5c505 100644 --- a/Minecraft.World/BiomeEdgeLayer.cpp +++ b/Minecraft.World/BiomeEdgeLayer.cpp @@ -1,3 +1,4 @@ +// TODO: fix cold-swampland edge-case scenario #include "stdafx.h" #include "BiomeEdgeLayer.h" #include "net.minecraft.world.level.biome.h" @@ -21,47 +22,92 @@ intArray BiomeEdgeLayer::getArea(int xo, int yo, int w, int h) initRandom(ix + xo, iy + yo); int center = b[(ix + 1) + (iy + 1) * stride]; - if (!checkEdge(b, result, ix, iy, stride, Biome::extremeHills->id, Biome::smallerExtremeHills->id, center) && - !checkEdge(b, result, ix, iy, stride, Biome::mesaPlateauF->id, Biome::mesaPlateau->id, center) && - !checkEdge(b, result, ix, iy, stride, Biome::mesaPlateau->id, Biome::mesaPlateau->id, center) && - !checkEdge(b, result, ix, iy, stride, Biome::megaTaiga->id, Biome::megaTaiga->id, center)) + if (checkEdge(b, result, ix, iy, stride, Biome::extremeHills->id, Biome::smallerExtremeHills->id, center)) + continue; + if (checkEdgeStrict(b, result, ix, iy, stride, Biome::mesaPlateauF->id, Biome::mesa->id, center)) + continue; + if (checkEdgeStrict(b, result, ix, iy, stride, Biome::mesaPlateau->id, Biome::mesa->id, center)) + continue; + if (checkEdgeStrict(b, result, ix, iy, stride, Biome::megaTaiga->id, Biome::taiga->id, center)) + continue; + + int n = b[(ix + 1) + (iy + 0) * stride]; + int e = b[(ix + 2) + (iy + 1) * stride]; + int w1 = b[(ix + 0) + (iy + 1) * stride]; + int s = b[(ix + 1) + (iy + 2) * stride]; + + if (center == Biome::desert->id) { - if (center == Biome::desert->id) { - int n = b[(ix + 1) + (iy + 0) * stride]; - int e = b[(ix + 2) + (iy + 1) * stride]; - int w1 = b[(ix + 0) + (iy + 1) * stride]; - int s = b[(ix + 1) + (iy + 2) * stride]; - if (n == Biome::iceFlats->id || e == Biome::iceFlats->id || w1 == Biome::iceFlats->id || s == Biome::iceFlats->id) { - center = Biome::extremeHills->id; - } - } - result[ix + iy * w] = center; + bool nearIce = (n == Biome::iceFlats->id || e == Biome::iceFlats->id || + w1 == Biome::iceFlats->id || s == Biome::iceFlats->id); + result[ix + iy * w] = nearIce ? Biome::extremeHills_plus->id : center; + } + else if (center == Biome::swampland->id) + { + bool nearDesert = (n == Biome::desert->id || e == Biome::desert->id || w1 == Biome::desert->id || s == Biome::desert->id); + bool nearColdTaiga = (n == Biome::coldTaiga->id || e == Biome::coldTaiga->id || w1 == Biome::coldTaiga->id || s == Biome::coldTaiga->id); + bool nearIceFlats = (n == Biome::iceFlats->id || e == Biome::iceFlats->id || w1 == Biome::iceFlats->id || s == Biome::iceFlats->id); + + if (nearDesert || nearColdTaiga || nearIceFlats) + { + result[ix + iy * w] = Biome::plains->id; + } + else + { + bool nearJungle = (n == Biome::jungle->id || e == Biome::jungle->id || w1 == Biome::jungle->id || s == Biome::jungle->id); + result[ix + iy * w] = nearJungle ? Biome::jungleEdge->id : center; + } + } + else + { + result[ix + iy * w] = center; } } } return result; } -bool BiomeEdgeLayer::checkEdge(intArray& b, intArray& result, int x, int y, int w, int biome, int target, int center) +bool BiomeEdgeLayer::checkEdge(intArray& b, intArray& result, int x, int y, int stride, int biome, int target, int center) +{ + if (!isSame(center, biome)) return false; + + int n = b[(x + 1) + (y + 0) * stride]; + int e = b[(x + 2) + (y + 1) * stride]; + int w1 = b[(x + 0) + (y + 1) * stride]; + int s = b[(x + 1) + (y + 2) * stride]; + + bool interior = isValidTemperatureEdge(n, biome) && isValidTemperatureEdge(e, biome) && + isValidTemperatureEdge(w1, biome) && isValidTemperatureEdge(s, biome); + + result[x + y * (stride - 2)] = interior ? center : target; + return true; +} + +bool BiomeEdgeLayer::checkEdgeStrict(intArray& b, intArray& result, int x, int y, int stride, int biome, int target, int center) { if (center != biome) return false; - int n = b[(x + 1) + (y + 0) * w]; - int e = b[(x + 2) + (y + 1) * w]; - int w1 = b[(x + 0) + (y + 1) * w]; - int s = b[(x + 1) + (y + 2) * w]; + int n = b[(x + 1) + (y + 0) * stride]; + int e = b[(x + 2) + (y + 1) * stride]; + int w1 = b[(x + 0) + (y + 1) * stride]; + int s = b[(x + 1) + (y + 2) * stride]; - if (n != biome || e != biome || w1 != biome || s != biome) + bool interior = isSame(n, biome) && isSame(e, biome) && isSame(w1, biome) && isSame(s, biome); + + result[x + y * (stride - 2)] = interior ? center : target; + return true; +} + +bool BiomeEdgeLayer::isValidTemperatureEdge(int neighbor, int target) +{ + if (isSame(neighbor, target)) return true; + Biome* a = Biome::getBiome(neighbor); + Biome* b = Biome::getBiome(target); + if (a != nullptr && b != nullptr) { - result[x + y * (w-2)] = target; - return true; + int catA = a->getTemperatureCategory(); + int catB = b->getTemperatureCategory(); + return catA == catB || catA == 2 || catB == 2; } return false; -} - -bool BiomeEdgeLayer::isValidTemperatureEdge(int a1biome, int a2biome) -{ - if (a1biome == a2biome) return true; - - return true; -} +} \ No newline at end of file diff --git a/Minecraft.World/BiomeEdgeLayer.h b/Minecraft.World/BiomeEdgeLayer.h index d8ee324a..822e3548 100644 --- a/Minecraft.World/BiomeEdgeLayer.h +++ b/Minecraft.World/BiomeEdgeLayer.h @@ -9,7 +9,7 @@ public: virtual intArray getArea(int xo, int yo, int w, int h) override; private: - static bool isValidTemperatureEdge(int a1biome, int a2biome); + bool isValidTemperatureEdge(int a1biome, int a2biome); bool checkEdge(intArray& b, intArray& result, int x, int y, int w, int biome, int target, int replacement); bool checkEdgeStrict(intArray& b, intArray& result, int x, int y, int w, int biome, int target, int replacement); }; \ No newline at end of file diff --git a/Minecraft.World/BiomeSource.cpp b/Minecraft.World/BiomeSource.cpp index 864a098e..158afe0f 100644 --- a/Minecraft.World/BiomeSource.cpp +++ b/Minecraft.World/BiomeSource.cpp @@ -453,15 +453,8 @@ void BiomeSource::getFracs(intArray indices, float *fracs, float *groupFracs) bool BiomeSource::getIsMatch(float *fracs, float *groupFracs) { if (fracs[0] + fracs[24] > 0.15f) return false; - int varietyCount = 0; for (int i = 0; i < 8; i++) - { - if (groupFracs[i] > 0.0f) - { - varietyCount++; - } - } - + if (groupFracs[i] > 0.0f) varietyCount++; return varietyCount >= 5; } \ No newline at end of file diff --git a/Minecraft.World/BirchFeature.cpp b/Minecraft.World/BirchFeature.cpp index 7a1d0f7a..413c9b2d 100644 --- a/Minecraft.World/BirchFeature.cpp +++ b/Minecraft.World/BirchFeature.cpp @@ -84,7 +84,7 @@ bool BirchFeature::place(Level *level, Random *random, int x, int y, int z) for (int hh = 0; hh < treeHeight; hh++) { int t = level->getTile(x, y + hh, z); - if (t == 0 || t == Tile::leaves_Id) placeBlock(level, x, y + hh, z, Tile::treeTrunk_Id, TreeTile::BIRCH_TRUNK); + if (t == 0 || t == Tile::leaves_Id) placeBlock(level, x, y + hh, z, Tile::log_Id, TreeTile::BIRCH_TRUNK); } return true; } \ No newline at end of file diff --git a/Minecraft.World/Blaze.cpp b/Minecraft.World/Blaze.cpp index c76d4e04..e80c164f 100644 --- a/Minecraft.World/Blaze.cpp +++ b/Minecraft.World/Blaze.cpp @@ -174,7 +174,7 @@ void Blaze::causeFallDamage(float distance) int Blaze::getDeathLoot() { - return Item::blazeRod_Id; + return Item::blaze_rod_Id; } bool Blaze::isOnFire() @@ -189,13 +189,13 @@ void Blaze::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) int count = random->nextInt(2 + playerBonusLevel); for (int i = 0; i < count; i++) { - spawnAtLocation(Item::blazeRod_Id, 1); + spawnAtLocation(Item::blaze_rod_Id, 1); } // 4J-PB - added to the XBLA version due to our limited amount of glowstone in the Nether - drop 0-2 glowstone dust count = random->nextInt(3 + playerBonusLevel); for (int i = 0; i < count; i++) { - spawnAtLocation(Item::yellowDust_Id, 1); + spawnAtLocation(Item::glowstone_dust_Id, 1); } } } diff --git a/Minecraft.World/BlockStateDecoder.cpp b/Minecraft.World/BlockStateDecoder.cpp new file mode 100644 index 00000000..0c6e081b --- /dev/null +++ b/Minecraft.World/BlockStateDecoder.cpp @@ -0,0 +1,782 @@ +// extra file dictating the data mappings in the f3 menu +// e.x. facing: north shows up instead of state: 2 + +#include "BlockStateDecoder.h" +#include "BlockStateDecoderRegistry.h" + +#include "CocoaTile.h" +#include "DirectionalTile.h" +#include "Direction.h" +#include "FireTile.h" +#include "ButtonTile.h" +#include "CropTile.h" +#include "BedTile.h" +#include "FenceGateTile.h" +#include "FenceTile.h" +#include "DoorTile.h" +#include "FlowerPotTile.h" +#include "HalfSlabTile.h" +#include "HayBlockTile.h" +#include "HugeMushroomTile.h" +#include "HopperTile.h" +#include "BrewingStandTile.h" +#include "PistonBaseTile.h" +#include "PistonExtensionTile.h" +#include "LeverTile.h" +#include "TorchTile.h" +#include "FurnaceTile.h" +#include "RedStoneOreTile.h" +#include "NotGateTile.h" +#include "RedlightTile.h" +#include "JukeboxTile.h" +#include "CakeTile.h" +#include "DispenserTile.h" +#include "TntTile.h" +#include "BaseRailTile.h" +#include "NetherStalkTile.h" +#include "ReedTile.h" +#include "RepeaterTile.h" +#include "Sapling.h" +#include "StoneSlabTile.h" +#include "StoneSlabTile2.h" +#include "StairTile.h" +#include "StemTile.h" +#include "TreeTile.h" +#include "TreeTile2.h" +#include "TheEndPortalFrameTile.h" +#include "TrapDoorTile.h" +#include "TripWireTile.h" +#include "WoodSlabTile.h" +#include "TallGrass.h" +#include "TallGrass2.h" +#include "VineTile.h" +#include "Facing.h" + +#include + +using namespace BlockStateDecoder; + +DoorProps BlockStateDecoder::decodeDoor(int composite) +{ + DoorProps p; + p.dir = composite & DoorTile::C_DIR_MASK; + static const std::wstring dirNames[] = { L"south", L"west", L"north", L"east" }; + if (p.dir >= 0 && p.dir < 4) p.dirName = dirNames[p.dir]; else p.dirName = L"unknown"; + p.open = (composite & DoorTile::C_OPEN_MASK) != 0; + p.upper = (composite & DoorTile::C_IS_UPPER_MASK) != 0; + p.hingeRight = (composite & DoorTile::C_RIGHT_HINGE_MASK) != 0; + return p; +} + +std::wstring BlockStateDecoder::doorPropsToString(const DoorProps &p) +{ + std::wstringstream ss; + ss << L"facing: " << p.dirName << L"\n"; + ss << L"open: " << (p.open ? L"true" : L"false") << L"\n"; + ss << L"half: " << (p.upper ? L"upper" : L"lower") << L"\n"; + ss << L"hinge: " << (p.hingeRight ? L"right" : L"left"); + return ss.str(); +} + +static std::wstring agePropsToString(int age) +{ + std::wstringstream ss; + ss << L"age: " << age; + return ss.str(); +} + +static std::wstring cocoaPropsToString(int composite) +{ + int dir = composite & 0x3; + int age = (composite >> 2) & 0x3; + static const std::wstring dirNames[] = { L"south", L"west", L"north", L"east" }; + std::wstring facing = (dir >= 0 && dir < 4) ? dirNames[dir] : L"unknown"; + std::wstringstream ss; + ss << L"facing: " << facing << L"\n"; + ss << L"age: " << age; + return ss.str(); +} + +static std::wstring stemPropsToString(int composite) +{ + int age = composite & 0x7; + int facingCode = (composite >> 3) & 0x7; + static const std::wstring facingNames[] = { L"none", L"west", L"east", L"north", L"south" }; + std::wstring facing = (facingCode >= 0 && facingCode < 5) ? facingNames[facingCode] : L"unknown"; + std::wstringstream ss; + ss << L"age: " << age << L"\n"; + ss << L"facing: " << facing; + return ss.str(); +} + +static std::wstring vinePropsToString(int composite) +{ + std::wstringstream ss; + ss << L"north: " << (((composite & VineTile::VINE_NORTH) != 0) ? L"true" : L"false") << L"\n"; + ss << L"south: " << (((composite & VineTile::VINE_SOUTH) != 0) ? L"true" : L"false") << L"\n"; + ss << L"east: " << (((composite & VineTile::VINE_EAST) != 0) ? L"true" : L"false") << L"\n"; + ss << L"west: " << (((composite & VineTile::VINE_WEST) != 0) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring flowerPotTypeToString(int type) +{ + switch (type) + { + case FlowerPotTile::TYPE_FLOWER_RED: return L"red_flower"; + case FlowerPotTile::TYPE_FLOWER_YELLOW: return L"yellow_flower"; + case FlowerPotTile::TYPE_SAPLING_DEFAULT: return L"sapling_default"; + case FlowerPotTile::TYPE_SAPLING_EVERGREEN: return L"sapling_evergreen"; + case FlowerPotTile::TYPE_SAPLING_BIRCH: return L"sapling_birch"; + case FlowerPotTile::TYPE_SAPLING_JUNGLE: return L"sapling_jungle"; + case FlowerPotTile::TYPE_MUSHROOM_RED: return L"red_mushroom"; + case FlowerPotTile::TYPE_MUSHROOM_BROWN: return L"brown_mushroom"; + case FlowerPotTile::TYPE_CACTUS: return L"cactus"; + case FlowerPotTile::TYPE_DEAD_BUSH: return L"dead_bush"; + case FlowerPotTile::TYPE_FERN: return L"fern"; + default: return L"empty"; + } +} + +static std::wstring flowerPotPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"type: " << flowerPotTypeToString(composite & 0xF); + return ss.str(); +} + +static std::wstring saplingPropsToString(int composite) +{ + int type = composite & 0x7; + bool grown = (composite & 0x8) != 0; + static const std::wstring typeNames[] = { L"oak", L"spruce", L"birch", L"jungle", L"acacia", L"dark_oak" }; + std::wstring typeName = (type >= 0 && type < 6) ? typeNames[type] : L"unknown"; + std::wstringstream ss; + ss << L"type: " << typeName << L"\n"; + ss << L"age: " << (grown ? 1 : 0); + return ss.str(); +} + +static std::wstring tallGrassPropsToString(int composite) +{ + int type = composite & 0x3; + static const std::wstring typeNames[] = { L"dead_shrub", L"tall_grass", L"fern" }; + std::wstring typeName = (type >= 0 && type < 3) ? typeNames[type] : L"unknown"; + std::wstringstream ss; + ss << L"variant: " << typeName; + return ss.str(); +} + +static std::wstring double_plantPropsToString(int composite) +{ + int type = composite & 0x7; + bool upper = (composite & TallGrass2::UPPER_BIT) != 0; + static const std::wstring typeNames[] = { L"sunflower", L"lilac", L"tall_grass", L"large_fern", L"rose_bush", L"peony" }; + std::wstring typeName = (type >= 0 && type < TallGrass2::VARIANT_COUNT) ? typeNames[type] : L"unknown"; + std::wstringstream ss; + ss << L"variant: " << typeName << L"\n"; + ss << L"half: " << (upper ? L"upper" : L"lower"); + return ss.str(); +} + +static std::wstring brewingStandPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"bottle_0: " << (((composite & 0x1) != 0) ? L"true" : L"false") << L"\n"; + ss << L"bottle_1: " << (((composite & 0x2) != 0) ? L"true" : L"false") << L"\n"; + ss << L"bottle_2: " << (((composite & 0x4) != 0) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring jukeboxPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"has_record: " << (((composite & 0x1) != 0) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring daylightDetectorPropsToString(int composite, bool inverted) +{ + std::wstringstream ss; + int power = composite & 0xF; + ss << L"inverted: " << (inverted ? L"true" : L"false") << L"\n"; + ss << L"power: " << power << L"\n"; + ss << L"powered: " << (power > 0 ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring snowPropsToString(int composite) +{ + std::wstringstream ss; + int layers = composite & 0x7; + if (layers == 0) layers = 8; + ss << L"layers: " << layers; + return ss.str(); +} + +static std::wstring cauldronPropsToString(int composite) +{ + std::wstringstream ss; + int level = composite & 0x3; + ss << L"level: " << level; + return ss.str(); +} + +static std::wstring bedPropsToString(int composite) +{ + int dir = DirectionalTile::getDirection(composite); + static const std::wstring dirNames[] = { L"south", L"west", L"north", L"east" }; + std::wstring facing = (dir >= 0 && dir < 4) ? dirNames[dir] : L"unknown"; + bool head = (composite & BedTile::HEAD_PIECE_DATA) != 0; + bool occupied = (composite & BedTile::OCCUPIED_DATA) != 0; + std::wstringstream ss; + ss << L"facing: " << facing << L"\n"; + ss << L"part: " << (head ? L"head" : L"foot") << L"\n"; + ss << L"occupied: " << (occupied ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring railPropsToString(int composite, bool usesDataBit) +{ + int shape = composite & BaseRailTile::RAIL_DIRECTION_MASK; + std::wstring shapeName = L"unknown"; + static const std::wstring shapeNames[] = { + L"north_south", L"east_west", L"ascending_east", L"ascending_west", + L"ascending_north", L"ascending_south", L"south_east", L"south_west", + L"north_west", L"north_east" + }; + if (shape >= 0 && shape < 10) shapeName = shapeNames[shape]; + std::wstringstream ss; + ss << L"shape: " << shapeName; + if (usesDataBit) + { + bool powered = (composite & BaseRailTile::RAIL_DATA_BIT) != 0; + ss << L"\n"; + ss << L"powered: " << (powered ? L"true" : L"false"); + } + return ss.str(); +} + +static std::wstring pressurePlatePropsToString(int composite) +{ + int power = composite & 0xF; + std::wstringstream ss; + ss << L"power: " << power << L"\n"; + ss << L"powered: " << (power > 0 ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring facingToString(int facing) +{ + static const std::wstring facingNames[] = { L"down", L"up", L"north", L"south", L"west", L"east" }; + return (facing >= 0 && facing < 6) ? facingNames[facing] : L"unknown"; +} + + +static std::wstring dispenserPropsToString(int composite) +{ + int facing = composite & DispenserTile::FACING_MASK; + bool triggered = (composite & DispenserTile::TRIGGER_BIT) != 0; + std::wstringstream ss; + ss << L"facing: " << facingToString(facing) << L"\n"; + ss << L"triggered: " << (triggered ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring tntPropsToString(int composite) +{ + bool explode = (composite & TntTile::EXPLODE_BIT) != 0; + std::wstringstream ss; + ss << L"explode: " << (explode ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring cakePropsToString(int composite) +{ + int bites = composite & 0x7; + std::wstringstream ss; + ss << L"bites: " << bites; + return ss.str(); +} + +static std::wstring comparatorPropsToString(int composite) +{ + int dir = DirectionalTile::getDirection(composite); + static const std::wstring dirNames[] = { L"south", L"west", L"north", L"east" }; + std::wstring facing = (dir >= 0 && dir < 4) ? dirNames[dir] : L"unknown"; + bool subtract = (composite & 0x4) != 0; + bool powered = (composite & 0x8) != 0; + std::wstringstream ss; + ss << L"facing: " << facing << L"\n"; + ss << L"mode: " << (subtract ? L"subtract" : L"compare") << L"\n"; + ss << L"powered: " << (powered ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring farmPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"moisture: " << (composite & 0x7); + return ss.str(); +} + +static std::wstring redstoneDustPropsToString(int composite) +{ + std::wstringstream ss; + int power = composite & 0xF; + ss << L"power: " << power << L"\n"; + ss << L"powered: " << (power > 0 ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring firePropsToString(int composite) { + std::wstringstream ss; + ss << L"age: " << (composite & FireTile::AGE_MASK); + return ss.str(); +} + +static std::wstring torchPropsToString(int composite) +{ +int dir = composite & 0x7; +static const std::wstring dirNames[] = { L"up", L"west", L"east", L"south", L"north", L"unknown" }; +std::wstring dirName = (dir >= 0 && dir < 6) ? dirNames[dir > 4 ? 5 : dir] : L"unknown"; +std::wstringstream ss; +ss << L"facing: " << dirName; +return ss.str(); +} + +static std::wstring furnacePropsToString(int composite) +{ +int facing = composite & 0x7; +static const std::wstring facingNames[] = { L"unknown", L"unknown", L"north", L"south", L"west", L"east" }; +std::wstring facingName = (facing >= 2 && facing <= 5) ? facingNames[facing] : L"unknown"; +std::wstringstream ss; +ss << L"facing: " << facingName; +return ss.str(); +} + +static std::wstring redstoneOrePropsToString(int composite) +{ +std::wstringstream ss; +ss << L"lit: " << (((composite & 0x1) != 0) ? L"true" : L"false"); +return ss.str(); +} + +static std::wstring redstoneTorchPropsToString(int composite) +{ +int dir = composite & 0x7; +static const std::wstring dirNames[] = { L"up", L"west", L"east", L"south", L"north", L"unknown" }; +std::wstring dirName = (dir >= 0 && dir < 6) ? dirNames[dir > 4 ? 5 : dir] : L"unknown"; +std::wstringstream ss; +ss << L"facing: " << dirName; +return ss.str(); +} + +static std::wstring redlightPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"lit: " << (((composite & 0x1) != 0) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring buttonFacingToString(int data) +{ + switch (data & 0x7) + { + case 1: return L"east"; + case 2: return L"west"; + case 3: return L"south"; + case 4: return L"north"; + case 5: return L"ceiling"; + case 6: return L"floor"; + default: return L"unknown"; + } +} + +static std::wstring buttonPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"facing: " << buttonFacingToString(composite) << L"\n"; + ss << L"powered: " << (((composite & 0x8) != 0) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring leverFacingToString(int data) +{ + static const std::wstring names[] = { + L"down_south", L"down_east", L"down_west", L"down_north", + L"up_south", L"up_north", L"ceiling_west", L"ceiling_east" + }; + int facing = data & 7; + return (facing >= 0 && facing < 8) ? names[facing] : L"unknown"; +} + +static std::wstring leverPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"facing: " << leverFacingToString(composite) << L"\n"; + ss << L"powered: " << (((composite & 0x8) != 0) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring fenceGatePropsToString(int composite) +{ + int dir = DirectionalTile::getDirection(composite); + static const std::wstring dirNames[] = { L"south", L"west", L"north", L"east" }; + std::wstring facing = (dir >= 0 && dir < 4) ? dirNames[dir] : L"unknown"; + bool powered = (composite & 0x8) != 0; + bool inWall = (composite & 0x10) != 0; + std::wstringstream ss; + ss << L"facing: " << facing << L"\n"; + ss << L"open: " << (FenceGateTile::isOpen(composite) ? L"true" : L"false") << L"\n"; + ss << L"powered: " << (powered ? L"true" : L"false") << L"\n"; + ss << L"in_wall: " << (inWall ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring slabTypeToString(int tileId, int type) +{ + if (tileId == Tile::double_wooden_slab_Id || tileId == Tile::wooden_slab_Id) + { + static const std::wstring typeNames[] = { L"oak", L"spruce", L"birch", L"jungle", L"acacia", L"dark_oak" }; + return (type >= 0 && type < 6) ? typeNames[type] : L"unknown"; + } + + if (tileId == Tile::stone_slab2_Id || tileId == Tile::double_stone_slab2_Id) + { + return (type == StoneSlabTile2::RED_SANDSTONE_SLAB) ? L"red_sandstone" : L"unknown"; + } + + static const std::wstring typeNames[] = { + L"stone", L"sandstone", L"wood", L"cobblestone", + L"brick", L"stone_brick", L"nether_brick", L"quartz" + }; + return (type >= 0 && type < 8) ? typeNames[type] : L"unknown"; +} + +static std::wstring slabPropsToString(int tileId, int composite) +{ + int type = composite & HalfSlabTile::TYPE_MASK; + bool top = (composite & HalfSlabTile::TOP_SLOT_BIT) != 0; + std::wstringstream ss; + ss << L"type: " << slabTypeToString(tileId, type); + if (tileId == Tile::wooden_slab_Id || tileId == Tile::stone_slab_Id || tileId == Tile::stone_slab2_Id) + { + ss << L"\n"; + ss << L"half: " << (top ? L"top" : L"bottom"); + } + else + { + ss << L"\n"; + ss << L"half: double"; + } + return ss.str(); +} + +static std::wstring trapDoorPropsToString(int composite) +{ + int dir = composite & 0x3; + static const std::wstring dirNames[] = { L"north", L"south", L"west", L"east" }; + std::wstring facing = (dir >= 0 && dir < 4) ? dirNames[dir] : L"unknown"; + bool open = (composite & 0x4) != 0; + bool top = (composite & 0x8) != 0; + + std::wstringstream ss; + ss << L"facing: " << facing << L"\n"; + ss << L"open: " << (open ? L"true" : L"false") << L"\n"; + ss << L"half: " << (top ? L"top" : L"bottom"); + return ss.str(); +} + +static std::wstring fencePropsToString(int composite) +{ + std::wstringstream ss; + ss << L"north: " << (((composite & 0x1) != 0) ? L"true" : L"false") << L"\n"; + ss << L"south: " << (((composite & 0x2) != 0) ? L"true" : L"false") << L"\n"; + ss << L"east: " << (((composite & 0x4) != 0) ? L"true" : L"false") << L"\n"; + ss << L"west: " << (((composite & 0x8) != 0) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring axisToString(int composite) +{ + switch (composite & RotatedPillarTile::MASK_FACING) + { + case RotatedPillarTile::FACING_X: return L"x"; + case RotatedPillarTile::FACING_Z: return L"z"; + default: return L"y"; + } +} + +static std::wstring hayBlockPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"axis: " << axisToString(composite); + return ss.str(); +} + +static std::wstring pistonBasePropsToString(int composite) +{ + int facing = PistonBaseTile::getFacing(composite); + std::wstringstream ss; + ss << L"facing: " << facingToString(facing) << L"\n"; + ss << L"extended: " << (PistonBaseTile::isExtended(composite) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring pistonExtensionPropsToString(int composite) +{ + int facing = PistonExtensionTile::getFacing(composite); + std::wstringstream ss; + ss << L"facing: " << facingToString(facing) << L"\n"; + ss << L"type: " << (((composite & PistonExtensionTile::STICKY_BIT) != 0) ? L"sticky" : L"normal"); + return ss.str(); +} + +static std::wstring endPortalFramePropsToString(int composite) +{ + static const std::wstring dirNames[] = { L"south", L"west", L"north", L"east" }; + int facing = composite & 0x3; + std::wstring facingName = (facing >= 0 && facing < 4) ? dirNames[facing] : L"unknown"; + std::wstringstream ss; + ss << L"facing: " << facingName << L"\n"; + ss << L"eye: " << ((composite & TheEndPortalFrameTile::EYE_BIT) != 0 ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring repeaterPropsToString(int composite, bool powered) +{ + int dir = DirectionalTile::getDirection(composite); + static const std::wstring dirNames[] = { L"south", L"west", L"north", L"east" }; + std::wstring facing = (dir >= 0 && dir < 4) ? dirNames[dir] : L"unknown"; + int delay = ((composite & RepeaterTile::DELAY_MASK) >> RepeaterTile::DELAY_SHIFT) + 1; + + std::wstringstream ss; + ss << L"facing: " << facing << L"\n"; + ss << L"delay: " << delay << L"\n"; + ss << L"powered: " << (powered ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring hugeMushroomPropsToString(int composite) +{ + std::wstringstream ss; + ss << L"variant: " << (composite & 0xF); + return ss.str(); +} + +static std::wstring hopperPropsToString(int composite) +{ + int face = HopperTile::getAttachedFace(composite); + static const std::wstring faceNames[] = { L"down", L"up", L"north", L"south", L"west", L"east" }; + std::wstring facing = (face >= 0 && face < 6) ? faceNames[face] : L"unknown"; + bool enabled = HopperTile::isTurnedOn(composite); + + std::wstringstream ss; + ss << L"facing: " << facing << L"\n"; + ss << L"enabled: " << (enabled ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring logBlockPropsToString(int tileId, int composite) +{ + int type = composite & RotatedPillarTile::MASK_TYPE; + std::wstring axis = axisToString(composite); + std::wstring typeName; + + if (tileId == Tile::log_Id) + { + static const std::wstring typeNames[] = { L"oak", L"spruce", L"birch", L"jungle" }; + typeName = (type >= 0 && type < 4) ? typeNames[type] : L"unknown"; + } + else + { + static const std::wstring typeNames[] = { L"acacia", L"dark_oak" }; + typeName = (type >= 0 && type < 2) ? typeNames[type] : L"unknown"; + } + + std::wstringstream ss; + ss << L"type: " << typeName << L"\n"; + ss << L"axis: " << axis; + return ss.str(); +} + +static std::wstring tripWirePropsToString(int composite) +{ + std::wstringstream ss; + ss << L"north: " << (((composite & 0x1) != 0) ? L"true" : L"false") << L"\n"; + ss << L"south: " << (((composite & 0x2) != 0) ? L"true" : L"false") << L"\n"; + ss << L"east: " << (((composite & 0x4) != 0) ? L"true" : L"false") << L"\n"; + ss << L"west: " << (((composite & 0x8) != 0) ? L"true" : L"false") << L"\n"; + ss << L"powered: " << (((composite & TripWireTile::BLOCKSTATE_POWERED_BIT) != 0) ? L"true" : L"false"); + return ss.str(); +} + +static std::wstring tripWireSourcePropsToString(int composite) +{ + int dir = composite & 0x3; + static const std::wstring dirNames[] = { L"north", L"east", L"south", L"west" }; + std::wstring facing = (dir >= 0 && dir < 4) ? dirNames[dir] : L"unknown"; + bool attached = (composite & 0x4) != 0; + bool powered = (composite & 0x8) != 0; + + std::wstringstream ss; + ss << L"facing: " << facing << L"\n"; + ss << L"attached: " << (attached ? L"true" : L"false") << L"\n"; + ss << L"powered: " << (powered ? L"true" : L"false"); + return ss.str(); +} + +static bool registerDoorDecoder() +{ + using namespace BlockStateDecoderRegistry; + DecoderFn fn = [](int composite)->std::wstring { + return BlockStateDecoder::doorPropsToString(BlockStateDecoder::decodeDoor(composite)); + }; + registerDecoder(Tile::wooden_door_Id, fn); + registerDecoder(Tile::iron_door_Id, fn); + registerDecoder(Tile::spruce_door_Id, fn); + registerDecoder(Tile::birch_door_Id, fn); + registerDecoder(Tile::jungle_door_Id, fn); + registerDecoder(Tile::acacia_door_Id, fn); + registerDecoder(Tile::dark_oak_door_Id, fn); + return true; +} + +static bool s_doorDecoderRegistered = registerDoorDecoder(); + +static bool registerStairDecoder() +{ + using namespace BlockStateDecoderRegistry; + DecoderFn fn = [](int composite)->std::wstring { + int dir = composite & 0x3; + static const std::wstring dirNames[] = { L"east", L"west", L"south", L"north" }; + std::wstring facing = (dir >= 0 && dir < 4) ? dirNames[dir] : L"unknown"; + bool upside = (composite & StairTile::UPSIDEDOWN_BIT) != 0; + int shape = (composite >> 3) & 0x7; + std::wstring shapeName = L"straight"; + if (shape == 1) shapeName = L"inner"; + else if (shape == 2) shapeName = L"outer"; + + std::wstringstream ss; + ss << L"facing: " << facing << L"\n"; + ss << L"half: " << (upside ? L"top" : L"bottom") << L"\n"; + ss << L"shape: " << shapeName; + return ss.str(); + }; + + registerDecoder(Tile::oak_stairs_Id, fn); + registerDecoder(Tile::stone_stairs_Id, fn); + registerDecoder(Tile::brick_stairs_Id, fn); + registerDecoder(Tile::stone_brick_stairs_Id, fn); + registerDecoder(Tile::nether_brick_stairs_Id, fn); + registerDecoder(Tile::sandstone_stairs_Id, fn); + registerDecoder(Tile::spruce_stairs_Id, fn); + registerDecoder(Tile::birch_stairs_Id, fn); + registerDecoder(Tile::jungle_stairs_Id, fn); + registerDecoder(Tile::quartz_stairs_Id, fn); + registerDecoder(Tile::acacia_stairs_Id, fn); + registerDecoder(Tile::dark_oak_stairs_Id, fn); + registerDecoder(Tile::red_sandstone_stairs_Id, fn); + return true; +} + +static bool s_stairDecoderRegistered = registerStairDecoder(); + +static bool registerPlantDecoders() +{ + using namespace BlockStateDecoderRegistry; + DecoderFn ageDecoder = [](int composite)->std::wstring { + return agePropsToString(composite); + }; + + registerDecoder(Tile::wheat_Id, ageDecoder); + registerDecoder(Tile::carrots_Id, ageDecoder); + registerDecoder(Tile::potatoes_Id, ageDecoder); + registerDecoder(Tile::cactus_Id, ageDecoder); + registerDecoder(Tile::nether_wart_Id, ageDecoder); + registerDecoder(Tile::reeds_Id, ageDecoder); + registerDecoder(Tile::bed_Id, [](int composite)->std::wstring { return bedPropsToString(composite); }); + registerDecoder(Tile::rail_Id, [](int composite)->std::wstring { return railPropsToString(composite, false); }); + registerDecoder(Tile::golden_rail_Id, [](int composite)->std::wstring { return railPropsToString(composite, true); }); + registerDecoder(Tile::detector_rail_Id, [](int composite)->std::wstring { return railPropsToString(composite, true); }); + registerDecoder(Tile::activator_rail_Id, [](int composite)->std::wstring { return railPropsToString(composite, true); }); + registerDecoder(Tile::dispenser_Id, [](int composite)->std::wstring { return dispenserPropsToString(composite); }); + registerDecoder(Tile::dropper_Id, [](int composite)->std::wstring { return dispenserPropsToString(composite); }); + registerDecoder(Tile::tnt_Id, [](int composite)->std::wstring { return tntPropsToString(composite); }); + registerDecoder(Tile::cake_Id, [](int composite)->std::wstring { return cakePropsToString(composite); }); + registerDecoder(Tile::stone_pressure_plate_Id, [](int composite)->std::wstring { return pressurePlatePropsToString(composite); }); + registerDecoder(Tile::wooden_pressure_plate_Id, [](int composite)->std::wstring { return pressurePlatePropsToString(composite); }); + registerDecoder(Tile::light_weighted_pressure_plate_Id, [](int composite)->std::wstring { return pressurePlatePropsToString(composite); }); + registerDecoder(Tile::heavy_weighted_pressure_plate_Id, [](int composite)->std::wstring { return pressurePlatePropsToString(composite); }); + registerDecoder(Tile::farmland_Id, [](int composite)->std::wstring { return farmPropsToString(composite); }); + registerDecoder(Tile::cocoa_Id, [](int composite)->std::wstring { return cocoaPropsToString(composite); }); + registerDecoder(Tile::brewing_stand_Id, [](int composite)->std::wstring { return brewingStandPropsToString(composite); }); + registerDecoder(Tile::fire_Id, [](int composite)->std::wstring { return firePropsToString(composite); }); + registerDecoder(Tile::stone_button_Id, [](int composite)->std::wstring { return buttonPropsToString(composite); }); + registerDecoder(Tile::wooden_button_Id, [](int composite)->std::wstring { return buttonPropsToString(composite); }); + registerDecoder(Tile::pumpkin_stem_Id, [](int composite)->std::wstring { return stemPropsToString(composite); }); + registerDecoder(Tile::melon_stem_Id, [](int composite)->std::wstring { return stemPropsToString(composite); }); + registerDecoder(Tile::vine_Id, [](int composite)->std::wstring { return vinePropsToString(composite); }); + registerDecoder(Tile::flower_pot_Id, [](int composite)->std::wstring { return flowerPotPropsToString(composite); }); + registerDecoder(Tile::sapling_Id, [](int composite)->std::wstring { return saplingPropsToString(composite); }); + registerDecoder(Tile::tallgrass_Id, [](int composite)->std::wstring { return tallGrassPropsToString(composite); }); + registerDecoder(Tile::double_plant_Id, [](int composite)->std::wstring { return double_plantPropsToString(composite); }); + registerDecoder(Tile::fence_Id, [](int composite)->std::wstring { return fencePropsToString(composite); }); + registerDecoder(Tile::nether_brick_fence_Id, [](int composite)->std::wstring { return fencePropsToString(composite); }); + registerDecoder(Tile::spruce_fence_Id, [](int composite)->std::wstring { return fencePropsToString(composite); }); + registerDecoder(Tile::birch_fence_Id, [](int composite)->std::wstring { return fencePropsToString(composite); }); + registerDecoder(Tile::jungle_fence_Id, [](int composite)->std::wstring { return fencePropsToString(composite); }); + registerDecoder(Tile::dark_oak_fence_Id, [](int composite)->std::wstring { return fencePropsToString(composite); }); + registerDecoder(Tile::acacia_fence_Id, [](int composite)->std::wstring { return fencePropsToString(composite); }); + registerDecoder(Tile::double_stone_slab_Id, [](int composite)->std::wstring { return slabPropsToString(Tile::double_stone_slab_Id, composite); }); + registerDecoder(Tile::stone_slab_Id, [](int composite)->std::wstring { return slabPropsToString(Tile::stone_slab_Id, composite); }); + registerDecoder(Tile::double_wooden_slab_Id, [](int composite)->std::wstring { return slabPropsToString(Tile::double_wooden_slab_Id, composite); }); + registerDecoder(Tile::wooden_slab_Id, [](int composite)->std::wstring { return slabPropsToString(Tile::wooden_slab_Id, composite); }); + registerDecoder(Tile::double_stone_slab2_Id, [](int composite)->std::wstring { return slabPropsToString(Tile::double_stone_slab2_Id, composite); }); + registerDecoder(Tile::stone_slab2_Id, [](int composite)->std::wstring { return slabPropsToString(Tile::stone_slab2_Id, composite); }); + registerDecoder(Tile::trapdoor_Id, [](int composite)->std::wstring { return trapDoorPropsToString(composite); }); + registerDecoder(Tile::iron_trapdoor_Id, [](int composite)->std::wstring { return trapDoorPropsToString(composite); }); + registerDecoder(Tile::tripwire_Id, [](int composite)->std::wstring { return tripWirePropsToString(composite); }); + registerDecoder(Tile::tripwire_hook_Id, [](int composite)->std::wstring { return tripWireSourcePropsToString(composite); }); + registerDecoder(Tile::hay_block_Id, [](int composite)->std::wstring { return hayBlockPropsToString(composite); }); + registerDecoder(Tile::log_Id, [](int composite)->std::wstring { return logBlockPropsToString(Tile::log_Id, composite); }); + registerDecoder(Tile::log2_Id, [](int composite)->std::wstring { return logBlockPropsToString(Tile::log2_Id, composite); }); + registerDecoder(Tile::lever_Id, [](int composite)->std::wstring { return leverPropsToString(composite); }); + registerDecoder(Tile::piston_Id, [](int composite)->std::wstring { return pistonBasePropsToString(composite); }); + registerDecoder(Tile::sticky_piston_Id, [](int composite)->std::wstring { return pistonBasePropsToString(composite); }); + registerDecoder(Tile::piston_head_Id, [](int composite)->std::wstring { return pistonExtensionPropsToString(composite); }); + registerDecoder(Tile::end_portal_frame_Id, [](int composite)->std::wstring { return endPortalFramePropsToString(composite); }); + registerDecoder(Tile::unpowered_repeater_Id, [](int composite)->std::wstring { return repeaterPropsToString(composite, false); }); + registerDecoder(Tile::powered_repeater_Id, [](int composite)->std::wstring { return repeaterPropsToString(composite, true); }); + registerDecoder(Tile::unpowered_comparator_Id, [](int composite)->std::wstring { return comparatorPropsToString(composite); }); + registerDecoder(Tile::powered_comparator_Id, [](int composite)->std::wstring { return comparatorPropsToString(composite); }); + registerDecoder(Tile::redstone_wire_Id, [](int composite)->std::wstring { return redstoneDustPropsToString(composite); }); + registerDecoder(Tile::brown_mushroom_block_Id, [](int composite)->std::wstring { return hugeMushroomPropsToString(composite); }); + registerDecoder(Tile::red_mushroom_block_Id, [](int composite)->std::wstring { return hugeMushroomPropsToString(composite); }); + registerDecoder(Tile::hopper_Id, [](int composite)->std::wstring { return hopperPropsToString(composite); }); + registerDecoder(Tile::jukebox_Id, [](int composite)->std::wstring { return jukeboxPropsToString(composite); }); + registerDecoder(Tile::fence_gate_Id, [](int composite)->std::wstring { return fenceGatePropsToString(composite); }); + registerDecoder(Tile::spruce_fence_gate_Id, [](int composite)->std::wstring { return fenceGatePropsToString(composite); }); + registerDecoder(Tile::birch_fence_gate_Id, [](int composite)->std::wstring { return fenceGatePropsToString(composite); }); + registerDecoder(Tile::jungle_fence_gate_Id, [](int composite)->std::wstring { return fenceGatePropsToString(composite); }); + registerDecoder(Tile::dark_oak_fence_gate_Id, [](int composite)->std::wstring { return fenceGatePropsToString(composite); }); + registerDecoder(Tile::acacia_fence_gate_Id, [](int composite)->std::wstring { return fenceGatePropsToString(composite); }); + registerDecoder(Tile::daylight_detector_Id, [](int composite)->std::wstring { return daylightDetectorPropsToString(composite, false); }); + registerDecoder(Tile::daylight_detector_inverted_Id, [](int composite)->std::wstring { return daylightDetectorPropsToString(composite, true); }); + registerDecoder(Tile::snow_Id, [](int composite)->std::wstring { return snowPropsToString(composite); }); + registerDecoder(Tile::snow_layer_Id, [](int composite)->std::wstring { return snowPropsToString(composite); }); + registerDecoder(Tile::cauldron_Id, [](int composite)->std::wstring { return cauldronPropsToString(composite); }); + registerDecoder(Tile::torch_Id, [](int composite)->std::wstring { return torchPropsToString(composite); }); + registerDecoder(Tile::furnace_Id, [](int composite)->std::wstring { return furnacePropsToString(composite); }); + registerDecoder(Tile::lit_furnace_Id, [](int composite)->std::wstring { return furnacePropsToString(composite); }); + registerDecoder(Tile::redstone_ore_Id, [](int composite)->std::wstring { return redstoneOrePropsToString(composite); }); + registerDecoder(Tile::lit_redstone_ore_Id, [](int composite)->std::wstring { return redstoneOrePropsToString(composite); }); + registerDecoder(Tile::unlit_redstone_torch_Id, [](int composite)->std::wstring { return redstoneTorchPropsToString(composite); }); + registerDecoder(Tile::redstone_torch_Id, [](int composite)->std::wstring { return redstoneTorchPropsToString(composite); }); + registerDecoder(Tile::redstone_lamp_Id, [](int composite)->std::wstring { return redlightPropsToString(composite); }); + registerDecoder(Tile::lit_redstone_lamp_Id, [](int composite)->std::wstring { return redlightPropsToString(composite); }); + return true; +} + +static bool s_plantDecoderRegistered = registerPlantDecoders(); diff --git a/Minecraft.World/BlockStateDecoder.h b/Minecraft.World/BlockStateDecoder.h new file mode 100644 index 00000000..815f89ef --- /dev/null +++ b/Minecraft.World/BlockStateDecoder.h @@ -0,0 +1,19 @@ +#pragma once +#include +#include "Tile.h" + +namespace BlockStateDecoder { + +// door stuff is here cause idk what i was doing when i intially started this +struct DoorProps { + int dir; + std::wstring dirName; + bool open; + bool upper; + bool hingeRight; +}; + +DoorProps decodeDoor(int composite); +std::wstring doorPropsToString(const DoorProps &p); + +} diff --git a/Minecraft.World/BlockStateDecoderRegistry.cpp b/Minecraft.World/BlockStateDecoderRegistry.cpp new file mode 100644 index 00000000..c9600fbf --- /dev/null +++ b/Minecraft.World/BlockStateDecoderRegistry.cpp @@ -0,0 +1,35 @@ +#include "BlockStateDecoderRegistry.h" +#include +#include + +namespace BlockStateDecoderRegistry { + +static std::unordered_map *g_map = nullptr; +static std::mutex g_mapMutex; + +static void ensureMap() +{ + if (!g_map) g_map = new std::unordered_map(); +} + +void registerDecoder(int tileId, DecoderFn fn) +{ + std::lock_guard l(g_mapMutex); + ensureMap(); + (*g_map)[tileId] = fn; +} + +std::wstring decode(int tileId, int composite) +{ + std::lock_guard l(g_mapMutex); + ensureMap(); + auto it = g_map->find(tileId); + if (it == g_map->end()) return L""; + try { + return it->second(composite); + } catch (...) { + return L""; + } +} + +} diff --git a/Minecraft.World/BlockStateDecoderRegistry.h b/Minecraft.World/BlockStateDecoderRegistry.h new file mode 100644 index 00000000..345ad939 --- /dev/null +++ b/Minecraft.World/BlockStateDecoderRegistry.h @@ -0,0 +1,12 @@ +#pragma once +#include +#include + +namespace BlockStateDecoderRegistry +{ + using DecoderFn = std::function; + + void registerDecoder(int tileId, DecoderFn fn); + + std::wstring decode(int tileId, int composite); +} diff --git a/Minecraft.World/Boat.cpp b/Minecraft.World/Boat.cpp index 7c62e4ee..faaca25d 100644 --- a/Minecraft.World/Boat.cpp +++ b/Minecraft.World/Boat.cpp @@ -336,7 +336,7 @@ void Boat::tick() remove(); for (int i = 0; i < 3; i++) { - spawnAtLocation(Tile::wood_Id, 1, 0); + spawnAtLocation(Tile::planks_Id, 1, 0); } for (int i = 0; i < 2; i++) { @@ -397,11 +397,11 @@ void Boat::tick() int yy = Mth::floor(y) + j; int tile = level->getTile(xx, yy, zz); - if (tile == Tile::topSnow_Id) + if (tile == Tile::snow_layer_Id) { level->removeTile(xx, yy, zz); } - else if (tile == Tile::waterLily_Id) + else if (tile == Tile::waterlily_Id) { level->destroyTile(xx, yy, zz, true); } diff --git a/Minecraft.World/BoatItem.cpp b/Minecraft.World/BoatItem.cpp index 5cf2cd38..5ae7f744 100644 --- a/Minecraft.World/BoatItem.cpp +++ b/Minecraft.World/BoatItem.cpp @@ -104,7 +104,7 @@ shared_ptr BoatItem::use(shared_ptr itemInstance, Le int yt = hr->y; int zt = hr->z; - if (level->getTile(xt, yt, zt) == Tile::topSnow_Id) yt--; + if (level->getTile(xt, yt, zt) == Tile::snow_layer_Id) yt--; if( level->countInstanceOf(eTYPE_BOAT, true) < Level::MAX_XBOX_BOATS ) // 4J - added limit { shared_ptr boat = std::make_shared(level, xt + 0.5f, yt + 1.0f, zt + 0.5f); diff --git a/Minecraft.World/BreakDoorGoal.cpp b/Minecraft.World/BreakDoorGoal.cpp index ea00f500..d86d471a 100644 --- a/Minecraft.World/BreakDoorGoal.cpp +++ b/Minecraft.World/BreakDoorGoal.cpp @@ -16,6 +16,8 @@ bool BreakDoorGoal::canUse() { if (!DoorInteractGoal::canUse()) return false; if (!mob->level->getGameRules()->getBoolean(GameRules::RULE_MOBGRIEFING)) return false; + // difficulty check + if (mob->level->difficulty != Difficulty::HARD) return false; return !doorTile->isOpen(mob->level, doorX, doorY, doorZ); } diff --git a/Minecraft.World/BrewingStandMenu.cpp b/Minecraft.World/BrewingStandMenu.cpp index d705f220..0bb9aff9 100644 --- a/Minecraft.World/BrewingStandMenu.cpp +++ b/Minecraft.World/BrewingStandMenu.cpp @@ -225,7 +225,7 @@ bool BrewingStandMenu::PotionSlot::mayCombine(shared_ptr second) bool BrewingStandMenu::PotionSlot::mayPlaceItem(shared_ptr item) { - return item != nullptr && (item->id == Item::potion_Id || item->id == Item::glassBottle_Id); + return item != nullptr && (item->id == Item::potion_Id || item->id == Item::glass_bottle_Id); } BrewingStandMenu::IngredientsSlot::IngredientsSlot(shared_ptr container, int slot, int x, int y) : Slot(container, slot, x ,y) @@ -249,7 +249,7 @@ bool BrewingStandMenu::IngredientsSlot::mayPlace(shared_ptr item) } else { - return Item::items[item->id]->hasPotionBrewingFormula() || item->id == Item::netherwart_seeds_Id || item->id == Item::bucket_water_Id; + return Item::items[item->id]->hasPotionBrewingFormula() || item->id == Item::netherwart_seeds_Id || item->id == Item::water_bucket_Id; } } return false; diff --git a/Minecraft.World/BrewingStandTile.cpp b/Minecraft.World/BrewingStandTile.cpp index ec7242c8..f66166d5 100644 --- a/Minecraft.World/BrewingStandTile.cpp +++ b/Minecraft.World/BrewingStandTile.cpp @@ -13,6 +13,32 @@ BrewingStandTile::BrewingStandTile(int id) : BaseEntityTile(id, Material::metal, iconBase = nullptr; } +void BrewingStandTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int BrewingStandTile::defaultBlockState() +{ + return 0; +} + +int BrewingStandTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x7) : 0; +} + +Tile::BlockState BrewingStandTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x7); +} + +Tile::BlockState BrewingStandTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x7); +} + BrewingStandTile::~BrewingStandTile() { delete random; @@ -123,12 +149,12 @@ void BrewingStandTile::onRemove(Level *level, int x, int y, int z, int id, int d int BrewingStandTile::getResource(int data, Random *random, int playerBonusLevel) { - return Item::brewingStand_Id; + return Item::brewing_stand_Id; } int BrewingStandTile::cloneTileId(Level *level, int x, int y, int z) { - return Item::brewingStand_Id; + return Item::brewing_stand_Id; } bool BrewingStandTile::hasAnalogOutputSignal() diff --git a/Minecraft.World/BrewingStandTile.h b/Minecraft.World/BrewingStandTile.h index bb1fed99..f846d09e 100644 --- a/Minecraft.World/BrewingStandTile.h +++ b/Minecraft.World/BrewingStandTile.h @@ -14,6 +14,11 @@ private: public: BrewingStandTile(int id); ~BrewingStandTile(); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual bool isSolidRender(bool isServerLevel = false); virtual int getRenderShape(); virtual shared_ptr newTileEntity(Level *level); diff --git a/Minecraft.World/BrewingStandTileEntity.cpp b/Minecraft.World/BrewingStandTileEntity.cpp index 3d081bae..0e7d2972 100644 --- a/Minecraft.World/BrewingStandTileEntity.cpp +++ b/Minecraft.World/BrewingStandTileEntity.cpp @@ -156,11 +156,11 @@ bool BrewingStandTileEntity::isBrewable() } else { - if (!Item::items[ingredient->id]->hasPotionBrewingFormula() && ingredient->id != Item::bucket_water_Id && ingredient->id != Item::netherwart_seeds_Id) + if (!Item::items[ingredient->id]->hasPotionBrewingFormula() && ingredient->id != Item::water_bucket_Id && ingredient->id != Item::netherwart_seeds_Id) { return false; } - bool isWater = ingredient->id == Item::bucket_water_Id; + bool isWater = ingredient->id == Item::water_bucket_Id; // at least one destination potion must have a result bool oneResult = false; @@ -176,7 +176,7 @@ bool BrewingStandTileEntity::isBrewable() break; } } - else if (isWater && items[dest] != nullptr && items[dest]->id == Item::glassBottle_Id) + else if (isWater && items[dest] != nullptr && items[dest]->id == Item::glass_bottle_Id) { oneResult = true; break; @@ -242,7 +242,7 @@ void BrewingStandTileEntity::doBrew() } else { - bool isWater = ingredient->id == Item::bucket_water_Id; + bool isWater = ingredient->id == Item::water_bucket_Id; for (int dest = 0; dest < 3; dest++) { @@ -252,7 +252,7 @@ void BrewingStandTileEntity::doBrew() int newBrew = NORMALISE_POTION_AUXVAL( applyIngredient(currentBrew, ingredient) ); items[dest]->setAuxValue(newBrew); } - else if (isWater && items[dest] != nullptr && items[dest]->id == Item::glassBottle_Id) + else if (isWater && items[dest] != nullptr && items[dest]->id == Item::glass_bottle_Id) { items[dest] = std::make_shared(Item::potion); } @@ -283,7 +283,7 @@ int BrewingStandTileEntity::applyIngredient(int currentBrew, shared_ptrid == Item::bucket_water_Id) + if (ingredient->id == Item::water_bucket_Id) { return PotionBrewing::applyBrew(currentBrew, PotionBrewing::MOD_WATER); } @@ -428,11 +428,11 @@ bool BrewingStandTileEntity::canPlaceItem(int slot, shared_ptr ite } else { - return Item::items[item->id]->hasPotionBrewingFormula() || item->id == Item::netherwart_seeds_Id || item->id == Item::bucket_water_Id; + return Item::items[item->id]->hasPotionBrewingFormula() || item->id == Item::netherwart_seeds_Id || item->id == Item::water_bucket_Id; } } - return item->id == Item::potion_Id || item->id == Item::glassBottle_Id; + return item->id == Item::potion_Id || item->id == Item::glass_bottle_Id; } void BrewingStandTileEntity::setBrewTime(int value) diff --git a/Minecraft.World/BucketItem.cpp b/Minecraft.World/BucketItem.cpp index f195e4fc..6af2831c 100644 --- a/Minecraft.World/BucketItem.cpp +++ b/Minecraft.World/BucketItem.cpp @@ -141,13 +141,13 @@ shared_ptr BucketItem::use(shared_ptr itemInstance, if (--itemInstance->count <= 0) { - return std::make_shared(Item::bucket_water); + return std::make_shared(Item::water_bucket); } else { - if (!player->inventory->add(std::make_shared(Item::bucket_water))) + if (!player->inventory->add(std::make_shared(Item::water_bucket))) { - player->drop(std::make_shared(Item::bucket_water_Id, 1, 0)); + player->drop(std::make_shared(Item::water_bucket_Id, 1, 0)); } return itemInstance; } @@ -168,13 +168,13 @@ shared_ptr BucketItem::use(shared_ptr itemInstance, } if (--itemInstance->count <= 0) { - return std::make_shared(Item::bucket_lava); + return std::make_shared(Item::lava_bucket); } else { - if (!player->inventory->add(std::make_shared(Item::bucket_lava))) + if (!player->inventory->add(std::make_shared(Item::lava_bucket))) { - player->drop(std::make_shared(Item::bucket_lava_Id, 1, 0)); + player->drop(std::make_shared(Item::lava_bucket_Id, 1, 0)); } return itemInstance; } @@ -183,7 +183,7 @@ shared_ptr BucketItem::use(shared_ptr itemInstance, else if (content < 0) { delete hr; - return std::make_shared(Item::bucket_empty); + return std::make_shared(Item::bucket); } else { @@ -199,7 +199,7 @@ shared_ptr BucketItem::use(shared_ptr itemInstance, if (emptyBucket(level, xt, yt, zt) && !player->abilities.instabuild) { - return std::make_shared(Item::bucket_empty); + return std::make_shared(Item::bucket); } } @@ -217,7 +217,7 @@ bool BucketItem::emptyBucket(Level *level, int xt, int yt, int zt) if (level->isEmptyTile(xt, yt, zt) || nonSolid) { - if (level->dimension->ultraWarm && content == Tile::water_Id) + if (level->dimension->ultraWarm && content == Tile::flowing_water_Id) { level->playSound(xt + 0.5f, yt + 0.5f, zt + 0.5f, eSoundType_RANDOM_FIZZ, 0.5f, 2.6f + (level->random->nextFloat() - level->random->nextFloat()) * 0.8f); diff --git a/Minecraft.World/ButtonTile.cpp b/Minecraft.World/ButtonTile.cpp index e95196a2..fc030101 100644 --- a/Minecraft.World/ButtonTile.cpp +++ b/Minecraft.World/ButtonTile.cpp @@ -11,11 +11,38 @@ ButtonTile::ButtonTile(int id, bool sensitive) : Tile(id, Material::decoration, { this->setTicking(true); this->sensitive = sensitive; + setLightBlock(0); +} + +void ButtonTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int ButtonTile::defaultBlockState() +{ + return 0; +} + +int ButtonTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState ButtonTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState ButtonTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); } Icon *ButtonTile::getTexture(int face, int data) { - if(id == Tile::button_wood_Id) return Tile::wood->getTexture(Facing::UP); + if(id == Tile::wooden_button_Id) return Tile::wood->getTexture(Facing::UP); else return Tile::stone->getTexture(Facing::UP); } diff --git a/Minecraft.World/ButtonTile.h b/Minecraft.World/ButtonTile.h index 96c49cdf..972c013a 100644 --- a/Minecraft.World/ButtonTile.h +++ b/Minecraft.World/ButtonTile.h @@ -18,6 +18,11 @@ protected: public: Icon *getTexture(int face, int data); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; virtual AABB *getAABB(Level *level, int x, int y, int z); virtual int getTickDelay(Level *level); virtual bool blocksLight(); diff --git a/Minecraft.World/CMakeLists.txt b/Minecraft.World/CMakeLists.txt index e397bf29..82169c29 100644 --- a/Minecraft.World/CMakeLists.txt +++ b/Minecraft.World/CMakeLists.txt @@ -11,6 +11,11 @@ set(MINECRAFT_WORLD_SOURCES ${SOURCES_COMMON} ) +list(APPEND MINECRAFT_WORLD_SOURCES + "${CMAKE_CURRENT_SOURCE_DIR}/BlockStateDecoder.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/BlockStateDecoderRegistry.cpp" +) + add_library(Minecraft.World STATIC ${MINECRAFT_WORLD_SOURCES}) target_include_directories(Minecraft.World diff --git a/Minecraft.World/CactusTile.cpp b/Minecraft.World/CactusTile.cpp index 731e722e..c63fc8c4 100644 --- a/Minecraft.World/CactusTile.cpp +++ b/Minecraft.World/CactusTile.cpp @@ -19,6 +19,32 @@ CactusTile::CactusTile(int id) : Tile(id, Material::cactus,isSolidRender()) iconBottom = nullptr; } +void CactusTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int CactusTile::defaultBlockState() +{ + return 0; +} + +int CactusTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState CactusTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState CactusTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + void CactusTile::tick(Level *level, int x, int y, int z, Random *random) { if (level->isEmptyTile(x, y + 1, z)) diff --git a/Minecraft.World/CactusTile.h b/Minecraft.World/CactusTile.h index 3c5e9b49..a5866a74 100644 --- a/Minecraft.World/CactusTile.h +++ b/Minecraft.World/CactusTile.h @@ -20,6 +20,11 @@ protected: CactusTile(int id); public: + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void tick(Level *level, int x, int y, int z, Random *random); virtual AABB *getAABB(Level *level, int x, int y, int z); virtual AABB *getTileAABB(Level *level, int x, int y, int z); diff --git a/Minecraft.World/CakeTile.cpp b/Minecraft.World/CakeTile.cpp index 0ef4fe18..b77639cf 100644 --- a/Minecraft.World/CakeTile.cpp +++ b/Minecraft.World/CakeTile.cpp @@ -18,6 +18,32 @@ CakeTile::CakeTile(int id) : Tile(id, Material::cake,isSolidRender()) iconInner = nullptr; } +void CakeTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int CakeTile::defaultBlockState() +{ + return 0; +} + +int CakeTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x7) : 0; +} + +Tile::BlockState CakeTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x7); +} + +Tile::BlockState CakeTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x7); +} + void CakeTile::updateShape(LevelSource *level, int x, int y, int z, int forceData, shared_ptr forceEntity) // 4J added forceData, forceEntity param { int d = level->getData(x, y, z); diff --git a/Minecraft.World/CakeTile.h b/Minecraft.World/CakeTile.h index 7f03577d..1fe7a3fb 100644 --- a/Minecraft.World/CakeTile.h +++ b/Minecraft.World/CakeTile.h @@ -41,4 +41,9 @@ public: virtual int getResourceCount(Random *random); virtual int getResource(int data, Random *random, int playerBonusLevel); int cloneTileId(Level *level, int x, int y, int z); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); }; \ No newline at end of file diff --git a/Minecraft.World/CanyonFeature.cpp b/Minecraft.World/CanyonFeature.cpp index d25def53..7645ada1 100644 --- a/Minecraft.World/CanyonFeature.cpp +++ b/Minecraft.World/CanyonFeature.cpp @@ -107,7 +107,7 @@ void CanyonFeature::addTunnel(int64_t seed, int xOffs, int zOffs, byteArray bloc { int p = (xx * 16 + zz) * Level::genDepth + yy; if (yy < 0 || yy >= Level::genDepth) continue; - if (blocks[p] == Tile::water_Id || blocks[p] == Tile::calmWater_Id) + if (blocks[p] == Tile::flowing_water_Id || blocks[p] == Tile::water_Id) { detectedWater = true; } @@ -141,7 +141,7 @@ void CanyonFeature::addTunnel(int64_t seed, int xOffs, int zOffs, byteArray bloc { if (yy < 10) { - blocks[p] = static_cast(Tile::lava_Id); + blocks[p] = static_cast(Tile::flowing_lava_Id); } else { diff --git a/Minecraft.World/CarrotOnAStickItem.cpp b/Minecraft.World/CarrotOnAStickItem.cpp index cc39196c..f8b48bee 100644 --- a/Minecraft.World/CarrotOnAStickItem.cpp +++ b/Minecraft.World/CarrotOnAStickItem.cpp @@ -35,7 +35,7 @@ shared_ptr CarrotOnAStickItem::use(shared_ptr itemIn if (itemInstance->count == 0) { - shared_ptr replacement = std::make_shared(Item::fishingRod); + shared_ptr replacement = std::make_shared(Item::fishing_rod); replacement->setTag(itemInstance->tag); return replacement; } diff --git a/Minecraft.World/CarrotTile.cpp b/Minecraft.World/CarrotTile.cpp index 8841e199..a59cbd71 100644 --- a/Minecraft.World/CarrotTile.cpp +++ b/Minecraft.World/CarrotTile.cpp @@ -25,12 +25,12 @@ Icon *CarrotTile::getTexture(int face, int data) int CarrotTile::getBaseSeedId() { - return Item::carrots_Id; + return Item::carrot_Id; } int CarrotTile::getBasePlantId() { - return Item::carrots_Id; + return Item::carrot_Id; } void CarrotTile::registerIcons(IconRegister *iconRegister) diff --git a/Minecraft.World/CauldronTile.cpp b/Minecraft.World/CauldronTile.cpp index 88890d48..d8b82afc 100644 --- a/Minecraft.World/CauldronTile.cpp +++ b/Minecraft.World/CauldronTile.cpp @@ -14,11 +14,38 @@ const wstring CauldronTile::TEXTURE_BOTTOM = L"cauldron_bottom"; CauldronTile::CauldronTile(int id) : Tile(id, Material::metal, isSolidRender()) { + setLightBlock(0); iconInner = nullptr; iconTop = nullptr; iconBottom = nullptr; } +void CauldronTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int CauldronTile::defaultBlockState() +{ + return 0; +} + +int CauldronTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x3) : 0; +} + +Tile::BlockState CauldronTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x3); +} + +Tile::BlockState CauldronTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x3); +} + Icon *CauldronTile::getTexture(int face, int data) { if (face == Facing::UP) @@ -123,13 +150,13 @@ bool CauldronTile::use(Level *level, int x, int y, int z, shared_ptr pla int currentData = level->getData(x, y, z); int fillLevel = getFillLevel(currentData); - if (item->id == Item::bucket_water_Id) + if (item->id == Item::water_bucket_Id) { if (fillLevel < 3) { if (!player->abilities.instabuild) { - player->inventory->setItem(player->inventory->selected, std::make_shared(Item::bucket_empty)); + player->inventory->setItem(player->inventory->selected, std::make_shared(Item::bucket)); } level->setData(x, y, z, 3, Tile::UPDATE_CLIENTS); @@ -137,7 +164,7 @@ bool CauldronTile::use(Level *level, int x, int y, int z, shared_ptr pla } return true; } - else if (item->id == Item::glassBottle_Id) + else if (item->id == Item::glass_bottle_Id) { if (fillLevel > 0) { diff --git a/Minecraft.World/CauldronTile.h b/Minecraft.World/CauldronTile.h index da810a28..3b21a675 100644 --- a/Minecraft.World/CauldronTile.h +++ b/Minecraft.World/CauldronTile.h @@ -16,6 +16,11 @@ private: public: CauldronTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); using Tile::getTexture; virtual Icon *getTexture(int face, int data); //@Override diff --git a/Minecraft.World/ChestTile.cpp b/Minecraft.World/ChestTile.cpp index ff3c0b40..6f6a991b 100644 --- a/Minecraft.World/ChestTile.cpp +++ b/Minecraft.World/ChestTile.cpp @@ -39,6 +39,18 @@ int ChestTile::getRenderShape() return Tile::SHAPE_ENTITYTILE_ANIMATED; } +AABB *ChestTile::getTileAABB(Level *level, int x, int y, int z) +{ + updateShape(level, x, y, z, -1, shared_ptr()); + return Tile::getTileAABB(level, x, y, z); +} + +AABB *ChestTile::getAABB(Level *level, int x, int y, int z) +{ + updateShape(level, x, y, z, -1, shared_ptr()); + return Tile::getAABB(level, x, y, z); +} + void ChestTile::updateShape(LevelSource *level, int x, int y, int z, int forceData, shared_ptr forceEntity) { if (level->getTile(x, y, z - 1) == id) diff --git a/Minecraft.World/ChestTile.h b/Minecraft.World/ChestTile.h index 4fefeea9..974cce04 100644 --- a/Minecraft.World/ChestTile.h +++ b/Minecraft.World/ChestTile.h @@ -30,6 +30,8 @@ public: virtual bool isSolidRender(bool isServerLevel = false); virtual bool isCubeShaped(); virtual int getRenderShape(); + virtual AABB *getTileAABB(Level *level, int x, int y, int z); + virtual AABB *getAABB(Level *level, int x, int y, int z); virtual void updateShape(LevelSource *level, int x, int y, int z, int forceData, shared_ptr forceEntity = shared_ptr()); virtual void onPlace(Level *level, int x, int y, int z); virtual void setPlacedBy(Level *level, int x, int y, int z, shared_ptr by, shared_ptr itemInstance); diff --git a/Minecraft.World/ChestTileEntity.cpp b/Minecraft.World/ChestTileEntity.cpp index ba277e24..4160e915 100644 --- a/Minecraft.World/ChestTileEntity.cpp +++ b/Minecraft.World/ChestTileEntity.cpp @@ -142,7 +142,31 @@ void ChestTileEntity::load(CompoundTag *base) { CompoundTag *tag = inventoryList->get(i); unsigned int slot = tag->getByte(L"Slot") & 0xff; - if (slot >= 0 && slot < items->length) (*items)[slot] = ItemInstance::fromTag(tag); + if (slot < items->length) + { + shared_ptr loadedItem = ItemInstance::fromTag(tag); + if (loadedItem == nullptr) + { + Tag *idTag = tag->get(L"id"); + int idType = idTag != nullptr ? idTag->getId() : -1; + + /* + if (idType == Tag::TAG_String) + { + app.DebugPrintf("[ChestTileEntity] Missing chest item at %d,%d,%d slot=%u idType=%d idStr=%ls count=%d damage=%d\n", x, y, z, slot, idType, tag->getString(L"id").c_str(), tag->getByte(L"Count"), tag->getShort(L"Damage")); + } + else if (idType == Tag::TAG_Int) + { + app.DebugPrintf("[ChestTileEntity] Missing chest item at %d,%d,%d slot=%u idType=%d id=%d count=%d damage=%d\n", x, y, z, slot, idType, tag->getInt(L"id"), tag->getByte(L"Count"), tag->getShort(L"Damage")); + } + else + { + app.DebugPrintf("[ChestTileEntity] Missing chest item at %d,%d,%d slot=%u idType=%d id=%d count=%d damage=%d\n", x, y, z, slot, idType, tag->getShort(L"id"), tag->getByte(L"Count"), tag->getShort(L"Damage")); + } + */ + } + (*items)[slot] = loadedItem; + } } isBonusChest = base->getBoolean(L"bonus"); } diff --git a/Minecraft.World/Chicken.cpp b/Minecraft.World/Chicken.cpp index b5a831ef..1af53bda 100644 --- a/Minecraft.World/Chicken.cpp +++ b/Minecraft.World/Chicken.cpp @@ -37,7 +37,7 @@ Chicken::Chicken(Level *level) : Animal( level ) goalSelector.addGoal(0, new FloatGoal(this)); goalSelector.addGoal(1, new PanicGoal(this, 1.4)); goalSelector.addGoal(2, new BreedGoal(this, 1.0)); - goalSelector.addGoal(3, new TemptGoal(this, 1.0, Item::seeds_wheat_Id, false)); + goalSelector.addGoal(3, new TemptGoal(this, 1.0, Item::wheat_seeds_Id, false)); goalSelector.addGoal(4, new FollowParentGoal(this, 1.1)); goalSelector.addGoal(5, new RandomStrollGoal(this, 1.0)); goalSelector.addGoal(6, new LookAtPlayerGoal(this, typeid(Player), 6)); @@ -131,11 +131,11 @@ void Chicken::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) // and some meat if (this->isOnFire()) { - spawnAtLocation(Item::chicken_cooked_Id, 1); + spawnAtLocation(Item::cooked_chicken_Id, 1); } else { - spawnAtLocation(Item::chicken_raw_Id, 1); + spawnAtLocation(Item::chicken_Id, 1); } } @@ -168,5 +168,5 @@ shared_ptr Chicken::getBreedOffspring(shared_ptr target) bool Chicken::isFood(shared_ptr itemInstance) { - return (itemInstance->id == Item::seeds_wheat_Id) || (itemInstance->id == Item::netherwart_seeds_Id) || (itemInstance->id == Item::seeds_melon_Id) || (itemInstance->id == Item::seeds_pumpkin_Id); + return (itemInstance->id == Item::wheat_seeds_Id) || (itemInstance->id == Item::netherwart_seeds_Id) || (itemInstance->id == Item::melon_seeds_Id) || (itemInstance->id == Item::pumpkin_seeds_Id); } diff --git a/Minecraft.World/ClothDyeRecipes.cpp b/Minecraft.World/ClothDyeRecipes.cpp index 084cf5e6..d934ca43 100644 --- a/Minecraft.World/ClothDyeRecipes.cpp +++ b/Minecraft.World/ClothDyeRecipes.cpp @@ -1,6 +1,8 @@ #include "stdafx.h" #include "net.minecraft.world.item.h" #include "net.minecraft.world.level.tile.h" +#include "Rose.h" +#include "TallGrass2.h" #include "Recipy.h" #include "Recipes.h" #include "ClothDyeRecipes.h" @@ -12,14 +14,14 @@ void ClothDyeRecipes::addRecipes(Recipes *r) { r->addShapelessRecipy(new ItemInstance(Tile::wool, 1, ColoredTile::getItemAuxValueForTileData(i)), // L"zzg", - new ItemInstance(Item::dye_powder, 1, i), new ItemInstance(Item::items[Tile::wool_Id], 1, 0),L'D'); - r->addShapedRecipy(new ItemInstance(Tile::clayHardened_colored, 8, ColoredTile::getItemAuxValueForTileData(i)), // + new ItemInstance(Item::dye, 1, i), new ItemInstance(Item::items[Tile::wool_Id], 1, 0),L'D'); + r->addShapedRecipy(new ItemInstance(Tile::stained_hardened_clay, 8, ColoredTile::getItemAuxValueForTileData(i)), // L"sssczczg", L"###", L"#X#", L"###", L'#', new ItemInstance(Tile::clayHardened), - L'X', new ItemInstance(Item::dye_powder, 1, i),L'D'); + L'X', new ItemInstance(Item::dye, 1, i),L'D'); //#if 0 // r->addShapedRecipy(new ItemInstance(Tile::stained_glass, 8, ColoredTile::getItemAuxValueForTileData(i)), // @@ -28,7 +30,7 @@ void ClothDyeRecipes::addRecipes(Recipes *r) // L"#X#", // L"###", // L'#', new ItemInstance(Tile::glass), -// L'X', new ItemInstance(Item::dye_powder, 1, i), L'D'); +// L'X', new ItemInstance(Item::dye, 1, i), L'D'); // r->addShapedRecipy(new ItemInstance(Tile::stained_glass_pane, 16, i), // // L"ssczg", // L"###", @@ -38,121 +40,81 @@ void ClothDyeRecipes::addRecipes(Recipes *r) } // some dye recipes - - //flowers - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::YELLOW), + r->addShapelessRecipy(new ItemInstance(Item::dye, 1, DyePowderItem::YELLOW), L"tg", Tile::flower,L'D'); - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), + r->addShapelessRecipy(new ItemInstance(Item::dye, 2, DyePowderItem::RED), L"tg", Tile::rose,L'D'); - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::LIGHT_BLUE), - L"zg", new ItemInstance(Item::items[Tile::rose_Id], 1, Rose::BLUE_ORCHID), L'D'); - - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::MAGENTA), - L"zg", new ItemInstance(Item::items[Tile::rose_Id], 1, Rose::ALLIUM), L'D'); - - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::SILVER), - L"zg", new ItemInstance(Item::items[Tile::rose_Id], 1, Rose::AZURE_BLUET), L'D'); - - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), - L"zg", new ItemInstance(Item::items[Tile::rose_Id], 1, Rose::RED_TULIP), L'D'); - - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::PINK), - L"zg", new ItemInstance(Item::items[Tile::rose_Id], 1, Rose::PINK_TULIP), L'D'); - - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::SILVER), - L"zg", new ItemInstance(Item::items[Tile::rose_Id], 1, Rose::WHITE_TULIP), L'D'); - - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::ORANGE), - L"zg", new ItemInstance(Item::items[Tile::rose_Id], 1, Rose::ORANGE_TULIP), L'D'); - - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::SILVER), - L"zg", new ItemInstance(Item::items[Tile::rose_Id], 1, Rose::OXEYE_DAISY), L'D'); - - // Tall flowers - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::YELLOW), - L"zg", new ItemInstance(Item::items[Tile::tallgrass2_Id], 1, TallGrass2::SUNFLOWER), L'D'); - - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::MAGENTA), - L"zg", new ItemInstance(Item::items[Tile::tallgrass2_Id], 1, TallGrass2::LILAC), L'D'); - - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::RED), - L"zg", new ItemInstance(Item::items[Tile::tallgrass2_Id], 1, TallGrass2::ROSE_BUSH), L'D'); - - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::MAGENTA), - L"zg", new ItemInstance(Item::items[Tile::tallgrass2_Id], 1, TallGrass2::PEONY), L'D'); - - - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 3, DyePowderItem::WHITE), + r->addShapelessRecipy(new ItemInstance(Item::dye, 3, DyePowderItem::WHITE), L"ig", Item::bone,L'D'); - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::PINK), // + r->addShapelessRecipy(new ItemInstance(Item::dye, 2, DyePowderItem::PINK), // L"zzg", - new ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), - new ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE),L'D'); + new ItemInstance(Item::dye, 1, DyePowderItem::RED), + new ItemInstance(Item::dye, 1, DyePowderItem::WHITE),L'D'); - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::ORANGE), // + r->addShapelessRecipy(new ItemInstance(Item::dye, 2, DyePowderItem::ORANGE), // L"zzg", - new ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), - new ItemInstance(Item::dye_powder, 1, DyePowderItem::YELLOW),L'D'); + new ItemInstance(Item::dye, 1, DyePowderItem::RED), + new ItemInstance(Item::dye, 1, DyePowderItem::YELLOW),L'D'); - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::LIME), // + r->addShapelessRecipy(new ItemInstance(Item::dye, 2, DyePowderItem::LIME), // L"zzg", - new ItemInstance(Item::dye_powder, 1, DyePowderItem::GREEN), - new ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE),L'D'); + new ItemInstance(Item::dye, 1, DyePowderItem::GREEN), + new ItemInstance(Item::dye, 1, DyePowderItem::WHITE),L'D'); - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::GRAY), // + r->addShapelessRecipy(new ItemInstance(Item::dye, 2, DyePowderItem::GRAY), // L"zzg", - new ItemInstance(Item::dye_powder, 1, DyePowderItem::BLACK), - new ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE),L'D'); + new ItemInstance(Item::dye, 1, DyePowderItem::BLACK), + new ItemInstance(Item::dye, 1, DyePowderItem::WHITE),L'D'); - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::SILVER), // + r->addShapelessRecipy(new ItemInstance(Item::dye, 2, DyePowderItem::SILVER), // L"zzg", - new ItemInstance(Item::dye_powder, 1, DyePowderItem::GRAY), - new ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE),L'D'); + new ItemInstance(Item::dye, 1, DyePowderItem::GRAY), + new ItemInstance(Item::dye, 1, DyePowderItem::WHITE),L'D'); - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 3, DyePowderItem::SILVER), // + r->addShapelessRecipy(new ItemInstance(Item::dye, 3, DyePowderItem::SILVER), // L"zzzg", - new ItemInstance(Item::dye_powder, 1, DyePowderItem::BLACK), - new ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE), - new ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE),L'D'); + new ItemInstance(Item::dye, 1, DyePowderItem::BLACK), + new ItemInstance(Item::dye, 1, DyePowderItem::WHITE), + new ItemInstance(Item::dye, 1, DyePowderItem::WHITE),L'D'); - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::LIGHT_BLUE), // + r->addShapelessRecipy(new ItemInstance(Item::dye, 2, DyePowderItem::LIGHT_BLUE), // L"zzg", - new ItemInstance(Item::dye_powder, 1, DyePowderItem::BLUE), - new ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE),L'D'); + new ItemInstance(Item::dye, 1, DyePowderItem::BLUE), + new ItemInstance(Item::dye, 1, DyePowderItem::WHITE),L'D'); - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::CYAN), // + r->addShapelessRecipy(new ItemInstance(Item::dye, 2, DyePowderItem::CYAN), // L"zzg", - new ItemInstance(Item::dye_powder, 1, DyePowderItem::BLUE), - new ItemInstance(Item::dye_powder, 1, DyePowderItem::GREEN),L'D'); + new ItemInstance(Item::dye, 1, DyePowderItem::BLUE), + new ItemInstance(Item::dye, 1, DyePowderItem::GREEN),L'D'); - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::PURPLE), // + r->addShapelessRecipy(new ItemInstance(Item::dye, 2, DyePowderItem::PURPLE), // L"zzg", - new ItemInstance(Item::dye_powder, 1, DyePowderItem::BLUE), - new ItemInstance(Item::dye_powder, 1, DyePowderItem::RED),L'D'); + new ItemInstance(Item::dye, 1, DyePowderItem::BLUE), + new ItemInstance(Item::dye, 1, DyePowderItem::RED),L'D'); - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::MAGENTA), // + r->addShapelessRecipy(new ItemInstance(Item::dye, 2, DyePowderItem::MAGENTA), // L"zzg", - new ItemInstance(Item::dye_powder, 1, DyePowderItem::PURPLE), - new ItemInstance(Item::dye_powder, 1, DyePowderItem::PINK),L'D'); + new ItemInstance(Item::dye, 1, DyePowderItem::PURPLE), + new ItemInstance(Item::dye, 1, DyePowderItem::PINK),L'D'); - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 3, DyePowderItem::MAGENTA), // + r->addShapelessRecipy(new ItemInstance(Item::dye, 3, DyePowderItem::MAGENTA), // L"zzzg", - new ItemInstance(Item::dye_powder, 1, DyePowderItem::BLUE), - new ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), - new ItemInstance(Item::dye_powder, 1, DyePowderItem::PINK),L'D'); + new ItemInstance(Item::dye, 1, DyePowderItem::BLUE), + new ItemInstance(Item::dye, 1, DyePowderItem::RED), + new ItemInstance(Item::dye, 1, DyePowderItem::PINK),L'D'); - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 4, DyePowderItem::MAGENTA), // + r->addShapelessRecipy(new ItemInstance(Item::dye, 4, DyePowderItem::MAGENTA), // L"zzzzg", - new ItemInstance(Item::dye_powder, 1, DyePowderItem::BLUE), - new ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), - new ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), - new ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE),L'D'); + new ItemInstance(Item::dye, 1, DyePowderItem::BLUE), + new ItemInstance(Item::dye, 1, DyePowderItem::RED), + new ItemInstance(Item::dye, 1, DyePowderItem::RED), + new ItemInstance(Item::dye, 1, DyePowderItem::WHITE),L'D'); diff --git a/Minecraft.World/ClothTileItem.cpp b/Minecraft.World/ClothTileItem.cpp index 35f3bb96..e60213da 100644 --- a/Minecraft.World/ClothTileItem.cpp +++ b/Minecraft.World/ClothTileItem.cpp @@ -63,6 +63,6 @@ int ClothTileItem::getLevelDataForAuxValue(int auxValue) unsigned int ClothTileItem::getDescriptionId(shared_ptr instance) { - if(getTileId() == Tile::woolCarpet_Id) return CARPET_COLOR_DESCS[ClothTile::getTileDataForItemAuxValue(instance->getAuxValue())]; + if(getTileId() == Tile::carpet_Id) return CARPET_COLOR_DESCS[ClothTile::getTileDataForItemAuxValue(instance->getAuxValue())]; else return COLOR_DESCS[ClothTile::getTileDataForItemAuxValue(instance->getAuxValue())]; } diff --git a/Minecraft.World/CocoaTile.cpp b/Minecraft.World/CocoaTile.cpp index 2a2fbd21..5385e99a 100644 --- a/Minecraft.World/CocoaTile.cpp +++ b/Minecraft.World/CocoaTile.cpp @@ -17,6 +17,32 @@ CocoaTile::CocoaTile(int id) : DirectionalTile(id, Material::plant, isSolidRende setTicking(true); } +void CocoaTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int CocoaTile::defaultBlockState() +{ + return 0; +} + +int CocoaTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? state->value : 0; +} + +Tile::BlockState CocoaTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState CocoaTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + Icon *CocoaTile::getTexture(int face, int data) { return icons[2]; @@ -62,7 +88,7 @@ bool CocoaTile::canSurvive(Level *level, int x, int y, int z) z += Direction::STEP_Z[dir]; int attachedTo = level->getTile(x, y, z); - return attachedTo == Tile::treeTrunk_Id && TreeTile::getWoodType(level->getData(x, y, z)) == TreeTile::JUNGLE_TRUNK; + return attachedTo == Tile::log_Id && TreeTile::getWoodType(level->getData(x, y, z)) == TreeTile::JUNGLE_TRUNK; } int CocoaTile::getRenderShape() @@ -159,13 +185,13 @@ void CocoaTile::spawnResources(Level *level, int x, int y, int z, int data, floa } for (int i = 0; i < count; i++) { - popResource(level, x, y, z, std::make_shared(Item::dye_powder, 1, DyePowderItem::BROWN)); + popResource(level, x, y, z, std::make_shared(Item::dye, 1, DyePowderItem::BROWN)); } } int CocoaTile::cloneTileId(Level *level, int x, int y, int z) { - return Item::dye_powder_Id; + return Item::dye_Id; } int CocoaTile::cloneTileData(Level *level, int x, int y, int z) diff --git a/Minecraft.World/CocoaTile.h b/Minecraft.World/CocoaTile.h index bcbb1d2f..78c1ca57 100644 --- a/Minecraft.World/CocoaTile.h +++ b/Minecraft.World/CocoaTile.h @@ -15,6 +15,11 @@ public: using Tile::setPlacedBy; CocoaTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual Icon *getTexture(int face, int data); virtual Icon *getTextureForAge(int age); diff --git a/Minecraft.World/CommonStats.cpp b/Minecraft.World/CommonStats.cpp index 44d6577c..408074a6 100644 --- a/Minecraft.World/CommonStats.cpp +++ b/Minecraft.World/CommonStats.cpp @@ -109,9 +109,9 @@ Stat *CommonStats::get_itemsUsed(int itemId) { #if (defined _EXTENDED_ACHIEVEMENTS) && (!defined _XBOX_ONE) // 4J-JEV: I've done the same thing here, we can't place these items anyway. - if (itemId == Item::porkChop_cooked_Id) return Stats::blocksPlaced[itemId]; + if (itemId == Item::cooked_porkchop_Id) return Stats::blocksPlaced[itemId]; #endif - if (itemId == Item::porkChop_cooked_Id) return Stats::blocksPlaced[itemId]; + if (itemId == Item::cooked_porkchop_Id) return Stats::blocksPlaced[itemId]; else return nullptr; //return nullptr; } @@ -176,7 +176,7 @@ Stat *CommonStats::get_achievement(eAward achievementId) case eAward_diamonds: return (Stat *) Achievements::diamonds; //case eAward_portal: return (Stat *) nullptr; // TODO case eAward_ghast: return (Stat *) Achievements::ghast; - case eAward_blazeRod: return (Stat *) Achievements::blazeRod; + case eAward_blazeRod: return (Stat *) Achievements::blaze_rod; case eAward_potion: return (Stat *) Achievements::potion; case eAward_theEnd: return (Stat *) Achievements::theEnd; case eAward_winGame: return (Stat *) Achievements::winGame; diff --git a/Minecraft.World/ComparatorTile.cpp b/Minecraft.World/ComparatorTile.cpp index 3fd46fde..cf534de3 100644 --- a/Minecraft.World/ComparatorTile.cpp +++ b/Minecraft.World/ComparatorTile.cpp @@ -12,6 +12,33 @@ ComparatorTile::ComparatorTile(int id, bool on) : DiodeTile(id, on) _isEntityTile = true; } +void ComparatorTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int ComparatorTile::defaultBlockState() +{ + return 0; +} + +int ComparatorTile::convertBlockStateToLegacyData(BlockState *state) +{ + if (!state) return 0; + return state->value & (DirectionalTile::DIRECTION_MASK | BIT_OUTPUT_SUBTRACT | BIT_IS_LIT); +} + +Tile::BlockState ComparatorTile::getBlockState(int data) +{ + return Tile::BlockState(data & (DirectionalTile::DIRECTION_MASK | BIT_OUTPUT_SUBTRACT | BIT_IS_LIT)); +} + +Tile::BlockState ComparatorTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & (DirectionalTile::DIRECTION_MASK | BIT_OUTPUT_SUBTRACT | BIT_IS_LIT)); +} + int ComparatorTile::getResource(int data, Random *random, int playerBonusLevel) { return Item::comparator_Id; diff --git a/Minecraft.World/ComparatorTile.h b/Minecraft.World/ComparatorTile.h index 3663c651..ef1f92b2 100644 --- a/Minecraft.World/ComparatorTile.h +++ b/Minecraft.World/ComparatorTile.h @@ -14,6 +14,11 @@ private: public: ComparatorTile(int id, bool on); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual int getResource(int data, Random *random, int playerBonusLevel); virtual int cloneTileId(Level *level, int x, int y, int z); diff --git a/Minecraft.World/CompoundTag.h b/Minecraft.World/CompoundTag.h index 83d0bfb2..9c314aeb 100644 --- a/Minecraft.World/CompoundTag.h +++ b/Minecraft.World/CompoundTag.h @@ -205,8 +205,19 @@ public: wstring getString(const wstring &name) { - if (tags.find(name) == tags.end()) return wstring( L"" ); - return static_cast(tags[name])->data; + auto it = tags.find(name); + + if (it == tags.end()) + return L""; + + Tag* tag = it->second; + + if (!tag || tag->getId() != Tag::TAG_String) + return L""; + + StringTag* stringTag = static_cast(tag); + + return stringTag->data; } byteArray getByteArray(const wstring &name) diff --git a/Minecraft.World/CompressedTileStorage.cpp b/Minecraft.World/CompressedTileStorage.cpp index c6ea725b..166f99a8 100644 --- a/Minecraft.World/CompressedTileStorage.cpp +++ b/Minecraft.World/CompressedTileStorage.cpp @@ -604,6 +604,7 @@ int CompressedTileStorage::get(int x, int y, int z) int block, tile; getBlockAndTile( &block, &tile, x, y, z ); + if (blockIndices[block] == 0) return 0; int indexType = blockIndices[block] & INDEX_TYPE_MASK; if( indexType == INDEX_TYPE_0_OR_8_BIT ) diff --git a/Minecraft.World/ControlledByPlayerGoal.cpp b/Minecraft.World/ControlledByPlayerGoal.cpp index c5203e6e..d379191c 100644 --- a/Minecraft.World/ControlledByPlayerGoal.cpp +++ b/Minecraft.World/ControlledByPlayerGoal.cpp @@ -117,13 +117,13 @@ void ControlledByPlayerGoal::tick() { shared_ptr carriedItem = player->getCarriedItem(); - if (carriedItem != nullptr && carriedItem->id == Item::carrotOnAStick_Id) + if (carriedItem != nullptr && carriedItem->id == Item::carrot_on_a_stick_Id) { carriedItem->hurtAndBreak(1, player); if (carriedItem->count == 0) { - shared_ptr replacement = std::make_shared(Item::fishingRod); + shared_ptr replacement = std::make_shared(Item::fishing_rod); replacement->setTag(carriedItem->tag); player->inventory->items[player->inventory->selected] = replacement; } diff --git a/Minecraft.World/Cow.cpp b/Minecraft.World/Cow.cpp index 2ecae481..86620892 100644 --- a/Minecraft.World/Cow.cpp +++ b/Minecraft.World/Cow.cpp @@ -94,11 +94,11 @@ void Cow::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) { if (isOnFire()) { - spawnAtLocation(Item::beef_cooked_Id, 1); + spawnAtLocation(Item::cooked_beef_Id, 1); } else { - spawnAtLocation(Item::beef_raw_Id, 1); + spawnAtLocation(Item::beef_Id, 1); } } } @@ -106,17 +106,17 @@ void Cow::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) bool Cow::mobInteract(shared_ptr player) { shared_ptr item = player->inventory->getSelected(); - if (item != nullptr && item->id == Item::bucket_empty->id && !player->abilities.instabuild) + if (item != nullptr && item->id == Item::bucket->id && !player->abilities.instabuild) { player->awardStat(GenericStats::cowsMilked(),GenericStats::param_cowsMilked()); if (item->count-- == 0) { - player->inventory->setItem(player->inventory->selected, std::make_shared(Item::bucket_milk)); + player->inventory->setItem(player->inventory->selected, std::make_shared(Item::milk_bucket)); } - else if (!player->inventory->add(std::make_shared(Item::bucket_milk))) + else if (!player->inventory->add(std::make_shared(Item::milk_bucket))) { - player->drop(std::make_shared(Item::bucket_milk)); + player->drop(std::make_shared(Item::milk_bucket)); } return true; diff --git a/Minecraft.World/CraftingMenu.cpp b/Minecraft.World/CraftingMenu.cpp index 88631a63..078032f3 100644 --- a/Minecraft.World/CraftingMenu.cpp +++ b/Minecraft.World/CraftingMenu.cpp @@ -65,7 +65,7 @@ void CraftingMenu::removed(shared_ptr player) bool CraftingMenu::stillValid(shared_ptr player) { - if (level->getTile(x, y, z) != Tile::workBench_Id) return false; + if (level->getTile(x, y, z) != Tile::crafting_table_Id) return false; if (player->distanceToSqr(x + 0.5, y + 0.5, z + 0.5) > 8 * 8) return false; return true; } diff --git a/Minecraft.World/Creeper.cpp b/Minecraft.World/Creeper.cpp index e5250fdb..1469d09e 100644 --- a/Minecraft.World/Creeper.cpp +++ b/Minecraft.World/Creeper.cpp @@ -145,7 +145,7 @@ void Creeper::die(DamageSource *source) if ( source->getEntity() != nullptr && source->getEntity()->instanceof(eTYPE_SKELETON) ) { - int recordId = Item::record_01_Id + random->nextInt(Item::record_12_Id - Item::record_01_Id + 1); + int recordId = Item::record_13_Id + random->nextInt(Item::record_wait_Id - Item::record_13_Id + 1); spawnAtLocation(recordId, 1); } @@ -207,7 +207,7 @@ bool Creeper::mobInteract(shared_ptr player) { shared_ptr item = player->inventory->getSelected(); - if (item == nullptr || item->id != Item::flintAndSteel_Id) + if (item == nullptr || item->id != Item::flint_and_steel_Id) return Mob::mobInteract(player); playSound(eSoundType_FIRE_NEWIGNITE, 1, random->nextFloat() * 0.4f + 0.8f); diff --git a/Minecraft.World/CropTile.cpp b/Minecraft.World/CropTile.cpp index 9c2acf78..1c84cc0b 100644 --- a/Minecraft.World/CropTile.cpp +++ b/Minecraft.World/CropTile.cpp @@ -21,6 +21,32 @@ CropTile::CropTile(int id) : Bush(id) sendTileData(); } +void CropTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int CropTile::defaultBlockState() +{ + return 0; +} + +int CropTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x7) : 0; +} + +Tile::BlockState CropTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x7); +} + +Tile::BlockState CropTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x7); +} + // 4J Added override void CropTile::updateDefaultShape() { @@ -118,7 +144,7 @@ int CropTile::getRenderShape() int CropTile::getBaseSeedId() { - return Item::seeds_wheat_Id; + return Item::wheat_seeds_Id; } int CropTile::getBasePlantId() diff --git a/Minecraft.World/CropTile.h b/Minecraft.World/CropTile.h index 165fd4af..3fbde034 100644 --- a/Minecraft.World/CropTile.h +++ b/Minecraft.World/CropTile.h @@ -19,6 +19,11 @@ protected: public: // 4J Added override virtual void updateDefaultShape(); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void tick(Level *level, int x, int y, int z, Random *random); virtual void growCrops(Level *level, int x, int y, int z); private: diff --git a/Minecraft.World/CustomLevelSource.cpp b/Minecraft.World/CustomLevelSource.cpp index de6923e8..ae38f192 100644 --- a/Minecraft.World/CustomLevelSource.cpp +++ b/Minecraft.World/CustomLevelSource.cpp @@ -211,7 +211,7 @@ void CustomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) } else if (yc * CHUNK_HEIGHT + y < waterHeight) { - tileId = static_cast(Tile::calmWater_Id); + tileId = static_cast(Tile::water_Id); } // 4J - more extra code to make sure that the column at the edge of the world is just water & rock, to match the infinite sea that @@ -221,7 +221,7 @@ void CustomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) { // This matches code in MultiPlayerChunkCache that makes the geometry which continues at the edge of the world if( yc * CHUNK_HEIGHT + y <= ( level->getSeaLevel() - 10 ) ) tileId = Tile::stone_Id; - else if( yc * CHUNK_HEIGHT + y < level->getSeaLevel() ) tileId = Tile::calmWater_Id; + else if( yc * CHUNK_HEIGHT + y < level->getSeaLevel() ) tileId = Tile::water_Id; } int indexY = (yc * CHUNK_HEIGHT + y); @@ -293,7 +293,7 @@ void CustomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks, Bi if (y <= 1 + random->nextInt(2)) // 4J - changed to make the bedrock not have bits you can get stuck in // if (y <= 0 + random->nextInt(5)) { - blocks[offs] = static_cast(Tile::unbreakable_Id); + blocks[offs] = static_cast(Tile::bedrock_Id); } else { @@ -325,7 +325,7 @@ void CustomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks, Bi if (y < waterHeight && top == 0) { if (temp < 0.15f) top = static_cast(Tile::ice_Id); - else top = static_cast(Tile::calmWater_Id); + else top = static_cast(Tile::water_Id); } run = runDepth; @@ -342,7 +342,7 @@ void CustomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks, Bi if (run == 0 && material == Tile::sand_Id) { run = random->nextInt(4); - material = static_cast(Tile::sandStone_Id); + material = static_cast(Tile::sandstone_Id); } } } @@ -452,10 +452,10 @@ void CustomLevelSource::calcWaterDepths(ChunkSource *parent, int xt, int zt) if (level->getHeightmap(xp - 1, zp) > 0 || level->getHeightmap(xp + 1, zp) > 0 || level->getHeightmap(xp, zp - 1) > 0 || level->getHeightmap(xp, zp + 1) > 0) { bool hadWater = false; - if (hadWater || (level->getTile(xp - 1, y, zp) == Tile::calmWater_Id && level->getData(xp - 1, y, zp) < 7)) hadWater = true; - if (hadWater || (level->getTile(xp + 1, y, zp) == Tile::calmWater_Id && level->getData(xp + 1, y, zp) < 7)) hadWater = true; - if (hadWater || (level->getTile(xp, y, zp - 1) == Tile::calmWater_Id && level->getData(xp, y, zp - 1) < 7)) hadWater = true; - if (hadWater || (level->getTile(xp, y, zp + 1) == Tile::calmWater_Id && level->getData(xp, y, zp + 1) < 7)) hadWater = true; + if (hadWater || (level->getTile(xp - 1, y, zp) == Tile::water_Id && level->getData(xp - 1, y, zp) < 7)) hadWater = true; + if (hadWater || (level->getTile(xp + 1, y, zp) == Tile::water_Id && level->getData(xp + 1, y, zp) < 7)) hadWater = true; + if (hadWater || (level->getTile(xp, y, zp - 1) == Tile::water_Id && level->getData(xp, y, zp - 1) < 7)) hadWater = true; + if (hadWater || (level->getTile(xp, y, zp + 1) == Tile::water_Id && level->getData(xp, y, zp + 1) < 7)) hadWater = true; if (hadWater) { for (int x2 = -5; x2 <= 5; x2++) @@ -467,7 +467,7 @@ void CustomLevelSource::calcWaterDepths(ChunkSource *parent, int xt, int zt) if (d <= 5) { d = 6 - d; - if (level->getTile(xp + x2, y, zp + z2) == Tile::calmWater_Id) + if (level->getTile(xp + x2, y, zp + z2) == Tile::water_Id) { int od = level->getData(xp + x2, y, zp + z2); if (od < 7 && od < d) @@ -480,10 +480,10 @@ void CustomLevelSource::calcWaterDepths(ChunkSource *parent, int xt, int zt) } if (hadWater) { - level->setTileAndData(xp, y, zp, Tile::calmWater_Id, 7, Tile::UPDATE_CLIENTS); + level->setTileAndData(xp, y, zp, Tile::water_Id, 7, Tile::UPDATE_CLIENTS); for (int y2 = 0; y2 < y; y2++) { - level->setTileAndData(xp, y2, zp, Tile::calmWater_Id, 8, Tile::UPDATE_CLIENTS); + level->setTileAndData(xp, y2, zp, Tile::water_Id, 8, Tile::UPDATE_CLIENTS); } } } @@ -534,7 +534,7 @@ void CustomLevelSource::postProcess(ChunkSource *parent, int xt, int zt) int y = pprandom->nextInt(Level::maxBuildHeight); int z = zo + pprandom->nextInt(16) + 8; - LakeFeature *calmWater = new LakeFeature(Tile::calmWater_Id); + LakeFeature *calmWater = new LakeFeature(Tile::water_Id); calmWater->place(level, pprandom, x, y, z); delete calmWater; } @@ -548,7 +548,7 @@ void CustomLevelSource::postProcess(ChunkSource *parent, int xt, int zt) int z = zo + pprandom->nextInt(16) + 8; if (y < level->seaLevel || pprandom->nextInt(10) == 0) { - LakeFeature *calmLava = new LakeFeature(Tile::calmLava_Id); + LakeFeature *calmLava = new LakeFeature(Tile::lava_Id); calmLava->place(level, pprandom, x, y, z); delete calmLava; } @@ -592,7 +592,7 @@ void CustomLevelSource::postProcess(ChunkSource *parent, int xt, int zt) } if (level->shouldSnow(x + xo, y, z + zo)) { - level->setTileAndData(x + xo, y, z + zo, Tile::topSnow_Id,0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x + xo, y, z + zo, Tile::snow_layer_Id,0, Tile::UPDATE_CLIENTS); } } } diff --git a/Minecraft.World/DaylightDetectorTile.cpp b/Minecraft.World/DaylightDetectorTile.cpp index 366db5ac..4c072ae3 100644 --- a/Minecraft.World/DaylightDetectorTile.cpp +++ b/Minecraft.World/DaylightDetectorTile.cpp @@ -14,6 +14,32 @@ DaylightDetectorTile::DaylightDetectorTile(int id, bool inverted) : BaseEntityTi updateDefaultShape(); } +void DaylightDetectorTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int DaylightDetectorTile::defaultBlockState() +{ + return 0; +} + +int DaylightDetectorTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState DaylightDetectorTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState DaylightDetectorTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + void DaylightDetectorTile::updateDefaultShape() { setShape(0, 0, 0, 1, 6.0f / 16.0f, 1); @@ -90,9 +116,9 @@ bool DaylightDetectorTile::use(Level *level, int x, int y, int z, shared_ptrgetData(x, y, z); if (inverted) - level->setTileAndData(x, y, z, Tile::daylightDetector_Id, data, Tile::UPDATE_INVISIBLE); + level->setTileAndData(x, y, z, Tile::daylight_detector_Id, data, Tile::UPDATE_INVISIBLE); else - level->setTileAndData(x, y, z, Tile::invertedDaylightDetector_Id, data, Tile::UPDATE_INVISIBLE); + level->setTileAndData(x, y, z, Tile::daylight_detector_inverted_Id, data, Tile::UPDATE_INVISIBLE); updateSignalStrength(level, x, y, z); } diff --git a/Minecraft.World/DaylightDetectorTile.h b/Minecraft.World/DaylightDetectorTile.h index 13b20c6d..d940eda0 100644 --- a/Minecraft.World/DaylightDetectorTile.h +++ b/Minecraft.World/DaylightDetectorTile.h @@ -12,6 +12,12 @@ private: public: DaylightDetectorTile(int id, bool inverted); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual void updateDefaultShape(); // 4J Added override virtual void updateShape(LevelSource *level, int x, int y, int z, int forceData = -1, shared_ptr forceEntity = shared_ptr()); virtual int getSignal(LevelSource *level, int x, int y, int z, int dir); diff --git a/Minecraft.World/DesertWellFeature.cpp b/Minecraft.World/DesertWellFeature.cpp index 62e19bb8..b5892468 100644 --- a/Minecraft.World/DesertWellFeature.cpp +++ b/Minecraft.World/DesertWellFeature.cpp @@ -33,17 +33,17 @@ bool DesertWellFeature::place(Level *level, Random *random, int x, int y, int z) { for (int oz = -2; oz <= 2; oz++) { - level->setTileAndData(x + ox, y + oy, z + oz, Tile::sandStone_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x + ox, y + oy, z + oz, Tile::sandstone_Id, 0, Tile::UPDATE_CLIENTS); } } } // place water cross - level->setTileAndData(x, y, z, Tile::water_Id, 0, Tile::UPDATE_CLIENTS); - level->setTileAndData(x - 1, y, z, Tile::water_Id, 0, Tile::UPDATE_CLIENTS); - level->setTileAndData(x + 1, y, z, Tile::water_Id, 0, Tile::UPDATE_CLIENTS); - level->setTileAndData(x, y, z - 1, Tile::water_Id, 0, Tile::UPDATE_CLIENTS); - level->setTileAndData(x, y, z + 1, Tile::water_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y, z, Tile::flowing_water_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x - 1, y, z, Tile::flowing_water_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x + 1, y, z, Tile::flowing_water_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y, z - 1, Tile::flowing_water_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y, z + 1, Tile::flowing_water_Id, 0, Tile::UPDATE_CLIENTS); // place "fence" for (int ox = -2; ox <= 2; ox++) @@ -52,14 +52,14 @@ bool DesertWellFeature::place(Level *level, Random *random, int x, int y, int z) { if (ox == -2 || ox == 2 || oz == -2 || oz == 2) { - level->setTileAndData(x + ox, y + 1, z + oz, Tile::sandStone_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x + ox, y + 1, z + oz, Tile::sandstone_Id, 0, Tile::UPDATE_CLIENTS); } } } - level->setTileAndData(x + 2, y + 1, z, Tile::stoneSlabHalf_Id, StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS); - level->setTileAndData(x - 2, y + 1, z, Tile::stoneSlabHalf_Id, StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS); - level->setTileAndData(x, y + 1, z + 2, Tile::stoneSlabHalf_Id, StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS); - level->setTileAndData(x, y + 1, z - 2, Tile::stoneSlabHalf_Id, StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS); + level->setTileAndData(x + 2, y + 1, z, Tile::stone_slab_Id, StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS); + level->setTileAndData(x - 2, y + 1, z, Tile::stone_slab_Id, StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y + 1, z + 2, Tile::stone_slab_Id, StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y + 1, z - 2, Tile::stone_slab_Id, StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS); // place roof for (int ox = -1; ox <= 1; ox++) @@ -68,11 +68,11 @@ bool DesertWellFeature::place(Level *level, Random *random, int x, int y, int z) { if (ox == 0 && oz == 0) { - level->setTileAndData(x + ox, y + 4, z + oz, Tile::sandStone_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x + ox, y + 4, z + oz, Tile::sandstone_Id, 0, Tile::UPDATE_CLIENTS); } else { - level->setTileAndData(x + ox, y + 4, z + oz, Tile::stoneSlabHalf_Id, StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS); + level->setTileAndData(x + ox, y + 4, z + oz, Tile::stone_slab_Id, StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS); } } } @@ -80,10 +80,10 @@ bool DesertWellFeature::place(Level *level, Random *random, int x, int y, int z) // place pillars for (int oy = 1; oy <= 3; oy++) { - level->setTileAndData(x - 1, y + oy, z - 1, Tile::sandStone_Id, 0, Tile::UPDATE_CLIENTS); - level->setTileAndData(x - 1, y + oy, z + 1, Tile::sandStone_Id, 0, Tile::UPDATE_CLIENTS); - level->setTileAndData(x + 1, y + oy, z - 1, Tile::sandStone_Id, 0, Tile::UPDATE_CLIENTS); - level->setTileAndData(x + 1, y + oy, z + 1, Tile::sandStone_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x - 1, y + oy, z - 1, Tile::sandstone_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x - 1, y + oy, z + 1, Tile::sandstone_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x + 1, y + oy, z - 1, Tile::sandstone_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x + 1, y + oy, z + 1, Tile::sandstone_Id, 0, Tile::UPDATE_CLIENTS); } return true; diff --git a/Minecraft.World/DiodeTile.cpp b/Minecraft.World/DiodeTile.cpp index b40a5af5..0c88fc0a 100644 --- a/Minecraft.World/DiodeTile.cpp +++ b/Minecraft.World/DiodeTile.cpp @@ -191,7 +191,7 @@ int DiodeTile::getInputSignal(Level *level, int x, int y, int z, int data) int input = level->getSignal(xx, y, zz, Direction::DIRECTION_FACING[dir]); if (input >= Redstone::SIGNAL_MAX) return input; - return max(input, level->getTile(xx, y, zz) == Tile::redStoneDust_Id ? level->getData(xx, y, zz) : Redstone::SIGNAL_NONE); + return max(input, level->getTile(xx, y, zz) == Tile::redstone_wire_Id ? level->getData(xx, y, zz) : Redstone::SIGNAL_NONE); } int DiodeTile::getAlternateSignal(LevelSource *level, int x, int y, int z, int data) @@ -217,7 +217,7 @@ int DiodeTile::getAlternateSignalAt(LevelSource *level, int x, int y, int z, int if (isAlternateInput(tile)) { - if (tile == Tile::redStoneDust_Id) + if (tile == Tile::redstone_wire_Id) { return level->getData(x, y, z); } @@ -309,7 +309,7 @@ int DiodeTile::getOutputSignal(LevelSource *level, int x, int y, int z, int data bool DiodeTile::isDiode(int id) { - return Tile::diode_off->isSameDiode(id) || Tile::comparator_off->isSameDiode(id); + return Tile::unpowered_repeater->isSameDiode(id) || Tile::comparator_off->isSameDiode(id); } bool DiodeTile::isSameDiode(int id) diff --git a/Minecraft.World/Direction.cpp b/Minecraft.World/Direction.cpp index c9ac93c7..f6e9fb1b 100644 --- a/Minecraft.World/Direction.cpp +++ b/Minecraft.World/Direction.cpp @@ -89,6 +89,16 @@ int Direction::getDirection(double xd, double zd) } } +int Direction::from2DDataValue(int param) +{ + return (param & 3); +} + +int Direction::getOpposite(int dir) +{ + return DIRECTION_OPPOSITE[dir & 3]; +} + int Direction::getDirection(int x0, int z0, int x1, int z1) { int xd = x0 - x1; diff --git a/Minecraft.World/Direction.h b/Minecraft.World/Direction.h index 8b8b91bf..d327d4ab 100644 --- a/Minecraft.World/Direction.h +++ b/Minecraft.World/Direction.h @@ -32,6 +32,9 @@ public: // for [direction][world-facing] it gives [tile-facing] static int RELATIVE_DIRECTION_FACING[4][6]; + static int getOpposite(int dir); + static int from2DDataValue(int param); + static int getDirection(double xd, double zd); static int getDirection(int x0, int z0, int x1, int z1); diff --git a/Minecraft.World/DirectionalTile.cpp b/Minecraft.World/DirectionalTile.cpp index e1231a00..65ad3c7d 100644 --- a/Minecraft.World/DirectionalTile.cpp +++ b/Minecraft.World/DirectionalTile.cpp @@ -4,6 +4,7 @@ DirectionalTile::DirectionalTile(int id, Material *material, bool isSolidRender) : Tile(id, material, isSolidRender) { + setLightBlock(0); } int DirectionalTile::getDirection(int data) diff --git a/Minecraft.World/DispenserTile.cpp b/Minecraft.World/DispenserTile.cpp index 5098fe30..0ffb76be 100644 --- a/Minecraft.World/DispenserTile.cpp +++ b/Minecraft.World/DispenserTile.cpp @@ -23,6 +23,32 @@ DispenserTile::DispenserTile(int id) : BaseEntityTile(id, Material::stone) iconFrontVertical = nullptr; } +void DispenserTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int DispenserTile::defaultBlockState() +{ + return 0; +} + +int DispenserTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & (FACING_MASK | TRIGGER_BIT)) : 0; +} + +Tile::BlockState DispenserTile::getBlockState(int data) +{ + return Tile::BlockState(data & (FACING_MASK | TRIGGER_BIT)); +} + +Tile::BlockState DispenserTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & (FACING_MASK | TRIGGER_BIT)); +} + int DispenserTile::getTickDelay(Level *level) { return 4; diff --git a/Minecraft.World/DispenserTile.h b/Minecraft.World/DispenserTile.h index 1205be94..d63fb427 100644 --- a/Minecraft.World/DispenserTile.h +++ b/Minecraft.World/DispenserTile.h @@ -29,6 +29,11 @@ protected: public: virtual int getTickDelay(Level *level); virtual void onPlace(Level *level, int x, int y, int z); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); private: void recalcLockDir(Level *level, int x, int y, int z); diff --git a/Minecraft.World/DoorInteractGoal.cpp b/Minecraft.World/DoorInteractGoal.cpp index 45805744..97fdf823 100644 --- a/Minecraft.World/DoorInteractGoal.cpp +++ b/Minecraft.World/DoorInteractGoal.cpp @@ -68,6 +68,6 @@ void DoorInteractGoal::tick() DoorTile *DoorInteractGoal::getDoorTile(int x, int y, int z) { int tileId = mob->level->getTile(x, y, z); - if (tileId != Tile::door_wood_Id) return nullptr; + if (tileId != Tile::wooden_door_Id) return nullptr; return static_cast(Tile::tiles[tileId]); } \ No newline at end of file diff --git a/Minecraft.World/DoorItem.cpp b/Minecraft.World/DoorItem.cpp index 7406a2fd..8171ecc1 100644 --- a/Minecraft.World/DoorItem.cpp +++ b/Minecraft.World/DoorItem.cpp @@ -26,13 +26,13 @@ bool DoorItem::useOn(shared_ptr instance, shared_ptr playe Tile *tile; - if (doorType == L"doorWood") tile = Tile::door_wood; - else if (doorType == L"doorIron") tile = Tile::door_iron; - else if (doorType == L"doorSpruce") tile = Tile::door_spruce; - else if (doorType == L"doorBirch") tile = Tile::door_birch; - else if (doorType == L"doorJungle") tile = Tile::door_jungle; - else if (doorType == L"doorAcacia") tile = Tile::door_acacia; - else if (doorType == L"doorDark") tile = Tile::door_dark; + if (doorType == L"doorWood") tile = Tile::wooden_door; + else if (doorType == L"doorIron") tile = Tile::iron_door; + else if (doorType == L"doorSpruce") tile = Tile::spruce_door; + else if (doorType == L"doorBirch") tile = Tile::birch_door; + else if (doorType == L"doorJungle") tile = Tile::jungle_door; + else if (doorType == L"doorAcacia") tile = Tile::acacia_door; + else if (doorType == L"doorDark") tile = Tile::dark_oak_door; if (!player->mayUseItemAt(x, y, z, face, instance) || !player->mayUseItemAt(x, y + 1, z, face, instance)) return false; if (!tile->mayPlace(level, x, y, z)) return false; diff --git a/Minecraft.World/DoorTile.cpp b/Minecraft.World/DoorTile.cpp index 300f4e39..31540b5b 100644 --- a/Minecraft.World/DoorTile.cpp +++ b/Minecraft.World/DoorTile.cpp @@ -9,17 +9,18 @@ #include "net.minecraft.h" static std::map doorItemMap = { - { L"doorWood", Item::door_wood_Id }, - { L"doorIron", Item::door_iron_Id }, - { L"doorSpruce", Item::door_spruce_Id }, - { L"doorBirch", Item::door_birch_Id }, - { L"doorJungle", Item::door_jungle_Id }, - { L"doorAcacia", Item::door_acacia_Id }, - { L"doorDark", Item::door_dark_Id } + { L"doorWood", Item::wooden_door_Id }, + { L"doorIron", Item::iron_door_Id }, + { L"doorSpruce", Item::spruce_door_Id }, + { L"doorBirch", Item::birch_door_Id }, + { L"doorJungle", Item::jungle_door_Id }, + { L"doorAcacia", Item::acacia_door_Id }, + { L"doorDark", Item::dark_oak_door_Id } }; DoorTile::DoorTile(int id, Material *material, const wstring& doorType) : Tile(id, material,isSolidRender()) { + setLightBlock(0); this->doorType = doorType; float r = 0.5f; @@ -180,7 +181,7 @@ void DoorTile::attack(Level *level, int x, int y, int z, shared_ptr play // 4J-PB - Adding a TestUse for tooltip display bool DoorTile::TestUse() { - return id == Tile::door_wood_Id; + return id == Tile::wooden_door_Id; } bool DoorTile::use(Level *level, int x, int y, int z, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly/*=false*/) // 4J added soundOnly param @@ -354,4 +355,86 @@ void DoorTile::playerWillDestroy(Level *level, int x, int y, int z, int data, sh } } } +} + +void DoorTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int DoorTile::defaultBlockState() +{ + return 0; // closed +} + +Tile::BlockState DoorTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + int composite = getCompositeData(level, x, y, z); + return Tile::BlockState(composite); +} + +int DoorTile::convertBlockStateToLegacyData(BlockState *state) +{ + if (!state) return 0; + int composite = state->value; + + if (composite & C_IS_UPPER_MASK) + { + int base = (composite & C_RIGHT_HINGE_MASK) ? 9 : 8; + if (composite & C_OPEN_MASK) base |= 2; + return base; + } + else + { + int base = composite & C_DIR_MASK; + if (composite & C_OPEN_MASK) base |= 4; + return base; + } +} + +Tile::BlockState DoorTile::getBlockState(int data) +{ + int composite = 0; + if ((data & UPPER_BIT) == 0) { + composite = data & C_LOWER_DATA_MASK; + } else { + composite = C_IS_UPPER_MASK; + if ((data & 1) != 0) composite |= C_RIGHT_HINGE_MASK; + } + return Tile::BlockState(composite); +} + +void DoorTile::fillVirtualBlockStateProperties(Tile::BlockState *state, LevelSource *level, const BlockPos &pos) +{ + if (!state) return; + int composite = getCompositeData(level, pos.getX(), pos.getY(), pos.getZ()); + state->value = composite; +} + +bool DoorTile::use(Level *level, const BlockPos &pos, Tile::BlockState *state, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly) +{ + if (soundOnly) + { + if (material != Material::metal) + level->levelEvent(player, LevelEvent::SOUND_OPEN_DOOR, pos.getX(), pos.getY(), pos.getZ(), 0); + return false; + } + + if (material == Material::metal) return true; + + int composite = state ? state->value : getCompositeData(level, pos.getX(), pos.getY(), pos.getZ()); + int lowerData = composite & C_LOWER_DATA_MASK; + lowerData ^= 4; + + if ((composite & C_IS_UPPER_MASK) == 0) { + level->setData(pos.getX(), pos.getY(), pos.getZ(), lowerData, Tile::UPDATE_CLIENTS); + level->setTilesDirty(pos.getX(), pos.getY(), pos.getZ(), pos.getX(), pos.getY(), pos.getZ()); + } else { + level->setData(pos.getX(), pos.getY() - 1, pos.getZ(), lowerData, Tile::UPDATE_CLIENTS); + level->setTilesDirty(pos.getX(), pos.getY() - 1, pos.getZ(), pos.getX(), pos.getY(), pos.getZ()); + } + + level->levelEvent(player, LevelEvent::SOUND_OPEN_DOOR, pos.getX(), pos.getY(), pos.getZ(), 0); + return true; } \ No newline at end of file diff --git a/Minecraft.World/DoorTile.h b/Minecraft.World/DoorTile.h index a2876d1c..a532e5cd 100644 --- a/Minecraft.World/DoorTile.h +++ b/Minecraft.World/DoorTile.h @@ -62,4 +62,15 @@ public: int getCompositeData(LevelSource *level, int x, int y, int z); virtual int cloneTileId(Level *level, int x, int y, int z); virtual void playerWillDestroy(Level *level, int x, int y, int z, int data, shared_ptr player); + + virtual void createBlockStateDefinition() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual int defaultBlockState() override; + + Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z); + Tile::BlockState getBlockState(int data); + + void fillVirtualBlockStateProperties(Tile::BlockState *state, LevelSource *level, const BlockPos &pos); + + virtual bool use(Level *level, const BlockPos &pos, Tile::BlockState *state, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false); }; diff --git a/Minecraft.World/DoublePlantFeature.cpp b/Minecraft.World/DoublePlantFeature.cpp index 7c5a9f6f..506610fa 100644 --- a/Minecraft.World/DoublePlantFeature.cpp +++ b/Minecraft.World/DoublePlantFeature.cpp @@ -30,11 +30,11 @@ bool DoublePlantFeature::place(Level* level, Random* rand, int x, int y, int z) if (level->getTile(bx, by + 1, bz) != 0) continue; - if (!static_cast(Tile::tiles[Tile::tallgrass2_Id])->mayPlace(level, bx, by, bz)) continue; + if (!static_cast(Tile::tiles[Tile::double_plant_Id])->mayPlace(level, bx, by, bz)) continue; - level->setTileAndData(bx, by, bz, Tile::tallgrass2_Id, m_plantType, 0); - level->setTileAndData(bx, by + 1, bz, Tile::tallgrass2_Id, TallGrass2::UPPER_BIT | m_plantType, 0); + level->setTileAndData(bx, by, bz, Tile::double_plant_Id, m_plantType, 0); + level->setTileAndData(bx, by + 1, bz, Tile::double_plant_Id, TallGrass2::UPPER_BIT | m_plantType, 0); placed = true; } diff --git a/Minecraft.World/DropperTile.cpp b/Minecraft.World/DropperTile.cpp index 180aec2a..cb5a88e4 100644 --- a/Minecraft.World/DropperTile.cpp +++ b/Minecraft.World/DropperTile.cpp @@ -12,6 +12,31 @@ DropperTile::DropperTile(int id) : DispenserTile(id) DISPENSE_BEHAVIOUR = new DefaultDispenseItemBehavior(); } +void DropperTile::createBlockStateDefinition() +{ + DispenserTile::createBlockStateDefinition(); +} + +int DropperTile::defaultBlockState() +{ + return DispenserTile::defaultBlockState(); +} + +int DropperTile::convertBlockStateToLegacyData(BlockState *state) +{ + return DispenserTile::convertBlockStateToLegacyData(state); +} + +Tile::BlockState DropperTile::getBlockState(int data) +{ + return DispenserTile::getBlockState(data); +} + +Tile::BlockState DropperTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return DispenserTile::getBlockState(level, x, y, z); +} + void DropperTile::registerIcons(IconRegister *iconRegister) { icon = iconRegister->registerIcon(L"furnace_side"); diff --git a/Minecraft.World/DropperTile.h b/Minecraft.World/DropperTile.h index 7769abde..3dbbd0b7 100644 --- a/Minecraft.World/DropperTile.h +++ b/Minecraft.World/DropperTile.h @@ -9,6 +9,11 @@ private: public: DropperTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void registerIcons(IconRegister *iconRegister); diff --git a/Minecraft.World/DungeonFeature.cpp b/Minecraft.World/DungeonFeature.cpp index 8c9abbe5..0941ee9a 100644 --- a/Minecraft.World/DungeonFeature.cpp +++ b/Minecraft.World/DungeonFeature.cpp @@ -110,7 +110,7 @@ void DungeonFeature::addTunnel(int xOffs, int zOffs, byteArray blocks, double xC { int p = (xx * 16 + zz) * Level::genDepth + yy; if (yy < 0 || yy >= Level::genDepth) continue; - if (blocks[p] == Tile::water_Id || blocks[p] == Tile::calmWater_Id) + if (blocks[p] == Tile::flowing_water_Id || blocks[p] == Tile::water_Id) { detectedWater = true; } @@ -142,7 +142,7 @@ void DungeonFeature::addTunnel(int xOffs, int zOffs, byteArray blocks, double xC { if (yy < 10) { - blocks[p] = static_cast(Tile::lava_Id); + blocks[p] = static_cast(Tile::flowing_lava_Id); } else { diff --git a/Minecraft.World/DurangoStats.cpp b/Minecraft.World/DurangoStats.cpp index 776927cb..97a0e79b 100644 --- a/Minecraft.World/DurangoStats.cpp +++ b/Minecraft.World/DurangoStats.cpp @@ -55,7 +55,7 @@ bool DsItemEvent::onLeaderboard(ELeaderboardId leaderboard, eAcquisitionMethod m switch (param->itemId) { case Tile::dirt_Id: - case Tile::stoneBrick_Id: + case Tile::stonebrick_Id: case Tile::sand_Id: case Tile::stone_Id: case Tile::gravel_Id: @@ -92,13 +92,13 @@ int DsItemEvent::mergeIds(int itemId) case Tile::farmland_Id: return Tile::dirt_Id; - case Tile::redstoneLight_Id: - case Tile::redstoneLight_lit_Id: - return Tile::redstoneLight_Id; + case Tile::redstone_lamp_Id: + case Tile::lit_redstone_lamp_Id: + return Tile::redstone_lamp_Id; - case Tile::redStoneOre_Id: - case Tile::redStoneOre_lit_Id: - return Tile::redStoneOre_Id; + case Tile::redstone_ore_Id: + case Tile::lit_redstone_ore_Id: + return Tile::redstone_ore_Id; } } @@ -769,7 +769,7 @@ Stat* DurangoStats::get_pigOneM() Stat *DurangoStats::get_cowsMilked() { - return get_itemsCrafted(Item::bucket_milk_Id); + return get_itemsCrafted(Item::milk_bucket_Id); } Stat* DurangoStats::get_killMob() @@ -828,14 +828,14 @@ Stat* DurangoStats::get_itemsCrafted(int itemId) { // 4J-JEV: These items can be crafted trivially to and from their block equivalents, // 'Acquire Hardware' also relies on 'Count_Crafted(IronIngot) == Count_Forged(IronIngot)" on the Stats server. - case Item::ironIngot_Id: - case Item::goldIngot_Id: + case Item::iron_ingot_Id: + case Item::gold_ingot_Id: case Item::diamond_Id: - case Item::redStone_Id: + case Item::redstone_Id: case Item::emerald_Id: return nullptr; - case Item::dye_powder_Id: + case Item::dye_Id: default: return (Stat*) itemsAcquired; } @@ -930,7 +930,7 @@ byteArray DurangoStats::getParam_pigOneM(int distance) byteArray DurangoStats::getParam_cowsMilked() { - return DsItemEvent::createParamBlob(DsItemEvent::eAcquisitionMethod_Crafted, Item::bucket_milk_Id, 0, 1); + return DsItemEvent::createParamBlob(DsItemEvent::eAcquisitionMethod_Crafted, Item::milk_bucket_Id, 0, 1); } byteArray DurangoStats::getParam_blocksPlaced(int blockId, int data, int count) diff --git a/Minecraft.World/DyePowderItem.cpp b/Minecraft.World/DyePowderItem.cpp index c857d782..e4a87ddb 100644 --- a/Minecraft.World/DyePowderItem.cpp +++ b/Minecraft.World/DyePowderItem.cpp @@ -144,7 +144,7 @@ bool DyePowderItem::useOn(shared_ptr itemInstance, shared_ptrgetTile(x, y, z); int data = level->getData(x, y, z); - if (tile == Tile::treeTrunk_Id && TreeTile::getWoodType(data) == TreeTile::JUNGLE_TRUNK) + if (tile == Tile::log_Id && TreeTile::getWoodType(data) == TreeTile::JUNGLE_TRUNK) { if (face == 0) return false; if (face == 1) return false; @@ -208,7 +208,7 @@ bool DyePowderItem::growCrop(shared_ptr itemInstance, Level *level } return true; } - else if (tile == Tile::melonStem_Id || tile == Tile::pumpkinStem_Id) + else if (tile == Tile::melon_stem_Id || tile == Tile::pumpkin_stem_Id) { if (level->getData(x, y, z) == 7) return false; if(!bTestUseOnOnly) @@ -296,11 +296,11 @@ bool DyePowderItem::growCrop(shared_ptr itemInstance, Level *level } else if (random->nextInt(3) != 0) { - if (Tile::flower->canSurvive(level, xx, yy, zz)) level->setTileAndUpdate(xx, yy, zz, Tile::flower_Id); + if (Tile::flower->canSurvive(level, xx, yy, zz)) level->setTileAndUpdate(xx, yy, zz, Tile::yellow_flower_Id); } else { - if (Tile::rose->canSurvive(level, xx, yy, zz)) level->setTileAndUpdate(xx, yy, zz, Tile::rose_Id); + if (Tile::rose->canSurvive(level, xx, yy, zz)) level->setTileAndUpdate(xx, yy, zz, Tile::red_flower_Id); } } diff --git a/Minecraft.World/EnchantmentHelper.cpp b/Minecraft.World/EnchantmentHelper.cpp index bdb4aa76..e02299b3 100644 --- a/Minecraft.World/EnchantmentHelper.cpp +++ b/Minecraft.World/EnchantmentHelper.cpp @@ -36,7 +36,7 @@ int EnchantmentHelper::getEnchantmentLevel(int enchantmentId, shared_ptr *EnchantmentHelper::getEnchantments(shared_ptr item) { unordered_map *result = new unordered_map(); - ListTag *list = item->id == Item::enchantedBook_Id ? Item::enchantedBook->getEnchantments(item) : item->getEnchantmentTags(); + ListTag *list = item->id == Item::enchanted_book_Id ? Item::enchanted_book->getEnchantments(item) : item->getEnchantmentTags(); if (list != nullptr) { @@ -67,15 +67,15 @@ void EnchantmentHelper::setEnchantments(unordered_map *enchantments, s list->add(tag); - if (item->id == Item::enchantedBook_Id) + if (item->id == Item::enchanted_book_Id) { - Item::enchantedBook->addEnchantment(item, new EnchantmentInstance(id, it.second)); + Item::enchanted_book->addEnchantment(item, new EnchantmentInstance(id, it.second)); } } if (list->size() > 0) { - if (item->id != Item::enchantedBook_Id) + if (item->id != Item::enchanted_book_Id) { item->addTagElement(L"ench", list); } @@ -304,7 +304,7 @@ shared_ptr EnchantmentHelper::enchantItem(Random *random, shared_p vector *newEnchantment = EnchantmentHelper::selectEnchantment(random, itemInstance, enchantmentCost); bool isBook = itemInstance->id == Item::book_Id; - if (isBook) itemInstance->id = Item::enchantedBook_Id; + if (isBook) itemInstance->id = Item::enchanted_book_Id; if ( newEnchantment ) { @@ -314,7 +314,7 @@ shared_ptr EnchantmentHelper::enchantItem(Random *random, shared_p { if (isBook) { - Item::enchantedBook->addEnchantment(itemInstance, e); + Item::enchanted_book->addEnchantment(itemInstance, e); } else { diff --git a/Minecraft.World/EnchantmentMenu.cpp b/Minecraft.World/EnchantmentMenu.cpp index eb94b11e..56505c00 100644 --- a/Minecraft.World/EnchantmentMenu.cpp +++ b/Minecraft.World/EnchantmentMenu.cpp @@ -238,7 +238,7 @@ bool EnchantmentMenu::clickMenuButton(shared_ptr player, int i) { player->giveExperienceLevels(-(i + 1)); - if (isBook) item->id = Item::enchantedBook_Id; + if (isBook) item->id = Item::enchanted_book_Id; int randomIndex = isBook ? random.nextInt(newEnchantment->size()) : -1; for (int index = 0; index < newEnchantment->size(); index++) @@ -246,7 +246,7 @@ bool EnchantmentMenu::clickMenuButton(shared_ptr player, int i) EnchantmentInstance* e = newEnchantment->at(index); if (isBook) { - Item::enchantedBook->addEnchantment(item, e); + Item::enchanted_book->addEnchantment(item, e); en = true; } else @@ -327,7 +327,7 @@ void EnchantmentMenu::removed(shared_ptr player) bool EnchantmentMenu::stillValid(shared_ptr player) { - if (level->getTile(x, y, z) != Tile::enchantTable_Id) return false; + if (level->getTile(x, y, z) != Tile::enchanting_table_Id) return false; if (player->distanceToSqr(x + 0.5, y + 0.5, z + 0.5) > 8 * 8) return false; return true; } diff --git a/Minecraft.World/EndPodiumFeature.cpp b/Minecraft.World/EndPodiumFeature.cpp index 7cf742fa..a3b08d60 100644 --- a/Minecraft.World/EndPodiumFeature.cpp +++ b/Minecraft.World/EndPodiumFeature.cpp @@ -33,8 +33,8 @@ bool EndPodiumFeature::place(Level *level, Random *random, int x, int y, int z) } else { - //level->setTile(xx, yy, zz, Tile::unbreakable_Id); - placeBlock(level, xx, yy, zz, Tile::unbreakable_Id, 0); + //level->setTile(xx, yy, zz, Tile::bedrock_Id); + placeBlock(level, xx, yy, zz, Tile::bedrock_Id, 0); } } else if (yy > y) @@ -46,8 +46,8 @@ bool EndPodiumFeature::place(Level *level, Random *random, int x, int y, int z) { if (d > r - 1 - 0.5) { - //level->setTile(xx, yy, zz, Tile::unbreakable_Id); - placeBlock(level, xx, yy, zz, Tile::unbreakable_Id, 0); + //level->setTile(xx, yy, zz, Tile::bedrock_Id); + placeBlock(level, xx, yy, zz, Tile::bedrock_Id, 0); } } } @@ -55,15 +55,15 @@ bool EndPodiumFeature::place(Level *level, Random *random, int x, int y, int z) } } - placeBlock(level,x, y + 0, z, Tile::unbreakable_Id, 0); - placeBlock(level,x, y + 1, z, Tile::unbreakable_Id, 0); - placeBlock(level,x, y + 2, z, Tile::unbreakable_Id, 0); + placeBlock(level,x, y + 0, z, Tile::bedrock_Id, 0); + placeBlock(level,x, y + 1, z, Tile::bedrock_Id, 0); + placeBlock(level,x, y + 2, z, Tile::bedrock_Id, 0); placeBlock(level,x - 1, y + 2, z, Tile::torch_Id, 0); placeBlock(level,x + 1, y + 2, z, Tile::torch_Id, 0); placeBlock(level,x, y + 2, z - 1, Tile::torch_Id, 0); placeBlock(level,x, y + 2, z + 1, Tile::torch_Id, 0); - placeBlock(level,x, y + 3, z, Tile::unbreakable_Id, 0); - //placeBlock(level,x, y + 4, z, Tile::dragonEgg_Id, 0); + placeBlock(level,x, y + 3, z, Tile::bedrock_Id, 0); + //placeBlock(level,x, y + 4, z, Tile::dragon_egg_Id, 0); // 4J-PB - The podium can be floating with nothing under it, so put some whiteStone under it if this is the case for (int yy = y - 5; yy < y - 1; yy++) @@ -74,7 +74,7 @@ bool EndPodiumFeature::place(Level *level, Random *random, int x, int y, int z) { if(level->isEmptyTile(xx,yy,zz)) { - placeBlock(level, xx, yy, zz, Tile::endStone_Id, 0); + placeBlock(level, xx, yy, zz, Tile::end_stone_Id, 0); } } } diff --git a/Minecraft.World/EnderChestTileEntity.cpp b/Minecraft.World/EnderChestTileEntity.cpp index 1ad682ae..457119e7 100644 --- a/Minecraft.World/EnderChestTileEntity.cpp +++ b/Minecraft.World/EnderChestTileEntity.cpp @@ -16,7 +16,7 @@ void EnderChestTileEntity::tick() if (++tickInterval % 20 * 4 == 0) { - level->tileEvent(x, y, z, Tile::enderChest_Id, ChestTile::EVENT_SET_OPEN_COUNT, openCount); + level->tileEvent(x, y, z, Tile::ender_chest_Id, ChestTile::EVENT_SET_OPEN_COUNT, openCount); } oOpenness = openness; @@ -74,13 +74,13 @@ void EnderChestTileEntity::setRemoved() void EnderChestTileEntity::startOpen() { openCount++; - level->tileEvent(x, y, z, Tile::enderChest_Id, ChestTile::EVENT_SET_OPEN_COUNT, openCount); + level->tileEvent(x, y, z, Tile::ender_chest_Id, ChestTile::EVENT_SET_OPEN_COUNT, openCount); } void EnderChestTileEntity::stopOpen() { openCount--; - level->tileEvent(x, y, z, Tile::enderChest_Id, ChestTile::EVENT_SET_OPEN_COUNT, openCount); + level->tileEvent(x, y, z, Tile::ender_chest_Id, ChestTile::EVENT_SET_OPEN_COUNT, openCount); } bool EnderChestTileEntity::stillValid(shared_ptr player) diff --git a/Minecraft.World/EnderDragon.cpp b/Minecraft.World/EnderDragon.cpp index 43f198be..80eb6e7e 100644 --- a/Minecraft.World/EnderDragon.cpp +++ b/Minecraft.World/EnderDragon.cpp @@ -1088,7 +1088,7 @@ bool EnderDragon::checkWalls(AABB *bb) { } - else if (t == Tile::obsidian_Id || t == Tile::endStone_Id || t == Tile::unbreakable_Id || !level->getGameRules()->getBoolean(GameRules::RULE_MOBGRIEFING)) + else if (t == Tile::obsidian_Id || t == Tile::end_stone_Id || t == Tile::bedrock_Id || !level->getGameRules()->getBoolean(GameRules::RULE_MOBGRIEFING)) { hitWall = true; } @@ -1274,7 +1274,7 @@ void EnderDragon::spawnExitPortal(int x, int z) } else { - level->setTileAndUpdate(xx, yy, zz, Tile::unbreakable_Id); + level->setTileAndUpdate(xx, yy, zz, Tile::bedrock_Id); } } else if (yy > y) @@ -1285,11 +1285,11 @@ void EnderDragon::spawnExitPortal(int x, int z) { if (d > r - 1 - 0.5) { - level->setTileAndUpdate(xx, yy, zz, Tile::unbreakable_Id); + level->setTileAndUpdate(xx, yy, zz, Tile::bedrock_Id); } else { - level->setTileAndUpdate(xx, yy, zz, Tile::endPortalTile_Id); + level->setTileAndUpdate(xx, yy, zz, Tile::end_portal_Id); } } } @@ -1297,15 +1297,15 @@ void EnderDragon::spawnExitPortal(int x, int z) } } - level->setTileAndUpdate(x, y + 0, z, Tile::unbreakable_Id); - level->setTileAndUpdate(x, y + 1, z, Tile::unbreakable_Id); - level->setTileAndUpdate(x, y + 2, z, Tile::unbreakable_Id); + level->setTileAndUpdate(x, y + 0, z, Tile::bedrock_Id); + level->setTileAndUpdate(x, y + 1, z, Tile::bedrock_Id); + level->setTileAndUpdate(x, y + 2, z, Tile::bedrock_Id); level->setTileAndUpdate(x - 1, y + 2, z, Tile::torch_Id); level->setTileAndUpdate(x + 1, y + 2, z, Tile::torch_Id); level->setTileAndUpdate(x, y + 2, z - 1, Tile::torch_Id); level->setTileAndUpdate(x, y + 2, z + 1, Tile::torch_Id); - level->setTileAndUpdate(x, y + 3, z, Tile::unbreakable_Id); - level->setTileAndUpdate(x, y + 4, z, Tile::dragonEgg_Id); + level->setTileAndUpdate(x, y + 3, z, Tile::bedrock_Id); + level->setTileAndUpdate(x, y + 4, z, Tile::dragon_egg_Id); // 4J-PB - The podium can be floating with nothing under it, so put some whiteStone under it if this is the case for (int yy = y - 5; yy < y - 1; yy++) @@ -1316,7 +1316,7 @@ void EnderDragon::spawnExitPortal(int x, int z) { if(level->isEmptyTile(xx,yy,zz)) { - level->setTileAndUpdate(xx, yy, zz, Tile::endStone_Id); + level->setTileAndUpdate(xx, yy, zz, Tile::end_stone_Id); } } } diff --git a/Minecraft.World/EnderEyeItem.cpp b/Minecraft.World/EnderEyeItem.cpp index 25b16d05..6027c368 100644 --- a/Minecraft.World/EnderEyeItem.cpp +++ b/Minecraft.World/EnderEyeItem.cpp @@ -18,12 +18,12 @@ bool EnderEyeItem::useOn(shared_ptr instance, shared_ptr p int targetType = level->getTile(x, y, z); int targetData = level->getData(x, y, z); - if (player->mayUseItemAt(x, y, z, face, instance) && targetType == Tile::endPortalFrameTile_Id && !TheEndPortalFrameTile::hasEye(targetData)) + if (player->mayUseItemAt(x, y, z, face, instance) && targetType == Tile::end_portal_frame_Id && !TheEndPortalFrameTile::hasEye(targetData)) { if(bTestUseOnOnly) return true; if (level->isClientSide) return true; level->setData(x, y, z, targetData + TheEndPortalFrameTile::EYE_BIT, Tile::UPDATE_CLIENTS); - level->updateNeighbourForOutputSignal(x, y, z, Tile::endPortalFrameTile_Id); + level->updateNeighbourForOutputSignal(x, y, z, Tile::end_portal_frame_Id); instance->count--; for (int i = 0; i < 16; i++) @@ -53,7 +53,7 @@ bool EnderEyeItem::useOn(shared_ptr instance, shared_ptr p int testZ = z + Direction::STEP_Z[rightHandDirection] * offset; int tile = level->getTile(testX, y, testZ); - if (tile == Tile::endPortalFrameTile->id) + if (tile == Tile::end_portal_frame->id) { int data = level->getData(testX, y, testZ); if (!TheEndPortalFrameTile::hasEye(data)) @@ -84,7 +84,7 @@ bool EnderEyeItem::useOn(shared_ptr instance, shared_ptr p int tile = level->getTile(testX, y, testZ); int data = level->getData(testX, y, testZ); - if (tile != Tile::endPortalFrameTile_Id || !TheEndPortalFrameTile::hasEye(data)) + if (tile != Tile::end_portal_frame_Id || !TheEndPortalFrameTile::hasEye(data)) { valid = false; break; @@ -102,7 +102,7 @@ bool EnderEyeItem::useOn(shared_ptr instance, shared_ptr p int tile = level->getTile(testX, y, testZ); int data = level->getData(testX, y, testZ); - if (tile != Tile::endPortalFrameTile_Id || !TheEndPortalFrameTile::hasEye(data)) + if (tile != Tile::end_portal_frame_Id || !TheEndPortalFrameTile::hasEye(data)) { valid = false; break; @@ -122,7 +122,7 @@ bool EnderEyeItem::useOn(shared_ptr instance, shared_ptr p targetX += Direction::STEP_X[direction] * pz; targetZ += Direction::STEP_Z[direction] * pz; - level->setTileAndData(targetX, y, targetZ, Tile::endPortalTile_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(targetX, y, targetZ, Tile::end_portal_Id, 0, Tile::UPDATE_CLIENTS); } } } @@ -140,7 +140,7 @@ bool EnderEyeItem::TestUse(shared_ptr itemInstance, Level *level, { int tile = level->getTile(hr->x, hr->y, hr->z); delete hr; - if (tile == Tile::endPortalFrameTile_Id) + if (tile == Tile::end_portal_frame_Id) { return false; } @@ -193,7 +193,7 @@ shared_ptr EnderEyeItem::use(shared_ptr instance, Le { int tile = level->getTile(hr->x, hr->y, hr->z); delete hr; - if (tile == Tile::endPortalFrameTile_Id) + if (tile == Tile::end_portal_frame_Id) { return instance; } diff --git a/Minecraft.World/EnderMan.cpp b/Minecraft.World/EnderMan.cpp index 108c5a90..7c69f3c4 100644 --- a/Minecraft.World/EnderMan.cpp +++ b/Minecraft.World/EnderMan.cpp @@ -27,16 +27,16 @@ void EnderMan::staticCtor() MAY_TAKE[Tile::dirt_Id] = true; MAY_TAKE[Tile::sand_Id] = true; MAY_TAKE[Tile::gravel_Id] = true; - MAY_TAKE[Tile::flower_Id] = true; - MAY_TAKE[Tile::rose_Id] = true; + MAY_TAKE[Tile::yellow_flower_Id] = true; + MAY_TAKE[Tile::red_flower_Id] = true; MAY_TAKE[Tile::mushroom_brown_Id] = true; MAY_TAKE[Tile::mushroom_red_Id] = true; MAY_TAKE[Tile::tnt_Id] = true; MAY_TAKE[Tile::cactus_Id] = true; MAY_TAKE[Tile::clay_Id] = true; MAY_TAKE[Tile::pumpkin_Id] = true; - MAY_TAKE[Tile::melon_Id] = true; - MAY_TAKE[Tile::mycel_Id] = true; + MAY_TAKE[Tile::melon_block_Id] = true; + MAY_TAKE[Tile::mycelium_Id] = true; } EnderMan::EnderMan(Level *level) : Monster( level ) @@ -392,7 +392,7 @@ int EnderMan::getDeathSound() int EnderMan::getDeathLoot() { - return Item::enderPearl_Id; + return Item::ender_pearl_Id; } void EnderMan::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) diff --git a/Minecraft.World/Entity.cpp b/Minecraft.World/Entity.cpp index 1b42ba6e..7d3d5820 100644 --- a/Minecraft.World/Entity.cpp +++ b/Minecraft.World/Entity.cpp @@ -356,6 +356,8 @@ void Entity::_init(bool useSmallId, Level *level) // 4J Added m_ignoreVerticalCollisions = false; + m_clearFallDamageThisTick = false; + m_ignoreFallDamageUntilGround = false; m_uiAnimOverrideBitmask = 0L; m_ignorePortal = false; } @@ -372,7 +374,11 @@ Entity::Entity(Level *level, bool useSmallId) // 4J - added useSmallId parameter if (level != nullptr) { - dimension = level->dimension->id; + auto dimensionPtr = level->dimension; + if (dimensionPtr != nullptr) + { + dimension = dimensionPtr->id; + } } if( entityData ) @@ -892,7 +898,20 @@ void Entity::move(double xa, double ya, double za, bool noEntityCubes) // 4J - checkFallDamage(ya, onGround); if (xaOrg != xa) xd = 0; - if (yaOrg != ya) yd = 0; + if (yaOrg != ya) { + // Fireblade - updated logic here cause previous check completely broke head hitter logic + bool isSlimeBlock = false; + if (level != nullptr) { + int blockBelowX = Mth::floor(x); + int blockBelowY = Mth::floor(y - 0.1f - heightOffset); + int blockBelowZ = Mth::floor(z); + int blockId = level->getTile(blockBelowX, blockBelowY, blockBelowZ); + isSlimeBlock = (blockId == Tile::slimeBlock->id); + } + if (!isSlimeBlock) { + yd = 0; + } + } if (zaOrg != za) zd = 0; double xm = x - xo; @@ -932,7 +951,9 @@ void Entity::move(double xa, double ya, double za, bool noEntityCubes) // 4J - playSound(eSoundType_LIQUID_SWIM, speed, 1 + (random->nextFloat() - random->nextFloat()) * 0.4f); } playStepSound(xt, yt, zt, t); - Tile::tiles[t]->stepOn(level, xt, yt, zt, self); + Tile *tile = Tile::tiles[t]; + if (tile == nullptr && t != 0) return; // tu31 tutorial world fix + tile->stepOn(level, xt, yt, zt, self); } } @@ -981,9 +1002,10 @@ void Entity::checkInsideTiles() for (int z = z0; z <= z1; z++) { int t = level->getTile(x, y, z); - if (t > 0) + Tile *tile = Tile::tiles[t]; + if (t > 0 && tile != nullptr) // tu31 tutorial world fix { - Tile::tiles[t]->entityInside(level, x, y, z, self); + tile->entityInside(level, x, y, z, self); } } } @@ -992,6 +1014,8 @@ void Entity::checkInsideTiles() void Entity::playStepSound(int xt, int yt, int zt, int t) { + Tile *tile = Tile::tiles[t]; + if (tile == nullptr && t != 0) return; // tu31 tutorial world fix const Tile::SoundType *soundType = Tile::tiles[t]->soundType; MemSect(31); @@ -1006,7 +1030,7 @@ void Entity::playStepSound(int xt, int yt, int zt, int t) } } - if (level->getTile(xt, yt + 1, zt) == Tile::topSnow_Id) + if (level->getTile(xt, yt + 1, zt) == Tile::snow_layer_Id) { soundType = Tile::topSnow->soundType; playSound(soundType->getStepSound(), soundType->getVolume() * 0.15f, soundType->getPitch()); @@ -1031,6 +1055,24 @@ bool Entity::makeStepSound() void Entity::checkFallDamage(double ya, bool onGround) { + if (m_clearFallDamageThisTick) + { + m_clearFallDamageThisTick = false; + fallDistance = 0; + return; + } + if (m_ignoreFallDamageUntilGround) + { + if (ya < 0) + { + m_ignoreFallDamageUntilGround = false; + fallDistance = 0; + } + else + { + return; + } + } if (onGround) { if (fallDistance > 0) @@ -1063,6 +1105,13 @@ bool Entity::isFireImmune() return fireImmune; } +void Entity::clearFallDamageQueue() +{ + fallDistance = 0.0f; + m_clearFallDamageThisTick = true; + m_ignoreFallDamageUntilGround = true; +} + void Entity::causeFallDamage(float distance) { if (rider.lock() != nullptr) rider.lock()->causeFallDamage(distance); @@ -1122,7 +1171,9 @@ bool Entity::isUnderLiquid(Material *material) int yt = Mth::floor(yp); // 4J - this used to be a nested pair of floors for some reason int zt = Mth::floor(z); int t = level->getTile(xt, yt, zt); - if (t != 0 && Tile::tiles[t]->material == material) { + Tile *tile = Tile::tiles[t]; + if (tile == nullptr) return false; // tu31 tutorial world fix + if (t != 0 && tile->material == material) { float hh = LiquidTile::getHeight(level->getData(xt, yt, zt)) - 1 / 9.0f; float h = yt + 1 - hh; return yp < h; @@ -1161,6 +1212,8 @@ void Entity::moveRelative(float xa, float za, float speed) // 4J - change brought forward from 1.8.2 int Entity::getLightColor(float a) { + if (level == nullptr) return 0; + int xTile = Mth::floor(x); int zTile = Mth::floor(z); @@ -1176,6 +1229,8 @@ int Entity::getLightColor(float a) // 4J - changes brought forward from 1.8.2 float Entity::getBrightness(float a) { + if (level == nullptr) return 0.0f; + int xTile = Mth::floor(x); int zTile = Mth::floor(z); if (level->hasChunkAt(xTile, 0, zTile)) diff --git a/Minecraft.World/Entity.h b/Minecraft.World/Entity.h index 4fe0fb44..93b68713 100644 --- a/Minecraft.World/Entity.h +++ b/Minecraft.World/Entity.h @@ -170,6 +170,8 @@ private: protected: // 4J Added so that client side simulations on the host are not affected by zero-lag bool m_ignoreVerticalCollisions; + bool m_clearFallDamageThisTick; + bool m_ignoreFallDamageUntilGround; bool m_ignorePortal; @@ -253,6 +255,7 @@ protected: public: bool isFireImmune(); + void clearFallDamageQueue(); protected: virtual void causeFallDamage(float distance); diff --git a/Minecraft.World/EntityHorse.cpp b/Minecraft.World/EntityHorse.cpp index 0c840d60..949fd455 100644 --- a/Minecraft.World/EntityHorse.cpp +++ b/Minecraft.World/EntityHorse.cpp @@ -263,15 +263,15 @@ int EntityHorse::getArmorTypeForItem(shared_ptr armorItem) { return ARMOR_NONE; } - if (armorItem->id == Item::horseArmorMetal_Id) + if (armorItem->id == Item::iron_horse_armor_Id) { return ARMOR_IRON; } - else if (armorItem->id == Item::horseArmorGold_Id) + else if (armorItem->id == Item::golden_horse_armor_Id) { return ARMOR_GOLD; } - else if (armorItem->id == Item::horseArmorDiamond_Id) + else if (armorItem->id == Item::diamond_horse_armor_Id) { return ARMOR_DIAMOND; } @@ -668,7 +668,7 @@ int EntityHorse::getMadSound() void EntityHorse::playStepSound(int xt, int yt, int zt, int t) { const Tile::SoundType *soundType = Tile::tiles[t]->soundType; - if (level->getTile(xt, yt + 1, zt) == Tile::topSnow_Id) + if (level->getTile(xt, yt + 1, zt) == Tile::snow_layer_Id) { soundType = Tile::topSnow->soundType; } @@ -815,7 +815,7 @@ bool EntityHorse::mobInteract(shared_ptr player) { shared_ptr itemstack = player->inventory->getSelected(); - if (itemstack != nullptr && itemstack->id == Item::spawnEgg_Id) + if (itemstack != nullptr && itemstack->id == Item::spawn_egg_Id) { return Animal::mobInteract(player); } @@ -848,15 +848,15 @@ bool EntityHorse::mobInteract(shared_ptr player) { int armorType = -1; - if (itemstack->id == Item::horseArmorMetal_Id) + if (itemstack->id == Item::iron_horse_armor_Id) { armorType = ARMOR_IRON; } - else if (itemstack->id == Item::horseArmorGold_Id) + else if (itemstack->id == Item::golden_horse_armor_Id) { armorType = ARMOR_GOLD; } - else if (itemstack->id == Item::horseArmorDiamond_Id) + else if (itemstack->id == Item::diamond_horse_armor_Id) { armorType = ARMOR_DIAMOND; } @@ -897,7 +897,7 @@ bool EntityHorse::mobInteract(shared_ptr player) _ageUp = 180; temper = 3; } - else if (itemstack->id == Tile::hayBlock_Id) + else if (itemstack->id == Tile::hay_block_Id) { _heal = 20; _ageUp = 180; @@ -908,7 +908,7 @@ bool EntityHorse::mobInteract(shared_ptr player) _ageUp = 60; temper = 3; } - else if (itemstack->id == Item::carrotGolden_Id) + else if (itemstack->id == Item::golden_carrot_Id) { _heal = 4; _ageUp = 60; @@ -919,7 +919,7 @@ bool EntityHorse::mobInteract(shared_ptr player) setInLove(); } } - else if (itemstack->id == Item::apple_gold_Id) + else if (itemstack->id == Item::golden_apple_Id) { _heal = 10; _ageUp = 240; @@ -1836,7 +1836,7 @@ EntityHorse::HorseGroupData::HorseGroupData(int type, int variant) bool EntityHorse::isHorseArmor(int itemId) { - return itemId == Item::horseArmorMetal_Id || itemId == Item::horseArmorGold_Id || itemId == Item::horseArmorDiamond_Id; + return itemId == Item::iron_horse_armor_Id || itemId == Item::golden_horse_armor_Id || itemId == Item::diamond_horse_armor_Id; } bool EntityHorse::onLadder() diff --git a/Minecraft.World/ExtremeHillsBiome.cpp b/Minecraft.World/ExtremeHillsBiome.cpp index 87be6845..2720cb91 100644 --- a/Minecraft.World/ExtremeHillsBiome.cpp +++ b/Minecraft.World/ExtremeHillsBiome.cpp @@ -15,7 +15,7 @@ ExtremeHillsBiome::ExtremeHillsBiome(int id) : ExtremeHillsBiome(id, false) ExtremeHillsBiome::ExtremeHillsBiome(int id, bool extraTrees) : Biome(id) { - silverfishFeature = new OreFeature(Tile::monsterStoneEgg_Id, 9); + silverfishFeature = new OreFeature(Tile::monster_egg_Id, 9); taigaFeature = new SpruceFeature(false); @@ -61,7 +61,7 @@ void ExtremeHillsBiome::decorate(Level* level, Random* random, int xo, int zo) int tile = level->getTile(x, y, z); if (tile == Tile::stone_Id) { - level->setTileAndData(x, y, z, Tile::emeraldOre_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y, z, Tile::emerald_ore_Id, 0, Tile::UPDATE_CLIENTS); } } } diff --git a/Minecraft.World/EyeOfEnderSignal.cpp b/Minecraft.World/EyeOfEnderSignal.cpp index ca76b272..37ac6c37 100644 --- a/Minecraft.World/EyeOfEnderSignal.cpp +++ b/Minecraft.World/EyeOfEnderSignal.cpp @@ -163,7 +163,7 @@ void EyeOfEnderSignal::tick() remove(); if (surviveAfterDeath) { - level->addEntity(std::make_shared(level, x, y, z, shared_ptr(new ItemInstance(Item::eyeOfEnder)))); + level->addEntity(std::make_shared(level, x, y, z, shared_ptr(new ItemInstance(Item::eye_of_ender)))); } else { diff --git a/Minecraft.World/FallingTile.cpp b/Minecraft.World/FallingTile.cpp index 0ff776fd..7e793c31 100644 --- a/Minecraft.World/FallingTile.cpp +++ b/Minecraft.World/FallingTile.cpp @@ -126,7 +126,7 @@ void FallingTile::tick() zd *= 0.7f; yd *= -0.5f; - if (level->getTile(xt, yt, zt) != Tile::pistonMovingPiece_Id) + if (level->getTile(xt, yt, zt) != Tile::piston_extension_Id) { remove(); if (!cancelDrop && level->mayPlace(tile, xt, yt, zt, true, 1, nullptr, nullptr) && !HeavyTile::isFree(level, xt, yt - 1, zt) && level->setTileAndData(xt, yt, zt, tile, data, Tile::UPDATE_ALL)) diff --git a/Minecraft.World/FarmTile.cpp b/Minecraft.World/FarmTile.cpp index 39bf685f..608b6ebd 100644 --- a/Minecraft.World/FarmTile.cpp +++ b/Minecraft.World/FarmTile.cpp @@ -16,6 +16,32 @@ FarmTile::FarmTile(int id) : Tile(id, Material::dirt,isSolidRender()) setLightBlock(255); } +void FarmTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int FarmTile::defaultBlockState() +{ + return 0; +} + +int FarmTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x7) : 0; +} + +Tile::BlockState FarmTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x7); +} + +Tile::BlockState FarmTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x7); +} + // 4J Added override void FarmTile::updateDefaultShape() { @@ -105,7 +131,7 @@ bool FarmTile::isUnderCrops(Level *level, int x, int y, int z) for (int zz = z - r; zz <= z + r; zz++) { int tile = level->getTile(xx, y + 1, zz); - if (tile == Tile::wheat_Id || tile == Tile::melonStem_Id || tile == Tile::pumpkinStem_Id || tile == Tile::potatoes_Id || tile == Tile::carrots_Id) + if (tile == Tile::wheat_Id || tile == Tile::melon_stem_Id || tile == Tile::pumpkin_stem_Id || tile == Tile::potatoes_Id || tile == Tile::carrots_Id) { return true; } diff --git a/Minecraft.World/FarmTile.h b/Minecraft.World/FarmTile.h index f9b4b031..e70a276f 100644 --- a/Minecraft.World/FarmTile.h +++ b/Minecraft.World/FarmTile.h @@ -16,6 +16,11 @@ private: protected: FarmTile(int id); public: + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void updateDefaultShape(); // 4J Added override virtual AABB *getAABB(Level *level, int x, int y, int z); virtual bool isSolidRender(bool isServerLevel = false); diff --git a/Minecraft.World/FenceGateTile.cpp b/Minecraft.World/FenceGateTile.cpp index e01e76c6..39584442 100644 --- a/Minecraft.World/FenceGateTile.cpp +++ b/Minecraft.World/FenceGateTile.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "FenceGateTile.h" #include "AABB.h" +#include "BlockPos.h" #include "net.minecraft.world.level.h" #include "net.minecraft.world.h" #include "net.minecraft.h" @@ -10,6 +11,88 @@ FenceGateTile::FenceGateTile(int id) : DirectionalTile(id, Material::wood, isSol { } +void FenceGateTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int FenceGateTile::defaultBlockState() +{ + return 0; +} + +int FenceGateTile::convertBlockStateToLegacyData(BlockState *state) +{ + if (!state) return 0; + return state->value & (DirectionalTile::DIRECTION_MASK | OPEN_BIT | POWERED_BIT); +} + +Tile::BlockState FenceGateTile::getBlockState(int data) +{ + return Tile::BlockState(data & (DirectionalTile::DIRECTION_MASK | OPEN_BIT | POWERED_BIT)); +} + +Tile::BlockState FenceGateTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + int data = level->getData(x, y, z) & (DirectionalTile::DIRECTION_MASK | OPEN_BIT | POWERED_BIT); + int dir = DirectionalTile::getDirection(data); + bool inWall = false; + + if (dir == Direction::NORTH || dir == Direction::SOUTH) + { + int westTile = level->getTile(x - 1, y, z); + int eastTile = level->getTile(x + 1, y, z); + inWall = (westTile == Tile::cobblestone_wall_Id) || (eastTile == Tile::cobblestone_wall_Id); + } + else + { + int northTile = level->getTile(x, y, z - 1); + int southTile = level->getTile(x, y, z + 1); + inWall = (northTile == Tile::cobblestone_wall_Id) || (southTile == Tile::cobblestone_wall_Id); + } + + if (inWall) + { + data |= IN_WALL_BIT; + } + + return Tile::BlockState(data); +} + +void FenceGateTile::fillVirtualBlockStateProperties(Tile::BlockState *state, LevelSource *level, const BlockPos &pos) +{ + if (!state || !level) return; + + int x = pos.getX(); + int y = pos.getY(); + int z = pos.getZ(); + + Tile::BlockState base = getBlockState(level, x, y, z); + state->value = base.value; + + int dir = DirectionalTile::getDirection(base.value); + bool inWall = false; + + if (dir == Direction::NORTH || dir == Direction::SOUTH) + { + int westTile = level->getTile(x - 1, y, z); + int eastTile = level->getTile(x + 1, y, z); + inWall = (westTile == Tile::cobblestone_wall_Id) || (eastTile == Tile::cobblestone_wall_Id); + } + else + { + int northTile = level->getTile(x, y, z - 1); + int southTile = level->getTile(x, y, z + 1); + inWall = (northTile == Tile::cobblestone_wall_Id) || (southTile == Tile::cobblestone_wall_Id); + } + + if (inWall) + { + state->value |= IN_WALL_BIT; + } +} + Icon *FenceGateTile::getTexture(int face, int data) { return icon; diff --git a/Minecraft.World/FenceGateTile.h b/Minecraft.World/FenceGateTile.h index 585908d3..986b48d4 100644 --- a/Minecraft.World/FenceGateTile.h +++ b/Minecraft.World/FenceGateTile.h @@ -5,9 +5,17 @@ class FenceGateTile : public DirectionalTile { private: static const int OPEN_BIT = 4; + static const int POWERED_BIT = 8; + static const int IN_WALL_BIT = 16; Icon* icon; public: FenceGateTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); + void fillVirtualBlockStateProperties(Tile::BlockState *state, LevelSource *level, const BlockPos &pos); Icon *getTexture(int face, int data); virtual bool mayPlace(Level *level, int x, int y, int z); virtual AABB *getAABB(Level *level, int x, int y, int z); diff --git a/Minecraft.World/FenceTile.cpp b/Minecraft.World/FenceTile.cpp index 324d22ed..53c59709 100644 --- a/Minecraft.World/FenceTile.cpp +++ b/Minecraft.World/FenceTile.cpp @@ -7,12 +7,44 @@ FenceTile::FenceTile(int id, const wstring &texture, Material *material) : Tile( id, material, isSolidRender()) { + setLightBlock(0); this->texture = texture; } +void FenceTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int FenceTile::defaultBlockState() +{ + return 0; +} + +int FenceTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState FenceTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState FenceTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + int state = 0; + if (connectsTo(level, x, y, z - 1)) state |= 0x1; + if (connectsTo(level, x, y, z + 1)) state |= 0x2; + if (connectsTo(level, x + 1, y, z)) state |= 0x4; + if (connectsTo(level, x - 1, y, z)) state |= 0x8; + return Tile::BlockState(state); +} + static const int fences[] = { - Tile::fence_Id, Tile::netherFence_Id, Tile::spruceFence_Id, - Tile::birchFence_Id, Tile::jungleFence_Id, Tile::acaciaFence_Id, Tile::darkFence_Id + Tile::fence_Id, Tile::nether_brick_fence_Id, Tile::spruce_fence_Id, + Tile::birch_fence_Id, Tile::jungle_fence_Id, Tile::acacia_fence_Id, Tile::dark_oak_fence_Id }; void FenceTile::addAABBs(Level *level, int x, int y, int z, AABB *box, AABBList *boxes, shared_ptr source) diff --git a/Minecraft.World/FenceTile.h b/Minecraft.World/FenceTile.h index ca22163a..84c0f7e4 100644 --- a/Minecraft.World/FenceTile.h +++ b/Minecraft.World/FenceTile.h @@ -9,6 +9,11 @@ private: public: FenceTile(int id, const wstring &texture, Material *material); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void addAABBs(Level *level, int x, int y, int z, AABB *box, AABBList *boxes, shared_ptr source); virtual void updateShape(LevelSource *level, int x, int y, int z, int forceData = -1, shared_ptr forceEntity = shared_ptr()); // 4J added forceData, forceEntity param virtual bool isSolidRender(bool isServerLevel = false); diff --git a/Minecraft.World/FileHeader.cpp b/Minecraft.World/FileHeader.cpp index b2ebe083..176bfedf 100644 --- a/Minecraft.World/FileHeader.cpp +++ b/Minecraft.World/FileHeader.cpp @@ -298,7 +298,7 @@ void FileHeader::ReadHeader( LPVOID saveMem, ESavePlatform plat /*= SAVE_FILE_PL default: #ifndef _CONTENT_PACKAGE app.DebugPrintf("********** Invalid save version %d\n",m_saveVersion); - DEBUG_BREAK(); + // DEBUG_BREAK(); #endif break; } diff --git a/Minecraft.World/FireTile.cpp b/Minecraft.World/FireTile.cpp index f8e2fe4e..dd06f353 100644 --- a/Minecraft.World/FireTile.cpp +++ b/Minecraft.World/FireTile.cpp @@ -38,27 +38,62 @@ FireTile::~FireTile() delete [] burnOdds; } +void FireTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int FireTile::defaultBlockState() +{ + return 0; +} + +int FireTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & AGE_MASK) : 0; +} + +Tile::BlockState FireTile::getBlockState(int data) +{ + return Tile::BlockState(data & AGE_MASK); +} + +Tile::BlockState FireTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + int age = level->getData(x, y, z) & AGE_MASK; + int state = age; + + if (canBurn(level, x + 1, y, z)) state |= EAST_BIT; + if (canBurn(level, x - 1, y, z)) state |= WEST_BIT; + if (canBurn(level, x, y, z + 1)) state |= SOUTH_BIT; + if (canBurn(level, x, y, z - 1)) state |= NORTH_BIT; + if (canBurn(level, x, y + 1, z)) state |= UP_BIT; + + return Tile::BlockState(state); +} + void FireTile::init() { - setFlammable(Tile::wood_Id, FLAME_HARD, BURN_MEDIUM); - setFlammable(Tile::woodSlab_Id, FLAME_HARD, BURN_MEDIUM); - setFlammable(Tile::woodSlabHalf_Id, FLAME_HARD, BURN_MEDIUM); + setFlammable(Tile::planks_Id, FLAME_HARD, BURN_MEDIUM); + setFlammable(Tile::double_wooden_slab_Id, FLAME_HARD, BURN_MEDIUM); + setFlammable(Tile::wooden_slab_Id, FLAME_HARD, BURN_MEDIUM); setFlammable(Tile::fence_Id, FLAME_HARD, BURN_MEDIUM); - setFlammable(Tile::stairs_wood_Id, FLAME_HARD, BURN_MEDIUM); - setFlammable(Tile::stairs_birchwood_Id, FLAME_HARD, BURN_MEDIUM); - setFlammable(Tile::stairs_sprucewood_Id, FLAME_HARD, BURN_MEDIUM); - setFlammable(Tile::stairs_junglewood_Id, FLAME_HARD, BURN_MEDIUM); - setFlammable(Tile::stairs_acaciawood_Id, FLAME_HARD, BURN_MEDIUM); - setFlammable(Tile::stairs_darkwood_Id, FLAME_HARD, BURN_MEDIUM); - setFlammable(Tile::treeTrunk_Id, FLAME_HARD, BURN_HARD); + setFlammable(Tile::oak_stairs_Id, FLAME_HARD, BURN_MEDIUM); + setFlammable(Tile::birch_stairs_Id, FLAME_HARD, BURN_MEDIUM); + setFlammable(Tile::spruce_stairs_Id, FLAME_HARD, BURN_MEDIUM); + setFlammable(Tile::jungle_stairs_Id, FLAME_HARD, BURN_MEDIUM); + setFlammable(Tile::acacia_stairs_Id, FLAME_HARD, BURN_MEDIUM); + setFlammable(Tile::dark_oak_stairs_Id, FLAME_HARD, BURN_MEDIUM); + setFlammable(Tile::log_Id, FLAME_HARD, BURN_HARD); setFlammable(Tile::leaves_Id, FLAME_EASY, BURN_EASY); setFlammable(Tile::bookshelf_Id, FLAME_EASY, BURN_MEDIUM); setFlammable(Tile::tnt_Id, FLAME_MEDIUM, BURN_INSTANT); setFlammable(Tile::tallgrass_Id, FLAME_INSTANT, BURN_INSTANT); setFlammable(Tile::wool_Id, FLAME_EASY, BURN_EASY); setFlammable(Tile::vine_Id, FLAME_MEDIUM, BURN_INSTANT); - setFlammable(Tile::coalBlock_Id, FLAME_HARD, BURN_HARD); - setFlammable(Tile::hayBlock_Id, FLAME_INSTANT, BURN_MEDIUM); + setFlammable(Tile::coal_block_Id, FLAME_HARD, BURN_HARD); + setFlammable(Tile::hay_block_Id, FLAME_INSTANT, BURN_MEDIUM); } void FireTile::setFlammable(int id, int flame, int burn) @@ -123,10 +158,10 @@ void FireTile::tick(Level *level, int x, int y, int z, Random *random) } - bool infiniBurn = level->getTile(x, y - 1, z) == Tile::netherRack_Id; + bool infiniBurn = level->getTile(x, y - 1, z) == Tile::netherrack_Id; if (level->dimension->id == 1) // 4J - was == instanceof TheEndDimension { - if (level->getTile(x, y - 1, z) == Tile::unbreakable_Id) infiniBurn = true; + if (level->getTile(x, y - 1, z) == Tile::bedrock_Id) infiniBurn = true; } if (!mayPlace(level, x, y, z)) diff --git a/Minecraft.World/FireTile.h b/Minecraft.World/FireTile.h index 1d823752..97da6022 100644 --- a/Minecraft.World/FireTile.h +++ b/Minecraft.World/FireTile.h @@ -11,6 +11,12 @@ class FireTile : public Tile public: static const wstring TEXTURE_FIRST; static const wstring TEXTURE_SECOND; + static const int AGE_MASK = 0xF; + static const int EAST_BIT = 1 << 4; + static const int WEST_BIT = 1 << 5; + static const int SOUTH_BIT = 1 << 6; + static const int NORTH_BIT = 1 << 7; + static const int UP_BIT = 1 << 8; static const int FLAME_INSTANT = 60; static const int FLAME_EASY = 30; @@ -31,6 +37,11 @@ protected: FireTile(int id); virtual ~FireTile(); public: + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); void init(); private: void setFlammable(int id, int flame, int burn); diff --git a/Minecraft.World/FireworksRecipe.cpp b/Minecraft.World/FireworksRecipe.cpp index c4a9ca80..c2a29be1 100644 --- a/Minecraft.World/FireworksRecipe.cpp +++ b/Minecraft.World/FireworksRecipe.cpp @@ -66,11 +66,11 @@ bool FireworksRecipe::matches(shared_ptr craftSlots, Level *l { sulphurCount++; } - else if (item->id == Item::fireworksCharge_Id) + else if (item->id == Item::firework_charge_Id) { chargeCount++; } - else if (item->id == Item::dye_powder_Id) + else if (item->id == Item::dye_Id) { colorCount++; } @@ -78,7 +78,7 @@ bool FireworksRecipe::matches(shared_ptr craftSlots, Level *l { paperCount++; } - else if (item->id == Item::yellowDust_Id) + else if (item->id == Item::glowstone_dust_Id) { // glowstone dust gives flickering chargeComponents++; @@ -88,7 +88,7 @@ bool FireworksRecipe::matches(shared_ptr craftSlots, Level *l // diamonds give trails chargeComponents++; } - else if (item->id == Item::fireball_Id) + else if (item->id == Item::fire_charge_Id) { // fireball gives larger explosion typeComponents++; @@ -98,7 +98,7 @@ bool FireworksRecipe::matches(shared_ptr craftSlots, Level *l // burst typeComponents++; } - else if (item->id == Item::goldNugget_Id) + else if (item->id == Item::gold_nugget_Id) { // star typeComponents++; @@ -135,7 +135,7 @@ bool FireworksRecipe::matches(shared_ptr craftSlots, Level *l for (int slot = 0; slot < craftSlots->getContainerSize(); slot++) { shared_ptr item = craftSlots->getItem(slot); - if (item == nullptr || item->id != Item::fireworksCharge_Id) continue; + if (item == nullptr || item->id != Item::firework_charge_Id) continue; if (item->hasTag() && item->getTag()->contains(FireworksItem::TAG_EXPLOSION)) { @@ -156,7 +156,7 @@ bool FireworksRecipe::matches(shared_ptr craftSlots, Level *l if (sulphurCount == 1 && paperCount == 0 && chargeCount == 0 && colorCount > 0 && typeComponents <= 1) { - resultItem = std::make_shared(Item::fireworksCharge); + resultItem = std::make_shared(Item::firework_charge); CompoundTag *itemTag = new CompoundTag(); CompoundTag *expTag = new CompoundTag(FireworksItem::TAG_EXPLOSION); @@ -168,11 +168,11 @@ bool FireworksRecipe::matches(shared_ptr craftSlots, Level *l shared_ptr item = craftSlots->getItem(slot); if (item == nullptr) continue; - if (item->id == Item::dye_powder_Id) + if (item->id == Item::dye_Id) { colors.push_back(DyePowderItem::COLOR_RGB[item->getAuxValue()]); } - else if (item->id == Item::yellowDust_Id) + else if (item->id == Item::glowstone_dust_Id) { // glowstone dust gives flickering expTag->putBoolean(FireworksItem::TAG_E_FLICKER, true); @@ -182,7 +182,7 @@ bool FireworksRecipe::matches(shared_ptr craftSlots, Level *l // diamonds give trails expTag->putBoolean(FireworksItem::TAG_E_TRAIL, true); } - else if (item->id == Item::fireball_Id) + else if (item->id == Item::fire_charge_Id) { type = FireworksItem::TYPE_BIG; } @@ -190,7 +190,7 @@ bool FireworksRecipe::matches(shared_ptr craftSlots, Level *l { type = FireworksItem::TYPE_BURST; } - else if (item->id == Item::goldNugget_Id) + else if (item->id == Item::gold_nugget_Id) { type = FireworksItem::TYPE_STAR; } @@ -224,11 +224,11 @@ bool FireworksRecipe::matches(shared_ptr craftSlots, Level *l shared_ptr item = craftSlots->getItem(slot); if (item == nullptr) continue; - if (item->id == Item::dye_powder_Id) + if (item->id == Item::dye_Id) { colors.push_back(DyePowderItem::COLOR_RGB[item->getAuxValue()]); } - else if (item->id == Item::fireworksCharge_Id) + else if (item->id == Item::firework_charge_Id) { resultItem = item->copy(); resultItem->count = 1; @@ -310,11 +310,11 @@ void FireworksRecipe::updatePossibleRecipes(shared_ptr craftS { sulphurCount++; } - else if (item->id == Item::fireworksCharge_Id) + else if (item->id == Item::firework_charge_Id) { chargeCount++; } - else if (item->id == Item::dye_powder_Id) + else if (item->id == Item::dye_Id) { colorCount++; } @@ -322,7 +322,7 @@ void FireworksRecipe::updatePossibleRecipes(shared_ptr craftS { paperCount++; } - else if (item->id == Item::yellowDust_Id) + else if (item->id == Item::glowstone_dust_Id) { // glowstone dust gives flickering chargeComponents++; @@ -332,7 +332,7 @@ void FireworksRecipe::updatePossibleRecipes(shared_ptr craftS // diamonds give trails chargeComponents++; } - else if (item->id == Item::fireball_Id) + else if (item->id == Item::fire_charge_Id) { // fireball gives larger explosion typeComponents++; @@ -342,7 +342,7 @@ void FireworksRecipe::updatePossibleRecipes(shared_ptr craftS // burst typeComponents++; } - else if (item->id == Item::goldNugget_Id) + else if (item->id == Item::gold_nugget_Id) { // star typeComponents++; @@ -389,28 +389,28 @@ bool FireworksRecipe::isValidIngredient(shared_ptr item, bool fire case Item::gunpowder_Id: valid = firework || charge; break; - case Item::fireworksCharge_Id: + case Item::firework_charge_Id: valid = firework || fade; break; - case Item::dye_powder_Id: + case Item::dye_Id: valid = charge || fade; break; case Item::paper_Id: valid = firework; break; - case Item::yellowDust_Id: + case Item::glowstone_dust_Id: valid = charge; break; case Item::diamond_Id: valid = charge; break; - case Item::fireball_Id: + case Item::fire_charge_Id: valid = charge; break; case Item::feather_Id: valid = charge; break; - case Item::goldNugget_Id: + case Item::gold_nugget_Id: valid = charge; break; case Item::skull_Id: diff --git a/Minecraft.World/FishingHelper.cpp b/Minecraft.World/FishingHelper.cpp index 518b76d0..3418b271 100644 --- a/Minecraft.World/FishingHelper.cpp +++ b/Minecraft.World/FishingHelper.cpp @@ -17,27 +17,27 @@ FishingHelper::FishingHelper() : fishingFishArray(4), fishingJunkArray(11), fish { fishingTreasuresArray[0] = new CatchWeighedItem(Item::bow_Id, 1, 0, 1); fishingTreasuresArray[1] = new CatchWeighedItem(Item::book_Id, 1, 0, 1); - fishingTreasuresArray[2] = new CatchWeighedItem(Item::fishingRod_Id, 1, 0, 1); - fishingTreasuresArray[3] = new CatchWeighedItem(Item::nameTag_Id, 1, 0, 1); + fishingTreasuresArray[2] = new CatchWeighedItem(Item::fishing_rod_Id, 1, 0, 1); + fishingTreasuresArray[3] = new CatchWeighedItem(Item::name_tag_Id, 1, 0, 1); fishingTreasuresArray[4] = new CatchWeighedItem(Item::saddle_Id, 1, 0, 1); - fishingTreasuresArray[5] = new CatchWeighedItem(Tile::waterLily_Id, 1, 0, 1); + fishingTreasuresArray[5] = new CatchWeighedItem(Tile::waterlily_Id, 1, 0, 1); - fishingFishArray[0] = new CatchWeighedItem(Item::fish_raw_Id, 1, 0, 60); // Fish - fishingFishArray[1] = new CatchWeighedItem(Item::fish_raw_Id, 1, 1, 25); // Salmon - fishingFishArray[2] = new CatchWeighedItem(Item::fish_raw_Id, 1, 2, 2); // Clownfish - fishingFishArray[3] = new CatchWeighedItem(Item::fish_raw_Id, 1, 3, 13); // Pufferfish + fishingFishArray[0] = new CatchWeighedItem(Item::fish_Id, 1, 0, 60); // Fish + fishingFishArray[1] = new CatchWeighedItem(Item::fish_Id, 1, 1, 25); // Salmon + fishingFishArray[2] = new CatchWeighedItem(Item::fish_Id, 1, 2, 2); // Clownfish + fishingFishArray[3] = new CatchWeighedItem(Item::fish_Id, 1, 3, 13); // Pufferfish fishingJunkArray[0] = new CatchWeighedItem(Item::leather_Id, 1, 0, 10); fishingJunkArray[1] = new CatchWeighedItem(Item::bone_Id, 1, 0, 10); fishingJunkArray[2] = new CatchWeighedItem(Item::potion_Id, 1, 0, 10); // Water bottle fishingJunkArray[3] = new CatchWeighedItem(Item::bowl_Id, 1, 0, 10); - fishingJunkArray[4] = new CatchWeighedItem(Item::boots_leather_Id, 1, 0, 10); + fishingJunkArray[4] = new CatchWeighedItem(Item::leather_boots_Id, 1, 0, 10); fishingJunkArray[5] = new CatchWeighedItem(Item::rotten_flesh_Id, 1, 0, 10); - fishingJunkArray[6] = new CatchWeighedItem(Tile::tripWireSource_Id, 1, 0, 10); + fishingJunkArray[6] = new CatchWeighedItem(Tile::tripwire_hook_Id, 1, 0, 10); fishingJunkArray[7] = new CatchWeighedItem(Item::stick_Id, 1, 0, 5); fishingJunkArray[8] = new CatchWeighedItem(Item::string_Id, 1, 0, 5); - fishingJunkArray[9] = new CatchWeighedItem(Item::fishingRod_Id, 1, 0, 2); - fishingJunkArray[10] = new CatchWeighedItem(Item::dye_powder_Id, 10, 0, 1); // 10 ink sacs + fishingJunkArray[9] = new CatchWeighedItem(Item::fishing_rod_Id, 1, 0, 2); + fishingJunkArray[10] = new CatchWeighedItem(Item::dye_Id, 10, 0, 1); // 10 ink sacs } CatchType FishingHelper::getRandCatchType(int luckLevel, int lureLevel, Random* random) @@ -85,10 +85,10 @@ std::shared_ptr FishingHelper::handleCatch(CatchWeighedItem* weigh weighedCatch->getItemId(), weighedCatch->getCount(), weighedCatch->getAuxValue() ); - if ((itemInstance->id == Item::fishingRod_Id && catchType == CatchType::JUNK) || (itemInstance->id == Item::boots_leather_Id)) { + if ((itemInstance->id == Item::fishing_rod_Id && catchType == CatchType::JUNK) || (itemInstance->id == Item::leather_boots_Id)) { itemInstance->setAuxValue((int) ((double) itemInstance->getMaxDamage() * ((double) random->nextInt(901) + 100.0) / 1000.0)); // 10% to 100% damage } - else if (itemInstance->id == Item::fishingRod_Id && catchType == CatchType::TREASURE) { + else if (itemInstance->id == Item::fishing_rod_Id && catchType == CatchType::TREASURE) { itemInstance->setAuxValue((int)((double) itemInstance->getMaxDamage() * ((double)random->nextInt(251) / 1000.0))); // 0% to 25% damage EnchantmentHelper::enchantItem(random, itemInstance, 30); } diff --git a/Minecraft.World/FishingHook.cpp b/Minecraft.World/FishingHook.cpp index a95fd8d9..c3b07232 100644 --- a/Minecraft.World/FishingHook.cpp +++ b/Minecraft.World/FishingHook.cpp @@ -116,10 +116,10 @@ FishingHook::FishingHook(Level *level, std::shared_ptr mob) : Entity( l void FishingHook::getEnchantLevels() { if (this->owner == nullptr) return; - std::shared_ptr fishingRod = owner->getSelectedItem(); + std::shared_ptr fishing_rod = owner->getSelectedItem(); // TODO; Account for luck effect once implemented. - this->luckLevel = EnchantmentHelper::getEnchantmentLevel(65, fishingRod); // Luck of the sea - this->lureLevel = EnchantmentHelper::getEnchantmentLevel(64, fishingRod); // Lure + this->luckLevel = EnchantmentHelper::getEnchantmentLevel(65, fishing_rod); // Luck of the sea + this->lureLevel = EnchantmentHelper::getEnchantmentLevel(64, fishing_rod); // Lure } void FishingHook::defineSynchedData() @@ -215,7 +215,7 @@ void FishingHook::tick() if (this->previousItem == nullptr) { this->previousItem = selectedItem; } - if (owner->removed || !owner->isAlive() || selectedItem == nullptr || selectedItem->getItem() != Item::fishingRod || distanceToSqr(owner) > 32 * 32 || selectedItem != this->previousItem) + if (owner->removed || !owner->isAlive() || selectedItem == nullptr || selectedItem->getItem() != Item::fishing_rod || distanceToSqr(owner) > 32 * 32 || selectedItem != this->previousItem) { remove(); owner->fishing = nullptr; diff --git a/Minecraft.World/FlatGeneratorInfo.cpp b/Minecraft.World/FlatGeneratorInfo.cpp index c983fd2c..d2650891 100644 --- a/Minecraft.World/FlatGeneratorInfo.cpp +++ b/Minecraft.World/FlatGeneratorInfo.cpp @@ -239,7 +239,7 @@ FlatGeneratorInfo *FlatGeneratorInfo::getDefault() FlatGeneratorInfo *result = new FlatGeneratorInfo(); result->setBiome(Biome::plains->id); - result->getLayers()->push_back(new FlatLayerInfo(1, Tile::unbreakable_Id)); + result->getLayers()->push_back(new FlatLayerInfo(1, Tile::bedrock_Id)); result->getLayers()->push_back(new FlatLayerInfo(2, Tile::dirt_Id)); result->getLayers()->push_back(new FlatLayerInfo(1, Tile::grass_Id)); result->updateLayers(); diff --git a/Minecraft.World/FlatLevelSource.cpp b/Minecraft.World/FlatLevelSource.cpp index 9ea1ed36..e7300cee 100644 --- a/Minecraft.World/FlatLevelSource.cpp +++ b/Minecraft.World/FlatLevelSource.cpp @@ -45,7 +45,7 @@ void FlatLevelSource::prepareHeights(byteArray blocks) int block = 0; if (yc == 0) { - block = Tile::unbreakable_Id; + block = Tile::bedrock_Id; } else if (yc <= 2) { diff --git a/Minecraft.World/FlowerPotTile.cpp b/Minecraft.World/FlowerPotTile.cpp index 80fdf2e4..552cf3dc 100644 --- a/Minecraft.World/FlowerPotTile.cpp +++ b/Minecraft.World/FlowerPotTile.cpp @@ -7,10 +7,37 @@ FlowerPotTile::FlowerPotTile(int id) : Tile(id, Material::decoration, isSolidRender() ) { + setLightBlock(0); updateDefaultShape(); sendTileData(); } +void FlowerPotTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int FlowerPotTile::defaultBlockState() +{ + return 0; +} + +int FlowerPotTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState FlowerPotTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState FlowerPotTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + void FlowerPotTile::updateDefaultShape() { float size = 6.0f / 16.0f; @@ -64,7 +91,7 @@ int FlowerPotTile::cloneTileId(Level *level, int x, int y, int z) if (item == nullptr) { - return Item::flowerPot_Id; + return Item::flower_pot_Id; } else { @@ -78,7 +105,7 @@ int FlowerPotTile::cloneTileData(Level *level, int x, int y, int z) if (item == nullptr) { - return Item::flowerPot_Id; + return Item::flower_pot_Id; } else { @@ -119,7 +146,7 @@ void FlowerPotTile::spawnResources(Level *level, int x, int y, int z, int data, int FlowerPotTile::getResource(int data, Random *random, int playerBonusLevel) { - return Item::flowerPot_Id; + return Item::flower_pot_Id; } shared_ptr FlowerPotTile::getItemFromType(int type) @@ -157,12 +184,12 @@ int FlowerPotTile::getTypeFromItem(shared_ptr item) { int id = item->getItem()->id; - if (id == Tile::rose_Id) return TYPE_FLOWER_RED; - if (id == Tile::flower_Id) return TYPE_FLOWER_YELLOW; + if (id == Tile::red_flower_Id) return TYPE_FLOWER_RED; + if (id == Tile::yellow_flower_Id) return TYPE_FLOWER_YELLOW; if (id == Tile::cactus_Id) return TYPE_CACTUS; if (id == Tile::mushroom_brown_Id) return TYPE_MUSHROOM_BROWN; if (id == Tile::mushroom_red_Id) return TYPE_MUSHROOM_RED; - if (id == Tile::deadBush_Id) return TYPE_DEAD_BUSH; + if (id == Tile::deadbush_Id) return TYPE_DEAD_BUSH; if (id == Tile::sapling_Id) { diff --git a/Minecraft.World/FlowerPotTile.h b/Minecraft.World/FlowerPotTile.h index 50dc18c4..a18c96f6 100644 --- a/Minecraft.World/FlowerPotTile.h +++ b/Minecraft.World/FlowerPotTile.h @@ -18,6 +18,11 @@ public: static const int TYPE_FERN = 11; FlowerPotTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); void updateDefaultShape(); bool isSolidRender(bool isServerLevel = false); diff --git a/Minecraft.World/FoodItem.cpp b/Minecraft.World/FoodItem.cpp index 557404cb..9a9affe6 100644 --- a/Minecraft.World/FoodItem.cpp +++ b/Minecraft.World/FoodItem.cpp @@ -74,7 +74,7 @@ shared_ptr FoodItem::use(shared_ptr instance, Level // 4J : WESTY : Other award ... eating cooked pork chop. // 4J-JEV: This is just for an avatar award on the xbox. #ifdef _XBOX - if ( instance->getItem() == Item::porkChop_cooked ) + if ( instance->getItem() == Item::cooked_porkchop ) { player->awardStat(GenericStats::eatPorkChop(),GenericStats::param_eatPorkChop()); } diff --git a/Minecraft.World/FoodRecipies.cpp b/Minecraft.World/FoodRecipies.cpp index 0aeccc59..cb53b271 100644 --- a/Minecraft.World/FoodRecipies.cpp +++ b/Minecraft.World/FoodRecipies.cpp @@ -9,15 +9,15 @@ void FoodRecipies::addRecipes(Recipes *r) { // 4J-JEV: Bumped up in the list to avoid a colision with the title. - r->addShapedRecipy(new ItemInstance(Item::apple_gold, 1, 0), // + r->addShapedRecipy(new ItemInstance(Item::golden_apple, 1, 0), // L"ssscicig", L"###", // L"#X#", // L"###", // - L'#', Item::goldIngot, L'X', Item::apple, + L'#', Item::gold_ingot, L'X', Item::apple, L'F'); - r->addShapedRecipy(new ItemInstance(Item::apple_gold, 1, 1), // + r->addShapedRecipy(new ItemInstance(Item::golden_apple, 1, 1), // L"sssctcig", L"###", // L"#X#", // @@ -25,38 +25,38 @@ void FoodRecipies::addRecipes(Recipes *r) L'#', Tile::goldBlock, L'X', Item::apple, L'F'); - r->addShapedRecipy(new ItemInstance(Item::speckledMelon, 1), // + r->addShapedRecipy(new ItemInstance(Item::speckled_melon, 1), // L"ssscicig", L"###", // L"#X#", // L"###", // - L'#', Item::goldNugget, L'X', Item::melon, + L'#', Item::gold_nugget, L'X', Item::melon, L'F'); - r->addShapelessRecipy(new ItemInstance(Item::mushroomStew), + r->addShapelessRecipy(new ItemInstance(Item::mushroom_stew), L"ttig", Tile::mushroom_brown, Tile::mushroom_red, Item::bowl, L'F'); - r->addShapedRecipy(new ItemInstance(Item::rabbitStew), + r->addShapedRecipy(new ItemInstance(Item::rabbit_stew), L"ssscicictcicig", L" 1 ",//s L"2X3",//s L" 4 ",//s - L'1', Item::rabbit_cooked, // ci + L'1', Item::cooked_rabbit, // ci L'2', Item::carrots, // ci L'3', Tile::mushroom_brown, // ct L'X', Item::potato, // ci L'4', Item::bowl, // ci L'F'); - r->addShapedRecipy(new ItemInstance(Item::rabbitStew), + r->addShapedRecipy(new ItemInstance(Item::rabbit_stew), L"ssscicictcicig", L" 1 ",//s L"2X3",//s L" 4 ",//s - L'1', Item::rabbit_cooked, // ci + L'1', Item::cooked_rabbit, // ci L'2', Item::carrots, // ci L'3', Tile::mushroom_red, // ct L'X', Item::potato, // ci @@ -69,7 +69,7 @@ void FoodRecipies::addRecipes(Recipes *r) L"sczcig", L"#X#", // - L'X', new ItemInstance(Item::dye_powder, 1, DyePowderItem::BROWN), + L'X', new ItemInstance(Item::dye, 1, DyePowderItem::BROWN), L'#', Item::wheat, L'F'); @@ -96,33 +96,33 @@ void FoodRecipies::addRecipes(Recipes *r) L'M', Tile::pumpkin, L'F'); - r->addShapelessRecipy(new ItemInstance(Item::pumpkinPie), // + r->addShapelessRecipy(new ItemInstance(Item::pumpkin_pie), // L"tiig", Tile::pumpkin, Item::sugar, Item::egg, L'F'); - r->addShapedRecipy(new ItemInstance(Item::carrotGolden, 1, 0), // + r->addShapedRecipy(new ItemInstance(Item::golden_carrot, 1, 0), // L"ssscicig", L"###", // L"#X#", // L"###", // - L'#', Item::goldNugget, L'X', Item::carrots, + L'#', Item::gold_nugget, L'X', Item::carrots, L'F'); - r->addShapelessRecipy(new ItemInstance(Item::fermentedSpiderEye), // + r->addShapelessRecipy(new ItemInstance(Item::fermented_spider_eye), // L"itig", - Item::spiderEye, Tile::mushroom_brown, Item::sugar, + Item::spider_eye, Tile::mushroom_brown, Item::sugar, L'F'); - r->addShapelessRecipy(new ItemInstance(Item::blazePowder, 2), // + r->addShapelessRecipy(new ItemInstance(Item::blaze_powder, 2), // L"ig", - Item::blazeRod, + Item::blaze_rod, L'F'); - r->addShapelessRecipy(new ItemInstance(Item::magmaCream), // + r->addShapelessRecipy(new ItemInstance(Item::magma_cream), // L"iig", - Item::blazePowder, Item::slimeBall, + Item::blaze_powder, Item::slime_ball, L'F'); } diff --git a/Minecraft.World/ForestBiome.cpp b/Minecraft.World/ForestBiome.cpp index f7d9b2a5..5f3f403f 100644 --- a/Minecraft.World/ForestBiome.cpp +++ b/Minecraft.World/ForestBiome.cpp @@ -268,15 +268,15 @@ Feature* ForestBiome::getFlowerFeature(Random* random, int x, int y, int z) int fType = random->nextInt(9); switch (fType) { - case 0: return new FlowerFeature(Tile::flower_Id, 0); - case 1: return new FlowerFeature(Tile::rose_Id, 0); - case 2: return new FlowerFeature(Tile::rose_Id, Rose::ALLIUM); - case 3: return new FlowerFeature(Tile::rose_Id, Rose::AZURE_BLUET); - case 4: return new FlowerFeature(Tile::rose_Id, Rose::RED_TULIP); - case 5: return new FlowerFeature(Tile::rose_Id, Rose::ORANGE_TULIP); - case 6: return new FlowerFeature(Tile::rose_Id, Rose::WHITE_TULIP); - case 7: return new FlowerFeature(Tile::rose_Id, Rose::PINK_TULIP); - case 8: return new FlowerFeature(Tile::rose_Id, Rose::OXEYE_DAISY); + case 0: return new FlowerFeature(Tile::yellow_flower_Id, 0); + case 1: return new FlowerFeature(Tile::red_flower_Id, 0); + case 2: return new FlowerFeature(Tile::red_flower_Id, Rose::ALLIUM); + case 3: return new FlowerFeature(Tile::red_flower_Id, Rose::AZURE_BLUET); + case 4: return new FlowerFeature(Tile::red_flower_Id, Rose::RED_TULIP); + case 5: return new FlowerFeature(Tile::red_flower_Id, Rose::ORANGE_TULIP); + case 6: return new FlowerFeature(Tile::red_flower_Id, Rose::WHITE_TULIP); + case 7: return new FlowerFeature(Tile::red_flower_Id, Rose::PINK_TULIP); + case 8: return new FlowerFeature(Tile::red_flower_Id, Rose::OXEYE_DAISY); } } else if (biomeType == 2 || biomeType == 3) diff --git a/Minecraft.World/FurnaceRecipes.cpp b/Minecraft.World/FurnaceRecipes.cpp index 48ba4b16..afffd8c8 100644 --- a/Minecraft.World/FurnaceRecipes.cpp +++ b/Minecraft.World/FurnaceRecipes.cpp @@ -18,36 +18,36 @@ FurnaceRecipes *FurnaceRecipes::getInstance() FurnaceRecipes::FurnaceRecipes() { - addFurnaceRecipy(Tile::ironOre_Id, new ItemInstance(Item::ironIngot), .7f); - addFurnaceRecipy(Tile::goldOre_Id, new ItemInstance(Item::goldIngot), 1); - addFurnaceRecipy(Tile::diamondOre_Id, new ItemInstance(Item::diamond), 1); + addFurnaceRecipy(Tile::iron_ore_Id, new ItemInstance(Item::iron_ingot), .7f); + addFurnaceRecipy(Tile::gold_ore_Id, new ItemInstance(Item::gold_ingot), 1); + addFurnaceRecipy(Tile::diamond_ore_Id, new ItemInstance(Item::diamond), 1); addFurnaceRecipy(Tile::sand_Id, new ItemInstance(Tile::glass), .1f); - addFurnaceRecipy(Item::porkChop_raw_Id, new ItemInstance(Item::porkChop_cooked), .35f); - addFurnaceRecipy(Item::beef_raw_Id, new ItemInstance(Item::beef_cooked), .35f); - addFurnaceRecipy(Item::rabbit_raw_Id, new ItemInstance(Item::rabbit_cooked), .35f); - addFurnaceRecipy(Item::mutton_raw_Id, new ItemInstance(Item::mutton_cooked), .35f); - addFurnaceRecipy(Item::chicken_raw_Id, new ItemInstance(Item::chicken_cooked), .35f); - addFurnaceRecipy(Item::fish_raw_Id, new ItemInstance(Item::fish_cooked), .35f); - addFurnaceRecipy(new ItemInstance(Item::fish_raw, 1, 1), new ItemInstance(Item::fish_cooked, 1, 1), .35f); // salmon + addFurnaceRecipy(Item::porkchop_Id, new ItemInstance(Item::cooked_porkchop), .35f); + addFurnaceRecipy(Item::beef_Id, new ItemInstance(Item::cooked_beef), .35f); + addFurnaceRecipy(Item::rabbit_Id, new ItemInstance(Item::cooked_rabbit), .35f); + addFurnaceRecipy(Item::mutton_Id, new ItemInstance(Item::cooked_mutton), .35f); + addFurnaceRecipy(Item::chicken_Id, new ItemInstance(Item::cooked_chicken), .35f); + addFurnaceRecipy(Item::fish_Id, new ItemInstance(Item::cooked_fish), .35f); + addFurnaceRecipy(new ItemInstance(Item::raw_fish, 1, 1), new ItemInstance(Item::cooked_fish, 1, 1), .35f); // salmon addFurnaceRecipy(Tile::cobblestone_Id, new ItemInstance(Tile::stone, 1, 0), .1f); - addFurnaceRecipy(Tile::stoneBrick_Id, new ItemInstance(Tile::stoneBrick, 1 , SmoothStoneBrickTile::TYPE_CRACKED), .1f); + addFurnaceRecipy(Tile::stonebrick_Id, new ItemInstance(Tile::stoneBrick, 1 , SmoothStoneBrickTile::TYPE_CRACKED), .1f); addFurnaceRecipy(Item::clay_Id, new ItemInstance(Item::brick), .3f); addFurnaceRecipy(Tile::clay_Id, new ItemInstance(Tile::clayHardened), .35f); - addFurnaceRecipy(Tile::cactus_Id, new ItemInstance(Item::dye_powder, 1, DyePowderItem::GREEN), .2f); - addFurnaceRecipy(Tile::treeTrunk_Id, new ItemInstance(Item::coal, 1, CoalItem::CHAR_COAL), .15f); - addFurnaceRecipy(Tile::emeraldOre_Id, new ItemInstance(Item::emerald), 1); - addFurnaceRecipy(Item::potato_Id, new ItemInstance(Item::potatoBaked), .35f); - addFurnaceRecipy(Tile::netherRack_Id, new ItemInstance(Item::netherbrick), .1f); + addFurnaceRecipy(Tile::cactus_Id, new ItemInstance(Item::dye, 1, DyePowderItem::GREEN), .2f); + addFurnaceRecipy(Tile::log_Id, new ItemInstance(Item::coal, 1, CoalItem::CHAR_COAL), .15f); + addFurnaceRecipy(Tile::emerald_ore_Id, new ItemInstance(Item::emerald), 1); + addFurnaceRecipy(Item::potato_Id, new ItemInstance(Item::baked_potato), .35f); + addFurnaceRecipy(Tile::netherrack_Id, new ItemInstance(Item::netherbrick), .1f); addFurnaceRecipy(new ItemInstance(Tile::sponge, 1, 1), new ItemInstance(Tile::sponge, 1, 0), .15f); // special silk touch related recipes: - addFurnaceRecipy(Tile::coalOre_Id, new ItemInstance(Item::coal), .1f); - addFurnaceRecipy(Tile::redStoneOre_Id, new ItemInstance(Item::redStone), .7f); - addFurnaceRecipy(Tile::lapisOre_Id, new ItemInstance(Item::dye_powder, 1, DyePowderItem::BLUE), .2f); - addFurnaceRecipy(Tile::netherQuartz_Id, new ItemInstance(Item::netherQuartz), .2f); + addFurnaceRecipy(Tile::coal_ore_Id, new ItemInstance(Item::coal), .1f); + addFurnaceRecipy(Tile::redstone_ore_Id, new ItemInstance(Item::redstone), .7f); + addFurnaceRecipy(Tile::lapis_ore_Id, new ItemInstance(Item::dye, 1, DyePowderItem::BLUE), .2f); + addFurnaceRecipy(Tile::quartz_ore_Id, new ItemInstance(Item::nether_quartz), .2f); - addFurnaceRecipy(Tile::tree2Trunk_Id, new ItemInstance(Item::coal, 1, CoalItem::CHAR_COAL), .15f); + addFurnaceRecipy(Tile::log2_Id, new ItemInstance(Item::coal, 1, CoalItem::CHAR_COAL), .15f); } void FurnaceRecipes::addFurnaceRecipy(int itemId, ItemInstance *result, float value) diff --git a/Minecraft.World/FurnaceResultSlot.cpp b/Minecraft.World/FurnaceResultSlot.cpp index 4ddcc726..a81ebfc6 100644 --- a/Minecraft.World/FurnaceResultSlot.cpp +++ b/Minecraft.World/FurnaceResultSlot.cpp @@ -85,9 +85,9 @@ void FurnaceResultSlot::checkTakeAchievements(shared_ptr carried) GenericStats::param_itemsSmelted(carried->id, carried->getAuxValue(), removeCount) ); } - if (carried->id == Item::ironIngot_Id) player->awardStat(GenericStats::acquireIron(), GenericStats::param_acquireIron()); - if (carried->id == Item::fish_cooked_Id) player->awardStat(GenericStats::cookFish(), GenericStats::param_cookFish()); - //if (carried->id == Item::porkChop_cooked_Id) GenericStats::itemsCrafted(Item::porkChop_cooked_Id); + if (carried->id == Item::iron_ingot_Id) player->awardStat(GenericStats::acquireIron(), GenericStats::param_acquireIron()); + if (carried->id == Item::cooked_fish_Id) player->awardStat(GenericStats::cookFish(), GenericStats::param_cookFish()); + //if (carried->id == Item::cooked_porkchop_Id) GenericStats::itemsCrafted(Item::cooked_porkchop_Id); removeCount = 0; } diff --git a/Minecraft.World/FurnaceTile.cpp b/Minecraft.World/FurnaceTile.cpp index d8856f4e..37fda9b4 100644 --- a/Minecraft.World/FurnaceTile.cpp +++ b/Minecraft.World/FurnaceTile.cpp @@ -127,7 +127,7 @@ void FurnaceTile::setLit(bool lit, Level *level, int x, int y, int z) shared_ptr te = level->getTileEntity(x, y, z); noDrop = true; - if (lit) level->setTileAndUpdate(x, y, z, Tile::furnace_lit_Id); + if (lit) level->setTileAndUpdate(x, y, z, Tile::lit_furnace_Id); else level->setTileAndUpdate(x, y, z, Tile::furnace_Id); noDrop = false; diff --git a/Minecraft.World/FurnaceTileEntity.cpp b/Minecraft.World/FurnaceTileEntity.cpp index b4f394f2..76f27ba2 100644 --- a/Minecraft.World/FurnaceTileEntity.cpp +++ b/Minecraft.World/FurnaceTileEntity.cpp @@ -320,11 +320,11 @@ int FurnaceTileEntity::getBurnDuration(shared_ptr itemInstance) if (id == Item::coal->id) return BURN_INTERVAL * 8; - if (id == Item::bucket_lava->id) return BURN_INTERVAL * 100; + if (id == Item::lava_bucket->id) return BURN_INTERVAL * 100; if (id == Tile::sapling_Id) return BURN_INTERVAL / 2; - if (id == Item::blazeRod_Id) return BURN_INTERVAL * 12; + if (id == Item::blaze_rod_Id) return BURN_INTERVAL * 12; return 0; } @@ -387,7 +387,7 @@ bool FurnaceTileEntity::canTakeItemThroughFace(int slot, shared_ptrid != Item::bucket_empty_Id) return false; + if (item->id != Item::bucket_Id) return false; } return true; diff --git a/Minecraft.World/GenericStats.cpp b/Minecraft.World/GenericStats.cpp index d507c675..0c9260c9 100644 --- a/Minecraft.World/GenericStats.cpp +++ b/Minecraft.World/GenericStats.cpp @@ -836,7 +836,7 @@ byteArray GenericStats::param_itemsSmelted(int id, int aux, int count) byteArray GenericStats::param_itemsUsed(shared_ptr plr, shared_ptr itm) { if ((plr != nullptr) && (itm != nullptr)) { - if (itm->id == Item::porkChop_cooked_Id) return instance->param_eatPorkChop(); + if (itm->id == Item::cooked_porkchop_Id) return instance->param_eatPorkChop(); return instance->getParam_itemsUsed(plr, itm); } else return instance->getParam_noArgs(); diff --git a/Minecraft.World/Ghast.cpp b/Minecraft.World/Ghast.cpp index d333f861..7a4963ba 100644 --- a/Minecraft.World/Ghast.cpp +++ b/Minecraft.World/Ghast.cpp @@ -225,7 +225,7 @@ void Ghast::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) int count = random->nextInt(2) + random->nextInt(1 + playerBonusLevel); for (int i = 0; i < count; i++) { - spawnAtLocation(Item::ghastTear_Id, 1); + spawnAtLocation(Item::ghast_tear_Id, 1); } count = random->nextInt(3) + random->nextInt(1 + playerBonusLevel); for (int i = 0; i < count; i++) diff --git a/Minecraft.World/GlowstoneTile.cpp b/Minecraft.World/GlowstoneTile.cpp index 5add7c25..180c6a46 100644 --- a/Minecraft.World/GlowstoneTile.cpp +++ b/Minecraft.World/GlowstoneTile.cpp @@ -18,5 +18,5 @@ int Glowstonetile::getResourceCount(Random *random) int Glowstonetile::getResource(int data, Random *random, int playerBonusLevel) { - return Item::yellowDust->id; + return Item::glowstone_dust->id; } \ No newline at end of file diff --git a/Minecraft.World/GrassTile.cpp b/Minecraft.World/GrassTile.cpp index 61460727..710cbc6f 100644 --- a/Minecraft.World/GrassTile.cpp +++ b/Minecraft.World/GrassTile.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "../Minecraft.Client/Minecraft.h" #include "GrassTile.h" +#include "HalfSlabTile.h" #include "net.minecraft.world.level.h" #include "net.minecraft.world.level.biome.h" #include "net.minecraft.h" @@ -96,7 +97,16 @@ void GrassTile::tick(Level *level, int x, int y, int z, Random *random) { if (level->isClientSide) return; - if (level->getRawBrightness(x, y + 1, z) < MIN_BRIGHTNESS && Tile::lightBlock[level->getTile(x, y + 1, z)] > 2) + int aboveTileId = level->getTile(x, y + 1, z); + Material* above = level->getMaterial(x, y + 1, z); + bool aboveIsTopSlab = false; + if (Tile::tiles[aboveTileId] != nullptr) + { + HalfSlabTile *aboveSlab = dynamic_cast(Tile::tiles[aboveTileId]); + aboveIsTopSlab = aboveSlab != nullptr && (level->getData(x, y + 1, z) & HalfSlabTile::TOP_SLOT_BIT) != 0; + } + + if (!aboveIsTopSlab && level->getRawBrightness(x, y + 1, z) < MIN_BRIGHTNESS && Tile::lightBlock[aboveTileId] > 2) { level->setTileAndUpdate(x, y, z, Tile::dirt_Id); } @@ -123,12 +133,10 @@ void GrassTile::tick(Level *level, int x, int y, int z, Random *random) // using isSolid() here is wrong because non full blocks like iron bars, // fences, walls are also flagged as solid by their material - int aboveTileId = level->getTile(x, y + 1, z); - Material* above = level->getMaterial(x, y + 1, z); - if (above->isLiquid() || Tile::lightBlock[aboveTileId] > 2) - { - level->setTileAndUpdate(x, y, z, Tile::dirt_Id); - } + if (!aboveIsTopSlab && (above->isLiquid() || Tile::lightBlock[aboveTileId] > 2)) + { + level->setTileAndUpdate(x, y, z, Tile::dirt_Id); + } } int GrassTile::getResource(int data, Random *random, int playerBonusLevel) diff --git a/Minecraft.World/GroundBushFeature.cpp b/Minecraft.World/GroundBushFeature.cpp index 88b7f733..0458c5f0 100644 --- a/Minecraft.World/GroundBushFeature.cpp +++ b/Minecraft.World/GroundBushFeature.cpp @@ -20,7 +20,7 @@ bool GroundBushFeature::place(Level *level, Random *random, int x, int y, int z) if (tile == Tile::dirt_Id || tile == Tile::grass_Id) { y++; - placeBlock(level, x, y, z, Tile::treeTrunk_Id, trunkTileType); + placeBlock(level, x, y, z, Tile::log_Id, trunkTileType); for (int yy = y; yy <= y + 2; yy++) { diff --git a/Minecraft.World/HalfSlabTile.cpp b/Minecraft.World/HalfSlabTile.cpp index e38b28c3..cfc69751 100644 --- a/Minecraft.World/HalfSlabTile.cpp +++ b/Minecraft.World/HalfSlabTile.cpp @@ -12,13 +12,43 @@ HalfSlabTile::HalfSlabTile(int id, Material *material) Tile::lightBlock[id] = 0xFF; } +void HalfSlabTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int HalfSlabTile::defaultBlockState() +{ + return 0; +} + +int HalfSlabTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & (TYPE_MASK | TOP_SLOT_BIT)) : 0; +} + +Tile::BlockState HalfSlabTile::getBlockState(int data) +{ + return Tile::BlockState(data & (TYPE_MASK | TOP_SLOT_BIT)); +} + +Tile::BlockState HalfSlabTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & (TYPE_MASK | TOP_SLOT_BIT)); +} + void HalfSlabTile::DerivedInit() { - if (!isFullSize()) + { + setLightBlock(0); setShape(0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 1.0f); + } else + { Tile::solid[id] = true; + } } void HalfSlabTile::updateDefaultShape() @@ -83,54 +113,33 @@ bool HalfSlabTile::isCubeShaped() return isFullSize() != 0; } -bool HalfSlabTile::shouldRenderFace( - LevelSource *level, int x, int y, int z, int face) +bool HalfSlabTile::shouldRenderFace(LevelSource *level, int x, int y, int z, int face) { - - if (isFullSize()) - return Tile::shouldRenderFace(level, x, y, z, face); + if (isFullSize()) return Tile::shouldRenderFace(level, x, y, z, face); - - if (face != Facing::UP && face != Facing::DOWN - && !Tile::shouldRenderFace(level, x, y, z, face)) - return false; + if (face != Facing::UP && face != Facing::DOWN && !Tile::shouldRenderFace(level, x, y, z, face)) + { + return false; + } - int oppFace = Facing::getOpposite(face); - int nx = x, ny = y, nz = z; - - if (oppFace == Facing::DOWN) ny--; - if (oppFace == Facing::UP) ny++; - if (oppFace == Facing::NORTH) nz--; - if (oppFace == Facing::SOUTH) nz++; - if (oppFace == Facing::WEST) nx--; - if (oppFace == Facing::EAST) nx++; + int ox = x, oy = y, oz = z; + ox += Facing::STEP_X[Facing::OPPOSITE_FACING[face]]; + oy += Facing::STEP_Y[Facing::OPPOSITE_FACING[face]]; + oz += Facing::STEP_Z[Facing::OPPOSITE_FACING[face]]; - int currentData = level->getData(x, y, z); - int neighborData = level->getData(nx, ny, nz); - int currentTile = level->getTile(x, y, z); - int neighborTile = level->getTile(nx, ny, nz); - - bool currentIsUpper = (currentData & TOP_SLOT_BIT) != 0; - bool neighborIsUpper = (neighborData & TOP_SLOT_BIT) != 0; - - bool currentIsSlab = isHalfSlab(currentTile); - bool neighborIsSlab = isHalfSlab(neighborTile); - - - if (neighborIsSlab && neighborIsUpper) - { - if (face == Facing::DOWN) - return true; - if (face == Facing::UP && !Tile::shouldRenderFace(level, x, y, z, face)) - return currentIsSlab && !currentIsUpper ? false : true; - return !(currentIsSlab && currentIsUpper); - } - - if (face == Facing::UP || (face == Facing::DOWN - && Tile::shouldRenderFace(level, x, y, z, face))) - return true; - - return !(currentIsSlab && !currentIsUpper); + boolean isUpper = (level->getData(ox, oy, oz) & TOP_SLOT_BIT) != 0; + if (isUpper) + { + if (face == Facing::DOWN) return true; + if (face == Facing::UP && Tile::shouldRenderFace(level, x, y, z, face)) return true; + return !(isHalfSlab(level->getTile(x, y, z)) && (level->getData(x, y, z) & TOP_SLOT_BIT) != 0); + } + else + { + if (face == Facing::UP) return true; + if (face == Facing::DOWN && Tile::shouldRenderFace(level, x, y, z, face)) return true; + return !(isHalfSlab(level->getTile(x, y, z)) && (level->getData(x, y, z) & TOP_SLOT_BIT) == 0); + } } int HalfSlabTile::getSpawnResourcesAuxValue(int data) diff --git a/Minecraft.World/HalfSlabTile.h b/Minecraft.World/HalfSlabTile.h index 7d65247b..45936e3f 100644 --- a/Minecraft.World/HalfSlabTile.h +++ b/Minecraft.World/HalfSlabTile.h @@ -21,6 +21,12 @@ public: virtual int isFullSize() = 0; + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); + virtual void updateShape( LevelSource *level, int x, int y, int z, int forceData = -1, diff --git a/Minecraft.World/HalfTransparentTile.cpp b/Minecraft.World/HalfTransparentTile.cpp index 1a996062..93ffcab9 100644 --- a/Minecraft.World/HalfTransparentTile.cpp +++ b/Minecraft.World/HalfTransparentTile.cpp @@ -5,6 +5,7 @@ HalfTransparentTile::HalfTransparentTile(int id, const wstring &tex, Material *material, bool allowSame) : Tile(id,material,isSolidRender()) { + setLightBlock(0); this->allowSame = allowSame; this->texture = tex; } diff --git a/Minecraft.World/HangingEntity.cpp b/Minecraft.World/HangingEntity.cpp index be26bd47..16649396 100644 --- a/Minecraft.World/HangingEntity.cpp +++ b/Minecraft.World/HangingEntity.cpp @@ -6,8 +6,8 @@ #include "net.minecraft.world.damagesource.h" #include "com.mojang.nbt.h" #include "HangingEntity.h" - - +#include "../Minecraft.Client/Minecraft.h" +#include "Level.h" void HangingEntity::_init(Level *level) { @@ -58,6 +58,7 @@ void HangingEntity::setDir(int dir) float x = xTile + 0.5f; float y = yTile + 0.5f; float z = zTile + 0.5f; + float originalX = x; float originalZ = z; float fOffs = 0.5f + 1.0f / 16.0f; @@ -65,10 +66,18 @@ void HangingEntity::setDir(int dir) fOffs = 0.5f + 1.0f / 32.0f; } - if (dir == Direction::NORTH) z -= fOffs; - if (dir == Direction::WEST) x -= fOffs; - if (dir == Direction::SOUTH) z += fOffs; - if (dir == Direction::EAST) x += fOffs; + int offset = 0; + + // set offset to 1 if placed in stock world + if (level->isClientSide && !placedByPlayer) + { + offset = 1; + } + + if (dir == Direction::NORTH) z -= fOffs - offset; + if (dir == Direction::WEST) x -= fOffs - offset; + if (dir == Direction::SOUTH) z += fOffs - offset; + if (dir == Direction::EAST) x += fOffs - offset; if (dir == Direction::NORTH) x -= offs(getWidth()); if (dir == Direction::WEST) z += offs(getWidth()); @@ -81,10 +90,10 @@ void HangingEntity::setDir(int dir) float ss = -(0.5f / 16.0f); if (this->GetType() == eTYPE_PAINTING) { fOffs = 0.5f + 1.0f / 16.0f; - if (dir == Direction::NORTH) originalZ -= fOffs; - if (dir == Direction::WEST) originalX -= fOffs; - if (dir == Direction::SOUTH) originalZ += fOffs; - if (dir == Direction::EAST) originalX += fOffs; + if (dir == Direction::NORTH) originalZ -= fOffs - offset; + if (dir == Direction::WEST) originalX -= fOffs - offset; + if (dir == Direction::SOUTH) originalZ += fOffs - offset; + if (dir == Direction::EAST) originalX += fOffs - offset; if (dir == Direction::NORTH) originalX -= offs(getWidth()); if (dir == Direction::WEST) originalZ += offs(getWidth()); if (dir == Direction::SOUTH) originalX += offs(getWidth()); @@ -118,7 +127,7 @@ void HangingEntity::tick() if (checkInterval++ == 20 * 5 && !level->isClientSide) { checkInterval = 0; - if (!removed && !survives()) + if (!removed && !survives() && placedByPlayer) { remove(); dropItem(nullptr); @@ -252,6 +261,7 @@ void HangingEntity::push(double xa, double ya, double za) void HangingEntity::addAdditonalSaveData(CompoundTag *tag) { + tag->putByte(L"PlacedByPlayer", placedByPlayer ? 1 : 0); tag->putByte(L"Direction", static_cast(dir)); tag->putInt(L"TileX", xTile); tag->putInt(L"TileY", yTile); @@ -277,32 +287,48 @@ void HangingEntity::addAdditonalSaveData(CompoundTag *tag) void HangingEntity::readAdditionalSaveData(CompoundTag *tag) { + if (tag->contains(L"TileX") && tag->contains(L"TileY") && tag->contains(L"TileZ")) + { + xTile = tag->getInt(L"TileX"); + yTile = tag->getInt(L"TileY"); + zTile = tag->getInt(L"TileZ"); + + setPos(xTile, yTile, zTile); + } + + if (tag->contains(L"PlacedByPlayer")) + { + placedByPlayer = tag->getByte(L"PlacedByPlayer") == 1; + } + + bool hasDir = false; if (tag->contains(L"Direction")) { dir = tag->getByte(L"Direction"); + hasDir = true; } - else + else if (tag->contains(L"Facing")) + { + int f = tag->getByte(L"Facing"); + dir = Direction::from2DDataValue(f); + hasDir = true; + } + else if (tag->contains(L"Dir")) { switch (tag->getByte(L"Dir")) { - case 0: - dir = Direction::NORTH; - break; - case 1: - dir = Direction::WEST; - break; - case 2: - dir = Direction::SOUTH; - break; - case 3: - dir = Direction::EAST; - break; + case 0: dir = Direction::NORTH; break; + case 1: dir = Direction::WEST; break; + case 2: dir = Direction::SOUTH; break; + case 3: dir = Direction::EAST; break; } + hasDir = true; + } + + if (hasDir) + { + setDir(dir); } - xTile = tag->getInt(L"TileX"); - yTile = tag->getInt(L"TileY"); - zTile = tag->getInt(L"TileZ"); - setDir(dir); } bool HangingEntity::repositionEntityAfterLoad() diff --git a/Minecraft.World/HangingEntity.h b/Minecraft.World/HangingEntity.h index 30d0a1bd..e6aa8c8d 100644 --- a/Minecraft.World/HangingEntity.h +++ b/Minecraft.World/HangingEntity.h @@ -20,6 +20,7 @@ protected: public: int dir; int xTile, yTile, zTile; + bool placedByPlayer = false; HangingEntity(Level *level); HangingEntity(Level *level, int xTile, int yTile, int zTile, int dir); @@ -39,6 +40,8 @@ public: virtual void addAdditonalSaveData(CompoundTag *tag); virtual void readAdditionalSaveData(CompoundTag *tag); + int getDirection(); + void getPos(Vec3i& out); virtual int getWidth()=0; virtual int getHeight()=0; virtual void dropItem(shared_ptr causedBy)=0; diff --git a/Minecraft.World/HangingEntityItem.cpp b/Minecraft.World/HangingEntityItem.cpp index 97ddb31d..ddb09497 100644 --- a/Minecraft.World/HangingEntityItem.cpp +++ b/Minecraft.World/HangingEntityItem.cpp @@ -43,7 +43,7 @@ bool HangingEntityItem::useOn(shared_ptr instance, shared_ptrawardStat(GenericStats::blocksPlaced(Item::painting_Id), GenericStats::param_blocksPlaced(Item::painting_Id,instance->getAuxValue(),1)); - else if (eType==eTYPE_ITEM_FRAME) player->awardStat(GenericStats::blocksPlaced(Item::itemFrame_Id), GenericStats::param_blocksPlaced(Item::itemFrame_Id,instance->getAuxValue(),1)); + else if (eType==eTYPE_ITEM_FRAME) player->awardStat(GenericStats::blocksPlaced(Item::item_frame_Id), GenericStats::param_blocksPlaced(Item::item_frame_Id,instance->getAuxValue(),1)); instance->count--; } @@ -67,6 +67,7 @@ shared_ptr HangingEntityItem::createEntity(Level *level, int x, i if (eType == eTYPE_PAINTING) { shared_ptr painting = std::make_shared(level, x, y, z, dir); + painting->placedByPlayer = true; #ifndef _CONTENT_PACKAGE if (app.DebugArtToolsOn() && auxValue > 0) @@ -84,6 +85,8 @@ shared_ptr HangingEntityItem::createEntity(Level *level, int x, i else if (eType == eTYPE_ITEM_FRAME) { shared_ptr itemFrame = std::make_shared(level, x, y, z, dir); + itemFrame->placedByPlayer = true; + itemFrame->setDir(dir); return dynamic_pointer_cast (itemFrame); } diff --git a/Minecraft.World/HayBlockTile.cpp b/Minecraft.World/HayBlockTile.cpp index c782835c..2f3ef905 100644 --- a/Minecraft.World/HayBlockTile.cpp +++ b/Minecraft.World/HayBlockTile.cpp @@ -6,6 +6,31 @@ HayBlockTile::HayBlockTile(int id) : RotatedPillarTile(id, Material::grass) { } +void HayBlockTile::createBlockStateDefinition() +{ + RotatedPillarTile::createBlockStateDefinition(); +} + +int HayBlockTile::defaultBlockState() +{ + return 0; +} + +int HayBlockTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & MASK_FACING) : 0; +} + +Tile::BlockState HayBlockTile::getBlockState(int data) +{ + return Tile::BlockState(data & MASK_FACING); +} + +Tile::BlockState HayBlockTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & MASK_FACING); +} + int HayBlockTile::getRenderShape() { return SHAPE_TREE; diff --git a/Minecraft.World/HayBlockTile.h b/Minecraft.World/HayBlockTile.h index fca2e449..49a7d309 100644 --- a/Minecraft.World/HayBlockTile.h +++ b/Minecraft.World/HayBlockTile.h @@ -9,6 +9,11 @@ public: HayBlockTile(int id); int getRenderShape(); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); protected: Icon *getTypeTexture(int type); diff --git a/Minecraft.World/HellFireFeature.cpp b/Minecraft.World/HellFireFeature.cpp index 4b32134c..1432a428 100644 --- a/Minecraft.World/HellFireFeature.cpp +++ b/Minecraft.World/HellFireFeature.cpp @@ -11,7 +11,7 @@ bool HellFireFeature::place(Level *level, Random *random, int x, int y, int z) int y2 = y + random->nextInt(4) - random->nextInt(4); int z2 = z + random->nextInt(8) - random->nextInt(8); if (!level->isEmptyTile(x2, y2, z2)) continue; - if (level->getTile(x2, y2 - 1, z2) != Tile::netherRack_Id) continue; + if (level->getTile(x2, y2 - 1, z2) != Tile::netherrack_Id) continue; level->setTileAndData(x2, y2, z2, Tile::fire_Id, 0, Tile::UPDATE_CLIENTS); } diff --git a/Minecraft.World/HellFlatLevelSource.cpp b/Minecraft.World/HellFlatLevelSource.cpp index c4ba062c..17c33930 100644 --- a/Minecraft.World/HellFlatLevelSource.cpp +++ b/Minecraft.World/HellFlatLevelSource.cpp @@ -35,7 +35,7 @@ void HellFlatLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) int block = 0; if ( (yc <= 6) || ( yc >= 121 ) ) { - block = Tile::netherRack_Id; + block = Tile::netherrack_Id; } blocks[xc << 11 | zc << 7 | yc] = static_cast(block); @@ -60,7 +60,7 @@ void HellFlatLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks) { if( z - random->nextInt( 4 ) <= 0 || xOffs < -(m_XZSize/2) ) { - blocks[offs] = static_cast(Tile::unbreakable_Id); + blocks[offs] = static_cast(Tile::bedrock_Id); blockSet = true; } } @@ -68,7 +68,7 @@ void HellFlatLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks) { if( x - random->nextInt( 4 ) <= 0 || zOffs < -(m_XZSize/2)) { - blocks[offs] = static_cast(Tile::unbreakable_Id); + blocks[offs] = static_cast(Tile::bedrock_Id); blockSet = true; } } @@ -76,7 +76,7 @@ void HellFlatLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks) { if( z + random->nextInt(4) >= 15 || xOffs > (m_XZSize/2)) { - blocks[offs] = static_cast(Tile::unbreakable_Id); + blocks[offs] = static_cast(Tile::bedrock_Id); blockSet = true; } } @@ -84,7 +84,7 @@ void HellFlatLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks) { if( x + random->nextInt(4) >= 15 || zOffs > (m_XZSize/2) ) { - blocks[offs] = static_cast(Tile::unbreakable_Id); + blocks[offs] = static_cast(Tile::bedrock_Id); blockSet = true; } } @@ -93,11 +93,11 @@ void HellFlatLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks) if (y >= Level::genDepthMinusOne - random->nextInt(5)) { - blocks[offs] = static_cast(Tile::unbreakable_Id); + blocks[offs] = static_cast(Tile::bedrock_Id); } else if (y <= 0 + random->nextInt(5)) { - blocks[offs] = static_cast(Tile::unbreakable_Id); + blocks[offs] = static_cast(Tile::bedrock_Id); } } } diff --git a/Minecraft.World/HellPortalFeature.cpp b/Minecraft.World/HellPortalFeature.cpp index 66485578..c41711f3 100644 --- a/Minecraft.World/HellPortalFeature.cpp +++ b/Minecraft.World/HellPortalFeature.cpp @@ -6,7 +6,7 @@ bool HellPortalFeature::place(Level *level, Random *random, int x, int y, int z) { if (!level->isEmptyTile(x, y, z)) return false; - if (level->getTile(x, y + 1, z) != Tile::netherRack_Id) return false; + if (level->getTile(x, y + 1, z) != Tile::netherrack_Id) return false; level->setTileAndData(x, y, z, Tile::glowstone_Id, 0, Tile::UPDATE_CLIENTS); for (int i = 0; i < 1500; i++) diff --git a/Minecraft.World/HellRandomLevelSource.cpp b/Minecraft.World/HellRandomLevelSource.cpp index 26127dde..64a70b96 100644 --- a/Minecraft.World/HellRandomLevelSource.cpp +++ b/Minecraft.World/HellRandomLevelSource.cpp @@ -97,11 +97,11 @@ void HellRandomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray block int tileId = 0; if (yc * CHUNK_HEIGHT + y < waterHeight) { - tileId = Tile::calmLava_Id; + tileId = Tile::lava_Id; } if (val > 0) { - tileId = Tile::netherRack_Id; + tileId = Tile::netherrack_Id; } blocks[offs] = static_cast(tileId); @@ -147,8 +147,8 @@ void HellRandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks int run = -1; - byte top = (byte) Tile::netherRack_Id; - byte material = (byte) Tile::netherRack_Id; + byte top = (byte) Tile::netherrack_Id; + byte material = (byte) Tile::netherrack_Id; for (int y = Level::genDepthMinusOne; y >= 0; y--) { @@ -160,7 +160,7 @@ void HellRandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks { if( z - random->nextInt( 4 ) <= 0 || xOffs < -(m_XZSize/2) ) { - blocks[offs] = static_cast(Tile::unbreakable_Id); + blocks[offs] = static_cast(Tile::bedrock_Id); blockSet = true; } } @@ -168,7 +168,7 @@ void HellRandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks { if( x - random->nextInt( 4 ) <= 0 || zOffs < -(m_XZSize/2)) { - blocks[offs] = static_cast(Tile::unbreakable_Id); + blocks[offs] = static_cast(Tile::bedrock_Id); blockSet = true; } } @@ -176,7 +176,7 @@ void HellRandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks { if( z + random->nextInt(4) >= 15 || xOffs > (m_XZSize/2)) { - blocks[offs] = static_cast(Tile::unbreakable_Id); + blocks[offs] = static_cast(Tile::bedrock_Id); blockSet = true; } } @@ -184,7 +184,7 @@ void HellRandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks { if( x + random->nextInt(4) >= 15 || zOffs > (m_XZSize/2) ) { - blocks[offs] = static_cast(Tile::unbreakable_Id); + blocks[offs] = static_cast(Tile::bedrock_Id); blockSet = true; } } @@ -193,7 +193,7 @@ void HellRandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks if (y >= Level::genDepthMinusOne - random->nextInt(5) || y <= 0 + random->nextInt(5)) { - blocks[offs] = static_cast(Tile::unbreakable_Id); + blocks[offs] = static_cast(Tile::bedrock_Id); } else { @@ -203,27 +203,27 @@ void HellRandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks { run = -1; } - else if (old == Tile::netherRack_Id) + else if (old == Tile::netherrack_Id) { if (run == -1) { if (runDepth <= 0) { top = 0; - material = static_cast(Tile::netherRack_Id); + material = static_cast(Tile::netherrack_Id); } else if (y >= waterHeight - 4 && y <= waterHeight + 1) { - top = static_cast(Tile::netherRack_Id); - material = static_cast(Tile::netherRack_Id); + top = static_cast(Tile::netherrack_Id); + material = static_cast(Tile::netherrack_Id); if (gravel) top = static_cast(Tile::gravel_Id); - if (gravel) material = static_cast(Tile::netherRack_Id); + if (gravel) material = static_cast(Tile::netherrack_Id); if (sand) { // 4J Stu - Make some nether wart spawn outside of the nether fortresses if(random->nextInt(16) == 0) { - top = static_cast(Tile::netherStalk_Id); + top = static_cast(Tile::nether_wart_Id); // Place the nether wart on top of the soul sand y += 1; @@ -234,13 +234,13 @@ void HellRandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks } else { - top = static_cast(Tile::soulsand_Id); + top = static_cast(Tile::soul_sand_Id); } } - if (sand) material = static_cast(Tile::soulsand_Id); + if (sand) material = static_cast(Tile::soul_sand_Id); } - if (y < waterHeight && top == 0) top = static_cast(Tile::calmLava_Id); + if (y < waterHeight && top == 0) top = static_cast(Tile::lava_Id); run = runDepth; // 4J Stu - If sand, then allow adding nether wart at heights below the water level @@ -441,7 +441,7 @@ void HellRandomLevelSource::postProcess(ChunkSource *parent, int xt, int zt) int x = xo + pprandom->nextInt(16) + 8; int y = pprandom->nextInt(Level::genDepth - 8) + 4; int z = zo + pprandom->nextInt(16) + 8; - HellSpringFeature(Tile::lava_Id, false).place(level, pprandom, x, y, z); + HellSpringFeature(Tile::flowing_lava_Id, false).place(level, pprandom, x, y, z); } int count = pprandom->nextInt(pprandom->nextInt(10) + 1) + 1; @@ -487,7 +487,7 @@ void HellRandomLevelSource::postProcess(ChunkSource *parent, int xt, int zt) FlowerFeature(Tile::mushroom_red_Id).place(level, pprandom, x, y, z); } - OreFeature quartzFeature(Tile::netherQuartz_Id, 13, Tile::netherRack_Id); + OreFeature quartzFeature(Tile::quartz_ore_Id, 0, 13, Tile::netherrack_Id); for (int i = 0; i < 16; i++) { int x = xo + pprandom->nextInt(16); @@ -501,7 +501,7 @@ void HellRandomLevelSource::postProcess(ChunkSource *parent, int xt, int zt) int x = xo + random->nextInt(16); int y = random->nextInt(Level::genDepth - 20) + 10; int z = zo + random->nextInt(16); - HellSpringFeature hellSpringFeature(Tile::lava_Id, true); + HellSpringFeature hellSpringFeature(Tile::flowing_lava_Id, true); hellSpringFeature.place(level, random, x, y, z); } @@ -540,7 +540,7 @@ vector *HellRandomLevelSource::getMobsAt(MobCategory *m { return netherBridgeFeature->getBridgeEnemies(); } - if ((netherBridgeFeature->isInsideBoundingFeature(x, y, z) && level->getTile(x, y - 1, z) == Tile::netherBrick_Id)) + if ((netherBridgeFeature->isInsideBoundingFeature(x, y, z) && level->getTile(x, y - 1, z) == Tile::nether_brick_Id)) { return netherBridgeFeature->getBridgeEnemies(); } diff --git a/Minecraft.World/HellSpringFeature.cpp b/Minecraft.World/HellSpringFeature.cpp index 1b62b9b2..1467e789 100644 --- a/Minecraft.World/HellSpringFeature.cpp +++ b/Minecraft.World/HellSpringFeature.cpp @@ -11,17 +11,17 @@ HellSpringFeature::HellSpringFeature(int tile, bool insideRock) bool HellSpringFeature::place(Level *level, Random *random, int x, int y, int z) { - if (level->getTile(x, y + 1, z) != Tile::netherRack_Id) return false; - if (level->getTile(x, y - 1, z) != Tile::netherRack_Id) return false; + if (level->getTile(x, y + 1, z) != Tile::netherrack_Id) return false; + if (level->getTile(x, y - 1, z) != Tile::netherrack_Id) return false; - if (level->getTile(x, y, z) != 0 && level->getTile(x, y, z) != Tile::netherRack_Id) return false; + if (level->getTile(x, y, z) != 0 && level->getTile(x, y, z) != Tile::netherrack_Id) return false; int rockCount = 0; - if (level->getTile(x - 1, y, z) == Tile::netherRack_Id) rockCount++; - if (level->getTile(x + 1, y, z) == Tile::netherRack_Id) rockCount++; - if (level->getTile(x, y, z - 1) == Tile::netherRack_Id) rockCount++; - if (level->getTile(x, y, z + 1) == Tile::netherRack_Id) rockCount++; - if (level->getTile(x, y - 1, z) == Tile::netherRack_Id) rockCount++; + if (level->getTile(x - 1, y, z) == Tile::netherrack_Id) rockCount++; + if (level->getTile(x + 1, y, z) == Tile::netherrack_Id) rockCount++; + if (level->getTile(x, y, z - 1) == Tile::netherrack_Id) rockCount++; + if (level->getTile(x, y, z + 1) == Tile::netherrack_Id) rockCount++; + if (level->getTile(x, y - 1, z) == Tile::netherrack_Id) rockCount++; int holeCount = 0; if (level->isEmptyTile(x - 1, y, z)) holeCount++; diff --git a/Minecraft.World/HoeItem.cpp b/Minecraft.World/HoeItem.cpp index a160f486..c6855cf5 100644 --- a/Minecraft.World/HoeItem.cpp +++ b/Minecraft.World/HoeItem.cpp @@ -21,7 +21,7 @@ bool HoeItem::useOn(shared_ptr instance, shared_ptr player int targetType = level->getTile(x, y, z); int above = level->getTile(x, y + 1, z); - if (face != 0 && above == 0 && (targetType == Tile::grass_Id || targetType == Tile::dirt_Id || targetType == Tile::mycel_Id)) + if (face != 0 && above == 0 && (targetType == Tile::grass_Id || targetType == Tile::dirt_Id || targetType == Tile::mycelium_Id)) { if(!bTestUseOnOnly) { diff --git a/Minecraft.World/HopperTile.cpp b/Minecraft.World/HopperTile.cpp index 0371712a..6cb54f36 100644 --- a/Minecraft.World/HopperTile.cpp +++ b/Minecraft.World/HopperTile.cpp @@ -16,6 +16,32 @@ HopperTile::HopperTile(int id) : BaseEntityTile(id, Material::metal, isSolidRend setShape(0, 0, 0, 1, 1, 1); } +void HopperTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int HopperTile::defaultBlockState() +{ + return 0; +} + +int HopperTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState HopperTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState HopperTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return getBlockState(level->getData(x, y, z)); +} + void HopperTile::updateShape(LevelSource *level, int x, int y, int z, int forceData , shared_ptr forceEntity) { setShape(0, 0, 0, 1, 1, 1); diff --git a/Minecraft.World/HopperTile.h b/Minecraft.World/HopperTile.h index 12631587..2d0790ef 100644 --- a/Minecraft.World/HopperTile.h +++ b/Minecraft.World/HopperTile.h @@ -26,6 +26,12 @@ private: public: HopperTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual void updateShape(LevelSource *level, int x, int y, int z, int forceData = -1, shared_ptr forceEntity = shared_ptr()); virtual void addAABBs(Level *level, int x, int y, int z, AABB *box, AABBList *boxes, shared_ptr source); virtual int getPlacedOnFaceDataValue(Level *level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue); diff --git a/Minecraft.World/HouseFeature.cpp b/Minecraft.World/HouseFeature.cpp index b6bba5a5..ebe3c81b 100644 --- a/Minecraft.World/HouseFeature.cpp +++ b/Minecraft.World/HouseFeature.cpp @@ -41,7 +41,7 @@ bool HouseFeature::place(Level *level, Random *random, int x, int y, int z) } else { - if (t == Tile::cobblestone_Id || t == Tile::mossyCobblestone_Id) return false; + if (t == Tile::cobblestone_Id || t == Tile::mossy_cobblestone_Id) return false; } } @@ -101,14 +101,14 @@ bool HouseFeature::place(Level *level, Random *random, int x, int y, int z) int material = -1; if (yy == y0 + h - 1) { - material = Tile::wood_Id; + material = Tile::planks_Id; } else if (xx >= xx0 && xx <= xx1 && zz >= zz0 && zz <= zz1) { material = 0; if (yy == y0 - 1 || yy == y0 + h - 1 || xx == xx0 || zz == zz0 || xx == xx1 || zz == zz1) { - if (yy <= y0 + random->nextInt(3)) material = Tile::mossyCobblestone_Id; + if (yy <= y0 + random->nextInt(3)) material = Tile::mossy_cobblestone_Id; else material = Tile::cobblestone_Id; } } @@ -137,7 +137,7 @@ bool HouseFeature::place(Level *level, Random *random, int x, int y, int z) if (doorSide == 1) dir = 2; if (doorSide == 3) dir = 3; - DoorItem::place(level, xx, y0, zz, dir, Tile::door_wood); + DoorItem::place(level, xx, y0, zz, dir, Tile::wooden_door); } for (int i = 0; i < (w * 2 + d * 2) * 3; i++) diff --git a/Minecraft.World/HugeMushroomFeature.cpp b/Minecraft.World/HugeMushroomFeature.cpp index a4025019..97c59305 100644 --- a/Minecraft.World/HugeMushroomFeature.cpp +++ b/Minecraft.World/HugeMushroomFeature.cpp @@ -46,7 +46,7 @@ bool HugeMushroomFeature::place(Level *level, Random *random, int x, int y, int } int belowTile = level->getTile(x, y - 1, z); - if (belowTile != Tile::dirt_Id && belowTile != Tile::grass_Id && belowTile != Tile::mycel_Id) + if (belowTile != Tile::dirt_Id && belowTile != Tile::grass_Id && belowTile != Tile::mycelium_Id) { return false; } @@ -91,7 +91,7 @@ bool HugeMushroomFeature::place(Level *level, Random *random, int x, int y, int if (data == 5 && yy < y + treeHeight) data = 0; if (data != 0 || y >= y + treeHeight - 1) { - if (!Tile::solid[level->getTile(xx, yy, zz)]) placeBlock(level, xx, yy, zz, Tile::hugeMushroom_brown_Id + type, data); + if (!Tile::solid[level->getTile(xx, yy, zz)]) placeBlock(level, xx, yy, zz, Tile::brown_mushroom_block_Id + type, data); } } } @@ -99,7 +99,7 @@ bool HugeMushroomFeature::place(Level *level, Random *random, int x, int y, int for (int hh = 0; hh < treeHeight; hh++) { int t = level->getTile(x, y + hh, z); - if (!Tile::solid[t]) placeBlock(level, x, y + hh, z, Tile::hugeMushroom_brown_Id + type, 10); + if (!Tile::solid[t]) placeBlock(level, x, y + hh, z, Tile::brown_mushroom_block_Id + type, 10); } return true; } diff --git a/Minecraft.World/HugeMushroomTile.cpp b/Minecraft.World/HugeMushroomTile.cpp index 8d3ef144..ce815db0 100644 --- a/Minecraft.World/HugeMushroomTile.cpp +++ b/Minecraft.World/HugeMushroomTile.cpp @@ -14,6 +14,32 @@ HugeMushroomTile::HugeMushroomTile(int id, Material *material, int type) : Tile( iconInside = nullptr; } +void HugeMushroomTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int HugeMushroomTile::defaultBlockState() +{ + return 0; +} + +int HugeMushroomTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState HugeMushroomTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState HugeMushroomTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return getBlockState(level->getData(x, y, z)); +} + Icon *HugeMushroomTile::getTexture(int face, int data) { // 123 diff --git a/Minecraft.World/HugeMushroomTile.h b/Minecraft.World/HugeMushroomTile.h index 0b45cf63..3b8c7731 100644 --- a/Minecraft.World/HugeMushroomTile.h +++ b/Minecraft.World/HugeMushroomTile.h @@ -21,6 +21,11 @@ private: Icon *iconInside; public: HugeMushroomTile(int id, Material *material, int type); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; Icon *getTexture(int face, int data); int getResourceCount(Random *random); int getResource(int data, Random *random, int playerBonusLevel); diff --git a/Minecraft.World/IceSpikeFeature.cpp b/Minecraft.World/IceSpikeFeature.cpp index 87c6a016..4861d915 100644 --- a/Minecraft.World/IceSpikeFeature.cpp +++ b/Minecraft.World/IceSpikeFeature.cpp @@ -54,7 +54,7 @@ bool IceSpikeFeature::place(Level *level, Random *random, int x, int y, int z) if (level->isEmptyTile(x + ix, y + k, z + iz) || currentTile == Tile::dirt_Id || currentTile == Tile::snow_Id || currentTile == Tile::ice_Id) { - level->setTileAndData(x + ix, y + k, z + iz, Tile::packedIce_Id, 0, 3); + level->setTileAndData(x + ix, y + k, z + iz, Tile::packed_ice_Id, 0, 3); } @@ -64,7 +64,7 @@ bool IceSpikeFeature::place(Level *level, Random *random, int x, int y, int z) if (level->isEmptyTile(x + ix, y - k, z + iz) || currentTile == Tile::dirt_Id || currentTile == Tile::snow_Id || currentTile == Tile::ice_Id) { - level->setTileAndData(x + ix, y - k, z + iz, Tile::packedIce_Id, 0, 3); + level->setTileAndData(x + ix, y - k, z + iz, Tile::packed_ice_Id, 0, 3); } } } @@ -90,12 +90,12 @@ bool IceSpikeFeature::place(Level *level, Random *random, int x, int y, int z) { int t = level->getTile(x + rx, curY, z + rz); if (!level->isEmptyTile(x + rx, curY, z + rz) && t != Tile::dirt_Id && - t != Tile::snow_Id && t != Tile::ice_Id && t != Tile::packedIce_Id) + t != Tile::snow_Id && t != Tile::ice_Id && t != Tile::packed_ice_Id) { break; } - level->setTileAndData(x + rx, curY, z + rz, Tile::packedIce_Id, 0, 3); + level->setTileAndData(x + rx, curY, z + rz, Tile::packed_ice_Id, 0, 3); curY--; depthCounter--; if (depthCounter <= 0) diff --git a/Minecraft.World/IceTile.cpp b/Minecraft.World/IceTile.cpp index 60e16291..773c61c3 100644 --- a/Minecraft.World/IceTile.cpp +++ b/Minecraft.World/IceTile.cpp @@ -48,7 +48,7 @@ void IceTile::playerDestroy(Level *level, shared_ptr player, int x, int Material *below = level->getMaterial(x, y - 1, z); if (below->blocksMotion() || below->isLiquid()) { - level->setTileAndUpdate(x, y, z, Tile::water_Id); + level->setTileAndUpdate(x, y, z, Tile::flowing_water_Id); } } } @@ -68,7 +68,7 @@ void IceTile::tick(Level *level, int x, int y, int z, Random *random) return; } this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTileAndUpdate(x, y, z, Tile::calmWater_Id); + level->setTileAndUpdate(x, y, z, Tile::water_Id); } } diff --git a/Minecraft.World/InventoryMenu.cpp b/Minecraft.World/InventoryMenu.cpp index 28b69694..70f574d7 100644 --- a/Minecraft.World/InventoryMenu.cpp +++ b/Minecraft.World/InventoryMenu.cpp @@ -236,7 +236,7 @@ shared_ptr InventoryMenu::clicked(int slotIndex, int buttonNum, in shared_ptr out = AbstractContainerMenu::clicked(slotIndex, buttonNum, clickType, player, looped); - static int ironItems[4] = {Item::helmet_iron_Id,Item::chestplate_iron_Id,Item::leggings_iron_Id,Item::boots_iron_Id}; + static int ironItems[4] = {Item::iron_helmet_Id,Item::iron_chestplate_Id,Item::iron_leggings_Id,Item::iron_boots_Id}; for (int i = ARMOR_SLOT_START; i < ARMOR_SLOT_END; i++) { Slot *slot = slots.at(i); diff --git a/Minecraft.World/Item.cpp b/Minecraft.World/Item.cpp index db644c77..3ffe9a5a 100644 --- a/Minecraft.World/Item.cpp +++ b/Minecraft.World/Item.cpp @@ -35,123 +35,123 @@ Random *Item::random = new Random(); ItemArray Item::items = ItemArray( ITEM_NUM_COUNT ); -Item *Item::shovel_iron = nullptr; -Item *Item::pickAxe_iron = nullptr; -Item *Item::hatchet_iron = nullptr; -Item *Item::flintAndSteel = nullptr; +Item *Item::iron_shovel = nullptr; +Item *Item::iron_pickaxe = nullptr; +Item *Item::iron_axe = nullptr; +Item *Item::flint_and_steel = nullptr; Item *Item::apple = nullptr; BowItem *Item::bow = nullptr; Item *Item::arrow = nullptr; Item *Item::coal = nullptr; Item *Item::diamond = nullptr; -Item *Item::ironIngot = nullptr; -Item *Item::goldIngot = nullptr; -Item *Item::sword_iron = nullptr; +Item *Item::iron_ingot = nullptr; +Item *Item::gold_ingot = nullptr; +Item *Item::iron_sword = nullptr; -Item *Item::sword_wood = nullptr; -Item *Item::shovel_wood = nullptr; -Item *Item::pickAxe_wood = nullptr; -Item *Item::hatchet_wood = nullptr; +Item *Item::wooden_sword = nullptr; +Item *Item::wooden_shovel = nullptr; +Item *Item::wooden_pickaxe = nullptr; +Item *Item::wooden_axe = nullptr; -Item *Item::sword_stone = nullptr; -Item *Item::shovel_stone = nullptr; -Item *Item::pickAxe_stone = nullptr; -Item *Item::hatchet_stone = nullptr; +Item *Item::stone_sword = nullptr; +Item *Item::stone_shovel = nullptr; +Item *Item::stone_pickaxe = nullptr; +Item *Item::stone_axe = nullptr; -Item *Item::sword_diamond = nullptr; -Item *Item::shovel_diamond = nullptr; -Item *Item::pickAxe_diamond = nullptr; -Item *Item::hatchet_diamond = nullptr; +Item *Item::diamond_sword = nullptr; +Item *Item::diamond_shovel = nullptr; +Item *Item::diamond_pickaxe = nullptr; +Item *Item::diamond_axe = nullptr; Item *Item::stick = nullptr; Item *Item::bowl = nullptr; -Item *Item::mushroomStew = nullptr; +Item *Item::mushroom_stew = nullptr; -Item *Item::sword_gold = nullptr; -Item *Item::shovel_gold = nullptr; -Item *Item::pickAxe_gold = nullptr; -Item *Item::hatchet_gold = nullptr; +Item *Item::golden_sword = nullptr; +Item *Item::golden_shovel = nullptr; +Item *Item::golden_pickaxe = nullptr; +Item *Item::golden_axe = nullptr; Item *Item::string = nullptr; Item *Item::feather = nullptr; Item *Item::gunpowder = nullptr; -Item *Item::hoe_wood = nullptr; -Item *Item::hoe_stone = nullptr; -Item *Item::hoe_iron = nullptr; -Item *Item::hoe_diamond = nullptr; -Item *Item::hoe_gold = nullptr; +Item *Item::wooden_hoe = nullptr; +Item *Item::stone_hoe = nullptr; +Item *Item::iron_hoe = nullptr; +Item *Item::diamond_hoe = nullptr; +Item *Item::golden_hoe = nullptr; -Item *Item::seeds_wheat = nullptr; +Item *Item::wheat_seeds = nullptr; Item *Item::wheat = nullptr; Item *Item::bread = nullptr; -ArmorItem *Item::helmet_leather = nullptr; -ArmorItem *Item::chestplate_leather = nullptr; -ArmorItem *Item::leggings_leather = nullptr; -ArmorItem *Item::boots_leather = nullptr; +ArmorItem *Item::leather_helmet = nullptr; +ArmorItem *Item::leather_chestplate = nullptr; +ArmorItem *Item::leather_leggings = nullptr; +ArmorItem *Item::leather_boots = nullptr; -ArmorItem *Item::helmet_chain = nullptr; -ArmorItem *Item::chestplate_chain = nullptr; -ArmorItem *Item::leggings_chain = nullptr; -ArmorItem *Item::boots_chain = nullptr; +ArmorItem *Item::chainmail_helmet = nullptr; +ArmorItem *Item::chainmail_chestplate = nullptr; +ArmorItem *Item::chainmail_leggings = nullptr; +ArmorItem *Item::chainmail_boots = nullptr; -ArmorItem *Item::helmet_iron = nullptr; -ArmorItem *Item::chestplate_iron = nullptr; -ArmorItem *Item::leggings_iron = nullptr; -ArmorItem *Item::boots_iron = nullptr; +ArmorItem *Item::iron_helmet = nullptr; +ArmorItem *Item::iron_chestplate = nullptr; +ArmorItem *Item::iron_leggings = nullptr; +ArmorItem *Item::iron_boots = nullptr; -ArmorItem *Item::helmet_diamond = nullptr; -ArmorItem *Item::chestplate_diamond = nullptr; -ArmorItem *Item::leggings_diamond = nullptr; -ArmorItem *Item::boots_diamond = nullptr; +ArmorItem *Item::diamond_helmet = nullptr; +ArmorItem *Item::diamond_chestplate = nullptr; +ArmorItem *Item::diamond_leggings = nullptr; +ArmorItem *Item::diamond_boots = nullptr; -ArmorItem *Item::helmet_gold = nullptr; -ArmorItem *Item::chestplate_gold = nullptr; -ArmorItem *Item::leggings_gold = nullptr; -ArmorItem *Item::boots_gold = nullptr; +ArmorItem *Item::golden_helmet = nullptr; +ArmorItem *Item::golden_chestplate = nullptr; +ArmorItem *Item::golden_leggings = nullptr; +ArmorItem *Item::golden_boots = nullptr; Item *Item::flint = nullptr; -Item *Item::porkChop_raw = nullptr; -Item *Item::porkChop_cooked = nullptr; +Item *Item::raw_porkchop = nullptr; +Item *Item::cooked_porkchop = nullptr; Item *Item::painting = nullptr; -Item *Item::apple_gold = nullptr; +Item *Item::golden_apple = nullptr; Item *Item::sign = nullptr; -Item *Item::door_wood = nullptr; +Item *Item::wooden_door = nullptr; -Item *Item::bucket_empty = nullptr; -Item *Item::bucket_water = nullptr; -Item *Item::bucket_lava = nullptr; +Item *Item::bucket = nullptr; +Item *Item::water_bucket = nullptr; +Item *Item::lava_bucket = nullptr; Item *Item::minecart = nullptr; Item *Item::saddle = nullptr; -Item *Item::door_iron = nullptr; -Item *Item::redStone = nullptr; -Item *Item::snowBall = nullptr; +Item *Item::iron_door = nullptr; +Item *Item::redstone = nullptr; +Item *Item::snowball = nullptr; Item *Item::boat = nullptr; Item *Item::leather = nullptr; -Item *Item::bucket_milk = nullptr; +Item *Item::milk_bucket = nullptr; Item *Item::brick = nullptr; Item *Item::clay = nullptr; Item *Item::reeds = nullptr; Item *Item::paper = nullptr; Item *Item::book = nullptr; -Item *Item::slimeBall = nullptr; -Item *Item::minecart_chest = nullptr; -Item *Item::minecart_furnace = nullptr; +Item *Item::slime_ball = nullptr; +Item *Item::chest_minecart = nullptr; +Item *Item::furnace_minecart = nullptr; Item *Item::egg = nullptr; Item *Item::compass = nullptr; -FishingRodItem *Item::fishingRod = nullptr; +FishingRodItem *Item::fishing_rod = nullptr; Item *Item::clock = nullptr; -Item *Item::yellowDust = nullptr; -Item *Item::fish_raw = nullptr; -Item *Item::fish_cooked = nullptr; +Item *Item::glowstone_dust = nullptr; +Item *Item::raw_fish = nullptr; +Item *Item::cooked_fish = nullptr; -Item *Item::dye_powder = nullptr; +Item *Item::dye = nullptr; Item *Item::bone = nullptr; Item *Item::sugar = nullptr; Item *Item::cake = nullptr; @@ -183,32 +183,32 @@ Item *Item::melon = nullptr; Item *Item::seeds_pumpkin = nullptr; Item *Item::seeds_melon = nullptr; -Item *Item::beef_raw = nullptr; -Item *Item::beef_cooked = nullptr; -Item *Item::chicken_raw = nullptr; -Item *Item::chicken_cooked = nullptr; +Item *Item::raw_beef = nullptr; +Item *Item::cooked_beef = nullptr; +Item *Item::raw_chicken = nullptr; +Item *Item::cooked_chicken = nullptr; Item *Item::rotten_flesh = nullptr; -Item *Item::enderPearl = nullptr; +Item *Item::ender_pearl = nullptr; -Item *Item::blazeRod = nullptr; -Item *Item::ghastTear = nullptr; -Item *Item::goldNugget = nullptr; +Item *Item::blaze_rod = nullptr; +Item *Item::ghast_tear = nullptr; +Item *Item::gold_nugget = nullptr; Item *Item::netherwart_seeds = nullptr; PotionItem *Item::potion = nullptr; Item *Item::glassBottle = nullptr; -Item *Item::spiderEye = nullptr; -Item *Item::fermentedSpiderEye = nullptr; -Item *Item::blazePowder = nullptr; -Item *Item::magmaCream = nullptr; -Item *Item::brewingStand = nullptr; +Item *Item::spider_eye = nullptr; +Item *Item::fermented_spider_eye = nullptr; +Item *Item::blaze_powder = nullptr; +Item *Item::magma_cream = nullptr; +Item *Item::brewing_stand = nullptr; Item *Item::cauldron = nullptr; -Item *Item::eyeOfEnder = nullptr; -Item *Item::speckledMelon = nullptr; +Item *Item::eye_of_ender = nullptr; +Item *Item::speckled_melon = nullptr; -Item *Item::spawnEgg = nullptr; +Item *Item::spawn_egg = nullptr; -Item *Item::expBottle = nullptr; +Item *Item::experience_bottle = nullptr; // TU9 Item *Item::fireball = nullptr; @@ -218,57 +218,57 @@ Item *Item::skull = nullptr; // TU14 -Item *Item::writingBook = nullptr; -Item *Item::writtenBook = nullptr; +Item *Item::writable_book = nullptr; +Item *Item::written_book = nullptr; Item *Item::emerald = nullptr; -Item *Item::flowerPot = nullptr; +Item *Item::flower_pot = nullptr; Item *Item::carrots = nullptr; Item *Item::potato = nullptr; -Item *Item::potatoBaked = nullptr; -Item *Item::potatoPoisonous = nullptr; +Item *Item::baked_potato = nullptr; +Item *Item::poisonous_potato = nullptr; -EmptyMapItem *Item::emptyMap = nullptr; +EmptyMapItem *Item::empty_map = nullptr; -Item *Item::carrotGolden = nullptr; +Item *Item::golden_carrot = nullptr; -Item *Item::carrotOnAStick = nullptr; -Item *Item::netherStar = nullptr; -Item *Item::pumpkinPie = nullptr; +Item *Item::carrot_on_a_stick = nullptr; +Item *Item::nether_star = nullptr; +Item *Item::pumpkin_pie = nullptr; Item *Item::fireworks = nullptr; -Item *Item::fireworksCharge = nullptr; +Item *Item::firework_charge = nullptr; -EnchantedBookItem *Item::enchantedBook = nullptr; +EnchantedBookItem *Item::enchanted_book = nullptr; Item *Item::comparator = nullptr; Item *Item::netherbrick = nullptr; -Item *Item::netherQuartz = nullptr; -Item *Item::minecart_tnt = nullptr; -Item *Item::minecart_hopper = nullptr; +Item *Item::nether_quartz = nullptr; +Item *Item::tnt_minecart = nullptr; +Item *Item::hopper_minecart = nullptr; -Item *Item::horseArmorMetal = nullptr; -Item *Item::horseArmorGold = nullptr; -Item *Item::horseArmorDiamond = nullptr; +Item *Item::iron_horse_armor = nullptr; +Item *Item::golden_horse_armor = nullptr; +Item *Item::diamond_horse_armor = nullptr; Item *Item::lead = nullptr; -Item *Item::nameTag = nullptr; +Item *Item::name_tag = nullptr; -Item* Item::door_spruce = nullptr; -Item* Item::door_birch = nullptr; -Item* Item::door_jungle = nullptr; -Item* Item::door_acacia = nullptr; -Item* Item::door_dark = nullptr; +Item* Item::spruce_door = nullptr; +Item* Item::birch_door = nullptr; +Item* Item::jungle_door = nullptr; +Item* Item::acacia_door = nullptr; +Item* Item::dark_oak_door = nullptr; //TU31 -Item* Item::mutton_raw = nullptr; -Item* Item::mutton_cooked = nullptr; -Item* Item::rabbit_raw = nullptr; -Item* Item::rabbit_cooked = nullptr; -Item* Item::rabbits_foot = nullptr; +Item* Item::raw_mutton = nullptr; +Item* Item::cooked_mutton = nullptr; +Item* Item::raw_rabbit = nullptr; +Item* Item::cooked_rabbit = nullptr; +Item* Item::rabbit_foot = nullptr; Item* Item::rabbit_hide = nullptr; Item* Item::armor_stand = nullptr; -Item* Item::rabbitStew = nullptr; +Item* Item::rabbit_stew = nullptr; Item* Item::prismarine_crystal = nullptr; Item* Item::prismarine_shard = nullptr; @@ -277,75 +277,75 @@ Item* Item::elytra = nullptr; void Item::staticCtor() { - Item::sword_wood = ( new WeaponItem(12, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_wood) ->setIconName(L"swordWood")->setDescriptionId(IDS_ITEM_SWORD_WOOD)->setUseDescriptionId(IDS_DESC_SWORD); - Item::sword_stone = ( new WeaponItem(16, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_stone) ->setIconName(L"swordStone")->setDescriptionId(IDS_ITEM_SWORD_STONE)->setUseDescriptionId(IDS_DESC_SWORD); - Item::sword_iron = ( new WeaponItem(11, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_iron) ->setIconName(L"swordIron")->setDescriptionId(IDS_ITEM_SWORD_IRON)->setUseDescriptionId(IDS_DESC_SWORD); - Item::sword_diamond = ( new WeaponItem(20, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_diamond) ->setIconName(L"swordDiamond")->setDescriptionId(IDS_ITEM_SWORD_DIAMOND)->setUseDescriptionId(IDS_DESC_SWORD); - Item::sword_gold = ( new WeaponItem(27, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_gold) ->setIconName(L"swordGold")->setDescriptionId(IDS_ITEM_SWORD_GOLD)->setUseDescriptionId(IDS_DESC_SWORD); + Item::wooden_sword = ( new WeaponItem(12, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_wood) ->setIconName(L"swordWood")->setDescriptionId(IDS_ITEM_SWORD_WOOD)->setUseDescriptionId(IDS_DESC_SWORD); + Item::stone_sword = ( new WeaponItem(16, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_stone) ->setIconName(L"swordStone")->setDescriptionId(IDS_ITEM_SWORD_STONE)->setUseDescriptionId(IDS_DESC_SWORD); + Item::iron_sword = ( new WeaponItem(11, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_iron) ->setIconName(L"swordIron")->setDescriptionId(IDS_ITEM_SWORD_IRON)->setUseDescriptionId(IDS_DESC_SWORD); + Item::diamond_sword = ( new WeaponItem(20, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_diamond) ->setIconName(L"swordDiamond")->setDescriptionId(IDS_ITEM_SWORD_DIAMOND)->setUseDescriptionId(IDS_DESC_SWORD); + Item::golden_sword = ( new WeaponItem(27, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_gold) ->setIconName(L"swordGold")->setDescriptionId(IDS_ITEM_SWORD_GOLD)->setUseDescriptionId(IDS_DESC_SWORD); - Item::shovel_wood = ( new ShovelItem(13, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_wood) ->setIconName(L"shovelWood")->setDescriptionId(IDS_ITEM_SHOVEL_WOOD)->setUseDescriptionId(IDS_DESC_SHOVEL); - Item::shovel_stone = ( new ShovelItem(17, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_stone) ->setIconName(L"shovelStone")->setDescriptionId(IDS_ITEM_SHOVEL_STONE)->setUseDescriptionId(IDS_DESC_SHOVEL); - Item::shovel_iron = ( new ShovelItem(0, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_iron) ->setIconName(L"shovelIron")->setDescriptionId(IDS_ITEM_SHOVEL_IRON)->setUseDescriptionId(IDS_DESC_SHOVEL); - Item::shovel_diamond = ( new ShovelItem(21, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_diamond) ->setIconName(L"shovelDiamond")->setDescriptionId(IDS_ITEM_SHOVEL_DIAMOND)->setUseDescriptionId(IDS_DESC_SHOVEL); - Item::shovel_gold = ( new ShovelItem(28, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_gold) ->setIconName(L"shovelGold")->setDescriptionId(IDS_ITEM_SHOVEL_GOLD)->setUseDescriptionId(IDS_DESC_SHOVEL); + Item::wooden_shovel = ( new ShovelItem(13, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_wood) ->setIconName(L"shovelWood")->setDescriptionId(IDS_ITEM_SHOVEL_WOOD)->setUseDescriptionId(IDS_DESC_SHOVEL); + Item::stone_shovel = ( new ShovelItem(17, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_stone) ->setIconName(L"shovelStone")->setDescriptionId(IDS_ITEM_SHOVEL_STONE)->setUseDescriptionId(IDS_DESC_SHOVEL); + Item::iron_shovel = ( new ShovelItem(0, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_iron) ->setIconName(L"shovelIron")->setDescriptionId(IDS_ITEM_SHOVEL_IRON)->setUseDescriptionId(IDS_DESC_SHOVEL); + Item::diamond_shovel = ( new ShovelItem(21, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_diamond) ->setIconName(L"shovelDiamond")->setDescriptionId(IDS_ITEM_SHOVEL_DIAMOND)->setUseDescriptionId(IDS_DESC_SHOVEL); + Item::golden_shovel = ( new ShovelItem(28, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_gold) ->setIconName(L"shovelGold")->setDescriptionId(IDS_ITEM_SHOVEL_GOLD)->setUseDescriptionId(IDS_DESC_SHOVEL); - Item::pickAxe_wood = ( new PickaxeItem(14, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_wood) ->setIconName(L"pickaxeWood")->setDescriptionId(IDS_ITEM_PICKAXE_WOOD)->setUseDescriptionId(IDS_DESC_PICKAXE); - Item::pickAxe_stone = ( new PickaxeItem(18, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_stone) ->setIconName(L"pickaxeStone")->setDescriptionId(IDS_ITEM_PICKAXE_STONE)->setUseDescriptionId(IDS_DESC_PICKAXE); - Item::pickAxe_iron = ( new PickaxeItem(1, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_iron) ->setIconName(L"pickaxeIron")->setDescriptionId(IDS_ITEM_PICKAXE_IRON)->setUseDescriptionId(IDS_DESC_PICKAXE); - Item::pickAxe_diamond = ( new PickaxeItem(22, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_diamond) ->setIconName(L"pickaxeDiamond")->setDescriptionId(IDS_ITEM_PICKAXE_DIAMOND)->setUseDescriptionId(IDS_DESC_PICKAXE); - Item::pickAxe_gold = ( new PickaxeItem(29, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_gold) ->setIconName(L"pickaxeGold")->setDescriptionId(IDS_ITEM_PICKAXE_GOLD)->setUseDescriptionId(IDS_DESC_PICKAXE); + Item::wooden_pickaxe = ( new PickaxeItem(14, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_wood) ->setIconName(L"pickaxeWood")->setDescriptionId(IDS_ITEM_PICKAXE_WOOD)->setUseDescriptionId(IDS_DESC_PICKAXE); + Item::stone_pickaxe = ( new PickaxeItem(18, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_stone) ->setIconName(L"pickaxeStone")->setDescriptionId(IDS_ITEM_PICKAXE_STONE)->setUseDescriptionId(IDS_DESC_PICKAXE); + Item::iron_pickaxe = ( new PickaxeItem(1, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_iron) ->setIconName(L"pickaxeIron")->setDescriptionId(IDS_ITEM_PICKAXE_IRON)->setUseDescriptionId(IDS_DESC_PICKAXE); + Item::diamond_pickaxe = ( new PickaxeItem(22, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_diamond) ->setIconName(L"pickaxeDiamond")->setDescriptionId(IDS_ITEM_PICKAXE_DIAMOND)->setUseDescriptionId(IDS_DESC_PICKAXE); + Item::golden_pickaxe = ( new PickaxeItem(29, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_gold) ->setIconName(L"pickaxeGold")->setDescriptionId(IDS_ITEM_PICKAXE_GOLD)->setUseDescriptionId(IDS_DESC_PICKAXE); - Item::hatchet_wood = ( new HatchetItem(15, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_wood) ->setIconName(L"hatchetWood")->setDescriptionId(IDS_ITEM_HATCHET_WOOD)->setUseDescriptionId(IDS_DESC_HATCHET); - Item::hatchet_stone = ( new HatchetItem(19, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_stone) ->setIconName(L"hatchetStone")->setDescriptionId(IDS_ITEM_HATCHET_STONE)->setUseDescriptionId(IDS_DESC_HATCHET); - Item::hatchet_iron = ( new HatchetItem(2, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_iron) ->setIconName(L"hatchetIron")->setDescriptionId(IDS_ITEM_HATCHET_IRON)->setUseDescriptionId(IDS_DESC_HATCHET); - Item::hatchet_diamond = ( new HatchetItem(23, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_diamond) ->setIconName(L"hatchetDiamond")->setDescriptionId(IDS_ITEM_HATCHET_DIAMOND)->setUseDescriptionId(IDS_DESC_HATCHET); - Item::hatchet_gold = ( new HatchetItem(30, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_gold) ->setIconName(L"hatchetGold")->setDescriptionId(IDS_ITEM_HATCHET_GOLD)->setUseDescriptionId(IDS_DESC_HATCHET); + Item::wooden_axe = ( new HatchetItem(15, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_wood) ->setIconName(L"hatchetWood")->setDescriptionId(IDS_ITEM_HATCHET_WOOD)->setUseDescriptionId(IDS_DESC_HATCHET); + Item::stone_axe = ( new HatchetItem(19, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_stone) ->setIconName(L"hatchetStone")->setDescriptionId(IDS_ITEM_HATCHET_STONE)->setUseDescriptionId(IDS_DESC_HATCHET); + Item::iron_axe = ( new HatchetItem(2, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_iron) ->setIconName(L"hatchetIron")->setDescriptionId(IDS_ITEM_HATCHET_IRON)->setUseDescriptionId(IDS_DESC_HATCHET); + Item::diamond_axe = ( new HatchetItem(23, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_diamond) ->setIconName(L"hatchetDiamond")->setDescriptionId(IDS_ITEM_HATCHET_DIAMOND)->setUseDescriptionId(IDS_DESC_HATCHET); + Item::golden_axe = ( new HatchetItem(30, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_gold) ->setIconName(L"hatchetGold")->setDescriptionId(IDS_ITEM_HATCHET_GOLD)->setUseDescriptionId(IDS_DESC_HATCHET); - Item::hoe_wood = ( new HoeItem(34, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_wood) ->setIconName(L"hoeWood")->setDescriptionId(IDS_ITEM_HOE_WOOD)->setUseDescriptionId(IDS_DESC_HOE); - Item::hoe_stone = ( new HoeItem(35, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_stone) ->setIconName(L"hoeStone")->setDescriptionId(IDS_ITEM_HOE_STONE)->setUseDescriptionId(IDS_DESC_HOE); - Item::hoe_iron = ( new HoeItem(36, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_iron) ->setIconName(L"hoeIron")->setDescriptionId(IDS_ITEM_HOE_IRON)->setUseDescriptionId(IDS_DESC_HOE); - Item::hoe_diamond = ( new HoeItem(37, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_diamond) ->setIconName(L"hoeDiamond")->setDescriptionId(IDS_ITEM_HOE_DIAMOND)->setUseDescriptionId(IDS_DESC_HOE); - Item::hoe_gold = ( new HoeItem(38, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_gold) ->setIconName(L"hoeGold")->setDescriptionId(IDS_ITEM_HOE_GOLD)->setUseDescriptionId(IDS_DESC_HOE); + Item::wooden_hoe = ( new HoeItem(34, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_wood) ->setIconName(L"hoeWood")->setDescriptionId(IDS_ITEM_HOE_WOOD)->setUseDescriptionId(IDS_DESC_HOE); + Item::stone_hoe = ( new HoeItem(35, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_stone) ->setIconName(L"hoeStone")->setDescriptionId(IDS_ITEM_HOE_STONE)->setUseDescriptionId(IDS_DESC_HOE); + Item::iron_hoe = ( new HoeItem(36, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_iron) ->setIconName(L"hoeIron")->setDescriptionId(IDS_ITEM_HOE_IRON)->setUseDescriptionId(IDS_DESC_HOE); + Item::diamond_hoe = ( new HoeItem(37, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_diamond) ->setIconName(L"hoeDiamond")->setDescriptionId(IDS_ITEM_HOE_DIAMOND)->setUseDescriptionId(IDS_DESC_HOE); + Item::golden_hoe = ( new HoeItem(38, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_gold) ->setIconName(L"hoeGold")->setDescriptionId(IDS_ITEM_HOE_GOLD)->setUseDescriptionId(IDS_DESC_HOE); - Item::door_wood = ( new DoorItem(68, Material::wood, L"doorWood"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"doorWood")->setDescriptionId(IDS_ITEM_DOOR_WOOD)->setUseDescriptionId(IDS_DESC_DOOR_WOOD); - Item::door_iron = ( new DoorItem(74, Material::metal, L"doorIron"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_iron)->setIconName(L"doorIron")->setDescriptionId(IDS_ITEM_DOOR_IRON)->setUseDescriptionId(IDS_DESC_DOOR_IRON); + Item::wooden_door = ( new DoorItem(68, Material::wood, L"doorWood"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"doorWood")->setDescriptionId(IDS_ITEM_DOOR_WOOD)->setUseDescriptionId(IDS_DESC_DOOR_WOOD); + Item::iron_door = ( new DoorItem(74, Material::metal, L"doorIron"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_iron)->setIconName(L"doorIron")->setDescriptionId(IDS_ITEM_DOOR_IRON)->setUseDescriptionId(IDS_DESC_DOOR_IRON); - Item::helmet_leather = static_cast((new ArmorItem(42, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_cloth)->setIconName(L"helmetCloth")->setDescriptionId(IDS_ITEM_HELMET_CLOTH)->setUseDescriptionId(IDS_DESC_HELMET_LEATHER)); - Item::helmet_iron = static_cast((new ArmorItem(50, ArmorItem::ArmorMaterial::IRON, 2, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_iron)->setIconName(L"helmetIron")->setDescriptionId(IDS_ITEM_HELMET_IRON)->setUseDescriptionId(IDS_DESC_HELMET_IRON)); - Item::helmet_diamond = static_cast((new ArmorItem(54, ArmorItem::ArmorMaterial::DIAMOND, 3, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_diamond)->setIconName(L"helmetDiamond")->setDescriptionId(IDS_ITEM_HELMET_DIAMOND)->setUseDescriptionId(IDS_DESC_HELMET_DIAMOND)); - Item::helmet_gold = static_cast((new ArmorItem(58, ArmorItem::ArmorMaterial::GOLD, 4, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_gold)->setIconName(L"helmetGold")->setDescriptionId(IDS_ITEM_HELMET_GOLD)->setUseDescriptionId(IDS_DESC_HELMET_GOLD)); + Item::leather_helmet = static_cast((new ArmorItem(42, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_cloth)->setIconName(L"helmetCloth")->setDescriptionId(IDS_ITEM_HELMET_CLOTH)->setUseDescriptionId(IDS_DESC_HELMET_LEATHER)); + Item::iron_helmet = static_cast((new ArmorItem(50, ArmorItem::ArmorMaterial::IRON, 2, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_iron)->setIconName(L"helmetIron")->setDescriptionId(IDS_ITEM_HELMET_IRON)->setUseDescriptionId(IDS_DESC_HELMET_IRON)); + Item::diamond_helmet = static_cast((new ArmorItem(54, ArmorItem::ArmorMaterial::DIAMOND, 3, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_diamond)->setIconName(L"helmetDiamond")->setDescriptionId(IDS_ITEM_HELMET_DIAMOND)->setUseDescriptionId(IDS_DESC_HELMET_DIAMOND)); + Item::golden_helmet = static_cast((new ArmorItem(58, ArmorItem::ArmorMaterial::GOLD, 4, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_gold)->setIconName(L"helmetGold")->setDescriptionId(IDS_ITEM_HELMET_GOLD)->setUseDescriptionId(IDS_DESC_HELMET_GOLD)); - Item::chestplate_leather = static_cast((new ArmorItem(43, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_cloth)->setIconName(L"chestplateCloth")->setDescriptionId(IDS_ITEM_CHESTPLATE_CLOTH)->setUseDescriptionId(IDS_DESC_CHESTPLATE_LEATHER)); - Item::chestplate_iron = static_cast((new ArmorItem(51, ArmorItem::ArmorMaterial::IRON, 2, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_iron)->setIconName(L"chestplateIron")->setDescriptionId(IDS_ITEM_CHESTPLATE_IRON)->setUseDescriptionId(IDS_DESC_CHESTPLATE_IRON)); - Item::chestplate_diamond = static_cast((new ArmorItem(55, ArmorItem::ArmorMaterial::DIAMOND, 3, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_diamond)->setIconName(L"chestplateDiamond")->setDescriptionId(IDS_ITEM_CHESTPLATE_DIAMOND)->setUseDescriptionId(IDS_DESC_CHESTPLATE_DIAMOND)); - Item::chestplate_gold = static_cast((new ArmorItem(59, ArmorItem::ArmorMaterial::GOLD, 4, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_gold)->setIconName(L"chestplateGold")->setDescriptionId(IDS_ITEM_CHESTPLATE_GOLD)->setUseDescriptionId(IDS_DESC_CHESTPLATE_GOLD)); + Item::leather_chestplate = static_cast((new ArmorItem(43, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_cloth)->setIconName(L"chestplateCloth")->setDescriptionId(IDS_ITEM_CHESTPLATE_CLOTH)->setUseDescriptionId(IDS_DESC_CHESTPLATE_LEATHER)); + Item::iron_chestplate = static_cast((new ArmorItem(51, ArmorItem::ArmorMaterial::IRON, 2, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_iron)->setIconName(L"chestplateIron")->setDescriptionId(IDS_ITEM_CHESTPLATE_IRON)->setUseDescriptionId(IDS_DESC_CHESTPLATE_IRON)); + Item::diamond_chestplate = static_cast((new ArmorItem(55, ArmorItem::ArmorMaterial::DIAMOND, 3, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_diamond)->setIconName(L"chestplateDiamond")->setDescriptionId(IDS_ITEM_CHESTPLATE_DIAMOND)->setUseDescriptionId(IDS_DESC_CHESTPLATE_DIAMOND)); + Item::golden_chestplate = static_cast((new ArmorItem(59, ArmorItem::ArmorMaterial::GOLD, 4, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_gold)->setIconName(L"chestplateGold")->setDescriptionId(IDS_ITEM_CHESTPLATE_GOLD)->setUseDescriptionId(IDS_DESC_CHESTPLATE_GOLD)); - Item::leggings_leather = static_cast((new ArmorItem(44, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_cloth)->setIconName(L"leggingsCloth")->setDescriptionId(IDS_ITEM_LEGGINGS_CLOTH)->setUseDescriptionId(IDS_DESC_LEGGINGS_LEATHER)); - Item::leggings_iron = static_cast((new ArmorItem(52, ArmorItem::ArmorMaterial::IRON, 2, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_iron)->setIconName(L"leggingsIron")->setDescriptionId(IDS_ITEM_LEGGINGS_IRON)->setUseDescriptionId(IDS_DESC_LEGGINGS_IRON)); - Item::leggings_diamond = static_cast((new ArmorItem(56, ArmorItem::ArmorMaterial::DIAMOND, 3, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_diamond)->setIconName(L"leggingsDiamond")->setDescriptionId(IDS_ITEM_LEGGINGS_DIAMOND)->setUseDescriptionId(IDS_DESC_LEGGINGS_DIAMOND)); - Item::leggings_gold = static_cast((new ArmorItem(60, ArmorItem::ArmorMaterial::GOLD, 4, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_gold)->setIconName(L"leggingsGold")->setDescriptionId(IDS_ITEM_LEGGINGS_GOLD)->setUseDescriptionId(IDS_DESC_LEGGINGS_GOLD)); + Item::leather_leggings = static_cast((new ArmorItem(44, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_cloth)->setIconName(L"leggingsCloth")->setDescriptionId(IDS_ITEM_LEGGINGS_CLOTH)->setUseDescriptionId(IDS_DESC_LEGGINGS_LEATHER)); + Item::iron_leggings = static_cast((new ArmorItem(52, ArmorItem::ArmorMaterial::IRON, 2, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_iron)->setIconName(L"leggingsIron")->setDescriptionId(IDS_ITEM_LEGGINGS_IRON)->setUseDescriptionId(IDS_DESC_LEGGINGS_IRON)); + Item::diamond_leggings = static_cast((new ArmorItem(56, ArmorItem::ArmorMaterial::DIAMOND, 3, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_diamond)->setIconName(L"leggingsDiamond")->setDescriptionId(IDS_ITEM_LEGGINGS_DIAMOND)->setUseDescriptionId(IDS_DESC_LEGGINGS_DIAMOND)); + Item::golden_leggings = static_cast((new ArmorItem(60, ArmorItem::ArmorMaterial::GOLD, 4, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_gold)->setIconName(L"leggingsGold")->setDescriptionId(IDS_ITEM_LEGGINGS_GOLD)->setUseDescriptionId(IDS_DESC_LEGGINGS_GOLD)); - Item::helmet_chain = static_cast((new ArmorItem(46, ArmorItem::ArmorMaterial::CHAIN, 1, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_chain)->setIconName(L"helmetChain")->setDescriptionId(IDS_ITEM_HELMET_CHAIN)->setUseDescriptionId(IDS_DESC_HELMET_CHAIN)); - Item::chestplate_chain = static_cast((new ArmorItem(47, ArmorItem::ArmorMaterial::CHAIN, 1, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_chain)->setIconName(L"chestplateChain")->setDescriptionId(IDS_ITEM_CHESTPLATE_CHAIN)->setUseDescriptionId(IDS_DESC_CHESTPLATE_CHAIN)); - Item::leggings_chain = static_cast((new ArmorItem(48, ArmorItem::ArmorMaterial::CHAIN, 1, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_chain)->setIconName(L"leggingsChain")->setDescriptionId(IDS_ITEM_LEGGINGS_CHAIN)->setUseDescriptionId(IDS_DESC_LEGGINGS_CHAIN)); - Item::boots_chain = static_cast((new ArmorItem(49, ArmorItem::ArmorMaterial::CHAIN, 1, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_chain)->setIconName(L"bootsChain")->setDescriptionId(IDS_ITEM_BOOTS_CHAIN)->setUseDescriptionId(IDS_DESC_BOOTS_CHAIN)); + Item::chainmail_helmet = static_cast((new ArmorItem(46, ArmorItem::ArmorMaterial::CHAIN, 1, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_chain)->setIconName(L"helmetChain")->setDescriptionId(IDS_ITEM_HELMET_CHAIN)->setUseDescriptionId(IDS_DESC_HELMET_CHAIN)); + Item::chainmail_chestplate = static_cast((new ArmorItem(47, ArmorItem::ArmorMaterial::CHAIN, 1, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_chain)->setIconName(L"chestplateChain")->setDescriptionId(IDS_ITEM_CHESTPLATE_CHAIN)->setUseDescriptionId(IDS_DESC_CHESTPLATE_CHAIN)); + Item::chainmail_leggings = static_cast((new ArmorItem(48, ArmorItem::ArmorMaterial::CHAIN, 1, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_chain)->setIconName(L"leggingsChain")->setDescriptionId(IDS_ITEM_LEGGINGS_CHAIN)->setUseDescriptionId(IDS_DESC_LEGGINGS_CHAIN)); + Item::chainmail_boots = static_cast((new ArmorItem(49, ArmorItem::ArmorMaterial::CHAIN, 1, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_chain)->setIconName(L"bootsChain")->setDescriptionId(IDS_ITEM_BOOTS_CHAIN)->setUseDescriptionId(IDS_DESC_BOOTS_CHAIN)); - Item::boots_leather = static_cast((new ArmorItem(45, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_cloth)->setIconName(L"bootsCloth")->setDescriptionId(IDS_ITEM_BOOTS_CLOTH)->setUseDescriptionId(IDS_DESC_BOOTS_LEATHER)); - Item::boots_iron = static_cast((new ArmorItem(53, ArmorItem::ArmorMaterial::IRON, 2, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_iron)->setIconName(L"bootsIron")->setDescriptionId(IDS_ITEM_BOOTS_IRON)->setUseDescriptionId(IDS_DESC_BOOTS_IRON)); - Item::boots_diamond = static_cast((new ArmorItem(57, ArmorItem::ArmorMaterial::DIAMOND, 3, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_diamond)->setIconName(L"bootsDiamond")->setDescriptionId(IDS_ITEM_BOOTS_DIAMOND)->setUseDescriptionId(IDS_DESC_BOOTS_DIAMOND)); - Item::boots_gold = static_cast((new ArmorItem(61, ArmorItem::ArmorMaterial::GOLD, 4, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_gold)->setIconName(L"bootsGold")->setDescriptionId(IDS_ITEM_BOOTS_GOLD)->setUseDescriptionId(IDS_DESC_BOOTS_GOLD)); + Item::leather_boots = static_cast((new ArmorItem(45, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_cloth)->setIconName(L"bootsCloth")->setDescriptionId(IDS_ITEM_BOOTS_CLOTH)->setUseDescriptionId(IDS_DESC_BOOTS_LEATHER)); + Item::iron_boots = static_cast((new ArmorItem(53, ArmorItem::ArmorMaterial::IRON, 2, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_iron)->setIconName(L"bootsIron")->setDescriptionId(IDS_ITEM_BOOTS_IRON)->setUseDescriptionId(IDS_DESC_BOOTS_IRON)); + Item::diamond_boots = static_cast((new ArmorItem(57, ArmorItem::ArmorMaterial::DIAMOND, 3, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_diamond)->setIconName(L"bootsDiamond")->setDescriptionId(IDS_ITEM_BOOTS_DIAMOND)->setUseDescriptionId(IDS_DESC_BOOTS_DIAMOND)); + Item::golden_boots = static_cast((new ArmorItem(61, ArmorItem::ArmorMaterial::GOLD, 4, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_gold)->setIconName(L"bootsGold")->setDescriptionId(IDS_ITEM_BOOTS_GOLD)->setUseDescriptionId(IDS_DESC_BOOTS_GOLD)); - Item::ironIngot = ( new Item(9) )->setIconName(L"ingotIron") ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_iron)->setDescriptionId(IDS_ITEM_INGOT_IRON)->setUseDescriptionId(IDS_DESC_INGOT); - Item::goldIngot = ( new Item(10) )->setIconName(L"ingotGold") ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_gold)->setDescriptionId(IDS_ITEM_INGOT_GOLD)->setUseDescriptionId(IDS_DESC_INGOT); + Item::iron_ingot = ( new Item(9) )->setIconName(L"ingotIron") ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_iron)->setDescriptionId(IDS_ITEM_INGOT_IRON)->setUseDescriptionId(IDS_DESC_INGOT); + Item::gold_ingot = ( new Item(10) )->setIconName(L"ingotGold") ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_gold)->setDescriptionId(IDS_ITEM_INGOT_GOLD)->setUseDescriptionId(IDS_DESC_INGOT); // 4J-PB - todo - add materials and base types to the ones below - Item::bucket_empty = ( new BucketItem(69, 0) ) ->setBaseItemTypeAndMaterial(eBaseItemType_utensil, eMaterial_water)->setIconName(L"bucket")->setDescriptionId(IDS_ITEM_BUCKET)->setUseDescriptionId(IDS_DESC_BUCKET)->setMaxStackSize(16); + Item::bucket = ( new BucketItem(69, 0) ) ->setBaseItemTypeAndMaterial(eBaseItemType_utensil, eMaterial_water)->setIconName(L"bucket")->setDescriptionId(IDS_ITEM_BUCKET)->setUseDescriptionId(IDS_DESC_BUCKET)->setMaxStackSize(16); Item::bowl = ( new Item(25) ) ->setBaseItemTypeAndMaterial(eBaseItemType_utensil, eMaterial_wood)->setIconName(L"bowl")->setDescriptionId(IDS_ITEM_BOWL)->setUseDescriptionId(IDS_DESC_BOWL)->setMaxStackSize(64); - Item::bucket_water = ( new BucketItem(70, Tile::water_Id) ) ->setIconName(L"bucketWater")->setDescriptionId(IDS_ITEM_BUCKET_WATER)->setCraftingRemainingItem(Item::bucket_empty)->setUseDescriptionId(IDS_DESC_BUCKET_WATER); - Item::bucket_lava = ( new BucketItem(71, Tile::lava_Id) ) ->setIconName(L"bucketLava")->setDescriptionId(IDS_ITEM_BUCKET_LAVA)->setCraftingRemainingItem(Item::bucket_empty)->setUseDescriptionId(IDS_DESC_BUCKET_LAVA); - Item::bucket_milk = ( new MilkBucketItem(79) )->setIconName(L"milk")->setDescriptionId(IDS_ITEM_BUCKET_MILK)->setCraftingRemainingItem(Item::bucket_empty)->setUseDescriptionId(IDS_DESC_BUCKET_MILK); + Item::water_bucket = ( new BucketItem(70, Tile::flowing_water_Id) ) ->setIconName(L"bucketWater")->setDescriptionId(IDS_ITEM_BUCKET_WATER)->setCraftingRemainingItem(Item::bucket)->setUseDescriptionId(IDS_DESC_BUCKET_WATER); + Item::lava_bucket = ( new BucketItem(71, Tile::flowing_lava_Id) ) ->setIconName(L"bucketLava")->setDescriptionId(IDS_ITEM_BUCKET_LAVA)->setCraftingRemainingItem(Item::bucket)->setUseDescriptionId(IDS_DESC_BUCKET_LAVA); + Item::milk_bucket = ( new MilkBucketItem(79) )->setIconName(L"milk")->setDescriptionId(IDS_ITEM_BUCKET_MILK)->setCraftingRemainingItem(Item::bucket)->setUseDescriptionId(IDS_DESC_BUCKET_MILK); Item::bow = static_cast((new BowItem(5))->setIconName(L"bow")->setBaseItemTypeAndMaterial(eBaseItemType_bow, eMaterial_bow)->setDescriptionId(IDS_ITEM_BOW)->setUseDescriptionId(IDS_DESC_BOW)); Item::arrow = ( new Item(6) ) ->setIconName(L"arrow")->setBaseItemTypeAndMaterial(eBaseItemType_bow, eMaterial_arrow) ->setDescriptionId(IDS_ITEM_ARROW)->setUseDescriptionId(IDS_DESC_ARROW); @@ -354,30 +354,30 @@ void Item::staticCtor() Item::clock = ( new ClockItem(91) ) ->setIconName(L"clock")->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_clock) ->setDescriptionId(IDS_ITEM_CLOCK)->setUseDescriptionId(IDS_DESC_CLOCK); Item::map = static_cast((new MapItem(102))->setIconName(L"map")->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_map)->setDescriptionId(IDS_ITEM_MAP)->setUseDescriptionId(IDS_DESC_MAP)); - Item::flintAndSteel = ( new FlintAndSteelItem(3) ) ->setIconName(L"flintAndSteel")->setBaseItemTypeAndMaterial(eBaseItemType_devicetool, eMaterial_flintandsteel)->setDescriptionId(IDS_ITEM_FLINT_AND_STEEL)->setUseDescriptionId(IDS_DESC_FLINTANDSTEEL); + Item::flint_and_steel = ( new FlintAndSteelItem(3) ) ->setIconName(L"flint_and_steel")->setBaseItemTypeAndMaterial(eBaseItemType_devicetool, eMaterial_flintandsteel)->setDescriptionId(IDS_ITEM_FLINT_AND_STEEL)->setUseDescriptionId(IDS_DESC_FLINTANDSTEEL); Item::apple = ( new FoodItem(4, 4, FoodConstants::FOOD_SATURATION_LOW, false) ) ->setIconName(L"apple")->setDescriptionId(IDS_ITEM_APPLE)->setUseDescriptionId(IDS_DESC_APPLE); Item::coal = ( new CoalItem(7) ) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_coal)->setIconName(L"coal")->setDescriptionId(IDS_ITEM_COAL)->setUseDescriptionId(IDS_DESC_COAL); Item::diamond = ( new Item(8) ) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_diamond)->setIconName(L"diamond")->setDescriptionId(IDS_ITEM_DIAMOND)->setUseDescriptionId(IDS_DESC_DIAMONDS); Item::stick = ( new Item(24) ) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stick, Item::eMaterial_wood)->setIconName(L"stick")->handEquipped()->setDescriptionId(IDS_ITEM_STICK)->setUseDescriptionId(IDS_DESC_STICK); - Item::mushroomStew = ( new BowlFoodItem(26, 6) ) ->setIconName(L"mushroomStew")->setDescriptionId(IDS_ITEM_MUSHROOM_STEW)->setUseDescriptionId(IDS_DESC_MUSHROOMSTEW); - Item::rabbitStew = ( new BowlFoodItem(157, 10) ) ->setIconName(L"rabbitStew")->setDescriptionId(IDS_ITEM_RABBIT_STEW)->setUseDescriptionId(IDS_DESC_RABBIT_STEW); + Item::mushroom_stew = ( new BowlFoodItem(26, 6) ) ->setIconName(L"mushroom_stew")->setDescriptionId(IDS_ITEM_MUSHROOM_STEW)->setUseDescriptionId(IDS_DESC_MUSHROOMSTEW); + Item::rabbit_stew = ( new BowlFoodItem(157, 10) ) ->setIconName(L"rabbit_stew")->setDescriptionId(IDS_ITEM_MUSHROOM_STEW)->setUseDescriptionId(IDS_DESC_MUSHROOMSTEW); Item::string = ( new TilePlanterItem(31, Tile::tripWire) ) ->setIconName(L"string")->setDescriptionId(IDS_ITEM_STRING)->setUseDescriptionId(IDS_DESC_STRING); Item::feather = ( new Item(32) ) ->setIconName(L"feather")->setDescriptionId(IDS_ITEM_FEATHER)->setUseDescriptionId(IDS_DESC_FEATHER); Item::gunpowder = ( new Item(33) ) ->setIconName(L"sulphur")->setDescriptionId(IDS_ITEM_SULPHUR)->setUseDescriptionId(IDS_DESC_SULPHUR)->setPotionBrewingFormula(PotionBrewing::MOD_GUNPOWDER); - Item::seeds_wheat = ( new SeedItem(39, Tile::wheat_Id, Tile::farmland_Id) ) ->setIconName(L"seeds")->setDescriptionId(IDS_ITEM_WHEAT_SEEDS)->setUseDescriptionId(IDS_DESC_WHEAT_SEEDS); + Item::wheat_seeds = ( new SeedItem(39, Tile::wheat_Id, Tile::farmland_Id) ) ->setIconName(L"seeds")->setDescriptionId(IDS_ITEM_WHEAT_SEEDS)->setUseDescriptionId(IDS_DESC_WHEAT_SEEDS); Item::wheat = ( new Item(40) ) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_wheat)->setIconName(L"wheat")->setDescriptionId(IDS_ITEM_WHEAT)->setUseDescriptionId(IDS_DESC_WHEAT); Item::bread = ( new FoodItem(41, 5, FoodConstants::FOOD_SATURATION_NORMAL, false) ) ->setIconName(L"bread")->setDescriptionId(IDS_ITEM_BREAD)->setUseDescriptionId(IDS_DESC_BREAD); Item::flint = ( new Item(62) ) ->setIconName(L"flint")->setDescriptionId(IDS_ITEM_FLINT)->setUseDescriptionId(IDS_DESC_FLINT); - Item::porkChop_raw = ( new FoodItem(63, 3, FoodConstants::FOOD_SATURATION_LOW, true) ) ->setIconName(L"porkchopRaw")->setDescriptionId(IDS_ITEM_PORKCHOP_RAW)->setUseDescriptionId(IDS_DESC_PORKCHOP_RAW); - Item::porkChop_cooked = ( new FoodItem(64, 8, FoodConstants::FOOD_SATURATION_GOOD, true) ) ->setIconName(L"porkchopCooked")->setDescriptionId(IDS_ITEM_PORKCHOP_COOKED)->setUseDescriptionId(IDS_DESC_PORKCHOP_COOKED); + Item::raw_porkchop = ( new FoodItem(63, 3, FoodConstants::FOOD_SATURATION_LOW, true) ) ->setIconName(L"porkchopRaw")->setDescriptionId(IDS_ITEM_PORKCHOP_RAW)->setUseDescriptionId(IDS_DESC_PORKCHOP_RAW); + Item::cooked_porkchop = ( new FoodItem(64, 8, FoodConstants::FOOD_SATURATION_GOOD, true) ) ->setIconName(L"porkchopCooked")->setDescriptionId(IDS_ITEM_PORKCHOP_COOKED)->setUseDescriptionId(IDS_DESC_PORKCHOP_COOKED); Item::painting = ( new HangingEntityItem(65,eTYPE_PAINTING) ) ->setBaseItemTypeAndMaterial(eBaseItemType_HangingItem, eMaterial_cloth)->setIconName(L"painting")->setDescriptionId(IDS_ITEM_PAINTING)->setUseDescriptionId(IDS_DESC_PICTURE); - Item::apple_gold = ( new GoldenAppleItem(66, 4, FoodConstants::FOOD_SATURATION_SUPERNATURAL, false) )->setCanAlwaysEat()->setEatEffect(MobEffect::regeneration->id, 5, 1, 1.0f) + Item::golden_apple = ( new GoldenAppleItem(66, 4, FoodConstants::FOOD_SATURATION_SUPERNATURAL, false) )->setCanAlwaysEat()->setEatEffect(MobEffect::regeneration->id, 5, 1, 1.0f) ->setBaseItemTypeAndMaterial(eBaseItemType_giltFruit,eMaterial_apple)->setIconName(L"appleGold")->setDescriptionId(IDS_ITEM_APPLE_GOLD);//->setUseDescriptionId(IDS_DESC_GOLDENAPPLE); Item::sign = ( new SignItem(67) ) ->setBaseItemTypeAndMaterial(eBaseItemType_HangingItem, eMaterial_wood)->setIconName(L"sign")->setDescriptionId(IDS_ITEM_SIGN)->setUseDescriptionId(IDS_DESC_SIGN); @@ -386,8 +386,8 @@ void Item::staticCtor() Item::minecart = ( new MinecartItem(72, Minecart::TYPE_RIDEABLE) ) ->setIconName(L"minecart")->setDescriptionId(IDS_ITEM_MINECART)->setUseDescriptionId(IDS_DESC_MINECART); Item::saddle = ( new SaddleItem(73) ) ->setIconName(L"saddle")->setDescriptionId(IDS_ITEM_SADDLE)->setUseDescriptionId(IDS_DESC_SADDLE); - Item::redStone = ( new RedStoneItem(75) ) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_redstone)->setIconName(L"redstone")->setDescriptionId(IDS_ITEM_REDSTONE)->setUseDescriptionId(IDS_DESC_REDSTONE_DUST)->setPotionBrewingFormula(PotionBrewing::MOD_REDSTONE); - Item::snowBall = ( new SnowballItem(76) ) ->setIconName(L"snowball")->setDescriptionId(IDS_ITEM_SNOWBALL)->setUseDescriptionId(IDS_DESC_SNOWBALL); + Item::redstone = ( new RedStoneItem(75) ) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_redstone)->setIconName(L"redstone")->setDescriptionId(IDS_ITEM_REDSTONE)->setUseDescriptionId(IDS_DESC_REDSTONE_DUST)->setPotionBrewingFormula(PotionBrewing::MOD_REDSTONE); + Item::snowball = ( new SnowballItem(76) ) ->setIconName(L"snowball")->setDescriptionId(IDS_ITEM_SNOWBALL)->setUseDescriptionId(IDS_DESC_SNOWBALL); Item::boat = ( new BoatItem(77) ) ->setIconName(L"boat")->setDescriptionId(IDS_ITEM_BOAT)->setUseDescriptionId(IDS_DESC_BOAT); @@ -397,16 +397,16 @@ void Item::staticCtor() Item::reeds = ( new TilePlanterItem(82, Tile::reeds) ) ->setIconName(L"reeds")->setDescriptionId(IDS_ITEM_REEDS)->setUseDescriptionId(IDS_DESC_REEDS); Item::paper = ( new Item(83) ) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_paper, Item::eMaterial_paper)->setIconName(L"paper")->setDescriptionId(IDS_ITEM_PAPER)->setUseDescriptionId(IDS_DESC_PAPER); Item::book = ( new BookItem(84) ) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_paper, Item::eMaterial_book)->setIconName(L"book")->setDescriptionId(IDS_ITEM_BOOK)->setUseDescriptionId(IDS_DESC_BOOK); - Item::slimeBall = ( new Item(85) ) ->setIconName(L"slimeball")->setDescriptionId(IDS_ITEM_SLIMEBALL)->setUseDescriptionId(IDS_DESC_SLIMEBALL); - Item::minecart_chest = ( new MinecartItem(86, Minecart::TYPE_CHEST) ) ->setIconName(L"minecart_chest")->setDescriptionId(IDS_ITEM_MINECART_CHEST)->setUseDescriptionId(IDS_DESC_MINECARTWITHCHEST); - Item::minecart_furnace = ( new MinecartItem(87, Minecart::TYPE_FURNACE) )->setIconName(L"minecart_furnace")->setDescriptionId(IDS_ITEM_MINECART_FURNACE)->setUseDescriptionId(IDS_DESC_MINECARTWITHFURNACE); + Item::slime_ball = ( new Item(85) ) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_treasure, Item::eMaterial_slime)->setIconName(L"slimeball")->setDescriptionId(IDS_ITEM_SLIMEBALL)->setUseDescriptionId(IDS_DESC_SLIMEBALL); + Item::chest_minecart = ( new MinecartItem(86, Minecart::TYPE_CHEST) ) ->setIconName(L"chest_minecart")->setDescriptionId(IDS_ITEM_MINECART_CHEST)->setUseDescriptionId(IDS_DESC_MINECARTWITHCHEST); + Item::furnace_minecart = ( new MinecartItem(87, Minecart::TYPE_FURNACE) )->setIconName(L"furnace_minecart")->setDescriptionId(IDS_ITEM_MINECART_FURNACE)->setUseDescriptionId(IDS_DESC_MINECARTWITHFURNACE); Item::egg = ( new EggItem(88) ) ->setIconName(L"egg")->setDescriptionId(IDS_ITEM_EGG)->setUseDescriptionId(IDS_DESC_EGG); - Item::fishingRod = static_cast((new FishingRodItem(90))->setBaseItemTypeAndMaterial(eBaseItemType_rod, eMaterial_wood)->setIconName(L"fishingRod")->setDescriptionId(IDS_ITEM_FISHING_ROD)->setUseDescriptionId(IDS_DESC_FISHINGROD)); - Item::yellowDust = ( new Item(92) ) ->setIconName(L"yellowDust")->setDescriptionId(IDS_ITEM_YELLOW_DUST)->setUseDescriptionId(IDS_DESC_YELLOW_DUST)->setPotionBrewingFormula(PotionBrewing::MOD_GLOWSTONE); - Item::fish_raw = ( new FishFoodItem(93, false) ) ->setIconName(L"fishRaw")->setDescriptionId(IDS_ITEM_FISH_RAW)->setUseDescriptionId(IDS_DESC_FISH_RAW)->setStackedByData(true)->setPotionBrewingFormula(PotionBrewing::MOD_PUFFERFISH); - Item::fish_cooked = (new FishFoodItem(94, true)) ->setIconName(L"fishCooked")->setDescriptionId(IDS_ITEM_FISH_COOKED)->setUseDescriptionId(IDS_DESC_FISH_COOKED)->setStackedByData(true); + Item::fishing_rod = static_cast((new FishingRodItem(90))->setBaseItemTypeAndMaterial(eBaseItemType_rod, eMaterial_wood)->setIconName(L"fishing_rod")->setDescriptionId(IDS_ITEM_FISHING_ROD)->setUseDescriptionId(IDS_DESC_FISHINGROD)); + Item::glowstone_dust = ( new Item(92) ) ->setIconName(L"glowstone_dust")->setDescriptionId(IDS_ITEM_YELLOW_DUST)->setUseDescriptionId(IDS_DESC_YELLOW_DUST)->setPotionBrewingFormula(PotionBrewing::MOD_GLOWSTONE); + Item::raw_fish = ( new FishFoodItem(93, false) ) ->setIconName(L"fishRaw")->setDescriptionId(IDS_ITEM_FISH_RAW)->setUseDescriptionId(IDS_DESC_FISH_RAW)->setStackedByData(true)->setPotionBrewingFormula(PotionBrewing::MOD_PUFFERFISH); + Item::cooked_fish = (new FishFoodItem(94, true)) ->setIconName(L"fishCooked")->setDescriptionId(IDS_ITEM_FISH_COOKED)->setUseDescriptionId(IDS_DESC_FISH_COOKED)->setStackedByData(true); - Item::dye_powder = ( new DyePowderItem(95) ) ->setBaseItemTypeAndMaterial(eBaseItemType_dyepowder, eMaterial_dye)->setIconName(L"dyePowder")->setDescriptionId(IDS_ITEM_DYE_POWDER)->setUseDescriptionId(-1); + Item::dye = ( new DyePowderItem(95) ) ->setBaseItemTypeAndMaterial(eBaseItemType_dyepowder, eMaterial_dye)->setIconName(L"dyePowder")->setDescriptionId(IDS_ITEM_DYE_POWDER)->setUseDescriptionId(-1); Item::bone = ( new Item(96) ) ->setIconName(L"bone")->setDescriptionId(IDS_ITEM_BONE)->handEquipped()->setUseDescriptionId(IDS_DESC_BONE); Item::sugar = ( new Item(97) ) ->setIconName(L"sugar")->setDescriptionId(IDS_ITEM_SUGAR)->setUseDescriptionId(IDS_DESC_SUGAR)->setPotionBrewingFormula(PotionBrewing::MOD_SUGAR); @@ -416,7 +416,7 @@ void Item::staticCtor() Item::bed = ( new BedItem(99) ) ->setMaxStackSize(1)->setIconName(L"bed")->setDescriptionId(IDS_ITEM_BED)->setUseDescriptionId(IDS_DESC_BED); - Item::repeater = ( new TilePlanterItem(100, static_cast(Tile::diode_off)) ) ->setIconName(L"diode")->setDescriptionId(IDS_ITEM_DIODE)->setUseDescriptionId(IDS_DESC_REDSTONEREPEATER); + Item::repeater = ( new TilePlanterItem(100, static_cast(Tile::unpowered_repeater)) ) ->setIconName(L"diode")->setDescriptionId(IDS_ITEM_DIODE)->setUseDescriptionId(IDS_DESC_REDSTONEREPEATER); Item::cookie = ( new FoodItem(101, 2, FoodConstants::FOOD_SATURATION_POOR, false) ) ->setIconName(L"cookie")->setDescriptionId(IDS_ITEM_COOKIE)->setUseDescriptionId(IDS_DESC_COOKIE); @@ -424,41 +424,41 @@ void Item::staticCtor() Item::melon = (new FoodItem(104, 2, FoodConstants::FOOD_SATURATION_LOW, false)) ->setIconName(L"melon")->setDescriptionId(IDS_ITEM_MELON_SLICE)->setUseDescriptionId(IDS_DESC_MELON_SLICE); - Item::seeds_pumpkin = (new SeedItem(105, Tile::pumpkinStem_Id, Tile::farmland_Id)) ->setIconName(L"seeds_pumpkin")->setBaseItemTypeAndMaterial(eBaseItemType_seed, eMaterial_pumpkin)->setDescriptionId(IDS_ITEM_PUMPKIN_SEEDS)->setUseDescriptionId(IDS_DESC_PUMPKIN_SEEDS); - Item::seeds_melon = (new SeedItem(106, Tile::melonStem_Id, Tile::farmland_Id)) ->setIconName(L"seeds_melon")->setBaseItemTypeAndMaterial(eBaseItemType_seed, eMaterial_melon)->setDescriptionId(IDS_ITEM_MELON_SEEDS)->setUseDescriptionId(IDS_DESC_MELON_SEEDS); + Item::seeds_pumpkin = (new SeedItem(105, Tile::pumpkin_stem_Id, Tile::farmland_Id)) ->setIconName(L"seeds_pumpkin")->setBaseItemTypeAndMaterial(eBaseItemType_seed, eMaterial_pumpkin)->setDescriptionId(IDS_ITEM_PUMPKIN_SEEDS)->setUseDescriptionId(IDS_DESC_PUMPKIN_SEEDS); + Item::seeds_melon = (new SeedItem(106, Tile::melon_stem_Id, Tile::farmland_Id)) ->setIconName(L"seeds_melon")->setBaseItemTypeAndMaterial(eBaseItemType_seed, eMaterial_melon)->setDescriptionId(IDS_ITEM_MELON_SEEDS)->setUseDescriptionId(IDS_DESC_MELON_SEEDS); - Item::beef_raw = (new FoodItem(107, 3, FoodConstants::FOOD_SATURATION_LOW, true)) ->setIconName(L"beefRaw")->setDescriptionId(IDS_ITEM_BEEF_RAW)->setUseDescriptionId(IDS_DESC_BEEF_RAW); - Item::beef_cooked = (new FoodItem(108, 8, FoodConstants::FOOD_SATURATION_GOOD, true))->setIconName(L"beefCooked")->setDescriptionId(IDS_ITEM_BEEF_COOKED)->setUseDescriptionId(IDS_DESC_BEEF_COOKED); - Item::chicken_raw = (new FoodItem(109, 2, FoodConstants::FOOD_SATURATION_LOW, true))->setEatEffect(MobEffect::hunger->id, 30, 0, .3f)->setIconName(L"chickenRaw")->setDescriptionId(IDS_ITEM_CHICKEN_RAW)->setUseDescriptionId(IDS_DESC_CHICKEN_RAW); - Item::chicken_cooked = (new FoodItem(110, 6, FoodConstants::FOOD_SATURATION_NORMAL, true))->setIconName(L"chickenCooked")->setDescriptionId(IDS_ITEM_CHICKEN_COOKED)->setUseDescriptionId(IDS_DESC_CHICKEN_COOKED); + Item::raw_beef = (new FoodItem(107, 3, FoodConstants::FOOD_SATURATION_LOW, true)) ->setIconName(L"beefRaw")->setDescriptionId(IDS_ITEM_BEEF_RAW)->setUseDescriptionId(IDS_DESC_BEEF_RAW); + Item::cooked_beef = (new FoodItem(108, 8, FoodConstants::FOOD_SATURATION_GOOD, true))->setIconName(L"beefCooked")->setDescriptionId(IDS_ITEM_BEEF_COOKED)->setUseDescriptionId(IDS_DESC_BEEF_COOKED); + Item::raw_chicken = (new FoodItem(109, 2, FoodConstants::FOOD_SATURATION_LOW, true))->setEatEffect(MobEffect::hunger->id, 30, 0, .3f)->setIconName(L"chickenRaw")->setDescriptionId(IDS_ITEM_CHICKEN_RAW)->setUseDescriptionId(IDS_DESC_CHICKEN_RAW); + Item::cooked_chicken = (new FoodItem(110, 6, FoodConstants::FOOD_SATURATION_NORMAL, true))->setIconName(L"chickenCooked")->setDescriptionId(IDS_ITEM_CHICKEN_COOKED)->setUseDescriptionId(IDS_DESC_CHICKEN_COOKED); Item::rotten_flesh = (new FoodItem(111, 4, FoodConstants::FOOD_SATURATION_POOR, true))->setEatEffect(MobEffect::hunger->id, 30, 0, .8f)->setIconName(L"rottenFlesh")->setDescriptionId(IDS_ITEM_ROTTEN_FLESH)->setUseDescriptionId(IDS_DESC_ROTTEN_FLESH); - Item::enderPearl = (new EnderpearlItem(112)) ->setIconName(L"enderPearl")->setDescriptionId(IDS_ITEM_ENDER_PEARL)->setUseDescriptionId(IDS_DESC_ENDER_PEARL); + Item::ender_pearl = (new EnderpearlItem(112)) ->setIconName(L"ender_pearl")->setDescriptionId(IDS_ITEM_ENDER_PEARL)->setUseDescriptionId(IDS_DESC_ENDER_PEARL); - Item::blazeRod = (new Item(113) ) ->setIconName(L"blazeRod")->setDescriptionId(IDS_ITEM_BLAZE_ROD)->setUseDescriptionId(IDS_DESC_BLAZE_ROD)->handEquipped(); - Item::ghastTear = (new Item(114) ) ->setIconName(L"ghastTear")->setDescriptionId(IDS_ITEM_GHAST_TEAR)->setUseDescriptionId(IDS_DESC_GHAST_TEAR)->setPotionBrewingFormula(PotionBrewing::MOD_GHASTTEARS); - Item::goldNugget = (new Item(115) ) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_gold)->setIconName(L"goldNugget")->setDescriptionId(IDS_ITEM_GOLD_NUGGET)->setUseDescriptionId(IDS_DESC_GOLD_NUGGET); + Item::blaze_rod = (new Item(113) ) ->setIconName(L"blaze_rod")->setDescriptionId(IDS_ITEM_BLAZE_ROD)->setUseDescriptionId(IDS_DESC_BLAZE_ROD)->handEquipped(); + Item::ghast_tear = (new Item(114) ) ->setIconName(L"ghast_tear")->setDescriptionId(IDS_ITEM_GHAST_TEAR)->setUseDescriptionId(IDS_DESC_GHAST_TEAR)->setPotionBrewingFormula(PotionBrewing::MOD_GHASTTEARS); + Item::gold_nugget = (new Item(115) ) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_gold)->setIconName(L"gold_nugget")->setDescriptionId(IDS_ITEM_GOLD_NUGGET)->setUseDescriptionId(IDS_DESC_GOLD_NUGGET); - Item::netherwart_seeds = (new SeedItem(116, Tile::netherStalk_Id, Tile::soulsand_Id) ) ->setIconName(L"netherStalkSeeds")->setDescriptionId(IDS_ITEM_NETHER_STALK_SEEDS)->setUseDescriptionId(IDS_DESC_NETHER_STALK_SEEDS)->setPotionBrewingFormula(PotionBrewing::MOD_NETHERWART); + Item::netherwart_seeds = (new SeedItem(116, Tile::nether_wart_Id, Tile::soul_sand_Id) ) ->setIconName(L"netherStalkSeeds")->setDescriptionId(IDS_ITEM_NETHER_STALK_SEEDS)->setUseDescriptionId(IDS_DESC_NETHER_STALK_SEEDS)->setPotionBrewingFormula(PotionBrewing::MOD_NETHERWART); Item::potion = static_cast((new PotionItem(117))->setIconName(L"potion")->setDescriptionId(IDS_ITEM_POTION)->setUseDescriptionId(IDS_DESC_POTION)); Item::glassBottle = (new BottleItem(118) ) ->setBaseItemTypeAndMaterial(eBaseItemType_utensil, eMaterial_glass)->setIconName(L"glassBottle")->setDescriptionId(IDS_ITEM_GLASS_BOTTLE)->setUseDescriptionId(IDS_DESC_GLASS_BOTTLE); - Item::spiderEye = (new FoodItem(119, 2, FoodConstants::FOOD_SATURATION_GOOD, false) ) ->setEatEffect(MobEffect::poison->id, 5, 0, 1.0f)->setIconName(L"spiderEye")->setDescriptionId(IDS_ITEM_SPIDER_EYE)->setUseDescriptionId(IDS_DESC_SPIDER_EYE)->setPotionBrewingFormula(PotionBrewing::MOD_SPIDEREYE); - Item::fermentedSpiderEye = (new Item(120) ) ->setIconName(L"fermentedSpiderEye")->setDescriptionId(IDS_ITEM_FERMENTED_SPIDER_EYE)->setUseDescriptionId(IDS_DESC_FERMENTED_SPIDER_EYE)->setPotionBrewingFormula(PotionBrewing::MOD_FERMENTEDEYE); + Item::spider_eye = (new FoodItem(119, 2, FoodConstants::FOOD_SATURATION_GOOD, false) ) ->setEatEffect(MobEffect::poison->id, 5, 0, 1.0f)->setIconName(L"spider_eye")->setDescriptionId(IDS_ITEM_SPIDER_EYE)->setUseDescriptionId(IDS_DESC_SPIDER_EYE)->setPotionBrewingFormula(PotionBrewing::MOD_SPIDEREYE); + Item::fermented_spider_eye = (new Item(120) ) ->setIconName(L"fermented_spider_eye")->setDescriptionId(IDS_ITEM_FERMENTED_SPIDER_EYE)->setUseDescriptionId(IDS_DESC_FERMENTED_SPIDER_EYE)->setPotionBrewingFormula(PotionBrewing::MOD_FERMENTEDEYE); - Item::blazePowder = (new Item(121) ) ->setIconName(L"blazePowder")->setDescriptionId(IDS_ITEM_BLAZE_POWDER)->setUseDescriptionId(IDS_DESC_BLAZE_POWDER)->setPotionBrewingFormula(PotionBrewing::MOD_BLAZEPOWDER); - Item::magmaCream = (new Item(122) ) ->setIconName(L"magmaCream")->setDescriptionId(IDS_ITEM_MAGMA_CREAM)->setUseDescriptionId(IDS_DESC_MAGMA_CREAM)->setPotionBrewingFormula(PotionBrewing::MOD_MAGMACREAM); + Item::blaze_powder = (new Item(121) ) ->setIconName(L"blaze_powder")->setDescriptionId(IDS_ITEM_BLAZE_POWDER)->setUseDescriptionId(IDS_DESC_BLAZE_POWDER)->setPotionBrewingFormula(PotionBrewing::MOD_BLAZEPOWDER); + Item::magma_cream = (new Item(122) ) ->setIconName(L"magma_cream")->setDescriptionId(IDS_ITEM_MAGMA_CREAM)->setUseDescriptionId(IDS_DESC_MAGMA_CREAM)->setPotionBrewingFormula(PotionBrewing::MOD_MAGMACREAM); - Item::brewingStand = (new TilePlanterItem(123, Tile::brewingStand) ) ->setBaseItemTypeAndMaterial(eBaseItemType_device, eMaterial_blaze)->setIconName(L"brewingStand")->setDescriptionId(IDS_ITEM_BREWING_STAND)->setUseDescriptionId(IDS_DESC_BREWING_STAND); + Item::brewing_stand = (new TilePlanterItem(123, Tile::brewingStand) ) ->setBaseItemTypeAndMaterial(eBaseItemType_device, eMaterial_blaze)->setIconName(L"brewing_stand")->setDescriptionId(IDS_ITEM_BREWING_STAND)->setUseDescriptionId(IDS_DESC_BREWING_STAND); Item::cauldron = (new TilePlanterItem(124, Tile::cauldron) ) ->setBaseItemTypeAndMaterial(eBaseItemType_utensil, eMaterial_iron)->setIconName(L"cauldron")->setDescriptionId(IDS_ITEM_CAULDRON)->setUseDescriptionId(IDS_DESC_CAULDRON); - Item::eyeOfEnder = (new EnderEyeItem(125) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_ender)->setIconName(L"eyeOfEnder")->setDescriptionId(IDS_ITEM_EYE_OF_ENDER)->setUseDescriptionId(IDS_DESC_EYE_OF_ENDER); - Item::speckledMelon = (new Item(126) ) ->setBaseItemTypeAndMaterial(eBaseItemType_giltFruit, eMaterial_melon)->setIconName(L"speckledMelon")->setDescriptionId(IDS_ITEM_SPECKLED_MELON)->setUseDescriptionId(IDS_DESC_SPECKLED_MELON)->setPotionBrewingFormula(PotionBrewing::MOD_SPECKLEDMELON); + Item::eye_of_ender = (new EnderEyeItem(125) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_ender)->setIconName(L"eye_of_ender")->setDescriptionId(IDS_ITEM_EYE_OF_ENDER)->setUseDescriptionId(IDS_DESC_EYE_OF_ENDER); + Item::speckled_melon = (new Item(126) ) ->setBaseItemTypeAndMaterial(eBaseItemType_giltFruit, eMaterial_melon)->setIconName(L"speckled_melon")->setDescriptionId(IDS_ITEM_SPECKLED_MELON)->setUseDescriptionId(IDS_DESC_SPECKLED_MELON)->setPotionBrewingFormula(PotionBrewing::MOD_SPECKLEDMELON); - Item::spawnEgg = (new SpawnEggItem(127)) ->setIconName(L"monsterPlacer")->setDescriptionId(IDS_ITEM_MONSTER_SPAWNER)->setUseDescriptionId(IDS_DESC_MONSTER_SPAWNER); + Item::spawn_egg = (new SpawnEggItem(127)) ->setIconName(L"monsterPlacer")->setDescriptionId(IDS_ITEM_MONSTER_SPAWNER)->setUseDescriptionId(IDS_DESC_MONSTER_SPAWNER); // 4J Stu - Brought this forward - Item::expBottle = (new ExperienceItem(128)) ->setIconName(L"expBottle")->setDescriptionId(IDS_ITEM_EXP_BOTTLE)->setUseDescriptionId(IDS_DESC_EXP_BOTTLE); + Item::experience_bottle = (new ExperienceItem(128)) ->setIconName(L"experience_bottle")->setDescriptionId(IDS_ITEM_EXP_BOTTLE)->setUseDescriptionId(IDS_DESC_EXP_BOTTLE); Item::record_01 = ( new RecordingItem(2000, L"13") ) ->setIconName(L"record")->setDescriptionId(IDS_ITEM_RECORD_01)->setUseDescriptionId(IDS_DESC_RECORD); Item::record_02 = ( new RecordingItem(2001, L"cat") ) ->setIconName(L"record")->setDescriptionId(IDS_ITEM_RECORD_02)->setUseDescriptionId(IDS_DESC_RECORD); @@ -485,57 +485,57 @@ void Item::staticCtor() Item::skull = (new SkullItem(141)) ->setIconName(L"skull")->setDescriptionId(IDS_ITEM_SKULL)->setUseDescriptionId(IDS_DESC_SKULL); // TU14 - //Item::writingBook = (new WritingBookItem(130))->setIcon(11, 11)->setDescriptionId("writingBook"); - //Item::writtenBook = (new WrittenBookItem(131))->setIcon(12, 11)->setDescriptionId("writtenBook"); + //Item::writable_book = (new WritingBookItem(130))->setIcon(11, 11)->setDescriptionId("writable_book"); + //Item::written_book = (new WrittenBookItem(131))->setIcon(12, 11)->setDescriptionId("written_book"); //Item::book = ( new BookItem(84) ) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_paper, Item::eMaterial_book)->setIconName(L"book")->setDescriptionId(IDS_ITEM_BOOK)->setUseDescriptionId(IDS_DESC_BOOK); //->setBaseItemTypeAndMaterial(Item::eBaseItemType_paper, Item::eMaterial_book) - Item::writingBook = (new WritingBookItem(130))->setBaseItemTypeAndMaterial(Item::eBaseItemType_paper, Item::eMaterial_book)->setIconName(L"writingBook")->setDescriptionId(IDS_ITEM_WRITINGBOOK)->setUseDescriptionId(IDS_DESC_WRITINGBOOK)->setMaxStackSize(1); - Item::writtenBook = (new WrittenBookItem(131))->setIconName(L"writtenBook")->setDescriptionId(IDS_ITEM_WRITTENBOOK)->setUseDescriptionId(IDS_DESC_WRITTENBOOK)->setMaxStackSize(1); + Item::writable_book = (new WritingBookItem(130))->setBaseItemTypeAndMaterial(Item::eBaseItemType_paper, Item::eMaterial_book)->setIconName(L"writable_book")->setDescriptionId(IDS_ITEM_WRITINGBOOK)->setUseDescriptionId(IDS_DESC_WRITINGBOOK)->setMaxStackSize(1); + Item::written_book = (new WrittenBookItem(131))->setIconName(L"written_book")->setDescriptionId(IDS_ITEM_WRITTENBOOK)->setUseDescriptionId(IDS_DESC_WRITTENBOOK)->setMaxStackSize(1); Item::emerald = (new Item(132)) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_emerald)->setIconName(L"emerald")->setDescriptionId(IDS_ITEM_EMERALD)->setUseDescriptionId(IDS_DESC_EMERALD); - Item::flowerPot = (new TilePlanterItem(134, Tile::flowerPot)) ->setIconName(L"flowerPot")->setDescriptionId(IDS_FLOWERPOT)->setUseDescriptionId(IDS_DESC_FLOWERPOT)->setBaseItemTypeAndMaterial(eBaseItemType_decoration,eMaterial_brick); + Item::flower_pot = (new TilePlanterItem(134, Tile::flower_pot)) ->setIconName(L"flower_pot")->setDescriptionId(IDS_FLOWERPOT)->setUseDescriptionId(IDS_DESC_FLOWERPOT)->setBaseItemTypeAndMaterial(eBaseItemType_decoration,eMaterial_brick); Item::carrots = (new SeedFoodItem(135, 4, FoodConstants::FOOD_SATURATION_NORMAL, Tile::carrots_Id, Tile::farmland_Id)) ->setIconName(L"carrots")->setDescriptionId(IDS_CARROTS)->setUseDescriptionId(IDS_DESC_CARROTS); Item::potato = (new SeedFoodItem(136, 1, FoodConstants::FOOD_SATURATION_LOW, Tile::potatoes_Id, Tile::farmland_Id)) ->setIconName(L"potato")->setDescriptionId(IDS_POTATO)->setUseDescriptionId(IDS_DESC_POTATO); - Item::potatoBaked = (new FoodItem(137, 6, FoodConstants::FOOD_SATURATION_NORMAL, false)) ->setIconName(L"potatoBaked")->setDescriptionId(IDS_ITEM_POTATO_BAKED)->setUseDescriptionId(IDS_DESC_POTATO_BAKED); - Item::potatoPoisonous = (new FoodItem(138, 2, FoodConstants::FOOD_SATURATION_LOW, false)) ->setEatEffect(MobEffect::poison->id, 5, 0, .6f)->setIconName(L"potatoPoisonous")->setDescriptionId(IDS_ITEM_POTATO_POISONOUS)->setUseDescriptionId(IDS_DESC_POTATO_POISONOUS); + Item::baked_potato = (new FoodItem(137, 6, FoodConstants::FOOD_SATURATION_NORMAL, false)) ->setIconName(L"baked_potato")->setDescriptionId(IDS_ITEM_POTATO_BAKED)->setUseDescriptionId(IDS_DESC_POTATO_BAKED); + Item::poisonous_potato = (new FoodItem(138, 2, FoodConstants::FOOD_SATURATION_LOW, false)) ->setEatEffect(MobEffect::poison->id, 5, 0, .6f)->setIconName(L"poisonous_potato")->setDescriptionId(IDS_ITEM_POTATO_POISONOUS)->setUseDescriptionId(IDS_DESC_POTATO_POISONOUS); - Item::emptyMap = (EmptyMapItem*)(new EmptyMapItem(139))->setIconName(L"map_empty")->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_map)->setDescriptionId(IDS_ITEM_MAP_EMPTY)->setUseDescriptionId(IDS_DESC_MAP_EMPTY); + Item::empty_map = (EmptyMapItem*)(new EmptyMapItem(139))->setIconName(L"map_empty")->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_map)->setDescriptionId(IDS_ITEM_MAP_EMPTY)->setUseDescriptionId(IDS_DESC_MAP_EMPTY); - Item::carrotGolden = (new FoodItem(140, 6, FoodConstants::FOOD_SATURATION_SUPERNATURAL, false)) ->setBaseItemTypeAndMaterial(eBaseItemType_giltFruit, eMaterial_carrot)->setIconName(L"carrotGolden")->setPotionBrewingFormula(PotionBrewing::MOD_GOLDENCARROT)->setDescriptionId(IDS_ITEM_CARROT_GOLDEN)->setUseDescriptionId(IDS_DESC_CARROT_GOLDEN); + Item::golden_carrot = (new FoodItem(140, 6, FoodConstants::FOOD_SATURATION_SUPERNATURAL, false)) ->setBaseItemTypeAndMaterial(eBaseItemType_giltFruit, eMaterial_carrot)->setIconName(L"golden_carrot")->setPotionBrewingFormula(PotionBrewing::MOD_GOLDENCARROT)->setDescriptionId(IDS_ITEM_CARROT_GOLDEN)->setUseDescriptionId(IDS_DESC_CARROT_GOLDEN); - Item::carrotOnAStick = (new CarrotOnAStickItem(142)) ->setBaseItemTypeAndMaterial(eBaseItemType_rod, eMaterial_carrot)->setIconName(L"carrotOnAStick")->setDescriptionId(IDS_ITEM_CARROT_ON_A_STICK)->setUseDescriptionId(IDS_DESC_CARROT_ON_A_STICK); - Item::netherStar = (new SimpleFoiledItem(143)) ->setIconName(L"nether_star")->setDescriptionId(IDS_NETHER_STAR)->setUseDescriptionId(IDS_DESC_NETHER_STAR); - Item::pumpkinPie = (new FoodItem(144, 8, FoodConstants::FOOD_SATURATION_LOW, false)) ->setIconName(L"pumpkinPie")->setDescriptionId(IDS_ITEM_PUMPKIN_PIE)->setUseDescriptionId(IDS_DESC_PUMPKIN_PIE); + Item::carrot_on_a_stick = (new CarrotOnAStickItem(142)) ->setBaseItemTypeAndMaterial(eBaseItemType_rod, eMaterial_carrot)->setIconName(L"carrot_on_a_stick")->setDescriptionId(IDS_ITEM_CARROT_ON_A_STICK)->setUseDescriptionId(IDS_DESC_CARROT_ON_A_STICK); + Item::nether_star = (new SimpleFoiledItem(143)) ->setIconName(L"nether_star")->setDescriptionId(IDS_NETHER_STAR)->setUseDescriptionId(IDS_DESC_NETHER_STAR); + Item::pumpkin_pie = (new FoodItem(144, 8, FoodConstants::FOOD_SATURATION_LOW, false)) ->setIconName(L"pumpkin_pie")->setDescriptionId(IDS_ITEM_PUMPKIN_PIE)->setUseDescriptionId(IDS_DESC_PUMPKIN_PIE); Item::fireworks = (new FireworksItem(145)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fireworks, Item::eMaterial_undefined)->setIconName(L"fireworks")->setDescriptionId(IDS_FIREWORKS)->setUseDescriptionId(IDS_DESC_FIREWORKS); - Item::fireworksCharge = (new FireworksChargeItem(146)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fireworks, Item::eMaterial_undefined)->setIconName(L"fireworks_charge")->setDescriptionId(IDS_FIREWORKS_CHARGE)->setUseDescriptionId(IDS_DESC_FIREWORKS_CHARGE); - EnchantedBookItem::enchantedBook = static_cast((new EnchantedBookItem(147))->setMaxStackSize(1)->setIconName(L"enchantedBook")->setDescriptionId(IDS_ITEM_ENCHANTED_BOOK)->setUseDescriptionId(IDS_DESC_ENCHANTED_BOOK)); + Item::firework_charge = (new FireworksChargeItem(146)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fireworks, Item::eMaterial_undefined)->setIconName(L"fireworks_charge")->setDescriptionId(IDS_FIREWORKS_CHARGE)->setUseDescriptionId(IDS_DESC_FIREWORKS_CHARGE); + EnchantedBookItem::enchanted_book = static_cast((new EnchantedBookItem(147))->setMaxStackSize(1)->setIconName(L"enchanted_book")->setDescriptionId(IDS_ITEM_ENCHANTED_BOOK)->setUseDescriptionId(IDS_DESC_ENCHANTED_BOOK)); Item::comparator = (new TilePlanterItem(148, Tile::comparator_off)) ->setIconName(L"comparator")->setDescriptionId(IDS_ITEM_COMPARATOR)->setUseDescriptionId(IDS_DESC_COMPARATOR); Item::netherbrick = (new Item(149)) ->setIconName(L"netherbrick")->setDescriptionId(IDS_ITEM_NETHERBRICK)->setUseDescriptionId(IDS_DESC_ITEM_NETHERBRICK); - Item::netherQuartz = (new Item(150)) ->setIconName(L"netherquartz")->setDescriptionId(IDS_ITEM_NETHER_QUARTZ)->setUseDescriptionId(IDS_DESC_NETHER_QUARTZ); - Item::minecart_tnt = (new MinecartItem(151, Minecart::TYPE_TNT)) ->setIconName(L"minecart_tnt")->setDescriptionId(IDS_ITEM_MINECART_TNT)->setUseDescriptionId(IDS_DESC_MINECART_TNT); - Item::minecart_hopper = (new MinecartItem(152, Minecart::TYPE_HOPPER)) ->setIconName(L"minecart_hopper")->setDescriptionId(IDS_ITEM_MINECART_HOPPER)->setUseDescriptionId(IDS_DESC_MINECART_HOPPER); + Item::nether_quartz = (new Item(150)) ->setIconName(L"netherquartz")->setDescriptionId(IDS_ITEM_NETHER_QUARTZ)->setUseDescriptionId(IDS_DESC_NETHER_QUARTZ); + Item::tnt_minecart = (new MinecartItem(151, Minecart::TYPE_TNT)) ->setIconName(L"tnt_minecart")->setDescriptionId(IDS_ITEM_MINECART_TNT)->setUseDescriptionId(IDS_DESC_MINECART_TNT); + Item::hopper_minecart = (new MinecartItem(152, Minecart::TYPE_HOPPER)) ->setIconName(L"hopper_minecart")->setDescriptionId(IDS_ITEM_MINECART_HOPPER)->setUseDescriptionId(IDS_DESC_MINECART_HOPPER); - Item::horseArmorMetal = (new Item(161)) ->setIconName(L"iron_horse_armor")->setMaxStackSize(1)->setDescriptionId(IDS_ITEM_IRON_HORSE_ARMOR)->setUseDescriptionId(IDS_DESC_IRON_HORSE_ARMOR); - Item::horseArmorGold = (new Item(162)) ->setIconName(L"gold_horse_armor")->setMaxStackSize(1)->setDescriptionId(IDS_ITEM_GOLD_HORSE_ARMOR)->setUseDescriptionId(IDS_DESC_GOLD_HORSE_ARMOR); - Item::horseArmorDiamond = (new Item(163)) ->setIconName(L"diamond_horse_armor")->setMaxStackSize(1)->setDescriptionId(IDS_ITEM_DIAMOND_HORSE_ARMOR)->setUseDescriptionId(IDS_DESC_DIAMOND_HORSE_ARMOR); + Item::iron_horse_armor = (new Item(161)) ->setIconName(L"iron_horse_armor")->setMaxStackSize(1)->setDescriptionId(IDS_ITEM_IRON_HORSE_ARMOR)->setUseDescriptionId(IDS_DESC_IRON_HORSE_ARMOR); + Item::golden_horse_armor = (new Item(162)) ->setIconName(L"golden_horse_armor")->setMaxStackSize(1)->setDescriptionId(IDS_ITEM_GOLD_HORSE_ARMOR)->setUseDescriptionId(IDS_DESC_GOLD_HORSE_ARMOR); + Item::diamond_horse_armor = (new Item(163)) ->setIconName(L"diamond_horse_armor")->setMaxStackSize(1)->setDescriptionId(IDS_ITEM_DIAMOND_HORSE_ARMOR)->setUseDescriptionId(IDS_DESC_DIAMOND_HORSE_ARMOR); Item::lead = (new LeashItem(164)) ->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_undefined)->setIconName(L"lead")->setDescriptionId(IDS_ITEM_LEAD)->setUseDescriptionId(IDS_DESC_LEAD); - Item::nameTag = (new NameTagItem(165)) ->setIconName(L"name_tag")->setDescriptionId(IDS_ITEM_NAME_TAG)->setUseDescriptionId(IDS_DESC_NAME_TAG); + Item::name_tag = (new NameTagItem(165)) ->setIconName(L"name_tag")->setDescriptionId(IDS_ITEM_NAME_TAG)->setUseDescriptionId(IDS_DESC_NAME_TAG); - Item::mutton_raw = (new FoodItem(167, 2, FoodConstants::FOOD_SATURATION_LOW, true))->setIconName(L"muttonRaw")->setDescriptionId(IDS_ITEM_MUTTON_RAW)->setUseDescriptionId(IDS_DESC_MUTTON_RAW); - Item::mutton_cooked = (new FoodItem(168, 6, FoodConstants::FOOD_SATURATION_NORMAL, true))->setIconName(L"muttonCooked")->setDescriptionId(IDS_ITEM_MUTTON_COOKED)->setUseDescriptionId(IDS_DESC_MUTTON_COOKED); - Item::rabbit_raw = (new FoodItem(155, 1, FoodConstants::FOOD_SATURATION_NORMAL, true))->setIconName(L"rabbitRaw")->setDescriptionId(IDS_ITEM_RABBIT_RAW)->setUseDescriptionId(IDS_DESC_RABBIT_RAW); - Item::rabbit_cooked = (new FoodItem(156, 5, FoodConstants::FOOD_SATURATION_NORMAL, true))->setIconName(L"rabbitCooked")->setDescriptionId(IDS_ITEM_RABBIT_COOKED)->setUseDescriptionId(IDS_DESC_RABBIT_COOKED); + Item::raw_mutton = (new FoodItem(167, 2, FoodConstants::FOOD_SATURATION_LOW, true))->setIconName(L"muttonRaw")->setDescriptionId(IDS_ITEM_MUTTON_RAW)->setUseDescriptionId(IDS_DESC_MUTTON_RAW); + Item::cooked_mutton = (new FoodItem(168, 6, FoodConstants::FOOD_SATURATION_NORMAL, true))->setIconName(L"muttonCooked")->setDescriptionId(IDS_ITEM_MUTTON_COOKED)->setUseDescriptionId(IDS_DESC_MUTTON_COOKED); + Item::raw_rabbit = (new FoodItem(155, 1, FoodConstants::FOOD_SATURATION_NORMAL, true))->setIconName(L"rabbitRaw")->setDescriptionId(IDS_ITEM_RABBIT_RAW)->setUseDescriptionId(IDS_DESC_RABBIT_RAW); + Item::cooked_rabbit = (new FoodItem(156, 5, FoodConstants::FOOD_SATURATION_NORMAL, true))->setIconName(L"rabbitCooked")->setDescriptionId(IDS_ITEM_RABBIT_COOKED)->setUseDescriptionId(IDS_DESC_RABBIT_COOKED); - Item::door_spruce = (new DoorItem(171, Material::wood, L"doorSpruce"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"doorSpruce")->setDescriptionId(IDS_ITEM_DOOR_SPRUCE)->setUseDescriptionId(IDS_DESC_DOOR_WOOD); - Item::door_birch = (new DoorItem(172, Material::wood, L"doorBirch"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"doorBirch")->setDescriptionId(IDS_ITEM_DOOR_BIRCH)->setUseDescriptionId(IDS_DESC_DOOR_WOOD); - Item::door_jungle = (new DoorItem(173, Material::wood, L"doorJungle"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"doorJungle")->setDescriptionId(IDS_ITEM_DOOR_JUNGLE)->setUseDescriptionId(IDS_DESC_DOOR_WOOD); - Item::door_acacia = (new DoorItem(174, Material::wood, L"doorAcacia"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"doorAcacia")->setDescriptionId(IDS_ITEM_DOOR_ACACIA)->setUseDescriptionId(IDS_DESC_DOOR_WOOD); - Item::door_dark = (new DoorItem(175, Material::wood, L"doorDark"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"doorDark")->setDescriptionId(IDS_ITEM_DOOR_DARK)->setUseDescriptionId(IDS_DESC_DOOR_WOOD); + Item::spruce_door = (new DoorItem(171, Material::wood, L"doorSpruce"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"doorSpruce")->setDescriptionId(IDS_ITEM_DOOR_SPRUCE)->setUseDescriptionId(IDS_DESC_DOOR_WOOD); + Item::birch_door = (new DoorItem(172, Material::wood, L"doorBirch"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"doorBirch")->setDescriptionId(IDS_ITEM_DOOR_BIRCH)->setUseDescriptionId(IDS_DESC_DOOR_WOOD); + Item::jungle_door = (new DoorItem(173, Material::wood, L"doorJungle"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"doorJungle")->setDescriptionId(IDS_ITEM_DOOR_JUNGLE)->setUseDescriptionId(IDS_DESC_DOOR_WOOD); + Item::acacia_door = (new DoorItem(174, Material::wood, L"doorAcacia"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"doorAcacia")->setDescriptionId(IDS_ITEM_DOOR_ACACIA)->setUseDescriptionId(IDS_DESC_DOOR_WOOD); + Item::dark_oak_door = (new DoorItem(175, Material::wood, L"doorDark"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"doorDark")->setDescriptionId(IDS_ITEM_DOOR_DARK)->setUseDescriptionId(IDS_DESC_DOOR_WOOD); Item::rabbit_hide = ( new Item(159) ) ->setIconName(L"rabbitHide")->setDescriptionId(IDS_ITEM_RABBIT_HIDE)->setUseDescriptionId(IDS_DESC_RABBIT_HIDE); - Item::rabbits_foot = ( new Item(158) ) ->setIconName(L"rabbitsFoot")->setDescriptionId(IDS_ITEM_RABBIT_FOOT)->setUseDescriptionId(IDS_DESC_RABBIT_FOOT)->setPotionBrewingFormula(PotionBrewing::MOD_RABBITS_FOOT);; + Item::rabbit_foot = ( new Item(158) ) ->setIconName(L"rabbitsFoot")->setDescriptionId(IDS_ITEM_RABBIT_FOOT)->setUseDescriptionId(IDS_DESC_RABBIT_FOOT)->setPotionBrewingFormula(PotionBrewing::MOD_RABBITS_FOOT);; Item::armor_stand = (new ArmorStandItem(160)) ->setBaseItemTypeAndMaterial(eBaseItemType_HangingItem,eMaterial_cloth)->setIconName(L"armorStand")->setDescriptionId(IDS_ITEM_ARMOR_STAND)->setUseDescriptionId(IDS_DESC_ARMOR_STAND); Item::prismarine_crystal = (new Item(154))->setIconName(L"prismarineCrystal")->setDescriptionId(IDS_ITEM_PRISMARINE_CRYSTAL)->setUseDescriptionId(IDS_ITEM_PRISMARINE_CRYSTAL_DESC); @@ -592,7 +592,7 @@ int _Tier::getTierItemId() const { if (this == Tier::WOOD) { - return Tile::wood_Id; + return Tile::planks_Id; } else if (this == Tier::STONE) { @@ -600,11 +600,11 @@ int _Tier::getTierItemId() const } else if (this == Tier::GOLD) { - return Item::goldIngot_Id; + return Item::gold_ingot_Id; } else if (this == Tier::IRON) { - return Item::ironIngot_Id; + return Item::iron_ingot_Id; } else if (this == Tier::DIAMOND) { @@ -1038,103 +1038,103 @@ attrAttrModMap *Item::getDefaultAttributeModifiers() (and 4 and Vita). */ #if (defined __PS3__ || defined __ORBIS__ || defined __PSVITA__) -const int Item::shovel_iron_Id ; -const int Item::pickAxe_iron_Id ; -const int Item::hatchet_iron_Id ; -const int Item::flintAndSteel_Id ; +const int Item::iron_shovel_Id ; +const int Item::iron_pickaxe_Id ; +const int Item::iron_axe_Id ; +const int Item::flint_and_steel_Id ; const int Item::apple_Id ; const int Item::bow_Id ; const int Item::arrow_Id ; const int Item::coal_Id ; const int Item::diamond_Id ; -const int Item::ironIngot_Id ; -const int Item::goldIngot_Id ; -const int Item::sword_iron_Id ; -const int Item::sword_wood_Id ; -const int Item::shovel_wood_Id ; -const int Item::pickAxe_wood_Id ; -const int Item::hatchet_wood_Id ; -const int Item::sword_stone_Id ; -const int Item::shovel_stone_Id ; -const int Item::pickAxe_stone_Id ; -const int Item::hatchet_stone_Id ; -const int Item::sword_diamond_Id ; -const int Item::shovel_diamond_Id ; -const int Item::pickAxe_diamond_Id ; -const int Item::hatchet_diamond_Id ; +const int Item::iron_ingot_Id ; +const int Item::gold_ingot_Id ; +const int Item::iron_sword_Id ; +const int Item::wooden_sword_Id ; +const int Item::wooden_shovel_Id ; +const int Item::wooden_pickaxe_Id ; +const int Item::wooden_axe_Id ; +const int Item::stone_sword_Id ; +const int Item::stone_shovel_Id ; +const int Item::stone_pickaxe_Id ; +const int Item::stone_axe_Id ; +const int Item::diamond_sword_Id ; +const int Item::diamond_shovel_Id ; +const int Item::diamond_pickaxe_Id ; +const int Item::diamond_axe_Id ; const int Item::stick_Id ; const int Item::bowl_Id ; -const int Item::mushroomStew_Id ; -const int Item::rabbitStew_Id ; -const int Item::sword_gold_Id ; -const int Item::shovel_gold_Id ; -const int Item::pickAxe_gold_Id ; -const int Item::hatchet_gold_Id ; +const int Item::mushroom_stew_Id ; +const int Item::rabbit_stew_Id ; +const int Item::golden_sword_Id ; +const int Item::golden_shovel_Id ; +const int Item::golden_pickaxe_Id ; +const int Item::golden_axe_Id ; const int Item::string_Id ; const int Item::feather_Id ; const int Item::gunpowder_Id ; -const int Item::hoe_wood_Id ; -const int Item::hoe_stone_Id ; -const int Item::hoe_iron_Id ; -const int Item::hoe_diamond_Id ; -const int Item::hoe_gold_Id ; -const int Item::seeds_wheat_Id ; +const int Item::wooden_hoe_Id ; +const int Item::stone_hoe_Id ; +const int Item::iron_hoe_Id ; +const int Item::diamond_hoe_Id ; +const int Item::golden_hoe_Id ; +const int Item::wheat_seeds_Id ; const int Item::wheat_Id ; const int Item::bread_Id ; -const int Item::helmet_leather_Id ; -const int Item::chestplate_leather_Id ; -const int Item::leggings_leather_Id ; -const int Item::boots_leather_Id ; -const int Item::helmet_chain_Id ; -const int Item::chestplate_chain_Id ; -const int Item::leggings_chain_Id ; -const int Item::boots_chain_Id ; -const int Item::helmet_iron_Id ; -const int Item::chestplate_iron_Id ; -const int Item::leggings_iron_Id ; -const int Item::boots_iron_Id ; -const int Item::helmet_diamond_Id ; -const int Item::chestplate_diamond_Id; -const int Item::leggings_diamond_Id ; -const int Item::boots_diamond_Id ; -const int Item::helmet_gold_Id ; -const int Item::chestplate_gold_Id ; -const int Item::leggings_gold_Id ; -const int Item::boots_gold_Id ; +const int Item::leather_helmet_Id ; +const int Item::leather_chestplate_Id ; +const int Item::leather_leggings_Id ; +const int Item::leather_boots_Id ; +const int Item::chainmail_helmet_Id ; +const int Item::chainmail_chestplate_Id ; +const int Item::chainmail_leggings_Id ; +const int Item::chainmail_boots_Id ; +const int Item::iron_helmet_Id ; +const int Item::iron_chestplate_Id ; +const int Item::iron_leggings_Id ; +const int Item::iron_boots_Id ; +const int Item::diamond_helmet_Id ; +const int Item::diamond_chestplate_Id; +const int Item::diamond_leggings_Id ; +const int Item::diamond_boots_Id ; +const int Item::golden_helmet_Id ; +const int Item::golden_chestplate_Id ; +const int Item::golden_leggings_Id ; +const int Item::golden_boots_Id ; const int Item::flint_Id ; -const int Item::porkChop_raw_Id ; -const int Item::porkChop_cooked_Id ; +const int Item::porkchop_Id ; +const int Item::cooked_porkchop_Id ; const int Item::painting_Id ; -const int Item::apple_gold_Id ; -const int Item::sign_Id ; -const int Item::door_wood_Id ; -const int Item::bucket_empty_Id ; -const int Item::bucket_water_Id ; -const int Item::bucket_lava_Id ; +const int Item::golden_apple_Id ; +const int Item::standing_sign_Id ; +const int Item::wooden_door_Id ; +const int Item::bucket_Id ; +const int Item::water_bucket_Id ; +const int Item::lava_bucket_Id ; const int Item::minecart_Id ; const int Item::saddle_Id ; -const int Item::door_iron_Id ; -const int Item::redStone_Id ; -const int Item::snowBall_Id ; +const int Item::iron_door_Id ; +const int Item::redstone_Id ; +const int Item::snowball_Id ; const int Item::boat_Id ; const int Item::leather_Id ; -const int Item::bucket_milk_Id ; +const int Item::milk_bucket_Id ; const int Item::brick_Id ; const int Item::clay_Id ; const int Item::reeds_Id ; const int Item::paper_Id ; const int Item::book_Id ; -const int Item::slimeBall_Id ; -const int Item::minecart_chest_Id ; -const int Item::minecart_furnace_Id ; +const int Item::slime_ball_Id ; +const int Item::chest_minecart_Id ; +const int Item::furnace_minecart_Id ; const int Item::egg_Id ; const int Item::compass_Id ; -const int Item::fishingRod_Id ; +const int Item::fishing_rod_Id ; const int Item::clock_Id ; -const int Item::yellowDust_Id ; -const int Item::fish_raw_Id ; -const int Item::fish_cooked_Id ; -const int Item::dye_powder_Id ; +const int Item::glowstone_dust_Id ; +const int Item::fish_Id ; +const int Item::cooked_fish_Id ; +const int Item::dye_Id ; const int Item::bone_Id ; const int Item::sugar_Id ; const int Item::cake_Id ; @@ -1143,57 +1143,57 @@ const int Item::repeater_Id ; const int Item::cookie_Id ; const int Item::map_Id ; const int Item::shears_Id ; -const int Item::melon_Id ; -const int Item::seeds_pumpkin_Id ; -const int Item::seeds_melon_Id ; -const int Item::beef_raw_Id ; -const int Item::beef_cooked_Id ; -const int Item::chicken_raw_Id ; -const int Item::chicken_cooked_Id ; +const int Item::melon_block_Id ; +const int Item::pumpkin_seeds_Id ; +const int Item::melon_seeds_Id ; +const int Item::beef_Id ; +const int Item::cooked_beef_Id ; +const int Item::chicken_Id ; +const int Item::cooked_chicken_Id ; const int Item::rotten_flesh_Id ; -const int Item::enderPearl_Id ; -const int Item::blazeRod_Id ; -const int Item::ghastTear_Id ; -const int Item::goldNugget_Id ; +const int Item::ender_pearl_Id ; +const int Item::blaze_rod_Id ; +const int Item::ghast_tear_Id ; +const int Item::gold_nugget_Id ; const int Item::netherwart_seeds_Id; const int Item::potion_Id ; -const int Item::glassBottle_Id ; -const int Item::spiderEye_Id ; -const int Item::fermentedSpiderEye_Id; -const int Item::blazePowder_Id ; -const int Item::magmaCream_Id ; -const int Item::brewingStand_Id ; +const int Item::glass_bottle_Id ; +const int Item::spider_eye_Id ; +const int Item::fermented_spider_eye_Id; +const int Item::blaze_powder_Id ; +const int Item::magma_cream_Id ; +const int Item::brewing_stand_Id ; const int Item::cauldron_Id ; -const int Item::eyeOfEnder_Id ; -const int Item::speckledMelon_Id ; -const int Item::spawnEgg_Id; -const int Item::expBottle_Id ; +const int Item::eye_of_ender_Id ; +const int Item::speckled_melon_block_Id ; +const int Item::spawn_egg_Id; +const int Item::experience_bottle_Id ; const int Item::skull_Id ; -const int Item::record_01_Id ; -const int Item::record_02_Id ; -const int Item::record_03_Id ; -const int Item::record_04_Id ; -const int Item::record_05_Id ; -const int Item::record_06_Id ; -const int Item::record_07_Id ; -const int Item::record_08_Id ; -const int Item::record_09_Id ; -const int Item::record_10_Id ; +const int Item::record_13_Id ; +const int Item::record_cat_Id ; +const int Item::record_blocks_Id ; +const int Item::record_chirp_Id ; +const int Item::record_far_Id ; +const int Item::record_mall_Id ; +const int Item::record_mellohi_Id ; +const int Item::record_stal_Id ; +const int Item::record_strad_Id ; +const int Item::record_ward_Id ; const int Item::record_11_Id ; -const int Item::record_12_Id ; -const int Item::fireball_Id ; -const int Item::itemFrame_Id ; -const int Item::netherbrick_Id ; +const int Item::record_wait_Id ; +const int Item::fire_charge_Id ; +const int Item::item_frame_Id ; +const int Item::nether_brick_Id ; const int Item::emerald_Id ; -const int Item::flowerPot_Id ; -const int Item::carrots_Id ; +const int Item::flower_pot_Id ; +const int Item::carrot_Id ; const int Item::potato_Id ; -const int Item::potatoBaked_Id ; -const int Item::potatoPoisonous_Id ; -const int Item::carrotGolden_Id ; -const int Item::carrotOnAStick_Id ; -const int Item::pumpkinPie_Id ; -const int Item::enchantedBook_Id ; -const int Item::netherQuartz_Id ; +const int Item::baked_potato_Id ; +const int Item::poisonous_potato_Id ; +const int Item::golden_carrot_Id ; +const int Item::carrot_on_a_stick_Id ; +const int Item::pumpkin_pie_Id ; +const int Item::enchanted_book_Id ; +const int Item::quartz_Id ; #endif diff --git a/Minecraft.World/Item.h b/Minecraft.World/Item.h index 8c474f5c..f1feb30f 100644 --- a/Minecraft.World/Item.h +++ b/Minecraft.World/Item.h @@ -87,6 +87,7 @@ public: eMaterial_redstone, eMaterial_coal, eMaterial_paper, + eMaterial_slime, eMaterial_book, eMaterial_bookshelf, eMaterial_wheat, @@ -195,124 +196,124 @@ private: public: static ItemArray items; - static Item *shovel_iron; - static Item *pickAxe_iron; - static Item *hatchet_iron; - static Item *flintAndSteel; + static Item *iron_shovel; + static Item *iron_pickaxe; + static Item *iron_axe; + static Item *flint_and_steel; static Item *apple; static BowItem *bow; static Item *arrow; static Item *coal; static Item *diamond; - static Item *ironIngot; - static Item *goldIngot; - static Item *sword_iron; + static Item *iron_ingot; + static Item *gold_ingot; + static Item *iron_sword; - static Item *sword_wood; - static Item *shovel_wood; - static Item *pickAxe_wood; - static Item *hatchet_wood; + static Item *wooden_sword; + static Item *wooden_shovel; + static Item *wooden_pickaxe; + static Item *wooden_axe; - static Item *sword_stone; - static Item *shovel_stone; - static Item *pickAxe_stone; - static Item *hatchet_stone; + static Item *stone_sword; + static Item *stone_shovel; + static Item *stone_pickaxe; + static Item *stone_axe; - static Item *sword_diamond; - static Item *shovel_diamond; - static Item *pickAxe_diamond; - static Item *hatchet_diamond; + static Item *diamond_sword; + static Item *diamond_shovel; + static Item *diamond_pickaxe; + static Item *diamond_axe; static Item *stick; static Item *bowl; - static Item *mushroomStew; - static Item *rabbitStew; + static Item *mushroom_stew; + static Item *rabbit_stew; - static Item *sword_gold; - static Item *shovel_gold; - static Item *pickAxe_gold; - static Item *hatchet_gold; + static Item *golden_sword; + static Item *golden_shovel; + static Item *golden_pickaxe; + static Item *golden_axe; static Item *string; static Item *feather; static Item *gunpowder; - static Item *hoe_wood; - static Item *hoe_stone; - static Item *hoe_iron; - static Item *hoe_diamond; - static Item *hoe_gold; + static Item *wooden_hoe; + static Item *stone_hoe; + static Item *iron_hoe; + static Item *diamond_hoe; + static Item *golden_hoe; - static Item *seeds_wheat; + static Item *wheat_seeds; static Item *wheat; static Item *bread; - static ArmorItem *helmet_leather; - static ArmorItem *chestplate_leather; - static ArmorItem *leggings_leather; - static ArmorItem *boots_leather; + static ArmorItem *leather_helmet; + static ArmorItem *leather_chestplate; + static ArmorItem *leather_leggings; + static ArmorItem *leather_boots; - static ArmorItem *helmet_chain; - static ArmorItem *chestplate_chain; - static ArmorItem *leggings_chain; - static ArmorItem *boots_chain; + static ArmorItem *chainmail_helmet; + static ArmorItem *chainmail_chestplate; + static ArmorItem *chainmail_leggings; + static ArmorItem *chainmail_boots; - static ArmorItem *helmet_iron; - static ArmorItem *chestplate_iron; - static ArmorItem *leggings_iron; - static ArmorItem *boots_iron; + static ArmorItem *iron_helmet; + static ArmorItem *iron_chestplate; + static ArmorItem *iron_leggings; + static ArmorItem *iron_boots; - static ArmorItem *helmet_diamond; - static ArmorItem *chestplate_diamond; - static ArmorItem *leggings_diamond; - static ArmorItem *boots_diamond; + static ArmorItem *diamond_helmet; + static ArmorItem *diamond_chestplate; + static ArmorItem *diamond_leggings; + static ArmorItem *diamond_boots; - static ArmorItem *helmet_gold; - static ArmorItem *chestplate_gold; - static ArmorItem *leggings_gold; - static ArmorItem *boots_gold; + static ArmorItem *golden_helmet; + static ArmorItem *golden_chestplate; + static ArmorItem *golden_leggings; + static ArmorItem *golden_boots; static Item *flint; - static Item *porkChop_raw; - static Item *porkChop_cooked; + static Item *raw_porkchop; + static Item *cooked_porkchop; static Item *painting; - static Item *apple_gold; + static Item *golden_apple; static Item *sign; - static Item *door_wood; + static Item *wooden_door; - static Item *bucket_empty; - static Item *bucket_water; - static Item *bucket_lava; + static Item *bucket; + static Item *water_bucket; + static Item *lava_bucket; static Item *minecart; static Item *saddle; - static Item *door_iron; - static Item *redStone; - static Item *snowBall; + static Item *iron_door; + static Item *redstone; + static Item *snowball; static Item *boat; static Item *leather; - static Item *bucket_milk; + static Item *milk_bucket; static Item *brick; static Item *clay; static Item *reeds; static Item *paper; static Item *book; - static Item *slimeBall; - static Item *minecart_chest; - static Item *minecart_furnace; + static Item *slime_ball; + static Item *chest_minecart; + static Item *furnace_minecart; static Item *egg; static Item *compass; - static FishingRodItem *fishingRod; + static FishingRodItem *fishing_rod; static Item *clock; - static Item *yellowDust; - static Item *fish_raw; - static Item *fish_cooked; + static Item *glowstone_dust; + static Item *raw_fish; + static Item *cooked_fish; - static Item *dye_powder; + static Item *dye; static Item *bone; static Item *sugar; static Item *cake; @@ -331,37 +332,37 @@ public: static Item *seeds_pumpkin; static Item *seeds_melon; - static Item *beef_raw; - static Item *beef_cooked; - static Item *chicken_raw; - static Item *chicken_cooked; + static Item *raw_beef; + static Item *cooked_beef; + static Item *raw_chicken; + static Item *cooked_chicken; static Item *rotten_flesh; - static Item *enderPearl; + static Item *ender_pearl; - static Item *blazeRod; - static Item *ghastTear; - static Item *goldNugget; + static Item *blaze_rod; + static Item *ghast_tear; + static Item *gold_nugget; static Item *netherwart_seeds; static PotionItem *potion; static Item *glassBottle; - static Item *spiderEye; - static Item *fermentedSpiderEye; + static Item *spider_eye; + static Item *fermented_spider_eye; - static Item *blazePowder; - static Item *magmaCream; + static Item *blaze_powder; + static Item *magma_cream; - static Item *brewingStand; + static Item *brewing_stand; static Item *cauldron; - static Item *eyeOfEnder; - static Item *speckledMelon; + static Item *eye_of_ender; + static Item *speckled_melon; - static Item *spawnEgg; + static Item *spawn_egg; - static Item *expBottle; + static Item *experience_bottle; static Item *skull; @@ -383,55 +384,55 @@ public: static Item *frame; // TU14 - static Item *writingBook; - static Item *writtenBook; + static Item *writable_book; + static Item *written_book; static Item *emerald; - static Item *flowerPot; + static Item *flower_pot; static Item *carrots; static Item *potato; - static Item *potatoBaked; - static Item *potatoPoisonous; + static Item *baked_potato; + static Item *poisonous_potato; - static EmptyMapItem *emptyMap; + static EmptyMapItem *empty_map; - static Item *carrotGolden; + static Item *golden_carrot; - static Item *carrotOnAStick; - static Item *netherStar; - static Item *pumpkinPie; + static Item *carrot_on_a_stick; + static Item *nether_star; + static Item *pumpkin_pie; static Item *fireworks; - static Item *fireworksCharge; - static Item *netherQuartz; + static Item *firework_charge; + static Item *nether_quartz; static Item *comparator; static Item *netherbrick; - static EnchantedBookItem *enchantedBook; - static Item *minecart_tnt; - static Item *minecart_hopper; + static EnchantedBookItem *enchanted_book; + static Item *tnt_minecart; + static Item *hopper_minecart; - static Item *horseArmorMetal; - static Item *horseArmorGold; - static Item *horseArmorDiamond; + static Item *iron_horse_armor; + static Item *golden_horse_armor; + static Item *diamond_horse_armor; static Item *lead; - static Item *nameTag; + static Item *name_tag; // TU25 - static Item* door_spruce; - static Item* door_birch; - static Item* door_jungle; - static Item* door_acacia; - static Item* door_dark; + static Item* spruce_door; + static Item* birch_door; + static Item* jungle_door; + static Item* acacia_door; + static Item* dark_oak_door; //TU31 - static Item* mutton_raw; - static Item* mutton_cooked; - static Item* rabbit_raw; - static Item* rabbit_cooked; + static Item* raw_mutton; + static Item* cooked_mutton; + static Item* raw_rabbit; + static Item* cooked_rabbit; static Item* rabbit_hide; - static Item* rabbits_foot; + static Item* rabbit_foot; static Item* armor_stand; static Item* prismarine_crystal; @@ -439,234 +440,234 @@ public: static Item* elytra; - static const int shovel_iron_Id = 256; - static const int pickAxe_iron_Id = 257; - static const int hatchet_iron_Id = 258; - static const int flintAndSteel_Id = 259; + static const int iron_shovel_Id = 256; + static const int iron_pickaxe_Id = 257; + static const int iron_axe_Id = 258; + static const int flint_and_steel_Id = 259; static const int apple_Id = 260; static const int bow_Id = 261; static const int arrow_Id = 262; static const int coal_Id = 263; static const int diamond_Id = 264; - static const int ironIngot_Id = 265; - static const int goldIngot_Id = 266; - static const int sword_iron_Id = 267; - static const int sword_wood_Id = 268; - static const int shovel_wood_Id = 269; - static const int pickAxe_wood_Id = 270; - static const int hatchet_wood_Id = 271; - static const int sword_stone_Id = 272; - static const int shovel_stone_Id = 273; - static const int pickAxe_stone_Id = 274; - static const int hatchet_stone_Id = 275; - static const int sword_diamond_Id = 276; - static const int shovel_diamond_Id = 277; - static const int pickAxe_diamond_Id = 278; - static const int hatchet_diamond_Id = 279; + static const int iron_ingot_Id = 265; + static const int gold_ingot_Id = 266; + static const int iron_sword_Id = 267; + static const int wooden_sword_Id = 268; + static const int wooden_shovel_Id = 269; + static const int wooden_pickaxe_Id = 270; + static const int wooden_axe_Id = 271; + static const int stone_sword_Id = 272; + static const int stone_shovel_Id = 273; + static const int stone_pickaxe_Id = 274; + static const int stone_axe_Id = 275; + static const int diamond_sword_Id = 276; + static const int diamond_shovel_Id = 277; + static const int diamond_pickaxe_Id = 278; + static const int diamond_axe_Id = 279; static const int stick_Id = 280; static const int bowl_Id = 281; - static const int mushroomStew_Id = 282; - static const int sword_gold_Id = 283; - static const int shovel_gold_Id = 284; - static const int pickAxe_gold_Id = 285; - static const int hatchet_gold_Id = 286; + static const int mushroom_stew_Id = 282; + static const int golden_sword_Id = 283; + static const int golden_shovel_Id = 284; + static const int golden_pickaxe_Id = 285; + static const int golden_axe_Id = 286; static const int string_Id = 287; static const int feather_Id = 288; static const int gunpowder_Id = 289; - static const int hoe_wood_Id = 290; - static const int hoe_stone_Id = 291; - static const int hoe_iron_Id = 292; - static const int hoe_diamond_Id = 293; - static const int hoe_gold_Id = 294; - static const int seeds_wheat_Id = 295; + static const int wooden_hoe_Id = 290; + static const int stone_hoe_Id = 291; + static const int iron_hoe_Id = 292; + static const int diamond_hoe_Id = 293; + static const int golden_hoe_Id = 294; + static const int wheat_seeds_Id = 295; static const int wheat_Id = 296; static const int bread_Id = 297; - static const int helmet_leather_Id = 298; - static const int chestplate_leather_Id = 299; - static const int leggings_leather_Id = 300; - static const int boots_leather_Id = 301; + static const int leather_helmet_Id = 298; + static const int leather_chestplate_Id = 299; + static const int leather_leggings_Id = 300; + static const int leather_boots_Id = 301; - static const int helmet_chain_Id = 302; - static const int chestplate_chain_Id = 303; - static const int leggings_chain_Id = 304; - static const int boots_chain_Id = 305; + static const int chainmail_helmet_Id = 302; + static const int chainmail_chestplate_Id = 303; + static const int chainmail_leggings_Id = 304; + static const int chainmail_boots_Id = 305; - static const int helmet_iron_Id = 306; - static const int chestplate_iron_Id = 307; - static const int leggings_iron_Id = 308; - static const int boots_iron_Id = 309; + static const int iron_helmet_Id = 306; + static const int iron_chestplate_Id = 307; + static const int iron_leggings_Id = 308; + static const int iron_boots_Id = 309; - static const int helmet_diamond_Id = 310; - static const int chestplate_diamond_Id = 311; - static const int leggings_diamond_Id = 312; - static const int boots_diamond_Id = 313; + static const int diamond_helmet_Id = 310; + static const int diamond_chestplate_Id = 311; + static const int diamond_leggings_Id = 312; + static const int diamond_boots_Id = 313; - static const int helmet_gold_Id = 314; - static const int chestplate_gold_Id = 315; - static const int leggings_gold_Id = 316; - static const int boots_gold_Id = 317; + static const int golden_helmet_Id = 314; + static const int golden_chestplate_Id = 315; + static const int golden_leggings_Id = 316; + static const int golden_boots_Id = 317; static const int flint_Id = 318; - static const int porkChop_raw_Id = 319; - static const int porkChop_cooked_Id = 320; + static const int porkchop_Id = 319; + static const int cooked_porkchop_Id = 320; static const int painting_Id = 321; - static const int apple_gold_Id = 322; - static const int sign_Id = 323; - static const int door_wood_Id = 324; - static const int bucket_empty_Id = 325; - static const int bucket_water_Id = 326; - static const int bucket_lava_Id = 327; + static const int golden_apple_Id = 322; + static const int standing_sign_Id = 323; + static const int wooden_door_Id = 324; + static const int bucket_Id = 325; + static const int water_bucket_Id = 326; + static const int lava_bucket_Id = 327; static const int minecart_Id = 328; static const int saddle_Id = 329; - static const int door_iron_Id = 330; - static const int redStone_Id = 331; - static const int snowBall_Id = 332; + static const int iron_door_Id = 330; + static const int redstone_Id = 331; + static const int snowball_Id = 332; static const int boat_Id = 333; static const int leather_Id = 334; - static const int bucket_milk_Id = 335; + static const int milk_bucket_Id = 335; static const int brick_Id = 336; static const int clay_Id = 337; static const int reeds_Id = 338; static const int paper_Id = 339; static const int book_Id = 340; - static const int slimeBall_Id = 341; - static const int minecart_chest_Id = 342; - static const int minecart_furnace_Id = 343; + static const int slime_ball_Id = 341; + static const int chest_minecart_Id = 342; + static const int furnace_minecart_Id = 343; static const int egg_Id = 344; static const int compass_Id = 345; - static const int fishingRod_Id = 346; + static const int fishing_rod_Id = 346; static const int clock_Id = 347; - static const int yellowDust_Id = 348; - static const int fish_raw_Id = 349; - static const int fish_cooked_Id = 350; - static const int dye_powder_Id = 351; + static const int glowstone_dust_Id = 348; + static const int fish_Id = 349; + static const int cooked_fish_Id = 350; + static const int dye_Id = 351; static const int bone_Id = 352; static const int sugar_Id = 353; static const int cake_Id = 354; static const int bed_Id = 355; static const int repeater_Id = 356; static const int cookie_Id = 357; - static const int map_Id = 358; + static const int filled_map_Id = 358; // 1.7.3 static const int shears_Id = 359; // 1.8.2 - static const int melon_Id = 360; - static const int seeds_pumpkin_Id = 361; - static const int seeds_melon_Id = 362; - static const int beef_raw_Id = 363; - static const int beef_cooked_Id = 364; - static const int chicken_raw_Id = 365; - static const int chicken_cooked_Id = 366; + static const int melon_block_Id = 360; + static const int pumpkin_seeds_Id = 361; + static const int melon_seeds_Id = 362; + static const int beef_Id = 363; + static const int cooked_beef_Id = 364; + static const int chicken_Id = 365; + static const int cooked_chicken_Id = 366; static const int rotten_flesh_Id = 367; - static const int enderPearl_Id = 368; + static const int ender_pearl_Id = 368; // 1.0.1 - static const int blazeRod_Id = 369; - static const int ghastTear_Id = 370; - static const int goldNugget_Id = 371; + static const int blaze_rod_Id = 369; + static const int ghast_tear_Id = 370; + static const int gold_nugget_Id = 371; static const int netherwart_seeds_Id = 372; static const int potion_Id = 373; - static const int glassBottle_Id = 374; - static const int spiderEye_Id = 375; - static const int fermentedSpiderEye_Id = 376; - static const int blazePowder_Id = 377; - static const int magmaCream_Id = 378; - static const int brewingStand_Id = 379; + static const int glass_bottle_Id = 374; + static const int spider_eye_Id = 375; + static const int fermented_spider_eye_Id = 376; + static const int blaze_powder_Id = 377; + static const int magma_cream_Id = 378; + static const int brewing_stand_Id = 379; static const int cauldron_Id = 380; - static const int eyeOfEnder_Id = 381; - static const int speckledMelon_Id = 382; + static const int eye_of_ender_Id = 381; + static const int speckled_melon_block_Id = 382; // 1.1 - static const int spawnEgg_Id = 383; + static const int spawn_egg_Id = 383; - static const int expBottle_Id = 384; + static const int experience_bottle_Id = 384; // TU 12 static const int skull_Id = 397; - static const int record_01_Id = 2256; - static const int record_02_Id = 2257; - static const int record_03_Id = 2258; - static const int record_04_Id = 2259; - static const int record_05_Id = 2260; - static const int record_06_Id = 2261; - static const int record_07_Id = 2262; + static const int record_13_Id = 2256; + static const int record_cat_Id = 2257; + static const int record_blocks_Id = 2258; + static const int record_chirp_Id = 2259; + static const int record_far_Id = 2260; + static const int record_mall_Id = 2261; + static const int record_mellohi_Id = 2262; // 4J-PB - this one isn't playable in the PC game, but is fine in ours - static const int record_08_Id = 2263; - static const int record_09_Id = 2264; - static const int record_10_Id = 2265; + static const int record_stal_Id = 2263; + static const int record_strad_Id = 2264; + static const int record_ward_Id = 2265; static const int record_11_Id = 2266; - static const int record_12_Id = 2267; + static const int record_wait_Id = 2267; // TU9 - static const int fireball_Id = 385; - static const int itemFrame_Id = 389; + static const int fire_charge_Id = 385; + static const int item_frame_Id = 389; // TU14 - static const int writingBook_Id = 386; - static const int writtenBook_Id = 387; + static const int writable_book_Id = 386; + static const int written_book_Id = 387; static const int emerald_Id = 388; - static const int flowerPot_Id = 390; + static const int flower_pot_Id = 390; - static const int carrots_Id = 391; + static const int carrot_Id = 391; static const int potato_Id = 392; - static const int potatoBaked_Id = 393; - static const int potatoPoisonous_Id = 394; + static const int baked_potato_Id = 393; + static const int poisonous_potato_Id = 394; - static const int emptyMap_Id = 395; + static const int map_Id = 395; - static const int carrotGolden_Id = 396; + static const int golden_carrot_Id = 396; - static const int carrotOnAStick_Id = 398; - static const int netherStar_Id = 399; - static const int pumpkinPie_Id = 400; + static const int carrot_on_a_stick_Id = 398; + static const int nether_star_Id = 399; + static const int pumpkin_pie_Id = 400; static const int fireworks_Id = 401; - static const int fireworksCharge_Id = 402; + static const int firework_charge_Id = 402; - static const int enchantedBook_Id = 403; + static const int enchanted_book_Id = 403; static const int comparator_Id = 404; - static const int netherbrick_Id = 405; - static const int netherQuartz_Id = 406; - static const int minecart_tnt_Id = 407; - static const int minecart_hopper_Id = 408; + static const int nether_brick_Id = 405; + static const int quartz_Id = 406; + static const int tnt_minecart_Id = 407; + static const int hopper_minecart_Id = 408; - static const int horseArmorMetal_Id = 417; - static const int horseArmorGold_Id = 418; - static const int horseArmorDiamond_Id = 419; + static const int iron_horse_armor_Id = 417; + static const int golden_horse_armor_Id = 418; + static const int diamond_horse_armor_Id = 419; static const int lead_Id = 420; - static const int nameTag_Id = 421; + static const int name_tag_Id = 421; // TU25 //422 command_block_minecart static const int prismarine_shard_Id = 409; - static const int prismarine_cystal_Id = 410; - static const int rabbit_raw_Id = 411; - static const int rabbit_cooked_Id = 412; - static const int rabbitStew_Id = 413; - static const int rabbits_foot_Id = 414; + static const int prismarine_crystals_Id = 410; + static const int rabbit_Id = 411; + static const int cooked_rabbit_Id = 412; + static const int rabbit_stew_Id = 413; + static const int rabbit_foot_Id = 414; static const int rabbit_hide_Id = 415; static const int armor_stand_Id = 416; - static const int mutton_raw_Id = 423; - static const int mutton_cooked_Id = 424; + static const int mutton_Id = 423; + static const int cooked_mutton_Id = 424; //425 banner //426 end_crystal - static const int door_spruce_Id = 427; - static const int door_birch_Id = 428; - static const int door_jungle_Id = 429; - static const int door_acacia_Id = 430; - static const int door_dark_Id = 431; + static const int spruce_door_Id = 427; + static const int birch_door_Id = 428; + static const int jungle_door_Id = 429; + static const int acacia_door_Id = 430; + static const int dark_oak_door_Id = 431; static const int elytra_Id = 443; diff --git a/Minecraft.World/ItemDispenseBehaviors.cpp b/Minecraft.World/ItemDispenseBehaviors.cpp index 8758dcfb..1bf90326 100644 --- a/Minecraft.World/ItemDispenseBehaviors.cpp +++ b/Minecraft.World/ItemDispenseBehaviors.cpp @@ -281,7 +281,7 @@ shared_ptr FilledBucketDispenseBehavior::execute(BlockSource *sour FacingEnum *facing = DispenserTile::getFacing(source->getData()); if (bucket->emptyBucket(source->getWorld(), sourceX + facing->getStepX(), sourceY + facing->getStepY(), sourceZ + facing->getStepZ())) { - dispensed->id = Item::bucket_empty->id; + dispensed->id = Item::bucket->id; dispensed->count = 1; outcome = ACTIVATED_ITEM; @@ -309,11 +309,11 @@ shared_ptr EmptyBucketDispenseBehavior::execute(BlockSource *sourc Item *targetType; if (Material::water == material && dataValue == 0) { - targetType = Item::bucket_water; + targetType = Item::water_bucket; } else if (Material::lava == material && dataValue == 0) { - targetType = Item::bucket_lava; + targetType = Item::lava_bucket; } else { diff --git a/Minecraft.World/ItemEntity.cpp b/Minecraft.World/ItemEntity.cpp index cf921d6c..137cced9 100644 --- a/Minecraft.World/ItemEntity.cpp +++ b/Minecraft.World/ItemEntity.cpp @@ -112,6 +112,8 @@ void ItemEntity::tick() { friction = 0.6f * 0.98f; int t = level->getTile( Mth::floor(x), Mth::floor(bb->y0) - 1, Mth::floor(z) ); + Tile *tile = Tile::tiles[t]; + if (tile == nullptr & t != 0) return; // tu31 tutorial world fix if (t > 0) { friction = Tile::tiles[t]->friction * 0.98f; @@ -195,7 +197,7 @@ bool ItemEntity::hurt(DamageSource *source, float damage) if (level->isClientSide ) return false; if (isInvulnerable()) return false; - if (getItem() != nullptr && getItem()->id == Item::netherStar_Id && source->isExplosion()) return false; + if (getItem() != nullptr && getItem()->id == Item::nether_star_Id && source->isExplosion()) return false; markHurt(); health -= damage; if (health <= 0) @@ -259,7 +261,7 @@ void ItemEntity::playerTouch(shared_ptr player) //if (item.id == Tile.treeTrunk.id) player.awardStat(Achievements.mineWood); //if (item.id == Item.leather.id) player.awardStat(Achievements.killCow); //if (item.id == Item.diamond.id) player.awardStat(Achievements.diamonds); - //if (item.id == Item.blazeRod.id) player.awardStat(Achievements.blazeRod); + //if (item.id == Item.blaze_rod.id) player.awardStat(Achievements.blaze_rod); if (item->id == Item::diamond_Id) { player->awardStat(GenericStats::diamonds(), GenericStats::param_diamonds()); @@ -275,7 +277,7 @@ void ItemEntity::playerTouch(shared_ptr player) } } - if (item->id == Item::blazeRod_Id) + if (item->id == Item::blaze_rod_Id) player->awardStat(GenericStats::blazeRod(), GenericStats::param_blazeRod()); playSound(eSoundType_RANDOM_POP, 0.2f, ((random->nextFloat() - random->nextFloat()) * 0.7f + 1.0f) * 2.0f); diff --git a/Minecraft.World/ItemInstance.cpp b/Minecraft.World/ItemInstance.cpp index 6581ea6c..16c2e308 100644 --- a/Minecraft.World/ItemInstance.cpp +++ b/Minecraft.World/ItemInstance.cpp @@ -13,6 +13,109 @@ #include "Item.h" #include "ItemInstance.h" #include "HtmlString.h" +#include "../Minecraft.Client/Common/Consoles_App.h" +#include "ItemNameMap.h" +#include +#include + +namespace +{ +wstring NormalizeItemNameId(const wstring &rawName) +{ + if (rawName.empty()) + { + return rawName; + } + + wstring normalized = rawName; + for (size_t i = 0; i < normalized.size(); ++i) + { + normalized[i] = static_cast(towlower(normalized[i])); + } + + size_t namespaceSep = normalized.find(L':'); + if (namespaceSep != wstring::npos && namespaceSep + 1 < normalized.size()) + { + normalized = normalized.substr(namespaceSep + 1); + } + + return normalized; +} + +wstring ToSnakeCase(const wstring &value) +{ + if (value.empty()) + { + return value; + } + + wstring out; + out.reserve(value.size() * 2); + for (size_t i = 0; i < value.size(); ++i) + { + const wchar_t c = value[i]; + if (c >= L'A' && c <= L'Z') + { + if (i > 0) + { + out.push_back(L'_'); + } + out.push_back(static_cast(towlower(c))); + } + else + { + out.push_back(c); + } + } + + return NormalizeItemNameId(out); +} + +int ResolveLegacyItemIdFromStringName(const wstring &rawName) +{ + const wstring name = NormalizeItemNameId(rawName); + int id = GetItemIdByName(name); + if (id >= 0) + { + return id; + } + + const wstring snakeName = ToSnakeCase(rawName); + return GetItemIdByName(snakeName); +} + +int ParseNumericItemId(const wstring &idString, bool &parsed) +{ + parsed = false; + if (idString.empty()) + { + return 0; + } + + try + { + size_t parseEnd = 0; + long parsedValue = std::stol(idString, &parseEnd, 10); + if (parseEnd == idString.size()) + { + parsed = true; + return static_cast(parsedValue); + } + } + catch (...) + { + } + + return 0; +} + +int ByteSwapShortToInt(short value) +{ + unsigned short raw = static_cast(value); + unsigned short swapped = static_cast((raw >> 8) | (raw << 8)); + return static_cast(swapped); +} +} const wstring ItemInstance::ATTRIBUTE_MODIFIER_FORMAT = L"#.###"; @@ -79,9 +182,22 @@ ItemInstance::ItemInstance(int id, int count, int damage) shared_ptr ItemInstance::fromTag(CompoundTag *itemTag) { + if (!itemTag) + { + app.DebugPrintf("[ItemInstance] NULL itemTag\n"); + return nullptr; + } + shared_ptr itemInstance = shared_ptr(new ItemInstance()); itemInstance->load(itemTag); - return itemInstance->getItem() != nullptr ? itemInstance : nullptr; + + Item *item = itemInstance->getItem(); + if (item == nullptr && itemInstance->id != 0) // air is not relevant + { + app.DebugPrintf("[ItemInstance] Missing item while loading: id=%d count=%d damage=%d\n", itemInstance->id, itemInstance->count, itemInstance->auxValue); + } + + return item != nullptr ? itemInstance : nullptr; } ItemInstance::~ItemInstance() @@ -105,6 +221,11 @@ shared_ptr ItemInstance::remove(int count) Item *ItemInstance::getItem() const { + if (id < 0 || id >= Item::items.length) + { + return nullptr; + } + return Item::items[id]; } @@ -155,7 +276,62 @@ CompoundTag *ItemInstance::save(CompoundTag *compoundTag) void ItemInstance::load(CompoundTag *compoundTag) { popTime = 0; - id = compoundTag->getShort(L"id"); + id = 0; + Tag *idTag = compoundTag->get(L"id"); + if (idTag != nullptr) + { + switch (idTag->getId()) + { + case Tag::TAG_Int: + id = compoundTag->getInt(L"id"); + break; + case Tag::TAG_Short: + { + short rawId = compoundTag->getShort(L"id"); + id = rawId; + + if ((id < 0 || id >= Item::items.length || Item::items[id] == nullptr) && rawId != 0) + { + int swappedId = ByteSwapShortToInt(rawId); + if (swappedId >= 0 && swappedId < Item::items.length && Item::items[swappedId] != nullptr) + { + app.DebugPrintf("[ItemInstance] Recovered byte-swapped short item id: raw=%d swapped=%d\n", id, swappedId); + id = swappedId; + } + } + break; + } + case Tag::TAG_String: + { + wstring idString = compoundTag->getString(L"id"); + + int mappedId = ResolveLegacyItemIdFromStringName(idString); + if (mappedId >= 0) + { + id = mappedId; + break; + } + + bool parsedNumeric = false; + id = ParseNumericItemId(idString, parsedNumeric); + if (!parsedNumeric) + { + app.DebugPrintf("[ItemInstance] Unsupported string item id '%ls' (expected numeric legacy id)\n", idString.c_str()); + id = 0; + } + break; + } + default: + app.DebugPrintf("[ItemInstance] Unsupported item id tag type %d\n", idTag->getId()); + id = 0; + break; + } + } +// else +// { +// app.DebugPrintf("[ItemInstance] Missing item id tag\n"); +// } + count = compoundTag->getByte(L"Count"); auxValue = compoundTag->getShort(L"Damage"); if (auxValue < 0) diff --git a/Minecraft.World/JukeboxTile.cpp b/Minecraft.World/JukeboxTile.cpp index 74e79e9e..db6f993d 100644 --- a/Minecraft.World/JukeboxTile.cpp +++ b/Minecraft.World/JukeboxTile.cpp @@ -66,6 +66,32 @@ JukeboxTile::JukeboxTile(int id) : BaseEntityTile(id, Material::wood) iconTop = nullptr; } +void JukeboxTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int JukeboxTile::defaultBlockState() +{ + return 0; +} + +int JukeboxTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x1) : 0; +} + +Tile::BlockState JukeboxTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x1); +} + +Tile::BlockState JukeboxTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x1); +} + Icon *JukeboxTile::getTexture(int face, int data) { if (face == Facing::UP) @@ -163,5 +189,5 @@ bool JukeboxTile::hasAnalogOutputSignal() int JukeboxTile::getAnalogOutputSignal(Level *level, int x, int y, int z, int dir) { shared_ptr record = dynamic_pointer_cast( level->getTileEntity(x, y, z))->getRecord(); - return record == nullptr ? Redstone::SIGNAL_NONE : record->id + 1 - Item::record_01_Id; + return record == nullptr ? Redstone::SIGNAL_NONE : record->id + 1 - Item::record_13_Id; } \ No newline at end of file diff --git a/Minecraft.World/JukeboxTile.h b/Minecraft.World/JukeboxTile.h index dd592872..0e41bf22 100644 --- a/Minecraft.World/JukeboxTile.h +++ b/Minecraft.World/JukeboxTile.h @@ -40,6 +40,11 @@ protected: JukeboxTile(int id); public: + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual Icon *getTexture(int face, int data); virtual bool TestUse(Level *level, int x, int y, int z, shared_ptr player); virtual bool use(Level *level, int x, int y, int z, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false); // 4J added soundOnly param diff --git a/Minecraft.World/LakeFeature.cpp b/Minecraft.World/LakeFeature.cpp index a25a7ece..abdf34d7 100644 --- a/Minecraft.World/LakeFeature.cpp +++ b/Minecraft.World/LakeFeature.cpp @@ -121,7 +121,7 @@ bool LakeFeature::place(Level *level, Random *random, int x, int y, int z) if (level->getTile(x + xx, y + yy - 1, z + zz) == Tile::dirt_Id && level->getBrightness(LightLayer::Sky, x + xx, y + yy, z + zz) > 0) { Biome *b = level->getBiome(x + xx, z + zz); - if (b->topMaterial == Tile::mycel_Id) level->setTileAndData(x + xx, y + yy - 1, z + zz, Tile::mycel_Id, 0, Tile::UPDATE_CLIENTS); + if (b->topMaterial == Tile::mycelium_Id) level->setTileAndData(x + xx, y + yy - 1, z + zz, Tile::mycelium_Id, 0, Tile::UPDATE_CLIENTS); else level->setTileAndData(x + xx, y + yy - 1, z + zz, Tile::grass_Id, 0, Tile::UPDATE_CLIENTS); } } diff --git a/Minecraft.World/LargeCaveFeature.cpp b/Minecraft.World/LargeCaveFeature.cpp index c70f1156..e07c7bf5 100644 --- a/Minecraft.World/LargeCaveFeature.cpp +++ b/Minecraft.World/LargeCaveFeature.cpp @@ -110,7 +110,7 @@ void LargeCaveFeature::addTunnel(int64_t seed, int xOffs, int zOffs, byteArray b { int p = (xx * 16 + zz) * Level::genDepth + yy; if (yy < 0 || yy >= Level::genDepth) continue; - if (blocks[p] == Tile::water_Id || blocks[p] == Tile::calmWater_Id) + if (blocks[p] == Tile::flowing_water_Id || blocks[p] == Tile::water_Id) { detectedWater = true; } @@ -144,7 +144,7 @@ void LargeCaveFeature::addTunnel(int64_t seed, int xOffs, int zOffs, byteArray b { if (yy < 10) { - blocks[p] = static_cast(Tile::lava_Id); + blocks[p] = static_cast(Tile::flowing_lava_Id); } else { diff --git a/Minecraft.World/LargeHellCaveFeature.cpp b/Minecraft.World/LargeHellCaveFeature.cpp index 9472c855..bb78aff6 100644 --- a/Minecraft.World/LargeHellCaveFeature.cpp +++ b/Minecraft.World/LargeHellCaveFeature.cpp @@ -110,7 +110,7 @@ void LargeHellCaveFeature::addTunnel(int64_t seed, int xOffs, int zOffs, byteArr { int p = (xx * 16 + zz) * Level::genDepth + yy; if (yy < 0 || yy >= Level::genDepth) continue; - if (blocks[p] == Tile::lava_Id || blocks[p] == Tile::calmLava_Id) + if (blocks[p] == Tile::flowing_lava_Id || blocks[p] == Tile::lava_Id) { detectedWater = true; } @@ -136,7 +136,7 @@ void LargeHellCaveFeature::addTunnel(int64_t seed, int xOffs, int zOffs, byteArr if (yd > -0.7 && xd * xd + yd * yd + zd * zd < 1) { int block = blocks[p]; - if (block == Tile::netherRack_Id || block == Tile::dirt_Id || block == Tile::grass_Id) + if (block == Tile::netherrack_Id || block == Tile::dirt_Id || block == Tile::grass_Id) { blocks[p] = static_cast(0); } diff --git a/Minecraft.World/LavaSlime.cpp b/Minecraft.World/LavaSlime.cpp index 30a87653..77ad827f 100644 --- a/Minecraft.World/LavaSlime.cpp +++ b/Minecraft.World/LavaSlime.cpp @@ -61,7 +61,7 @@ shared_ptr LavaSlime::createChild() int LavaSlime::getDeathLoot() { // 4J-PB - brought forward the magma cream drops - return Item::magmaCream_Id; + return Item::magma_cream_Id; } void LavaSlime::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) diff --git a/Minecraft.World/Layer.cpp b/Minecraft.World/Layer.cpp index 52010d59..996be729 100644 --- a/Minecraft.World/Layer.cpp +++ b/Minecraft.World/Layer.cpp @@ -61,7 +61,8 @@ LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType, void* sup zoomLevel = 6; - shared_ptr riverInit = make_shared(seed, baseLayer, 0x64); + shared_ptr riverBase = ZoomLayer::zoom(seed, baseLayer, 0x3E8, 0); + shared_ptr riverInit = make_shared(seed, riverBase, 0x64); shared_ptr hillsNoise = ZoomLayer::zoom(seed, riverInit, 0x3E8, 2); @@ -71,7 +72,7 @@ LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType, void* sup riverLayerFinal = make_shared(seed, riverLayerFinal, 0x3E8); shared_ptr biomeLayer = make_shared(seed, baseLayer, 0xC8, levelType, superflatConfig); - biomeLayer = ZoomLayer::zoom(seed, biomeLayer, 0x3E8, 2); + biomeLayer = ZoomLayer::zoom(seed, biomeLayer, 0x3E8, 0); biomeLayer = make_shared(seed, biomeLayer, 0x3E8); biomeLayer = make_shared(seed, biomeLayer, hillsNoise, 0x3E8); biomeLayer = make_shared(seed, biomeLayer, 0x3E9); diff --git a/Minecraft.World/Layer.h b/Minecraft.World/Layer.h index cfc3cf28..b82e7062 100644 --- a/Minecraft.World/Layer.h +++ b/Minecraft.World/Layer.h @@ -26,8 +26,8 @@ public: Layer(int64_t seedMixup); virtual void init(int64_t seed); - bool isOcean(int biomeId); - bool isSame(int biomeIdA, int biomeIdB); + static bool isOcean(int biomeId); + static bool isSame(int biomeIdA, int biomeIdB); virtual void initRandom(int64_t x, int64_t y); protected: diff --git a/Minecraft.World/LeafTile.cpp b/Minecraft.World/LeafTile.cpp index 5f40d55e..2e41c092 100644 --- a/Minecraft.World/LeafTile.cpp +++ b/Minecraft.World/LeafTile.cpp @@ -137,7 +137,7 @@ void LeafTile::tick(Level *level, int x, int y, int z, Random *random) for (int yo = -r; yo <= r; yo++) { int t = level->getTile(x + xo, y + yo, z + zo); - if (t == Tile::treeTrunk_Id || t == Tile::tree2Trunk_Id) + if (t == Tile::log_Id || t == Tile::log2_Id) { checkBuffer[(xo + WO) * WW + (yo + WO) * W + (zo + WO)] = 0; } diff --git a/Minecraft.World/Level.cpp b/Minecraft.World/Level.cpp index 8478535b..1c6bc110 100644 --- a/Minecraft.World/Level.cpp +++ b/Minecraft.World/Level.cpp @@ -891,12 +891,14 @@ bool Level::reallyHasChunksAt(int x0, int y0, int z0, int x1, int y1, int z1) bool Level::hasChunk(int x, int z) { + if (this->chunkSource == nullptr) return false; return this->chunkSource->hasChunk(x, z); } // 4J added bool Level::reallyHasChunk(int x, int z) { + if (this->chunkSource == nullptr) return false; return this->chunkSource->reallyHasChunk(x, z); } @@ -963,7 +965,9 @@ Material *Level::getMaterial(int x, int y, int z) { int t = getTile(x, y, z); if (t == 0) return Material::air; - return Tile::tiles[t]->material; + Tile *tile = Tile::tiles[t]; + if (tile == nullptr) return Material::air; + return tile->material; } int Level::getData(int x, int y, int z) @@ -1516,7 +1520,7 @@ HitResult *Level::clip(Vec3 *a, Vec3 *b, bool liquid, bool solidOnly) // No collision } - else if (t > 0 && tile->mayPick(data, liquid)) + else if (t > 0 && tile != nullptr && tile->mayPick(data, liquid)) { HitResult *r = tile->clip(this, xTile0, yTile0, zTile0, a, b); if (r != nullptr) return r; @@ -1618,7 +1622,7 @@ HitResult *Level::clip(Vec3 *a, Vec3 *b, bool liquid, bool solidOnly) // No collision } - else if (t > 0 && tile->mayPick(data, liquid)) + else if (t > 0 && tile != nullptr && tile->mayPick(data, liquid)) { HitResult *r = tile->clip(this, xTile0, yTile0, zTile0, a, b); if (r != nullptr) return r; @@ -2682,7 +2686,7 @@ bool Level::containsFireTile(AABB *box) { int t = getTile(x, y, z); - if (t == Tile::fire_Id || t == Tile::lava_Id || t == Tile::calmLava_Id) return true; + if (t == Tile::fire_Id || t == Tile::flowing_lava_Id || t == Tile::lava_Id) return true; } } return false; @@ -3321,13 +3325,17 @@ void Level::tickClientSideTiles(int xo, int zo, LevelChunk *lc) shared_ptr player = getNearestPlayer(x + 0.5, y + 0.5, z + 0.5, 8); if (player != nullptr && player->distanceToSqr(x + 0.5, y + 0.5, z + 0.5) > 2 * 2) { - // 4J-PB - Fixed issue with cave audio event having 2 sounds at 192k + // check for cave sound functionality + if (app.GetGameSettings(static_cast(player->getPlayerIndex()), eGameSetting_CaveSounds)) + { + // 4J-PB - Fixed issue with cave audio event having 2 sounds at 192k #ifdef _XBOX - this->playSound(x + 0.5, y + 0.5, z + 0.5,eSoundType_AMBIENT_CAVE_CAVE2, 0.7f, 0.8f + random->nextFloat() * 0.2f); + this->playSound(x + 0.5, y + 0.5, z + 0.5,eSoundType_AMBIENT_CAVE_CAVE2, 0.7f, 0.8f + random->nextFloat() * 0.2f); #else - this->playSound(x + 0.5, y + 0.5, z + 0.5,eSoundType_AMBIENT_CAVE_CAVE, 0.7f, 0.8f + random->nextFloat() * 0.2f); + this->playSound(x + 0.5, y + 0.5, z + 0.5,eSoundType_AMBIENT_CAVE_CAVE, 0.7f, 0.8f + random->nextFloat() * 0.2f); #endif - delayUntilNextMoodSound = random->nextInt(SharedConstants::TICKS_PER_SECOND * 60 * 10) + SharedConstants::TICKS_PER_SECOND * 60 * 5; + delayUntilNextMoodSound = random->nextInt(SharedConstants::TICKS_PER_SECOND * 60 * 10) + SharedConstants::TICKS_PER_SECOND * 60 * 5; + } } } } @@ -3360,7 +3368,7 @@ bool Level::shouldFreeze(int x, int y, int z, bool checkNeighbors) if (y >= 0 && y < maxBuildHeight && getBrightness(LightLayer::Block, x, y, z) < 10) { int current = getTile(x, y, z); - if ((current == Tile::calmWater_Id || current == Tile::water_Id) && getData(x, y, z) == 0) + if ((current == Tile::water_Id || current == Tile::flowing_water_Id) && getData(x, y, z) == 0) { if (!checkNeighbors) return true; @@ -3991,7 +3999,9 @@ int Level::getDirectSignal(int x, int y, int z, int dir) { int t = getTile(x, y, z); if (t == 0) return Redstone::SIGNAL_NONE; - return Tile::tiles[t]->getDirectSignal(this, x, y, z, dir); + Tile *tile = Tile::tiles[t]; + if (tile == nullptr) return Redstone::SIGNAL_NONE; // tu31 tutorial world fix + return tile->getDirectSignal(this, x, y, z, dir); } int Level::getDirectSignalTo(int x, int y, int z) @@ -4024,8 +4034,9 @@ int Level::getSignal(int x, int y, int z, int dir) return getDirectSignalTo(x, y, z); } int t = getTile(x, y, z); - if (t == 0) return Redstone::SIGNAL_NONE; - return Tile::tiles[t]->getSignal(this, x, y, z, dir); + Tile *tile = Tile::tiles[t]; + if (t == 0 || tile == nullptr) return Redstone::SIGNAL_NONE; + return tile->getSignal(this, x, y, z, dir); } bool Level::hasNeighborSignal(int x, int y, int z) diff --git a/Minecraft.World/LevelChunk.cpp b/Minecraft.World/LevelChunk.cpp index 5800abd7..0cb11539 100644 --- a/Minecraft.World/LevelChunk.cpp +++ b/Minecraft.World/LevelChunk.cpp @@ -949,9 +949,12 @@ bool LevelChunk::setTileAndData(int x, int y, int z, int _tile, int _data) } int xOffs = this->x * 16 + x; int zOffs = this->z * 16 + z; + + Tile *oldTile = Tile::tiles[old]; + if (oldTile == nullptr & old != 0) return false; // tu31 tutorial world fix if (old != 0 && !level->isClientSide) { - Tile::tiles[old]->onRemoving(level, xOffs, y, zOffs, oldData); + oldTile->onRemoving(level, xOffs, y, zOffs, oldData); } PIXBeginNamedEvent(0,"Chunk setting tile"); blocks->set(x,y % Level::COMPRESSED_CHUNK_SECTION_HEIGHT,z,tile); @@ -1329,7 +1332,9 @@ shared_ptr LevelChunk::getTileEntity(int x, int y, int z) if(level->m_bDisableAddNewTileEntities) return nullptr; int t = getTile(x, y, z); - if (t <= 0 || !Tile::tiles[t]->isEntityTile()) return nullptr; + Tile *tile = Tile::tiles[t]; + if (tile == nullptr) return nullptr; // tu31 tutorial world fix + if (t <= 0 || !tile->isEntityTile()) return nullptr; // 4J-PB changed from this in 1.7.3 //EntityTile *et = (EntityTile *) Tile::tiles[t]; @@ -1337,7 +1342,7 @@ shared_ptr LevelChunk::getTileEntity(int x, int y, int z) //if (tileEntity == nullptr) //{ - tileEntity = dynamic_cast(Tile::tiles[t])->newTileEntity(level); + tileEntity = dynamic_cast(tile)->newTileEntity(level); level->setTileEntity(this->x * 16 + x, y, this->z * 16 + z, tileEntity); //} @@ -2096,6 +2101,9 @@ void LevelChunk::setBiomes(byteArray biomes) // 4J - optimisation brought forward from 1.8.2 int LevelChunk::getTopRainBlock(int x, int z) { + // check if sent data is not malformed causing a crash + if (x < 0 || x >= 16 || z < 0 || z >= 16) return 0; + int slot = x | (z << 4); int h = rainHeights[slot]; @@ -2106,7 +2114,8 @@ int LevelChunk::getTopRainBlock(int x, int z) while (y > 0 && h == -1) { int t = getTile(x, y, z); - Material *m = t == 0 ? Material::air : Tile::tiles[t]->material; + Tile *tile = (t == 0) ? nullptr : Tile::tiles[t]; + Material *m = (tile == nullptr) ? Material::air : tile->material; if (!m->blocksMotion() && !m->isLiquid()) { y--; diff --git a/Minecraft.World/LeverTile.cpp b/Minecraft.World/LeverTile.cpp index 7a7cdfd5..3c4af525 100644 --- a/Minecraft.World/LeverTile.cpp +++ b/Minecraft.World/LeverTile.cpp @@ -8,6 +8,32 @@ LeverTile::LeverTile(int id) : Tile(id, Material::decoration,isSolidRender()) { } +void LeverTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int LeverTile::defaultBlockState() +{ + return 0; +} + +int LeverTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState LeverTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState LeverTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + AABB *LeverTile::getAABB(Level *level, int x, int y, int z) { return nullptr; diff --git a/Minecraft.World/LeverTile.h b/Minecraft.World/LeverTile.h index da719868..2f054e57 100644 --- a/Minecraft.World/LeverTile.h +++ b/Minecraft.World/LeverTile.h @@ -7,6 +7,11 @@ class LeverTile : public Tile protected: LeverTile(int id); public: + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; virtual AABB *getAABB(Level *level, int x, int y, int z); virtual bool blocksLight(); virtual bool isSolidRender(bool isServerLevel = false); diff --git a/Minecraft.World/LightGemFeature.cpp b/Minecraft.World/LightGemFeature.cpp index 6ad1193a..09a288a8 100644 --- a/Minecraft.World/LightGemFeature.cpp +++ b/Minecraft.World/LightGemFeature.cpp @@ -6,7 +6,7 @@ bool LightGemFeature::place(Level *level, Random *random, int x, int y, int z) { if (!level->isEmptyTile(x, y, z)) return false; - if (level->getTile(x, y + 1, z) != Tile::netherRack_Id) return false; + if (level->getTile(x, y + 1, z) != Tile::netherrack_Id) return false; level->setTileAndData(x, y, z, Tile::glowstone_Id, 0, Tile::UPDATE_CLIENTS); for (int i = 0; i < 1500; i++) diff --git a/Minecraft.World/LightGemTile.cpp b/Minecraft.World/LightGemTile.cpp index 3aa7d101..e8ae28b7 100644 --- a/Minecraft.World/LightGemTile.cpp +++ b/Minecraft.World/LightGemTile.cpp @@ -18,5 +18,5 @@ int LightGemTile::getResourceCount(Random *random) int LightGemTile::getResource(int data, Random *random, int playerBonusLevel) { - return Item::yellowDust->id; + return Item::glowstone_dust->id; } \ No newline at end of file diff --git a/Minecraft.World/LiquidTileDynamic.cpp b/Minecraft.World/LiquidTileDynamic.cpp index 43d6366c..25a8e821 100644 --- a/Minecraft.World/LiquidTileDynamic.cpp +++ b/Minecraft.World/LiquidTileDynamic.cpp @@ -207,7 +207,9 @@ void LiquidTileDynamic::trySpreadTo(Level *level, int x, int y, int z, int fromX } else { - Tile::tiles[old]->spawnResources(level, x, y, z, level->getData(x, y, z), 0); + Tile *tile = Tile::tiles[old]; + if (tile == nullptr) return; // tu31 tutorial world fix + tile->spawnResources(level, x, y, z, level->getData(x, y, z), 0); } } } @@ -313,12 +315,13 @@ bool *LiquidTileDynamic::getSpread(Level *level, int x, int y, int z) bool LiquidTileDynamic::isWaterBlocking(Level *level, int x, int y, int z) { int t = level->getTile(x, y, z); - if (t == Tile::door_wood_Id || t == Tile::door_iron_Id || t == Tile::sign_Id || t == Tile::ladder_Id || t == Tile::reeds_Id) + if (t == Tile::wooden_door_Id || t == Tile::iron_door_Id || t == Tile::standing_sign_Id || t == Tile::ladder_Id || t == Tile::reeds_Id) { return true; } - if (t == 0) return false; - Material *m = Tile::tiles[t]->material; + Tile *tile = Tile::tiles[t]; + if (t == 0 || tile == nullptr) return false; // tu31 tutorial world fix + Material *m = tile->material; if (m == Material::portal) return true; if (m->blocksMotion()) return true; return false; diff --git a/Minecraft.World/LivingEntity.cpp b/Minecraft.World/LivingEntity.cpp index 642ec3b1..8dbfa494 100644 --- a/Minecraft.World/LivingEntity.cpp +++ b/Minecraft.World/LivingEntity.cpp @@ -164,7 +164,7 @@ void LivingEntity::checkFallDamage(double ya, bool onGround) updateInWaterState(); } - if (onGround && fallDistance > 0) + if (onGround) { int xt = Mth::floor(x); int yt = Mth::floor(y - 0.2f - heightOffset); @@ -179,9 +179,14 @@ void LivingEntity::checkFallDamage(double ya, bool onGround) } } - if (t > 0) + Tile *tile = Tile::tiles[t]; + if (t > 0 && tile != nullptr) // tu31 tutorial world fix { - Tile::tiles[t]->fallOn(level, xt, yt, zt, shared_from_this(), fallDistance); + if (fallDistance > 0 || t == Tile::slimeBlock->id) + { + auto ent = shared_from_this(); + Tile::tiles[t]->fallOn(level, xt, yt, zt, ent, fallDistance); + } } } @@ -1560,10 +1565,12 @@ void LivingEntity::travel(float xa, float ya) if (onGround) { frictionTile = level->getTile(Mth::floor(x), Mth::floor(bb->y0) - 1, Mth::floor(z)); + Tile *tile = Tile::tiles[frictionTile]; friction = 0.6f * 0.91f; if (frictionTile > 0) { - friction = Tile::tiles[frictionTile]->friction * 0.91f; + if (tile == nullptr) tile = Tile::tiles[1]; + friction = tile->friction * 0.91f; } } @@ -1586,8 +1593,10 @@ void LivingEntity::travel(float xa, float ya) { friction = 0.6f * 0.91f; if (frictionTile > 0) - { - friction = Tile::tiles[frictionTile]->friction * 0.91f; + { + Tile *tile = Tile::tiles[frictionTile]; + if (tile == nullptr) tile = Tile::tiles[1]; + friction = tile->friction * 0.91f; } } if (onLadder()) diff --git a/Minecraft.World/Material.h b/Minecraft.World/Material.h index aa735a20..6b4d4acc 100644 --- a/Minecraft.World/Material.h +++ b/Minecraft.World/Material.h @@ -45,6 +45,7 @@ public: static const int PUSH_NORMAL = 0; static const int PUSH_DESTROY = 1; static const int PUSH_BLOCK = 2; // not pushable + static const int PUSH_SLIME = 3; // slime block static void staticCtor(); diff --git a/Minecraft.World/MegaPineTreeFeature.cpp b/Minecraft.World/MegaPineTreeFeature.cpp index 59c026cd..d6aec09a 100644 --- a/Minecraft.World/MegaPineTreeFeature.cpp +++ b/Minecraft.World/MegaPineTreeFeature.cpp @@ -164,9 +164,9 @@ bool MegaPineTreeFeature::isReplaceable(int tileId) || tileId == Tile::leaves2_Id || tileId == Tile::grass_Id || tileId == Tile::dirt_Id - || tileId == Tile::treeTrunk_Id + || tileId == Tile::log_Id || tileId == Tile::sapling_Id - || tileId == Tile::deadBush_Id + || tileId == Tile::deadbush_Id || tileId == Tile::tallgrass_Id || tileId == Tile::snow_Id; } @@ -191,21 +191,21 @@ bool MegaPineTreeFeature::place(Level *level, Random *random, int x, int y, int { if (isAirLeaves(level, x, y + j, z)) { - placeBlock(level, x, y + j, z, Tile::treeTrunk_Id, TreeTile::SPRUCE_TRUNK); + placeBlock(level, x, y + j, z, Tile::log_Id, TreeTile::SPRUCE_TRUNK); } if (j < height - 1) // 3 extra columns stop 1 short of the top { if (isAirLeaves(level, x + 1, y + j, z)) { - placeBlock(level, x + 1, y + j, z, Tile::treeTrunk_Id, TreeTile::SPRUCE_TRUNK); + placeBlock(level, x + 1, y + j, z, Tile::log_Id, TreeTile::SPRUCE_TRUNK); } if (isAirLeaves(level, x + 1, y + j, z + 1)) { - placeBlock(level, x + 1, y + j, z + 1, Tile::treeTrunk_Id, TreeTile::SPRUCE_TRUNK); + placeBlock(level, x + 1, y + j, z + 1, Tile::log_Id, TreeTile::SPRUCE_TRUNK); } if (isAirLeaves(level, x, y + j, z + 1)) { - placeBlock(level, x, y + j, z + 1, Tile::treeTrunk_Id, TreeTile::SPRUCE_TRUNK); + placeBlock(level, x, y + j, z + 1, Tile::log_Id, TreeTile::SPRUCE_TRUNK); } } } diff --git a/Minecraft.World/MegaTreeFeature.cpp b/Minecraft.World/MegaTreeFeature.cpp index db4a336a..478ca61b 100644 --- a/Minecraft.World/MegaTreeFeature.cpp +++ b/Minecraft.World/MegaTreeFeature.cpp @@ -40,7 +40,7 @@ bool MegaTreeFeature::place(Level *level, Random *random, int x, int y, int z) if (yy >= 0 && yy < Level::maxBuildHeight) { int tt = level->getTile(xx, yy, zz); - if (tt != 0 && tt != Tile::leaves_Id && tt != Tile::grass_Id && tt != Tile::dirt_Id && tt != Tile::treeTrunk_Id && tt != Tile::sapling_Id) free = false; + if (tt != 0 && tt != Tile::leaves_Id && tt != Tile::grass_Id && tt != Tile::dirt_Id && tt != Tile::log_Id && tt != Tile::sapling_Id) free = false; } else { @@ -77,7 +77,7 @@ bool MegaTreeFeature::place(Level *level, Random *random, int x, int y, int z) { bx = x + static_cast(1.5f + Mth::cos(angle) * b); bz = z + static_cast(1.5f + Mth::sin(angle) * b); - placeBlock(level, bx, branchHeight - 3 + b / 2, bz, Tile::treeTrunk_Id, trunkType); + placeBlock(level, bx, branchHeight - 3 + b / 2, bz, Tile::log_Id, trunkType); } branchHeight -= 2 + random->nextInt(4); @@ -90,7 +90,7 @@ bool MegaTreeFeature::place(Level *level, Random *random, int x, int y, int z) int t = level->getTile(x, y + hh, z); if (t == 0 || t == Tile::leaves_Id) { - placeBlock(level, x, y + hh, z, Tile::treeTrunk_Id, trunkType); + placeBlock(level, x, y + hh, z, Tile::log_Id, trunkType); if (hh > 0) { if (random->nextInt(3) > 0 && level->isEmptyTile(x - 1, y + hh, z)) @@ -108,7 +108,7 @@ bool MegaTreeFeature::place(Level *level, Random *random, int x, int y, int z) t = level->getTile(x + 1, y + hh, z); if (t == 0 || t == Tile::leaves_Id) { - placeBlock(level, x + 1, y + hh, z, Tile::treeTrunk_Id, trunkType); + placeBlock(level, x + 1, y + hh, z, Tile::log_Id, trunkType); if (hh > 0) { if (random->nextInt(3) > 0 && level->isEmptyTile(x + 2, y + hh, z)) @@ -124,7 +124,7 @@ bool MegaTreeFeature::place(Level *level, Random *random, int x, int y, int z) t = level->getTile(x + 1, y + hh, z + 1); if (t == 0 || t == Tile::leaves_Id) { - placeBlock(level, x + 1, y + hh, z + 1, Tile::treeTrunk_Id, trunkType); + placeBlock(level, x + 1, y + hh, z + 1, Tile::log_Id, trunkType); if (hh > 0) { if (random->nextInt(3) > 0 && level->isEmptyTile(x + 2, y + hh, z + 1)) @@ -140,7 +140,7 @@ bool MegaTreeFeature::place(Level *level, Random *random, int x, int y, int z) t = level->getTile(x, y + hh, z + 1); if (t == 0 || t == Tile::leaves_Id) { - placeBlock(level, x, y + hh, z + 1, Tile::treeTrunk_Id, trunkType); + placeBlock(level, x, y + hh, z + 1, Tile::log_Id, trunkType); if (hh > 0) { if (random->nextInt(3) > 0 && level->isEmptyTile(x - 1, y + hh, z + 1)) diff --git a/Minecraft.World/MelonFeature.cpp b/Minecraft.World/MelonFeature.cpp index 0921fd09..fab3c987 100644 --- a/Minecraft.World/MelonFeature.cpp +++ b/Minecraft.World/MelonFeature.cpp @@ -14,7 +14,7 @@ bool MelonFeature::place(Level *level, Random *random, int x, int y, int z) { if (Tile::melon->mayPlace(level, x2, y2, z2)) { - level->setTileAndData(x2, y2, z2, Tile::melon_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x2, y2, z2, Tile::melon_block_Id, 0, Tile::UPDATE_CLIENTS); } } } diff --git a/Minecraft.World/MerchantRecipe.cpp b/Minecraft.World/MerchantRecipe.cpp index b4eb1b54..ad190418 100644 --- a/Minecraft.World/MerchantRecipe.cpp +++ b/Minecraft.World/MerchantRecipe.cpp @@ -64,6 +64,10 @@ shared_ptr MerchantRecipe::getSellItem() bool MerchantRecipe::isSame(MerchantRecipe *other) { + if (!other || !buyA || !sell || !other->buyA || !other->sell) + { + return false; + } if (buyA->id != other->buyA->id || sell->id != other->sell->id) { return false; @@ -74,7 +78,11 @@ bool MerchantRecipe::isSame(MerchantRecipe *other) bool MerchantRecipe::isSameSameButBetter(MerchantRecipe *other) { // same deal, but cheaper - return isSame(other) && (buyA->count < other->buyA->count || (buyB != nullptr && buyB->count < other->buyB->count)); + if (!isSame(other) || !buyA || !other || !other->buyA) + { + return false; + } + return buyA->count < other->buyA->count || (buyB != nullptr && buyB->count < other->buyB->count); } int MerchantRecipe::getUses() @@ -110,9 +118,9 @@ void MerchantRecipe::enforceDeprecated() void MerchantRecipe::load(CompoundTag *tag) { CompoundTag *buyTag = tag->getCompound(L"buy"); - buyA = ItemInstance::fromTag(buyTag); + buyA = buyTag ? ItemInstance::fromTag(buyTag) : nullptr; CompoundTag *sellTag = tag->getCompound(L"sell"); - sell = ItemInstance::fromTag(sellTag); + sell = sellTag ? ItemInstance::fromTag(sellTag) : nullptr; if (tag->contains(L"buyB")) { buyB = ItemInstance::fromTag(tag->getCompound(L"buyB")); @@ -134,8 +142,14 @@ void MerchantRecipe::load(CompoundTag *tag) CompoundTag *MerchantRecipe::createTag() { CompoundTag *tag = new CompoundTag(); - tag->putCompound(L"buy", buyA->save(new CompoundTag(L"buy"))); - tag->putCompound(L"sell", sell->save(new CompoundTag(L"sell"))); + if (buyA != nullptr) + { + tag->putCompound(L"buy", buyA->save(new CompoundTag(L"buy"))); + } + if (sell != nullptr) + { + tag->putCompound(L"sell", sell->save(new CompoundTag(L"sell"))); + } if (buyB != nullptr) { tag->putCompound(L"buyB", buyB->save(new CompoundTag(L"buyB"))); diff --git a/Minecraft.World/MesaBiome.cpp b/Minecraft.World/MesaBiome.cpp index 0aef5182..9e8eda19 100644 --- a/Minecraft.World/MesaBiome.cpp +++ b/Minecraft.World/MesaBiome.cpp @@ -28,7 +28,7 @@ MesaBiome::MesaBiome(int id, bool mesaPlateau, bool hasTrees) : Biome(id) this->topMaterial = static_cast(Tile::sand_Id); this->topMaterialData = static_cast(SandTile::RED_SAND); - this->material = static_cast(Tile::clayHardened_colored_Id); + this->material = static_cast(Tile::stained_hardened_clay_Id); this->materialData = static_cast(orangeColoredClayState); this->lastSeed = INVALID_SEED; @@ -68,7 +68,7 @@ void MesaBiome::generateBands(int64_t seed) for (int i = 0; i < BAND_COUNT; ++i) { - clayBands[i].blockId = Tile::clayHardened_Id; + clayBands[i].blockId = Tile::hardened_clay_Id; clayBands[i].blockData = defaultHardenedClayState; } @@ -85,7 +85,7 @@ void MesaBiome::generateBands(int64_t seed) i += r.nextInt(5) + 1; if (i < BAND_COUNT) { - clayBands[i].blockId = Tile::clayHardened_colored_Id; + clayBands[i].blockId = Tile::stained_hardened_clay_Id; clayBands[i].blockData = orangeColoredClayState; } } @@ -99,7 +99,7 @@ void MesaBiome::generateBands(int64_t seed) int start = r.nextInt(BAND_COUNT); for (int k = 0; start + k < BAND_COUNT && k < len; ++k) { - clayBands[start + k].blockId = Tile::clayHardened_colored_Id; + clayBands[start + k].blockId = Tile::stained_hardened_clay_Id; clayBands[start + k].blockData = yellowColoredClayState; } } @@ -113,7 +113,7 @@ void MesaBiome::generateBands(int64_t seed) int start = r.nextInt(BAND_COUNT); for (int k = 0; start + k < BAND_COUNT && k < len; ++k) { - clayBands[start + k].blockId = Tile::clayHardened_colored_Id; + clayBands[start + k].blockId = Tile::stained_hardened_clay_Id; clayBands[start + k].blockData = brownColoredClayState; } } @@ -127,7 +127,7 @@ void MesaBiome::generateBands(int64_t seed) int start = r.nextInt(BAND_COUNT); for (int k = 0; start + k < BAND_COUNT && k < len; ++k) { - clayBands[start + k].blockId = Tile::clayHardened_colored_Id; + clayBands[start + k].blockId = Tile::stained_hardened_clay_Id; clayBands[start + k].blockData = redColoredClayState; } } @@ -141,19 +141,19 @@ void MesaBiome::generateBands(int64_t seed) cursor += r.nextInt(16) + 4; if (cursor >= BAND_COUNT) break; - clayBands[cursor].blockId = Tile::clayHardened_colored_Id; + clayBands[cursor].blockId = Tile::stained_hardened_clay_Id; clayBands[cursor].blockData = whiteColoredClayState; if (cursor > 1 && r.nextBoolean()) { - clayBands[cursor - 1].blockId = Tile::clayHardened_colored_Id; + clayBands[cursor - 1].blockId = Tile::stained_hardened_clay_Id; clayBands[cursor - 1].blockData = silverColoredClayState; } if (cursor < 63 && r.nextBoolean()) { - clayBands[cursor + 1].blockId = Tile::clayHardened_colored_Id; + clayBands[cursor + 1].blockId = Tile::stained_hardened_clay_Id; clayBands[cursor + 1].blockData = silverColoredClayState; } } @@ -164,7 +164,7 @@ void MesaBiome::generateBands(int64_t seed) BandEntry MesaBiome::getBand(int x, int y, int z) { if (!clayBandsOffsetNoise || !clayBands) - return { Tile::clayHardened_Id, 0 }; + return { Tile::hardened_clay_Id, 0 }; double noiseVal = clayBandsOffsetNoise->getValue( @@ -277,7 +277,7 @@ void MesaBiome::buildSurfaceAtDefault(Level* level, Random* random, if (y <= random->nextInt(5)) { - chunkBlocks[idx] = static_cast(Tile::unbreakable_Id); + chunkBlocks[idx] = static_cast(Tile::bedrock_Id); continue; } @@ -309,7 +309,7 @@ void MesaBiome::buildSurfaceAtDefault(Level* level, Random* random, } else { - chunkBlocks[idx] = static_cast(Tile::clayHardened_colored_Id); + chunkBlocks[idx] = static_cast(Tile::stained_hardened_clay_Id); chunkData[idx] = static_cast(BAND_ORANGE); } } @@ -339,26 +339,26 @@ void MesaBiome::buildSurfaceAtDefault(Level* level, Random* random, { if (cosFlag) { - chunkBlocks[idx] = static_cast(Tile::clayHardened_Id); + chunkBlocks[idx] = static_cast(Tile::hardened_clay_Id); } else { BandEntry band = getBand(x, y, z); chunkBlocks[idx] = static_cast(band.blockId); - if (band.blockId == Tile::clayHardened_colored_Id) + if (band.blockId == Tile::stained_hardened_clay_Id) chunkData[idx] = static_cast(band.blockData); } } else { - chunkBlocks[idx] = static_cast(Tile::clayHardened_colored_Id); + chunkBlocks[idx] = static_cast(Tile::stained_hardened_clay_Id); chunkData[idx] = static_cast(BAND_ORANGE); } } if (y < seaLevel && chunkBlocks[idx] == 0) - chunkBlocks[idx] = static_cast(Tile::calmWater_Id); + chunkBlocks[idx] = static_cast(Tile::water_Id); } else if (run > 0) { @@ -366,14 +366,14 @@ void MesaBiome::buildSurfaceAtDefault(Level* level, Random* random, if (underRedSand) { - chunkBlocks[idx] = static_cast(Tile::clayHardened_colored_Id); + chunkBlocks[idx] = static_cast(Tile::stained_hardened_clay_Id); chunkData[idx] = static_cast(BAND_ORANGE); } else { BandEntry band = getBand(x, y, z); chunkBlocks[idx] = static_cast(band.blockId); - if (band.blockId == Tile::clayHardened_colored_Id) + if (band.blockId == Tile::stained_hardened_clay_Id) chunkData[idx] = static_cast(band.blockData); } } diff --git a/Minecraft.World/MilkBucketItem.cpp b/Minecraft.World/MilkBucketItem.cpp index 8c8ea674..ee358f38 100644 --- a/Minecraft.World/MilkBucketItem.cpp +++ b/Minecraft.World/MilkBucketItem.cpp @@ -19,7 +19,7 @@ shared_ptr MilkBucketItem::useTimeDepleted(shared_ptrcount <= 0) { - return std::make_shared(Item::bucket_empty); + return std::make_shared(Item::bucket); } return instance; } diff --git a/Minecraft.World/MineShaftPieces.cpp b/Minecraft.World/MineShaftPieces.cpp index 97caf366..d81223f8 100644 --- a/Minecraft.World/MineShaftPieces.cpp +++ b/Minecraft.World/MineShaftPieces.cpp @@ -14,20 +14,20 @@ WeighedTreasureArray MineShaftPieces::smallTreasureItems;; void MineShaftPieces::staticCtor() { smallTreasureItems = WeighedTreasureArray(13); - smallTreasureItems[0] = new WeighedTreasure(Item::ironIngot_Id, 0, 1, 5, 10); - smallTreasureItems[1] = new WeighedTreasure(Item::goldIngot_Id, 0, 1, 3, 5); - smallTreasureItems[2] = new WeighedTreasure(Item::redStone_Id, 0, 4, 9, 5); - smallTreasureItems[3] = new WeighedTreasure(Item::dye_powder_Id, DyePowderItem::BLUE, 4, 9, 5); + smallTreasureItems[0] = new WeighedTreasure(Item::iron_ingot_Id, 0, 1, 5, 10); + smallTreasureItems[1] = new WeighedTreasure(Item::gold_ingot_Id, 0, 1, 3, 5); + smallTreasureItems[2] = new WeighedTreasure(Item::redstone_Id, 0, 4, 9, 5); + smallTreasureItems[3] = new WeighedTreasure(Item::dye_Id, DyePowderItem::BLUE, 4, 9, 5); smallTreasureItems[4] = new WeighedTreasure(Item::diamond_Id, 0, 1, 2, 3); smallTreasureItems[5] = new WeighedTreasure(Item::coal_Id, CoalItem::STONE_COAL, 3, 8, 10); smallTreasureItems[6] = new WeighedTreasure(Item::bread_Id, 0, 1, 3, 15); - smallTreasureItems[7] = new WeighedTreasure(Item::pickAxe_iron_Id, 0, 1, 1, 1); + smallTreasureItems[7] = new WeighedTreasure(Item::iron_pickaxe_Id, 0, 1, 1, 1); smallTreasureItems[8] = new WeighedTreasure(Tile::rail_Id, 0, 4, 8, 1); - smallTreasureItems[9] = new WeighedTreasure(Item::seeds_melon_Id, 0, 2, 4, 10); - smallTreasureItems[10] = new WeighedTreasure(Item::seeds_pumpkin_Id, 0, 2, 4, 10); + smallTreasureItems[9] = new WeighedTreasure(Item::melon_seeds_Id, 0, 2, 4, 10); + smallTreasureItems[10] = new WeighedTreasure(Item::pumpkin_seeds_Id, 0, 2, 4, 10); // very rare for shafts ... smallTreasureItems[11] = new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 3); - smallTreasureItems[12] = new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 1); + smallTreasureItems[12] = new WeighedTreasure(Item::iron_horse_armor_Id, 0, 1, 1, 1); } void MineShaftPieces::loadStatic() @@ -477,12 +477,12 @@ bool MineShaftPieces::MineShaftCorridor::postProcess(Level *level, Random *rando generateBox(level, chunkBB, x1, y0, z, x1, y1 - 1, z, Tile::fence_Id, 0, false); if (random->nextInt(4) == 0) { - generateBox(level, chunkBB, x0, y1, z, x0, y1, z, Tile::wood_Id, 0, false); - generateBox(level, chunkBB, x1, y1, z, x1, y1, z, Tile::wood_Id, 0, false); + generateBox(level, chunkBB, x0, y1, z, x0, y1, z, Tile::planks_Id, 0, false); + generateBox(level, chunkBB, x1, y1, z, x1, y1, z, Tile::planks_Id, 0, false); } else { - generateBox(level, chunkBB, x0, y1, z, x1, y1, z, Tile::wood_Id, 0, false); + generateBox(level, chunkBB, x0, y1, z, x1, y1, z, Tile::planks_Id, 0, false); } maybeGenerateBlock(level, chunkBB, random, .1f, x0, y1, z - 1, Tile::web_Id, 0); maybeGenerateBlock(level, chunkBB, random, .1f, x1, y1, z - 1, Tile::web_Id, 0); @@ -498,11 +498,11 @@ bool MineShaftPieces::MineShaftCorridor::postProcess(Level *level, Random *rando if (random->nextInt(100) == 0) { - createChest(level, chunkBB, random, x1, y0, z - 1, WeighedTreasure::addToTreasure(smallTreasureItems, Item::enchantedBook->createForRandomTreasure(random)), 3 + random->nextInt(4)); + createChest(level, chunkBB, random, x1, y0, z - 1, WeighedTreasure::addToTreasure(smallTreasureItems, Item::enchanted_book->createForRandomTreasure(random)), 3 + random->nextInt(4)); } if (random->nextInt(100) == 0) { - createChest(level, chunkBB, random, x0, y0, z + 1, WeighedTreasure::addToTreasure(smallTreasureItems, Item::enchantedBook->createForRandomTreasure(random)), 3 + random->nextInt(4)); + createChest(level, chunkBB, random, x0, y0, z + 1, WeighedTreasure::addToTreasure(smallTreasureItems, Item::enchanted_book->createForRandomTreasure(random)), 3 + random->nextInt(4)); } if (spiderCorridor && !hasPlacedSpider) @@ -513,7 +513,7 @@ bool MineShaftPieces::MineShaftCorridor::postProcess(Level *level, Random *rando if (chunkBB->isInside(x, y, newZ)) { hasPlacedSpider = true; - level->setTileAndData(x, y, newZ, Tile::mobSpawner_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y, newZ, Tile::mob_spawner_Id, 0, Tile::UPDATE_CLIENTS); shared_ptr entity = dynamic_pointer_cast( level->getTileEntity(x, y, newZ) ); if (entity != nullptr) entity->getSpawner()->setEntityId(L"CaveSpider"); } @@ -528,7 +528,7 @@ bool MineShaftPieces::MineShaftCorridor::postProcess(Level *level, Random *rando int block = getBlock(level, x, -1, z, chunkBB); if (block == 0) { - placeBlock(level, Tile::wood_Id, 0, x, -1, z, chunkBB); + placeBlock(level, Tile::planks_Id, 0, x, -1, z, chunkBB); } } } @@ -677,10 +677,10 @@ bool MineShaftPieces::MineShaftCrossing::postProcess(Level *level, Random *rando } // support pillars - generateBox(level, chunkBB, boundingBox->x0 + 1, boundingBox->y0, boundingBox->z0 + 1, boundingBox->x0 + 1, boundingBox->y1, boundingBox->z0 + 1, Tile::wood_Id, 0, false); - generateBox(level, chunkBB, boundingBox->x0 + 1, boundingBox->y0, boundingBox->z1 - 1, boundingBox->x0 + 1, boundingBox->y1, boundingBox->z1 - 1, Tile::wood_Id, 0, false); - generateBox(level, chunkBB, boundingBox->x1 - 1, boundingBox->y0, boundingBox->z0 + 1, boundingBox->x1 - 1, boundingBox->y1, boundingBox->z0 + 1, Tile::wood_Id, 0, false); - generateBox(level, chunkBB, boundingBox->x1 - 1, boundingBox->y0, boundingBox->z1 - 1, boundingBox->x1 - 1, boundingBox->y1, boundingBox->z1 - 1, Tile::wood_Id, 0, false); + generateBox(level, chunkBB, boundingBox->x0 + 1, boundingBox->y0, boundingBox->z0 + 1, boundingBox->x0 + 1, boundingBox->y1, boundingBox->z0 + 1, Tile::planks_Id, 0, false); + generateBox(level, chunkBB, boundingBox->x0 + 1, boundingBox->y0, boundingBox->z1 - 1, boundingBox->x0 + 1, boundingBox->y1, boundingBox->z1 - 1, Tile::planks_Id, 0, false); + generateBox(level, chunkBB, boundingBox->x1 - 1, boundingBox->y0, boundingBox->z0 + 1, boundingBox->x1 - 1, boundingBox->y1, boundingBox->z0 + 1, Tile::planks_Id, 0, false); + generateBox(level, chunkBB, boundingBox->x1 - 1, boundingBox->y0, boundingBox->z1 - 1, boundingBox->x1 - 1, boundingBox->y1, boundingBox->z1 - 1, Tile::planks_Id, 0, false); // prevent air floating // note: use world coordinates because the corridor hasn't defined @@ -692,7 +692,7 @@ bool MineShaftPieces::MineShaftCrossing::postProcess(Level *level, Random *rando int block = getBlock(level, x, boundingBox->y0 - 1, z, chunkBB); if (block == 0) { - placeBlock(level, Tile::wood_Id, 0, x, boundingBox->y0 - 1, z, chunkBB); + placeBlock(level, Tile::planks_Id, 0, x, boundingBox->y0 - 1, z, chunkBB); } } } diff --git a/Minecraft.World/Minecart.cpp b/Minecraft.World/Minecart.cpp index efefb7ea..9d50f33f 100644 --- a/Minecraft.World/Minecart.cpp +++ b/Minecraft.World/Minecart.cpp @@ -13,6 +13,7 @@ #include "../Minecraft.Client/ServerLevel.h" #include "com.mojang.nbt.h" #include "Minecart.h" +#include "MinecartSoundInstance.h" #include "SharedConstants.h" @@ -44,7 +45,8 @@ void Minecart::_init() blocksBuilding = true; setSize(0.98f, 0.7f); heightOffset = bbHeight / 2.0f; - soundUpdater = nullptr; + m_rollingSound = nullptr; + m_ridingSound = nullptr; name = L""; // @@ -61,26 +63,43 @@ Minecart::Minecart(Level *level) : Entity( level ) Minecart::~Minecart() { - delete soundUpdater; + delete m_rollingSound; + delete m_ridingSound; } shared_ptr Minecart::createMinecart(Level *level, double x, double y, double z, int type) { + shared_ptr minecart; + switch (type) { case TYPE_CHEST: - return std::make_shared(level, x, y, z); + minecart = std::make_shared(level, x, y, z); + break; case TYPE_FURNACE: - return std::make_shared(level, x, y, z); + minecart = std::make_shared(level, x, y, z); + break; case TYPE_TNT: - return std::make_shared(level, x, y, z); + minecart = std::make_shared(level, x, y, z); + break; case TYPE_SPAWNER: - return std::make_shared(level, x, y, z); + minecart = std::make_shared(level, x, y, z); + break; case TYPE_HOPPER: - return std::make_shared(level, x, y, z); + minecart = std::make_shared(level, x, y, z); + break; default: - return std::make_shared(level, x, y, z); + minecart = std::make_shared(level, x, y, z); + break; } + + if (level != nullptr && level->isClientSide) + { + minecart->m_rollingSound = new MinecartSoundInstance(minecart); + minecart->m_ridingSound = new RidingMinecartSoundInstance(minecart); + } + + return minecart; } bool Minecart::makeStepSound() @@ -207,11 +226,36 @@ bool Minecart::isPickable() void Minecart::remove() { Entity::remove(); + // clean up sounds after invalidation + if (m_rollingSound) + { + delete m_rollingSound; + m_rollingSound = nullptr; + } + if (m_ridingSound) + { + delete m_ridingSound; + m_ridingSound = nullptr; + } //if (soundUpdater != nullptr) soundUpdater->tick(); } void Minecart::tick() { + // minecart tick handler + if (level->isClientSide) + { + if (m_rollingSound) + { + m_rollingSound->tick(); + } + + if (m_ridingSound) + { + m_ridingSound->tick(); + } + } + //if (soundUpdater != nullptr) soundUpdater->tick(); // 4J - make minecarts (server-side) tick twice, to put things back to how they were when we were accidently ticking them twice for( int i = 0; i < 2; i++ ) @@ -313,7 +357,7 @@ void Minecart::tick() int data = level->getData(xt, yt, zt); moveAlongTrack(xt, yt, zt, max, slideSpeed, tile, data); - if (tile == Tile::activatorRail_Id) + if (tile == Tile::activator_rail_Id) { activateMinecart(xt, yt, zt, (data & BaseRailTile::RAIL_DATA_BIT) != 0); } @@ -410,7 +454,7 @@ void Minecart::moveAlongTrack(int xt, int yt, int zt, double maxSpeed, double sl bool powerTrack = false; bool haltTrack = false; - if (tile == Tile::goldenRail_Id) + if (tile == Tile::golden_rail_Id) { powerTrack = (data & BaseRailTile::RAIL_DATA_BIT) != 0; haltTrack = !powerTrack; diff --git a/Minecraft.World/Minecart.h b/Minecraft.World/Minecart.h index bd1a69e6..e4a9121c 100644 --- a/Minecraft.World/Minecart.h +++ b/Minecraft.World/Minecart.h @@ -2,7 +2,8 @@ #include "Entity.h" class DamageSource; -class Tickable; +class MinecartSoundInstance; +class RidingMinecartSoundInstance; class Minecart : public Entity { @@ -30,7 +31,8 @@ private: static const int DATA_ID_CUSTOM_DISPLAY = 22; bool flipped; - Tickable *soundUpdater; + MinecartSoundInstance *m_rollingSound; + RidingMinecartSoundInstance *m_ridingSound; wstring name; protected: diff --git a/Minecraft.World/MinecartSoundInstance.cpp b/Minecraft.World/MinecartSoundInstance.cpp new file mode 100644 index 00000000..482ff8eb --- /dev/null +++ b/Minecraft.World/MinecartSoundInstance.cpp @@ -0,0 +1,175 @@ +#include "stdafx.h" +#include "MinecartSoundInstance.h" +#include "Minecart.h" +#include "net.minecraft.world.level.h" +#include "../Minecraft.Client/Minecraft.h" +#include "../Minecraft.Client/Common/Audio/SoundEngine.h" + +// MinecartSoundInstance + +MinecartSoundInstance::MinecartSoundInstance(shared_ptr minecart) + : m_minecart(minecart), m_bIsCurrentlyPlaying(false), m_sound(nullptr), m_volume(0.0f), m_pitch(1.0f) +{ +} + +MinecartSoundInstance::~MinecartSoundInstance() +{ + if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine) + { + Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound); + } + m_sound = nullptr; +} + +void MinecartSoundInstance::tick() +{ + if (!m_minecart || m_minecart->removed) + { + if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine) + { + Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound); + m_sound = nullptr; + } + m_bIsCurrentlyPlaying = false; + return; + } + + // minecart sound functionality check + if (!app.GetGameSettings(0, eGameSetting_MinecartSounds)) + { + if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine) + { + Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound); + m_sound = nullptr; + } + m_bIsCurrentlyPlaying = false; + return; + } + + // volume + pitch calculations + // relative to minecart velocity + double xd = m_minecart->xd; + double zd = m_minecart->zd; + double velocity = sqrt(xd * xd + zd * zd); + + if (velocity >= 0.01) + { + float clampedVel = (float)(velocity > 1.0 ? 1.0 : (velocity < 0.0 ? 0.0 : velocity)); + m_volume = clampedVel * 0.75f; + m_pitch = 1.0f; + + if (!m_bIsCurrentlyPlaying) + { + m_bIsCurrentlyPlaying = true; + if (Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine) + { + m_sound = Minecraft::GetInstance()->soundEngine->startLoopingSound(L"mob.minecart.rolling", (float)m_minecart->x, (float)m_minecart->y, (float)m_minecart->z, m_volume, m_pitch, true); + } + } + else if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine) + { + Minecraft::GetInstance()->soundEngine->updateLoopingSound(m_sound, (float)m_minecart->x, (float)m_minecart->y, (float)m_minecart->z, m_volume, m_pitch); + } + } + else + { + if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine) + { + Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound); + m_sound = nullptr; + } + m_volume = 0.0f; + m_pitch = 0.0f; + m_bIsCurrentlyPlaying = false; + } +} + +// RidingMinecartSoundInstance + +RidingMinecartSoundInstance::RidingMinecartSoundInstance(shared_ptr minecart) + : m_minecart(minecart), m_bIsCurrentlyPlaying(false), m_sound(nullptr), m_volume(0.0f), m_pitch(0.0f) +{ +} + +RidingMinecartSoundInstance::~RidingMinecartSoundInstance() +{ + if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine) + { + Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound); + } + m_sound = nullptr; +} + +void RidingMinecartSoundInstance::tick() +{ + if (!m_minecart || m_minecart->removed) + { + if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine) + { + Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound); + m_sound = nullptr; + } + m_bIsCurrentlyPlaying = false; + return; + } + + // minecart sound functionality check + if (!app.GetGameSettings(0, eGameSetting_MinecartSounds)) + { + if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine) + { + Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound); + m_sound = nullptr; + } + m_bIsCurrentlyPlaying = false; + return; + } + + // minecart passenger check + if (m_minecart->rider.lock() == nullptr) + { + if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine) + { + Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound); + m_sound = nullptr; + } + m_bIsCurrentlyPlaying = false; + return; + } + + // volume + pitch calculations + // relative to minecart velocity + double xd = m_minecart->xd; + double zd = m_minecart->zd; + double velocity = sqrt(xd * xd + zd * zd); + + if (velocity >= 0.01) + { + float clampedVel = (float)(velocity > 1.0 ? 1.0 : (velocity < 0.0 ? 0.0 : velocity)); + m_volume = clampedVel * 0.75f; + m_pitch = 1.0f; + + if (!m_bIsCurrentlyPlaying) + { + m_bIsCurrentlyPlaying = true; + if (Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine) + { + m_sound = Minecraft::GetInstance()->soundEngine->startLoopingSound(L"mob.minecart.inside", (float)m_minecart->x, (float)m_minecart->y, (float)m_minecart->z, m_volume, m_pitch, false); + } + } + else if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine) + { + Minecraft::GetInstance()->soundEngine->updateLoopingSound(m_sound, (float)m_minecart->x, (float)m_minecart->y, (float)m_minecart->z, m_volume, m_pitch); + } + } + else + { + if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine) + { + Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound); + m_sound = nullptr; + } + m_volume = 0.0f; + m_bIsCurrentlyPlaying = false; + } +} diff --git a/Minecraft.World/MinecartSoundInstance.h b/Minecraft.World/MinecartSoundInstance.h new file mode 100644 index 00000000..e7d2ba78 --- /dev/null +++ b/Minecraft.World/MinecartSoundInstance.h @@ -0,0 +1,43 @@ +#pragma once + +#include + +class Minecart; +class SoundEngine; +struct MiniAudioSound; + +// minecart rolling sound +class MinecartSoundInstance +{ +protected: + shared_ptr m_minecart; + bool m_bIsCurrentlyPlaying; + MiniAudioSound* m_sound; + float m_volume; + float m_pitch; + +public: + MinecartSoundInstance(shared_ptr minecart); + virtual ~MinecartSoundInstance(); + + virtual void tick(); + bool isCurrentlyPlaying() const { return m_bIsCurrentlyPlaying; } +}; + +// minecart passenger sound +class RidingMinecartSoundInstance +{ +protected: + shared_ptr m_minecart; + bool m_bIsCurrentlyPlaying; + MiniAudioSound* m_sound; + float m_volume; + float m_pitch; + +public: + RidingMinecartSoundInstance(shared_ptr minecart); + virtual ~RidingMinecartSoundInstance(); + + virtual void tick(); + bool isCurrentlyPlaying() const { return m_bIsCurrentlyPlaying; } +}; diff --git a/Minecraft.World/Mob.cpp b/Minecraft.World/Mob.cpp index 2b5dcb86..08fd01c1 100644 --- a/Minecraft.World/Mob.cpp +++ b/Minecraft.World/Mob.cpp @@ -769,29 +769,29 @@ Item *Mob::getEquipmentForSlot(int slot, int type) switch (slot) { case SLOT_HELM: - if (type == 0) return Item::helmet_leather; - if (type == 1) return Item::helmet_gold; - if (type == 2) return Item::helmet_chain; - if (type == 3) return Item::helmet_iron; - if (type == 4) return Item::helmet_diamond; + if (type == 0) return Item::leather_helmet; + if (type == 1) return Item::golden_helmet; + if (type == 2) return Item::chainmail_helmet; + if (type == 3) return Item::iron_helmet; + if (type == 4) return Item::diamond_helmet; case SLOT_CHEST: - if (type == 0) return Item::chestplate_leather; - if (type == 1) return Item::chestplate_gold; - if (type == 2) return Item::chestplate_chain; - if (type == 3) return Item::chestplate_iron; - if (type == 4) return Item::chestplate_diamond; + if (type == 0) return Item::leather_chestplate; + if (type == 1) return Item::golden_chestplate; + if (type == 2) return Item::chainmail_chestplate; + if (type == 3) return Item::iron_chestplate; + if (type == 4) return Item::diamond_chestplate; case SLOT_LEGGINGS: - if (type == 0) return Item::leggings_leather; - if (type == 1) return Item::leggings_gold; - if (type == 2) return Item::leggings_chain; - if (type == 3) return Item::leggings_iron; - if (type == 4) return Item::leggings_diamond; + if (type == 0) return Item::leather_leggings; + if (type == 1) return Item::golden_leggings; + if (type == 2) return Item::chainmail_leggings; + if (type == 3) return Item::iron_leggings; + if (type == 4) return Item::diamond_leggings; case SLOT_BOOTS: - if (type == 0) return Item::boots_leather; - if (type == 1) return Item::boots_gold; - if (type == 2) return Item::boots_chain; - if (type == 3) return Item::boots_iron; - if (type == 4) return Item::boots_diamond; + if (type == 0) return Item::leather_boots; + if (type == 1) return Item::golden_boots; + if (type == 2) return Item::chainmail_boots; + if (type == 3) return Item::iron_boots; + if (type == 4) return Item::diamond_boots; } return nullptr; diff --git a/Minecraft.World/MobSpawner.cpp b/Minecraft.World/MobSpawner.cpp index f43d9532..3afc4b3d 100644 --- a/Minecraft.World/MobSpawner.cpp +++ b/Minecraft.World/MobSpawner.cpp @@ -423,7 +423,7 @@ bool MobSpawner::isSpawnPositionOk(MobCategory *category, Level *level, int x, i { if (!level->isTopSolidBlocking(x, y - 1, z)) return false; int tt = level->getTile(x, y - 1, z); - return tt != Tile::unbreakable_Id && !level->isSolidBlockingTile(x, y, z) && !level->getMaterial(x, y, z)->isLiquid() && !level->isSolidBlockingTile(x, y + 1, z); + return tt != Tile::bedrock_Id && !level->isSolidBlockingTile(x, y, z) && !level->getMaterial(x, y, z)->isLiquid() && !level->isSolidBlockingTile(x, y + 1, z); } } diff --git a/Minecraft.World/MobSpawnerTileEntity.cpp b/Minecraft.World/MobSpawnerTileEntity.cpp index 1db58f41..1d3b02f2 100644 --- a/Minecraft.World/MobSpawnerTileEntity.cpp +++ b/Minecraft.World/MobSpawnerTileEntity.cpp @@ -11,7 +11,7 @@ MobSpawnerTileEntity::TileEntityMobSpawner::TileEntityMobSpawner(MobSpawnerTileE void MobSpawnerTileEntity::TileEntityMobSpawner::broadcastEvent(int id) { - m_parent->level->tileEvent(m_parent->x, m_parent->y, m_parent->z, Tile::mobSpawner_Id, id, 0); + m_parent->level->tileEvent(m_parent->x, m_parent->y, m_parent->z, Tile::mob_spawner_Id, id, 0); } Level *MobSpawnerTileEntity::TileEntityMobSpawner::getLevel() diff --git a/Minecraft.World/MonsterPlacerItem.cpp b/Minecraft.World/MonsterPlacerItem.cpp index f3cf2387..e20bb76b 100644 --- a/Minecraft.World/MonsterPlacerItem.cpp +++ b/Minecraft.World/MonsterPlacerItem.cpp @@ -176,11 +176,11 @@ bool MonsterPlacerItem::useOn(shared_ptr itemInstance, shared_ptr< int tile = level->getTile(x, y, z); #ifndef _CONTENT_PACKAGE - if(app.DebugSettingsOn() && tile == Tile::mobSpawner_Id) + if(app.DebugSettingsOn() && tile == Tile::mob_spawner_Id) { // 4J Stu - Force adding this as a tile update level->setTile(x,y,z,0); - level->setTile(x,y,z,Tile::mobSpawner_Id); + level->setTile(x,y,z,Tile::mob_spawner_Id); shared_ptr mste = dynamic_pointer_cast( level->getTileEntity(x,y,z) ); if(mste != NULL) { @@ -196,7 +196,7 @@ bool MonsterPlacerItem::useOn(shared_ptr itemInstance, shared_ptr< double yOff = 0; // 4J-PB - missing parentheses added - if (face == Facing::UP && (tile == Tile::fence_Id || tile == Tile::netherFence_Id)) + if (face == Facing::UP && (tile == Tile::fence_Id || tile == Tile::nether_brick_fence_Id)) { // special case yOff = .5; diff --git a/Minecraft.World/MonsterRoomFeature.cpp b/Minecraft.World/MonsterRoomFeature.cpp index e11ebcb2..a6c8ba71 100644 --- a/Minecraft.World/MonsterRoomFeature.cpp +++ b/Minecraft.World/MonsterRoomFeature.cpp @@ -10,20 +10,20 @@ WeighedTreasure *MonsterRoomFeature::monsterRoomTreasure[MonsterRoomFeature::TREASURE_ITEMS_COUNT] = { new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 10), - new WeighedTreasure(Item::ironIngot_Id, 0, 1, 4, 10), + new WeighedTreasure(Item::iron_ingot_Id, 0, 1, 4, 10), new WeighedTreasure(Item::bread_Id, 0, 1, 1, 10), new WeighedTreasure(Item::wheat_Id, 0, 1, 4, 10), new WeighedTreasure(Item::gunpowder_Id, 0, 1, 4, 10), new WeighedTreasure(Item::string_Id, 0, 1, 4, 10), - new WeighedTreasure(Item::bucket_empty_Id, 0, 1, 1, 10), - new WeighedTreasure(Item::apple_gold_Id, 0, 1, 1, 1), - new WeighedTreasure(Item::redStone_Id, 0, 1, 4, 10), - new WeighedTreasure(Item::record_01_Id, 0, 1, 1, 10), - new WeighedTreasure(Item::record_02_Id, 0, 1, 1, 10), - new WeighedTreasure(Item::nameTag_Id, 0, 1, 1, 10), - new WeighedTreasure(Item::horseArmorGold_Id, 0, 1, 1, 2), - new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 5), - new WeighedTreasure(Item::horseArmorDiamond_Id, 0, 1, 1, 1), + new WeighedTreasure(Item::bucket_Id, 0, 1, 1, 10), + new WeighedTreasure(Item::golden_apple_Id, 0, 1, 1, 1), + new WeighedTreasure(Item::redstone_Id, 0, 1, 4, 10), + new WeighedTreasure(Item::record_13_Id, 0, 1, 1, 10), + new WeighedTreasure(Item::record_cat_Id, 0, 1, 1, 10), + new WeighedTreasure(Item::name_tag_Id, 0, 1, 1, 10), + new WeighedTreasure(Item::golden_horse_armor_Id, 0, 1, 1, 2), + new WeighedTreasure(Item::iron_horse_armor_Id, 0, 1, 1, 5), + new WeighedTreasure(Item::diamond_horse_armor_Id, 0, 1, 1, 1), }; bool MonsterRoomFeature::place(Level *level, Random *random, int x, int y, int z) @@ -74,7 +74,7 @@ bool MonsterRoomFeature::place(Level *level, Random *random, int x, int y, int z { if (yy == y - 1 && random->nextInt(4) != 0) { - level->setTileAndData(xx, yy, zz, Tile::mossyCobblestone_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(xx, yy, zz, Tile::mossy_cobblestone_Id, 0, Tile::UPDATE_CLIENTS); } else { @@ -108,7 +108,7 @@ bool MonsterRoomFeature::place(Level *level, Random *random, int x, int y, int z level->setTileAndData(xc, yc, zc, Tile::chest_Id, 0, Tile::UPDATE_CLIENTS); WeighedTreasureArray wrapperArray(monsterRoomTreasure, TREASURE_ITEMS_COUNT); - WeighedTreasureArray treasure = WeighedTreasure::addToTreasure(wrapperArray, Item::enchantedBook->createForRandomTreasure(random)); + WeighedTreasureArray treasure = WeighedTreasure::addToTreasure(wrapperArray, Item::enchanted_book->createForRandomTreasure(random)); shared_ptr chest = dynamic_pointer_cast( level->getTileEntity(xc, yc, zc) ); if (chest != nullptr ) { @@ -120,7 +120,7 @@ bool MonsterRoomFeature::place(Level *level, Random *random, int x, int y, int z } - level->setTileAndData(x, y, z, Tile::mobSpawner_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y, z, Tile::mob_spawner_Id, 0, Tile::UPDATE_CLIENTS); shared_ptr entity = dynamic_pointer_cast( level->getTileEntity(x, y, z) ); if( entity != nullptr ) { diff --git a/Minecraft.World/Mushroom.cpp b/Minecraft.World/Mushroom.cpp index 91ba3f7a..72bcfd01 100644 --- a/Minecraft.World/Mushroom.cpp +++ b/Minecraft.World/Mushroom.cpp @@ -77,7 +77,7 @@ bool Mushroom::canSurvive(Level *level, int x, int y, int z) int below = level->getTile(x, y - 1, z); - return below == Tile::mycel_Id || (level->getDaytimeRawBrightness(x, y, z) < 13 && mayPlaceOn(below)); + return below == Tile::mycelium_Id || (level->getDaytimeRawBrightness(x, y, z) < 13 && mayPlaceOn(below)); } bool Mushroom::growTree(Level *level, int x, int y, int z, Random *random, bool naturalGrowth, int entityId) { diff --git a/Minecraft.World/MushroomCow.cpp b/Minecraft.World/MushroomCow.cpp index 6452e73d..45653285 100644 --- a/Minecraft.World/MushroomCow.cpp +++ b/Minecraft.World/MushroomCow.cpp @@ -28,11 +28,11 @@ bool MushroomCow::mobInteract(shared_ptr player) { if (item->count == 1) { - player->inventory->setItem(player->inventory->selected, std::make_shared(Item::mushroomStew)); + player->inventory->setItem(player->inventory->selected, std::make_shared(Item::mushroom_stew)); return true; } - if (player->inventory->add(std::make_shared(Item::mushroomStew)) && !player->abilities.instabuild) + if (player->inventory->add(std::make_shared(Item::mushroom_stew)) && !player->abilities.instabuild) { player->inventory->removeItem(player->inventory->selected, 1); return true; @@ -68,7 +68,7 @@ bool MushroomCow::canSpawn() int xt = Mth::floor(x); int yt = Mth::floor(bb->y0); int zt = Mth::floor(z); - return ( level->getTile(xt, yt - 1, zt) == Tile::grass_Id || level->getTile(xt, yt - 1, zt) == Tile::mycel_Id ) && level->getDaytimeRawBrightness(xt, yt, zt) > 8 && PathfinderMob::canSpawn(); + return ( level->getTile(xt, yt - 1, zt) == Tile::grass_Id || level->getTile(xt, yt - 1, zt) == Tile::mycelium_Id ) && level->getDaytimeRawBrightness(xt, yt, zt) > 8 && PathfinderMob::canSpawn(); } shared_ptr MushroomCow::getBreedOffspring(shared_ptr target) diff --git a/Minecraft.World/MushroomIslandBiome.cpp b/Minecraft.World/MushroomIslandBiome.cpp index 91bd8097..ce24f36f 100644 --- a/Minecraft.World/MushroomIslandBiome.cpp +++ b/Minecraft.World/MushroomIslandBiome.cpp @@ -13,7 +13,7 @@ MushroomIslandBiome::MushroomIslandBiome(int id) : Biome(id) decorator->mushroomCount = 1; decorator->hugeMushrooms = 1; - topMaterial = static_cast(Tile::mycel_Id); + topMaterial = static_cast(Tile::mycelium_Id); enemies.clear(); friendlies.clear(); diff --git a/Minecraft.World/NetherBridgePieces.cpp b/Minecraft.World/NetherBridgePieces.cpp index d9fbbf35..f75f67b1 100644 --- a/Minecraft.World/NetherBridgePieces.cpp +++ b/Minecraft.World/NetherBridgePieces.cpp @@ -138,16 +138,16 @@ NetherBridgePieces::NetherBridgePiece *NetherBridgePieces::findAndCreateBridgePi WeighedTreasure *NetherBridgePieces::NetherBridgePiece::fortressTreasureItems[FORTRESS_TREASURE_ITEMS_COUNT] = { new WeighedTreasure(Item::diamond_Id, 0, 1, 3, 5), - new WeighedTreasure(Item::ironIngot_Id, 0, 1, 5, 5), - new WeighedTreasure(Item::goldIngot_Id, 0, 1, 3, 15), - new WeighedTreasure(Item::sword_gold_Id, 0, 1, 1, 5), - new WeighedTreasure(Item::chestplate_gold_Id, 0, 1, 1, 5), - new WeighedTreasure(Item::flintAndSteel_Id, 0, 1, 1, 5), + new WeighedTreasure(Item::iron_ingot_Id, 0, 1, 5, 5), + new WeighedTreasure(Item::gold_ingot_Id, 0, 1, 3, 15), + new WeighedTreasure(Item::golden_sword_Id, 0, 1, 1, 5), + new WeighedTreasure(Item::golden_chestplate_Id, 0, 1, 1, 5), + new WeighedTreasure(Item::flint_and_steel_Id, 0, 1, 1, 5), new WeighedTreasure(Item::netherwart_seeds_Id, 0, 3, 7, 5), new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 10), - new WeighedTreasure(Item::horseArmorGold_Id, 0, 1, 1, 8), - new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 5), - new WeighedTreasure(Item::horseArmorDiamond_Id, 0, 1, 1, 3), + new WeighedTreasure(Item::golden_horse_armor_Id, 0, 1, 1, 8), + new WeighedTreasure(Item::iron_horse_armor_Id, 0, 1, 1, 5), + new WeighedTreasure(Item::diamond_horse_armor_Id, 0, 1, 1, 3), }; NetherBridgePieces::NetherBridgePiece::NetherBridgePiece() @@ -326,11 +326,11 @@ void NetherBridgePieces::NetherBridgePiece::generateLightPost(Level *level, Rand if (level->isEmptyTile(worldX, worldY, worldZ) && level->isEmptyTile(worldX, worldY + 1, worldZ) && level->isEmptyTile(worldX, worldY + 2, worldZ) && level->isEmptyTile(worldX, worldY + 3, worldZ)) { - level->setTileAndData(worldX, worldY, worldZ, Tile::netherFence_Id, 0, Tile::UPDATE_CLIENTS); - level->setTileAndData(worldX, worldY + 1, worldZ, Tile::netherFence_Id, 0, Tile::UPDATE_CLIENTS); - level->setTileAndData(worldX, worldY + 2, worldZ, Tile::netherFence_Id, 0, Tile::UPDATE_CLIENTS); - level->setTileAndData(worldX, worldY + 3, worldZ, Tile::netherFence_Id, 0, Tile::UPDATE_CLIENTS); - placeBlock(level, Tile::netherFence_Id, 0, x + xOff, y + 3, z + zOff, chunkBB); + level->setTileAndData(worldX, worldY, worldZ, Tile::nether_brick_fence_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(worldX, worldY + 1, worldZ, Tile::nether_brick_fence_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(worldX, worldY + 2, worldZ, Tile::nether_brick_fence_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(worldX, worldY + 3, worldZ, Tile::nether_brick_fence_Id, 0, Tile::UPDATE_CLIENTS); + placeBlock(level, Tile::nether_brick_fence_Id, 0, x + xOff, y + 3, z + zOff, chunkBB); placeBlock(level, Tile::glowstone_Id, 0, x + xOff, y + 2, z + zOff, chunkBB); } } @@ -390,37 +390,37 @@ NetherBridgePieces::BridgeStraight *NetherBridgePieces::BridgeStraight::createPi bool NetherBridgePieces::BridgeStraight::postProcess(Level *level, Random *random, BoundingBox *chunkBB) { // floor - generateBox(level, chunkBB, 0, 3, 0, width - 1, 4, depth - 1, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 3, 0, width - 1, 4, depth - 1, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // room air generateBox(level, chunkBB, 1, 5, 0, 3, 7, depth - 1, 0, 0, false); // hand rails - generateBox(level, chunkBB, 0, 5, 0, 0, 5, depth - 1, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 4, 5, 0, 4, 5, depth - 1, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 5, 0, 0, 5, depth - 1, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 4, 5, 0, 4, 5, depth - 1, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // supports - generateBox(level, chunkBB, 0, 2, 0, 4, 2, 5, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 2, 13, 4, 2, 18, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 0, 0, 4, 1, 3, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 0, 15, 4, 1, 18, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 2, 0, 4, 2, 5, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 2, 13, 4, 2, 18, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 0, 0, 4, 1, 3, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 0, 15, 4, 1, 18, Tile::nether_brick_Id, Tile::nether_brick_Id, false); for (int x = 0; x <= 4; x++) { for (int z = 0; z <= 2; z++) { - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, z, chunkBB); - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, 18 - z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, 18 - z, chunkBB); } } - generateBox(level, chunkBB, 0, 1, 1, 0, 4, 1, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 0, 3, 4, 0, 4, 4, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 0, 3, 14, 0, 4, 14, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 0, 1, 17, 0, 4, 17, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 4, 1, 1, 4, 4, 1, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 4, 3, 4, 4, 4, 4, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 4, 3, 14, 4, 4, 14, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 4, 1, 17, 4, 4, 17, Tile::netherFence_Id, Tile::netherFence_Id, false); + generateBox(level, chunkBB, 0, 1, 1, 0, 4, 1, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 0, 3, 4, 0, 4, 4, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 0, 3, 14, 0, 4, 14, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 0, 1, 17, 0, 4, 17, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 4, 1, 1, 4, 4, 1, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 4, 3, 4, 4, 4, 4, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 4, 3, 14, 4, 4, 14, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 4, 1, 17, 4, 4, 17, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); return true; } @@ -463,32 +463,32 @@ bool NetherBridgePieces::BridgeEndFiller::postProcess(Level *level, Random *rand for (int y = 3; y <= 4; y++) { int z = selfRandom->nextInt(8); - generateBox(level, chunkBB, x, y, 0, x, y, z, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, x, y, 0, x, y, z, Tile::nether_brick_Id, Tile::nether_brick_Id, false); } } // hand rails { int z = selfRandom->nextInt(8); - generateBox(level, chunkBB, 0, 5, 0, 0, 5, z, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 5, 0, 0, 5, z, Tile::nether_brick_Id, Tile::nether_brick_Id, false); } { int z = selfRandom->nextInt(8); - generateBox(level, chunkBB, 4, 5, 0, 4, 5, z, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 4, 5, 0, 4, 5, z, Tile::nether_brick_Id, Tile::nether_brick_Id, false); } // supports for (int x = 0; x <= 4; x++) { int z = selfRandom->nextInt(5); - generateBox(level, chunkBB, x, 2, 0, x, 2, z, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, x, 2, 0, x, 2, z, Tile::nether_brick_Id, Tile::nether_brick_Id, false); } for (int x = 0; x <= 4; x++) { for (int y = 0; y <= 1; y++) { int z = selfRandom->nextInt(3); - generateBox(level, chunkBB, x, y, 0, x, y, z, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, x, y, 0, x, y, z, Tile::nether_brick_Id, Tile::nether_brick_Id, false); } } @@ -564,45 +564,45 @@ NetherBridgePieces::BridgeCrossing *NetherBridgePieces::BridgeCrossing::createPi bool NetherBridgePieces::BridgeCrossing::postProcess(Level *level, Random *random, BoundingBox *chunkBB) { // floor - generateBox(level, chunkBB, 7, 3, 0, 11, 4, 18, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 3, 7, 18, 4, 11, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 7, 3, 0, 11, 4, 18, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 3, 7, 18, 4, 11, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // room air generateBox(level, chunkBB, 8, 5, 0, 10, 7, 18, 0, 0, false); generateBox(level, chunkBB, 0, 5, 8, 18, 7, 10, 0, 0, false); // hand rails - generateBox(level, chunkBB, 7, 5, 0, 7, 5, 7, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 7, 5, 11, 7, 5, 18, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 11, 5, 0, 11, 5, 7, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 11, 5, 11, 11, 5, 18, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 5, 7, 7, 5, 7, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 11, 5, 7, 18, 5, 7, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 5, 11, 7, 5, 11, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 11, 5, 11, 18, 5, 11, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 7, 5, 0, 7, 5, 7, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 7, 5, 11, 7, 5, 18, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 11, 5, 0, 11, 5, 7, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 11, 5, 11, 11, 5, 18, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 5, 7, 7, 5, 7, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 11, 5, 7, 18, 5, 7, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 5, 11, 7, 5, 11, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 11, 5, 11, 18, 5, 11, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // supports - generateBox(level, chunkBB, 7, 2, 0, 11, 2, 5, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 7, 2, 13, 11, 2, 18, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 7, 0, 0, 11, 1, 3, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 7, 0, 15, 11, 1, 18, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 7, 2, 0, 11, 2, 5, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 7, 2, 13, 11, 2, 18, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 7, 0, 0, 11, 1, 3, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 7, 0, 15, 11, 1, 18, Tile::nether_brick_Id, Tile::nether_brick_Id, false); for (int x = 7; x <= 11; x++) { for (int z = 0; z <= 2; z++) { - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, z, chunkBB); - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, 18 - z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, 18 - z, chunkBB); } } - generateBox(level, chunkBB, 0, 2, 7, 5, 2, 11, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 13, 2, 7, 18, 2, 11, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 0, 7, 3, 1, 11, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 15, 0, 7, 18, 1, 11, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 2, 7, 5, 2, 11, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 13, 2, 7, 18, 2, 11, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 0, 7, 3, 1, 11, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 15, 0, 7, 18, 1, 11, Tile::nether_brick_Id, Tile::nether_brick_Id, false); for (int x = 0; x <= 2; x++) { for (int z = 7; z <= 11; z++) { - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, z, chunkBB); - fillColumnDown(level, Tile::netherBrick_Id, 0, 18 - x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, 18 - x, -1, z, chunkBB); } } @@ -683,35 +683,35 @@ NetherBridgePieces::RoomCrossing *NetherBridgePieces::RoomCrossing::createPiece( bool NetherBridgePieces::RoomCrossing::postProcess(Level *level, Random *random, BoundingBox *chunkBB) { // floor - generateBox(level, chunkBB, 0, 0, 0, width - 1, 1, depth - 1, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 0, 0, width - 1, 1, depth - 1, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // room air generateBox(level, chunkBB, 0, 2, 0, 6, 7, 6, 0, 0, false); // walls - generateBox(level, chunkBB, 0, 2, 0, 1, 6, 0, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 2, 6, 1, 6, 6, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 5, 2, 0, 6, 6, 0, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 5, 2, 6, 6, 6, 6, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 2, 0, 0, 6, 1, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 2, 5, 0, 6, 6, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 6, 2, 0, 6, 6, 1, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 6, 2, 5, 6, 6, 6, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 2, 0, 1, 6, 0, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 2, 6, 1, 6, 6, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 5, 2, 0, 6, 6, 0, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 5, 2, 6, 6, 6, 6, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 2, 0, 0, 6, 1, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 2, 5, 0, 6, 6, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 6, 2, 0, 6, 6, 1, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 6, 2, 5, 6, 6, 6, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // entries - generateBox(level, chunkBB, 2, 6, 0, 4, 6, 0, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 2, 5, 0, 4, 5, 0, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 2, 6, 6, 4, 6, 6, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 2, 5, 6, 4, 5, 6, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 0, 6, 2, 0, 6, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 5, 2, 0, 5, 4, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 6, 6, 2, 6, 6, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 6, 5, 2, 6, 5, 4, Tile::netherFence_Id, Tile::netherFence_Id, false); + generateBox(level, chunkBB, 2, 6, 0, 4, 6, 0, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 2, 5, 0, 4, 5, 0, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 2, 6, 6, 4, 6, 6, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 2, 5, 6, 4, 5, 6, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 0, 6, 2, 0, 6, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 5, 2, 0, 5, 4, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 6, 6, 2, 6, 6, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 6, 5, 2, 6, 5, 4, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); for (int x = 0; x <= 6; x++) { for (int z = 0; z <= 6; z++) { - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, z, chunkBB); } } @@ -753,42 +753,42 @@ NetherBridgePieces::StairsRoom *NetherBridgePieces::StairsRoom::createPiece(list bool NetherBridgePieces::StairsRoom::postProcess(Level *level, Random *random, BoundingBox *chunkBB) { // floor - generateBox(level, chunkBB, 0, 0, 0, width - 1, 1, depth - 1, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 0, 0, width - 1, 1, depth - 1, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // room air generateBox(level, chunkBB, 0, 2, 0, 6, 10, 6, 0, 0, false); // walls - generateBox(level, chunkBB, 0, 2, 0, 1, 8, 0, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 5, 2, 0, 6, 8, 0, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 2, 1, 0, 8, 6, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 6, 2, 1, 6, 8, 6, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 1, 2, 6, 5, 8, 6, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 2, 0, 1, 8, 0, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 5, 2, 0, 6, 8, 0, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 2, 1, 0, 8, 6, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 6, 2, 1, 6, 8, 6, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 1, 2, 6, 5, 8, 6, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // wall decorations - generateBox(level, chunkBB, 0, 3, 2, 0, 5, 4, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 6, 3, 2, 6, 5, 2, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 6, 3, 4, 6, 5, 4, Tile::netherFence_Id, Tile::netherFence_Id, false); + generateBox(level, chunkBB, 0, 3, 2, 0, 5, 4, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 6, 3, 2, 6, 5, 2, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 6, 3, 4, 6, 5, 4, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); // stair - placeBlock(level, Tile::netherBrick_Id, 0, 5, 2, 5, chunkBB); - generateBox(level, chunkBB, 4, 2, 5, 4, 3, 5, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 3, 2, 5, 3, 4, 5, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 2, 2, 5, 2, 5, 5, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 1, 2, 5, 1, 6, 5, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + placeBlock(level, Tile::nether_brick_Id, 0, 5, 2, 5, chunkBB); + generateBox(level, chunkBB, 4, 2, 5, 4, 3, 5, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 3, 2, 5, 3, 4, 5, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 2, 2, 5, 2, 5, 5, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 1, 2, 5, 1, 6, 5, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // top floor - generateBox(level, chunkBB, 1, 7, 1, 5, 7, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 1, 7, 1, 5, 7, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); generateBox(level, chunkBB, 6, 8, 2, 6, 8, 4, 0, 0, false); // entries - generateBox(level, chunkBB, 2, 6, 0, 4, 8, 0, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 2, 5, 0, 4, 5, 0, Tile::netherFence_Id, Tile::netherFence_Id, false); + generateBox(level, chunkBB, 2, 6, 0, 4, 8, 0, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 2, 5, 0, 4, 5, 0, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); for (int x = 0; x <= 6; x++) { for (int z = 0; z <= 6; z++) { - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, z, chunkBB); } } @@ -843,26 +843,26 @@ bool NetherBridgePieces::MonsterThrone::postProcess(Level *level, Random *random generateBox(level, chunkBB, 0, 2, 0, 6, 7, 7, 0, 0, false); // floors - generateBox(level, chunkBB, 1, 0, 0, 5, 1, 7, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 1, 2, 1, 5, 2, 7, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 1, 3, 2, 5, 3, 7, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 1, 4, 3, 5, 4, 7, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 1, 0, 0, 5, 1, 7, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 1, 2, 1, 5, 2, 7, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 1, 3, 2, 5, 3, 7, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 1, 4, 3, 5, 4, 7, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // rails - generateBox(level, chunkBB, 1, 2, 0, 1, 4, 2, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 5, 2, 0, 5, 4, 2, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 1, 5, 2, 1, 5, 3, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 5, 5, 2, 5, 5, 3, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 5, 3, 0, 5, 8, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 6, 5, 3, 6, 5, 8, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 1, 5, 8, 5, 5, 8, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 1, 2, 0, 1, 4, 2, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 5, 2, 0, 5, 4, 2, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 1, 5, 2, 1, 5, 3, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 5, 5, 2, 5, 5, 3, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 5, 3, 0, 5, 8, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 6, 5, 3, 6, 5, 8, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 1, 5, 8, 5, 5, 8, Tile::nether_brick_Id, Tile::nether_brick_Id, false); - placeBlock(level, Tile::netherFence_Id, 0, 1, 6, 3, chunkBB); - placeBlock(level, Tile::netherFence_Id, 0, 5, 6, 3, chunkBB); - generateBox(level, chunkBB, 0, 6, 3, 0, 6, 8, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 6, 6, 3, 6, 6, 8, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 1, 6, 8, 5, 7, 8, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 2, 8, 8, 4, 8, 8, Tile::netherFence_Id, Tile::netherFence_Id, false); + placeBlock(level, Tile::nether_brick_fence_Id, 0, 1, 6, 3, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, 5, 6, 3, chunkBB); + generateBox(level, chunkBB, 0, 6, 3, 0, 6, 8, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 6, 6, 3, 6, 6, 8, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 1, 6, 8, 5, 7, 8, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 2, 8, 8, 4, 8, 8, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); if (!hasPlacedMobSpawner) @@ -871,7 +871,7 @@ bool NetherBridgePieces::MonsterThrone::postProcess(Level *level, Random *random if (chunkBB->isInside(x, y, z)) { hasPlacedMobSpawner = true; - level->setTileAndData(x, y, z, Tile::mobSpawner_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y, z, Tile::mob_spawner_Id, 0, Tile::UPDATE_CLIENTS); shared_ptr entity = dynamic_pointer_cast( level->getTileEntity(x, y, z) ); if (entity != nullptr) entity->getSpawner()->setEntityId(L"Blaze"); } @@ -881,7 +881,7 @@ bool NetherBridgePieces::MonsterThrone::postProcess(Level *level, Random *random { for (int z = 0; z <= 6; z++) { - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, z, chunkBB); } } @@ -923,85 +923,85 @@ NetherBridgePieces::CastleEntrance *NetherBridgePieces::CastleEntrance::createPi bool NetherBridgePieces::CastleEntrance::postProcess(Level *level, Random *random, BoundingBox *chunkBB) { // floor - generateBox(level, chunkBB, 0, 3, 0, 12, 4, 12, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 3, 0, 12, 4, 12, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // room air generateBox(level, chunkBB, 0, 5, 0, 12, 13, 12, 0, 0, false); // walls - generateBox(level, chunkBB, 0, 5, 0, 1, 12, 12, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 11, 5, 0, 12, 12, 12, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 2, 5, 11, 4, 12, 12, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 8, 5, 11, 10, 12, 12, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 5, 9, 11, 7, 12, 12, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 2, 5, 0, 4, 12, 1, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 8, 5, 0, 10, 12, 1, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 5, 9, 0, 7, 12, 1, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 5, 0, 1, 12, 12, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 11, 5, 0, 12, 12, 12, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 2, 5, 11, 4, 12, 12, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 8, 5, 11, 10, 12, 12, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 5, 9, 11, 7, 12, 12, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 2, 5, 0, 4, 12, 1, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 8, 5, 0, 10, 12, 1, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 5, 9, 0, 7, 12, 1, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // roof - generateBox(level, chunkBB, 2, 11, 2, 10, 12, 10, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 2, 11, 2, 10, 12, 10, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // entrance decoration - generateBox(level, chunkBB, 5, 8, 0, 7, 8, 0, Tile::netherFence_Id, Tile::netherFence_Id, false); + generateBox(level, chunkBB, 5, 8, 0, 7, 8, 0, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); // wall decorations for (int i = 1; i <= 11; i += 2) { - generateBox(level, chunkBB, i, 10, 0, i, 11, 0, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, i, 10, 12, i, 11, 12, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 0, 10, i, 0, 11, i, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 12, 10, i, 12, 11, i, Tile::netherFence_Id, Tile::netherFence_Id, false); - placeBlock(level, Tile::netherBrick_Id, 0, i, 13, 0, chunkBB); - placeBlock(level, Tile::netherBrick_Id, 0, i, 13, 12, chunkBB); - placeBlock(level, Tile::netherBrick_Id, 0, 0, 13, i, chunkBB); - placeBlock(level, Tile::netherBrick_Id, 0, 12, 13, i, chunkBB); - placeBlock(level, Tile::netherFence_Id, 0, i + 1, 13, 0, chunkBB); - placeBlock(level, Tile::netherFence_Id, 0, i + 1, 13, 12, chunkBB); - placeBlock(level, Tile::netherFence_Id, 0, 0, 13, i + 1, chunkBB); - placeBlock(level, Tile::netherFence_Id, 0, 12, 13, i + 1, chunkBB); + generateBox(level, chunkBB, i, 10, 0, i, 11, 0, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, i, 10, 12, i, 11, 12, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 0, 10, i, 0, 11, i, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 12, 10, i, 12, 11, i, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + placeBlock(level, Tile::nether_brick_Id, 0, i, 13, 0, chunkBB); + placeBlock(level, Tile::nether_brick_Id, 0, i, 13, 12, chunkBB); + placeBlock(level, Tile::nether_brick_Id, 0, 0, 13, i, chunkBB); + placeBlock(level, Tile::nether_brick_Id, 0, 12, 13, i, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, i + 1, 13, 0, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, i + 1, 13, 12, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, 0, 13, i + 1, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, 12, 13, i + 1, chunkBB); } - placeBlock(level, Tile::netherFence_Id, 0, 0, 13, 0, chunkBB); - placeBlock(level, Tile::netherFence_Id, 0, 0, 13, 12, chunkBB); - placeBlock(level, Tile::netherFence_Id, 0, 0, 13, 0, chunkBB); - placeBlock(level, Tile::netherFence_Id, 0, 12, 13, 0, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, 0, 13, 0, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, 0, 13, 12, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, 0, 13, 0, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, 12, 13, 0, chunkBB); // inside decorations for (int z = 3; z <= 9; z += 2) { - generateBox(level, chunkBB, 1, 7, z, 1, 8, z, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 11, 7, z, 11, 8, z, Tile::netherFence_Id, Tile::netherFence_Id, false); + generateBox(level, chunkBB, 1, 7, z, 1, 8, z, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 11, 7, z, 11, 8, z, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); } // supports - generateBox(level, chunkBB, 4, 2, 0, 8, 2, 12, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 2, 4, 12, 2, 8, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 4, 2, 0, 8, 2, 12, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 2, 4, 12, 2, 8, Tile::nether_brick_Id, Tile::nether_brick_Id, false); - generateBox(level, chunkBB, 4, 0, 0, 8, 1, 3, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 4, 0, 9, 8, 1, 12, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 0, 4, 3, 1, 8, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 9, 0, 4, 12, 1, 8, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 4, 0, 0, 8, 1, 3, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 4, 0, 9, 8, 1, 12, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 0, 4, 3, 1, 8, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 9, 0, 4, 12, 1, 8, Tile::nether_brick_Id, Tile::nether_brick_Id, false); for (int x = 4; x <= 8; x++) { for (int z = 0; z <= 2; z++) { - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, z, chunkBB); - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, 12 - z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, 12 - z, chunkBB); } } for (int x = 0; x <= 2; x++) { for (int z = 4; z <= 8; z++) { - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, z, chunkBB); - fillColumnDown(level, Tile::netherBrick_Id, 0, 12 - x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, 12 - x, -1, z, chunkBB); } } // lava well - generateBox(level, chunkBB, 5, 5, 5, 7, 5, 7, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 5, 5, 5, 7, 5, 7, Tile::nether_brick_Id, Tile::nether_brick_Id, false); generateBox(level, chunkBB, 6, 1, 6, 6, 4, 6, 0, 0, false); - placeBlock(level, Tile::netherBrick_Id, 0, 6, 0, 6, chunkBB); - placeBlock(level, Tile::lava_Id, 0, 6, 5, 6, chunkBB); + placeBlock(level, Tile::nether_brick_Id, 0, 6, 0, 6, chunkBB); + placeBlock(level, Tile::flowing_lava_Id, 0, 6, 5, 6, chunkBB); // tick lava well int x = getWorldX(6, 6); int y = getWorldY(5); @@ -1009,7 +1009,7 @@ bool NetherBridgePieces::CastleEntrance::postProcess(Level *level, Random *rando if (chunkBB->isInside(x, y, z)) { level->setInstaTick(true); - Tile::tiles[Tile::lava_Id]->tick(level, x, y, z, random); + Tile::tiles[Tile::flowing_lava_Id]->tick(level, x, y, z, random); level->setInstaTick(false); } @@ -1053,67 +1053,67 @@ NetherBridgePieces::CastleStalkRoom *NetherBridgePieces::CastleStalkRoom::create bool NetherBridgePieces::CastleStalkRoom::postProcess(Level *level, Random *random, BoundingBox *chunkBB) { // floor - generateBox(level, chunkBB, 0, 3, 0, 12, 4, 12, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 3, 0, 12, 4, 12, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // room air generateBox(level, chunkBB, 0, 5, 0, 12, 13, 12, 0, 0, false); // walls - generateBox(level, chunkBB, 0, 5, 0, 1, 12, 12, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 11, 5, 0, 12, 12, 12, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 2, 5, 11, 4, 12, 12, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 8, 5, 11, 10, 12, 12, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 5, 9, 11, 7, 12, 12, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 2, 5, 0, 4, 12, 1, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 8, 5, 0, 10, 12, 1, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 5, 9, 0, 7, 12, 1, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 5, 0, 1, 12, 12, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 11, 5, 0, 12, 12, 12, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 2, 5, 11, 4, 12, 12, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 8, 5, 11, 10, 12, 12, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 5, 9, 11, 7, 12, 12, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 2, 5, 0, 4, 12, 1, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 8, 5, 0, 10, 12, 1, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 5, 9, 0, 7, 12, 1, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // roof - generateBox(level, chunkBB, 2, 11, 2, 10, 12, 10, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 2, 11, 2, 10, 12, 10, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // wall decorations for (int i = 1; i <= 11; i += 2) { - generateBox(level, chunkBB, i, 10, 0, i, 11, 0, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, i, 10, 12, i, 11, 12, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 0, 10, i, 0, 11, i, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 12, 10, i, 12, 11, i, Tile::netherFence_Id, Tile::netherFence_Id, false); - placeBlock(level, Tile::netherBrick_Id, 0, i, 13, 0, chunkBB); - placeBlock(level, Tile::netherBrick_Id, 0, i, 13, 12, chunkBB); - placeBlock(level, Tile::netherBrick_Id, 0, 0, 13, i, chunkBB); - placeBlock(level, Tile::netherBrick_Id, 0, 12, 13, i, chunkBB); - placeBlock(level, Tile::netherFence_Id, 0, i + 1, 13, 0, chunkBB); - placeBlock(level, Tile::netherFence_Id, 0, i + 1, 13, 12, chunkBB); - placeBlock(level, Tile::netherFence_Id, 0, 0, 13, i + 1, chunkBB); - placeBlock(level, Tile::netherFence_Id, 0, 12, 13, i + 1, chunkBB); + generateBox(level, chunkBB, i, 10, 0, i, 11, 0, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, i, 10, 12, i, 11, 12, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 0, 10, i, 0, 11, i, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 12, 10, i, 12, 11, i, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + placeBlock(level, Tile::nether_brick_Id, 0, i, 13, 0, chunkBB); + placeBlock(level, Tile::nether_brick_Id, 0, i, 13, 12, chunkBB); + placeBlock(level, Tile::nether_brick_Id, 0, 0, 13, i, chunkBB); + placeBlock(level, Tile::nether_brick_Id, 0, 12, 13, i, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, i + 1, 13, 0, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, i + 1, 13, 12, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, 0, 13, i + 1, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, 12, 13, i + 1, chunkBB); } - placeBlock(level, Tile::netherFence_Id, 0, 0, 13, 0, chunkBB); - placeBlock(level, Tile::netherFence_Id, 0, 0, 13, 12, chunkBB); - placeBlock(level, Tile::netherFence_Id, 0, 0, 13, 0, chunkBB); - placeBlock(level, Tile::netherFence_Id, 0, 12, 13, 0, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, 0, 13, 0, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, 0, 13, 12, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, 0, 13, 0, chunkBB); + placeBlock(level, Tile::nether_brick_fence_Id, 0, 12, 13, 0, chunkBB); // inside decorations for (int z = 3; z <= 9; z += 2) { - generateBox(level, chunkBB, 1, 7, z, 1, 8, z, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 11, 7, z, 11, 8, z, Tile::netherFence_Id, Tile::netherFence_Id, false); + generateBox(level, chunkBB, 1, 7, z, 1, 8, z, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 11, 7, z, 11, 8, z, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); } // inside stair - int stairOrientation = getOrientationData(Tile::stairs_netherBricks_Id, 3); + int stairOrientation = getOrientationData(Tile::nether_brick_stairs_Id, 3); for (int i = 0; i <= 6; i++) { int z = i + 4; for (int x = 5; x <= 7; x++) { - placeBlock(level, Tile::stairs_netherBricks_Id, stairOrientation, x, 5 + i, z, chunkBB); + placeBlock(level, Tile::nether_brick_stairs_Id, stairOrientation, x, 5 + i, z, chunkBB); } if (z >= 5 && z <= 8) { - generateBox(level, chunkBB, 5, 5, z, 7, i + 4, z, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 5, 5, z, 7, i + 4, z, Tile::nether_brick_Id, Tile::nether_brick_Id, false); } else if (z >= 9 && z <= 10) { - generateBox(level, chunkBB, 5, 8, z, 7, i + 4, z, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 5, 8, z, 7, i + 4, z, Tile::nether_brick_Id, Tile::nether_brick_Id, false); } if (i >= 1) { @@ -1122,59 +1122,59 @@ bool NetherBridgePieces::CastleStalkRoom::postProcess(Level *level, Random *rand } for (int x = 5; x <= 7; x++) { - placeBlock(level, Tile::stairs_netherBricks_Id, stairOrientation, x, 12, 11, chunkBB); + placeBlock(level, Tile::nether_brick_stairs_Id, stairOrientation, x, 12, 11, chunkBB); } - generateBox(level, chunkBB, 5, 6, 7, 5, 7, 7, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 7, 6, 7, 7, 7, 7, Tile::netherFence_Id, Tile::netherFence_Id, false); + generateBox(level, chunkBB, 5, 6, 7, 5, 7, 7, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 7, 6, 7, 7, 7, 7, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); generateBox(level, chunkBB, 5, 13, 12, 7, 13, 12, 0, 0, false); // farmland catwalks - generateBox(level, chunkBB, 2, 5, 2, 3, 5, 3, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 2, 5, 9, 3, 5, 10, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 2, 5, 4, 2, 5, 8, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 9, 5, 2, 10, 5, 3, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 9, 5, 9, 10, 5, 10, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 10, 5, 4, 10, 5, 8, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - int eastOrientation = getOrientationData(Tile::stairs_netherBricks_Id, 0); - int westOrientation = getOrientationData(Tile::stairs_netherBricks_Id, 1); - placeBlock(level, Tile::stairs_netherBricks_Id, westOrientation, 4, 5, 2, chunkBB); - placeBlock(level, Tile::stairs_netherBricks_Id, westOrientation, 4, 5, 3, chunkBB); - placeBlock(level, Tile::stairs_netherBricks_Id, westOrientation, 4, 5, 9, chunkBB); - placeBlock(level, Tile::stairs_netherBricks_Id, westOrientation, 4, 5, 10, chunkBB); - placeBlock(level, Tile::stairs_netherBricks_Id, eastOrientation, 8, 5, 2, chunkBB); - placeBlock(level, Tile::stairs_netherBricks_Id, eastOrientation, 8, 5, 3, chunkBB); - placeBlock(level, Tile::stairs_netherBricks_Id, eastOrientation, 8, 5, 9, chunkBB); - placeBlock(level, Tile::stairs_netherBricks_Id, eastOrientation, 8, 5, 10, chunkBB); + generateBox(level, chunkBB, 2, 5, 2, 3, 5, 3, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 2, 5, 9, 3, 5, 10, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 2, 5, 4, 2, 5, 8, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 9, 5, 2, 10, 5, 3, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 9, 5, 9, 10, 5, 10, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 10, 5, 4, 10, 5, 8, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + int eastOrientation = getOrientationData(Tile::nether_brick_stairs_Id, 0); + int westOrientation = getOrientationData(Tile::nether_brick_stairs_Id, 1); + placeBlock(level, Tile::nether_brick_stairs_Id, westOrientation, 4, 5, 2, chunkBB); + placeBlock(level, Tile::nether_brick_stairs_Id, westOrientation, 4, 5, 3, chunkBB); + placeBlock(level, Tile::nether_brick_stairs_Id, westOrientation, 4, 5, 9, chunkBB); + placeBlock(level, Tile::nether_brick_stairs_Id, westOrientation, 4, 5, 10, chunkBB); + placeBlock(level, Tile::nether_brick_stairs_Id, eastOrientation, 8, 5, 2, chunkBB); + placeBlock(level, Tile::nether_brick_stairs_Id, eastOrientation, 8, 5, 3, chunkBB); + placeBlock(level, Tile::nether_brick_stairs_Id, eastOrientation, 8, 5, 9, chunkBB); + placeBlock(level, Tile::nether_brick_stairs_Id, eastOrientation, 8, 5, 10, chunkBB); // farmlands - generateBox(level, chunkBB, 3, 4, 4, 4, 4, 8, Tile::soulsand_Id, Tile::soulsand_Id, false); - generateBox(level, chunkBB, 8, 4, 4, 9, 4, 8, Tile::soulsand_Id, Tile::soulsand_Id, false); - generateBox(level, chunkBB, 3, 5, 4, 4, 5, 8, Tile::netherStalk_Id, Tile::netherStalk_Id, false); - generateBox(level, chunkBB, 8, 5, 4, 9, 5, 8, Tile::netherStalk_Id, Tile::netherStalk_Id, false); + generateBox(level, chunkBB, 3, 4, 4, 4, 4, 8, Tile::soul_sand_Id, Tile::soul_sand_Id, false); + generateBox(level, chunkBB, 8, 4, 4, 9, 4, 8, Tile::soul_sand_Id, Tile::soul_sand_Id, false); + generateBox(level, chunkBB, 3, 5, 4, 4, 5, 8, Tile::nether_wart_Id, Tile::nether_wart_Id, false); + generateBox(level, chunkBB, 8, 5, 4, 9, 5, 8, Tile::nether_wart_Id, Tile::nether_wart_Id, false); // supports - generateBox(level, chunkBB, 4, 2, 0, 8, 2, 12, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 2, 4, 12, 2, 8, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 4, 2, 0, 8, 2, 12, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 2, 4, 12, 2, 8, Tile::nether_brick_Id, Tile::nether_brick_Id, false); - generateBox(level, chunkBB, 4, 0, 0, 8, 1, 3, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 4, 0, 9, 8, 1, 12, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 0, 4, 3, 1, 8, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 9, 0, 4, 12, 1, 8, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 4, 0, 0, 8, 1, 3, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 4, 0, 9, 8, 1, 12, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 0, 4, 3, 1, 8, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 9, 0, 4, 12, 1, 8, Tile::nether_brick_Id, Tile::nether_brick_Id, false); for (int x = 4; x <= 8; x++) { for (int z = 0; z <= 2; z++) { - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, z, chunkBB); - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, 12 - z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, 12 - z, chunkBB); } } for (int x = 0; x <= 2; x++) { for (int z = 4; z <= 8; z++) { - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, z, chunkBB); - fillColumnDown(level, Tile::netherBrick_Id, 0, 12 - x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, 12 - x, -1, z, chunkBB); } } @@ -1219,27 +1219,27 @@ NetherBridgePieces::CastleSmallCorridorPiece *NetherBridgePieces::CastleSmallCor bool NetherBridgePieces::CastleSmallCorridorPiece::postProcess(Level *level, Random *random, BoundingBox *chunkBB) { // floor - generateBox(level, chunkBB, 0, 0, 0, 4, 1, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 0, 0, 4, 1, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // room air generateBox(level, chunkBB, 0, 2, 0, 4, 5, 4, 0, 0, false); // walls - generateBox(level, chunkBB, 0, 2, 0, 0, 5, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 4, 2, 0, 4, 5, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 3, 1, 0, 4, 1, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 0, 3, 3, 0, 4, 3, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 4, 3, 1, 4, 4, 1, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 4, 3, 3, 4, 4, 3, Tile::netherFence_Id, Tile::netherFence_Id, false); + generateBox(level, chunkBB, 0, 2, 0, 0, 5, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 4, 2, 0, 4, 5, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 3, 1, 0, 4, 1, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 0, 3, 3, 0, 4, 3, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 4, 3, 1, 4, 4, 1, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 4, 3, 3, 4, 4, 3, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); // roof - generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // supports for (int x = 0; x <= 4; x++) { for (int z = 0; z <= 4; z++) { - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, z, chunkBB); } } @@ -1283,25 +1283,25 @@ NetherBridgePieces::CastleSmallCorridorCrossingPiece *NetherBridgePieces::Castle bool NetherBridgePieces::CastleSmallCorridorCrossingPiece::postProcess(Level *level, Random *random, BoundingBox *chunkBB) { // floor - generateBox(level, chunkBB, 0, 0, 0, 4, 1, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 0, 0, 4, 1, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // room air generateBox(level, chunkBB, 0, 2, 0, 4, 5, 4, 0, 0, false); // walls - generateBox(level, chunkBB, 0, 2, 0, 0, 5, 0, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 4, 2, 0, 4, 5, 0, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 2, 4, 0, 5, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 4, 2, 4, 4, 5, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 2, 0, 0, 5, 0, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 4, 2, 0, 4, 5, 0, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 2, 4, 0, 5, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 4, 2, 4, 4, 5, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // roof - generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // supports for (int x = 0; x <= 4; x++) { for (int z = 0; z <= 4; z++) { - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, z, chunkBB); } } @@ -1359,20 +1359,20 @@ NetherBridgePieces::CastleSmallCorridorRightTurnPiece *NetherBridgePieces::Castl bool NetherBridgePieces::CastleSmallCorridorRightTurnPiece::postProcess(Level *level, Random *random, BoundingBox *chunkBB) { // floor - generateBox(level, chunkBB, 0, 0, 0, 4, 1, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 0, 0, 4, 1, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // room air generateBox(level, chunkBB, 0, 2, 0, 4, 5, 4, 0, 0, false); // walls - generateBox(level, chunkBB, 0, 2, 0, 0, 5, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 0, 3, 1, 0, 4, 1, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 0, 3, 3, 0, 4, 3, Tile::netherFence_Id, Tile::netherFence_Id, false); + generateBox(level, chunkBB, 0, 2, 0, 0, 5, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 0, 3, 1, 0, 4, 1, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 0, 3, 3, 0, 4, 3, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); - generateBox(level, chunkBB, 4, 2, 0, 4, 5, 0, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 4, 2, 0, 4, 5, 0, Tile::nether_brick_Id, Tile::nether_brick_Id, false); - generateBox(level, chunkBB, 1, 2, 4, 4, 5, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 1, 3, 4, 1, 4, 4, Tile::netherFence_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 3, 3, 4, 3, 4, 4, Tile::netherFence_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 1, 2, 4, 4, 5, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 1, 3, 4, 1, 4, 4, Tile::nether_brick_fence_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 3, 3, 4, 3, 4, 4, Tile::nether_brick_fence_Id, Tile::nether_brick_Id, false); if (isNeedingChest) { @@ -1386,14 +1386,14 @@ bool NetherBridgePieces::CastleSmallCorridorRightTurnPiece::postProcess(Level *l } // roof - generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // supports for (int x = 0; x <= 4; x++) { for (int z = 0; z <= 4; z++) { - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, z, chunkBB); } } @@ -1451,20 +1451,20 @@ NetherBridgePieces::CastleSmallCorridorLeftTurnPiece *NetherBridgePieces::Castle bool NetherBridgePieces::CastleSmallCorridorLeftTurnPiece::postProcess(Level *level, Random *random, BoundingBox *chunkBB) { // floor - generateBox(level, chunkBB, 0, 0, 0, 4, 1, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 0, 0, 4, 1, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // room air generateBox(level, chunkBB, 0, 2, 0, 4, 5, 4, 0, 0, false); // walls - generateBox(level, chunkBB, 4, 2, 0, 4, 5, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 4, 3, 1, 4, 4, 1, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 4, 3, 3, 4, 4, 3, Tile::netherFence_Id, Tile::netherFence_Id, false); + generateBox(level, chunkBB, 4, 2, 0, 4, 5, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 4, 3, 1, 4, 4, 1, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 4, 3, 3, 4, 4, 3, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); - generateBox(level, chunkBB, 0, 2, 0, 0, 5, 0, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 2, 0, 0, 5, 0, Tile::nether_brick_Id, Tile::nether_brick_Id, false); - generateBox(level, chunkBB, 0, 2, 4, 3, 5, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 1, 3, 4, 1, 4, 4, Tile::netherFence_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 3, 3, 4, 3, 4, 4, Tile::netherFence_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 2, 4, 3, 5, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 1, 3, 4, 1, 4, 4, Tile::nether_brick_fence_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 3, 3, 4, 3, 4, 4, Tile::nether_brick_fence_Id, Tile::nether_brick_Id, false); if (isNeedingChest) { @@ -1478,14 +1478,14 @@ bool NetherBridgePieces::CastleSmallCorridorLeftTurnPiece::postProcess(Level *le } // roof - generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // supports for (int x = 0; x <= 4; x++) { for (int z = 0; z <= 4; z++) { - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, z, chunkBB); } } @@ -1527,7 +1527,7 @@ NetherBridgePieces::CastleCorridorStairsPiece *NetherBridgePieces::CastleCorrido bool NetherBridgePieces::CastleCorridorStairsPiece::postProcess(Level *level, Random *random, BoundingBox *chunkBB) { // generate stairs - int stairsData = getOrientationData(Tile::stairs_netherBricks_Id, 2); + int stairsData = getOrientationData(Tile::nether_brick_stairs_Id, 2); for (int step = 0; step <= 9; step++) { int floor = max(1, 7 - step); @@ -1535,30 +1535,30 @@ bool NetherBridgePieces::CastleCorridorStairsPiece::postProcess(Level *level, Ra int z = step; // floor - generateBox(level, chunkBB, 0, 0, z, 4, floor, z, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 0, z, 4, floor, z, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // room air generateBox(level, chunkBB, 1, floor + 1, z, 3, roof - 1, z, 0, 0, false); if (step <= 6) { - placeBlock(level, Tile::stairs_netherBricks_Id, stairsData, 1, floor + 1, z, chunkBB); - placeBlock(level, Tile::stairs_netherBricks_Id, stairsData, 2, floor + 1, z, chunkBB); - placeBlock(level, Tile::stairs_netherBricks_Id, stairsData, 3, floor + 1, z, chunkBB); + placeBlock(level, Tile::nether_brick_stairs_Id, stairsData, 1, floor + 1, z, chunkBB); + placeBlock(level, Tile::nether_brick_stairs_Id, stairsData, 2, floor + 1, z, chunkBB); + placeBlock(level, Tile::nether_brick_stairs_Id, stairsData, 3, floor + 1, z, chunkBB); } // roof - generateBox(level, chunkBB, 0, roof, z, 4, roof, z, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, roof, z, 4, roof, z, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // walls - generateBox(level, chunkBB, 0, floor + 1, z, 0, roof - 1, z, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 4, floor + 1, z, 4, roof - 1, z, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, floor + 1, z, 0, roof - 1, z, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 4, floor + 1, z, 4, roof - 1, z, Tile::nether_brick_Id, Tile::nether_brick_Id, false); if ((step & 1) == 0) { - generateBox(level, chunkBB, 0, floor + 2, z, 0, floor + 3, z, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 4, floor + 2, z, 4, floor + 3, z, Tile::netherFence_Id, Tile::netherFence_Id, false); + generateBox(level, chunkBB, 0, floor + 2, z, 0, floor + 3, z, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 4, floor + 2, z, 4, floor + 3, z, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); } // supports for (int x = 0; x <= 4; x++) { - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, z, chunkBB); } } @@ -1609,42 +1609,42 @@ NetherBridgePieces::CastleCorridorTBalconyPiece *NetherBridgePieces::CastleCorri bool NetherBridgePieces::CastleCorridorTBalconyPiece::postProcess(Level *level, Random *random, BoundingBox *chunkBB) { // floor - generateBox(level, chunkBB, 0, 0, 0, 8, 1, 8, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 0, 0, 8, 1, 8, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // room air generateBox(level, chunkBB, 0, 2, 0, 8, 5, 8, 0, 0, false); // corridor roof - generateBox(level, chunkBB, 0, 6, 0, 8, 6, 5, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 6, 0, 8, 6, 5, Tile::nether_brick_Id, Tile::nether_brick_Id, false); // inside walls - generateBox(level, chunkBB, 0, 2, 0, 2, 5, 0, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 6, 2, 0, 8, 5, 0, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 1, 3, 0, 1, 4, 0, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 7, 3, 0, 7, 4, 0, Tile::netherFence_Id, Tile::netherFence_Id, false); + generateBox(level, chunkBB, 0, 2, 0, 2, 5, 0, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 6, 2, 0, 8, 5, 0, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 1, 3, 0, 1, 4, 0, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 7, 3, 0, 7, 4, 0, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); // balcony floor - generateBox(level, chunkBB, 0, 2, 4, 8, 2, 8, Tile::netherBrick_Id, Tile::netherBrick_Id, false); + generateBox(level, chunkBB, 0, 2, 4, 8, 2, 8, Tile::nether_brick_Id, Tile::nether_brick_Id, false); generateBox(level, chunkBB, 1, 1, 4, 2, 2, 4, 0, 0, false); generateBox(level, chunkBB, 6, 1, 4, 7, 2, 4, 0, 0, false); // hand rails - generateBox(level, chunkBB, 0, 3, 8, 8, 3, 8, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 0, 3, 6, 0, 3, 7, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 8, 3, 6, 8, 3, 7, Tile::netherFence_Id, Tile::netherFence_Id, false); + generateBox(level, chunkBB, 0, 3, 8, 8, 3, 8, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 0, 3, 6, 0, 3, 7, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 8, 3, 6, 8, 3, 7, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); // balcony walls - generateBox(level, chunkBB, 0, 3, 4, 0, 5, 5, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 8, 3, 4, 8, 5, 5, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 1, 3, 5, 2, 5, 5, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 6, 3, 5, 7, 5, 5, Tile::netherBrick_Id, Tile::netherBrick_Id, false); - generateBox(level, chunkBB, 1, 4, 5, 1, 5, 5, Tile::netherFence_Id, Tile::netherFence_Id, false); - generateBox(level, chunkBB, 7, 4, 5, 7, 5, 5, Tile::netherFence_Id, Tile::netherFence_Id, false); + generateBox(level, chunkBB, 0, 3, 4, 0, 5, 5, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 8, 3, 4, 8, 5, 5, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 1, 3, 5, 2, 5, 5, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 6, 3, 5, 7, 5, 5, Tile::nether_brick_Id, Tile::nether_brick_Id, false); + generateBox(level, chunkBB, 1, 4, 5, 1, 5, 5, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); + generateBox(level, chunkBB, 7, 4, 5, 7, 5, 5, Tile::nether_brick_fence_Id, Tile::nether_brick_fence_Id, false); // supports for (int z = 0; z <= 5; z++) { for (int x = 0; x <= 8; x++) { - fillColumnDown(level, Tile::netherBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::nether_brick_Id, 0, x, -1, z, chunkBB); } } diff --git a/Minecraft.World/NetherStalkTile.cpp b/Minecraft.World/NetherStalkTile.cpp index eadf9646..04e7ddf0 100644 --- a/Minecraft.World/NetherStalkTile.cpp +++ b/Minecraft.World/NetherStalkTile.cpp @@ -15,6 +15,32 @@ NetherStalkTile::NetherStalkTile(int id) : Bush(id) icons = NULL; } +void NetherStalkTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int NetherStalkTile::defaultBlockState() +{ + return 0; +} + +int NetherStalkTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x3) : 0; +} + +Tile::BlockState NetherStalkTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x3); +} + +Tile::BlockState NetherStalkTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x3); +} + // 4J Added override void NetherStalkTile::updateDefaultShape() { diff --git a/Minecraft.World/NetherStalkTile.h b/Minecraft.World/NetherStalkTile.h index 39093274..81247aa3 100644 --- a/Minecraft.World/NetherStalkTile.h +++ b/Minecraft.World/NetherStalkTile.h @@ -16,6 +16,11 @@ private: public: NetherStalkTile(int id); virtual void updateDefaultShape(); // 4J Added override + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual bool mayPlaceOn(int tile); // Brought forward to fix #60073 - TU7: Content: Gameplay: Nether Warts cannot be placed next to each other in the Nether diff --git a/Minecraft.World/NetherWartTile.cpp b/Minecraft.World/NetherWartTile.cpp index 3c855040..ef04fc90 100644 --- a/Minecraft.World/NetherWartTile.cpp +++ b/Minecraft.World/NetherWartTile.cpp @@ -15,6 +15,32 @@ NetherWartTile::NetherWartTile(int id) : Bush(id) updateDefaultShape(); } +void NetherWartTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int NetherWartTile::defaultBlockState() +{ + return 0; +} + +int NetherWartTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x3) : 0; +} + +Tile::BlockState NetherWartTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x3); +} + +Tile::BlockState NetherWartTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x3); +} + // 4J Added override void NetherWartTile::updateDefaultShape() { @@ -24,7 +50,7 @@ void NetherWartTile::updateDefaultShape() bool NetherWartTile::mayPlaceOn(int tile) { - return tile == Tile::soulsand_Id; + return tile == Tile::soul_sand_Id; } // Brought forward to fix #60073 - TU7: Content: Gameplay: Nether Warts cannot be placed next to each other in the Nether diff --git a/Minecraft.World/NetherWartTile.h b/Minecraft.World/NetherWartTile.h index 3e5088b2..d43f272b 100644 --- a/Minecraft.World/NetherWartTile.h +++ b/Minecraft.World/NetherWartTile.h @@ -14,6 +14,11 @@ private: public: NetherWartTile(int id); virtual void updateDefaultShape(); // 4J Added override + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual bool mayPlaceOn(int tile); // Brought forward to fix #60073 - TU7: Content: Gameplay: Nether Warts cannot be placed next to each other in the Nether diff --git a/Minecraft.World/NotGateTile.cpp b/Minecraft.World/NotGateTile.cpp index 969778d8..caec1fb4 100644 --- a/Minecraft.World/NotGateTile.cpp +++ b/Minecraft.World/NotGateTile.cpp @@ -125,7 +125,7 @@ void NotGateTile::tick(Level *level, int x, int y, int z, Random *random) { if (neighborSignal) { - level->setTileAndData(x, y, z, Tile::redstoneTorch_off_Id, level->getData(x, y, z), Tile::UPDATE_ALL); + level->setTileAndData(x, y, z, Tile::unlit_redstone_torch_Id, level->getData(x, y, z), Tile::UPDATE_ALL); if (isToggledTooFrequently(level, x, y, z, true)) { @@ -149,7 +149,7 @@ void NotGateTile::tick(Level *level, int x, int y, int z, Random *random) { if (!isToggledTooFrequently(level, x, y, z, false)) { - level->setTileAndData(x, y, z, Tile::redstoneTorch_on_Id, level->getData(x, y, z), Tile::UPDATE_ALL); + level->setTileAndData(x, y, z, Tile::redstone_torch_Id, level->getData(x, y, z), Tile::UPDATE_ALL); } else { @@ -184,7 +184,7 @@ int NotGateTile::getDirectSignal(LevelSource *level, int x, int y, int z, int fa int NotGateTile::getResource(int data, Random *random, int playerBonusLevel) { - return Tile::redstoneTorch_on_Id; + return Tile::redstone_torch_Id; } bool NotGateTile::isSignalSource() @@ -226,7 +226,7 @@ void NotGateTile::animateTick(Level *level, int xt, int yt, int zt, Random *rand int NotGateTile::cloneTileId(Level *level, int x, int y, int z) { - return Tile::redstoneTorch_on_Id; + return Tile::redstone_torch_Id; } void NotGateTile::levelTimeChanged(Level *level, int64_t delta, int64_t newTime) @@ -244,5 +244,5 @@ void NotGateTile::levelTimeChanged(Level *level, int64_t delta, int64_t newTime) bool NotGateTile::isMatching(int id) { - return id == Tile::redstoneTorch_off_Id || id == Tile::redstoneTorch_on_Id; + return id == Tile::unlit_redstone_torch_Id || id == Tile::redstone_torch_Id; } \ No newline at end of file diff --git a/Minecraft.World/OceanMonumentPieces.cpp b/Minecraft.World/OceanMonumentPieces.cpp index 4cb9f536..dbad5f23 100644 --- a/Minecraft.World/OceanMonumentPieces.cpp +++ b/Minecraft.World/OceanMonumentPieces.cpp @@ -51,9 +51,9 @@ void OceanMonumentPieces::loadStatic() int OceanMonumentPieces::blockPrismarine() { return PrismarineTile::TYPE_DEFAULT; } int OceanMonumentPieces::blockPrismarineBricks() { return PrismarineTile::TYPE_BRICKS; } // meta BRICKS int OceanMonumentPieces::blockDarkPrismarine() { return PrismarineTile::TYPE_DARK; } // meta DARK -int OceanMonumentPieces::blockWater() { return Tile::water_Id; } -int OceanMonumentPieces::blockSeaLantern() { return Tile::seaLantern_Id; } -int OceanMonumentPieces::blockGoldBlock() { return Tile::goldBlock_Id; } +int OceanMonumentPieces::blockWater() { return Tile::flowing_water_Id; } +int OceanMonumentPieces::blockSeaLantern() { return Tile::sea_lantern_Id; } +int OceanMonumentPieces::blockGoldBlock() { return Tile::gold_block_Id; } int OceanMonumentPieces::blockSponge() { return Tile::sponge_Id; } int OceanMonumentPieces::blockAir() { return 0; } diff --git a/Minecraft.World/Ocelot.cpp b/Minecraft.World/Ocelot.cpp index 6816cabc..ea2f543e 100644 --- a/Minecraft.World/Ocelot.cpp +++ b/Minecraft.World/Ocelot.cpp @@ -44,7 +44,7 @@ Ocelot::Ocelot(Level *level) : TamableAnimal(level) getNavigation()->setAvoidWater(true); goalSelector.addGoal(1, new FloatGoal(this)); goalSelector.addGoal(2, sitGoal, false); - goalSelector.addGoal(3, temptGoal = new TemptGoal(this, SNEAK_SPEED_MOD, Item::fish_raw_Id, true), false); + goalSelector.addGoal(3, temptGoal = new TemptGoal(this, SNEAK_SPEED_MOD, Item::fish_Id, true), false); goalSelector.addGoal(5, new FollowOwnerGoal(this, FOLLOW_SPEED_MOD, 10, 5)); goalSelector.addGoal(6, new OcelotSitOnTileGoal(this, SPRINT_SPEED_MOD)); goalSelector.addGoal(7, new LeapAtTargetGoal(this, 0.3f)); @@ -220,7 +220,7 @@ bool Ocelot::mobInteract(shared_ptr player) //player must be close holding raw fish // temptGoal->isRunning() check removed // when the player enters interaction range, which would block taming entirely - if (item != nullptr && item->id == Item::fish_raw_Id && player->distanceToSqr(shared_from_this()) < 3 * 3) + if (item != nullptr && item->id == Item::fish_Id && player->distanceToSqr(shared_from_this()) < 3 * 3) { // 4J-PB - don't lose the fish in creative mode if (!player->abilities.instabuild) item->count--; @@ -278,7 +278,7 @@ shared_ptr Ocelot::getBreedOffspring(shared_ptr target) bool Ocelot::isFood(shared_ptr itemInstance) { - return itemInstance != nullptr && itemInstance->id == Item::fish_raw_Id; + return itemInstance != nullptr && itemInstance->id == Item::fish_Id; } bool Ocelot::canMate(shared_ptr animal) diff --git a/Minecraft.World/OcelotSitOnTileGoal.cpp b/Minecraft.World/OcelotSitOnTileGoal.cpp index 09b98650..1ecdc3fc 100644 --- a/Minecraft.World/OcelotSitOnTileGoal.cpp +++ b/Minecraft.World/OcelotSitOnTileGoal.cpp @@ -118,7 +118,7 @@ bool OcelotSitOnTileGoal::isValidTarget(Level *level, int x, int y, int z) return true; } } - else if (tile == Tile::furnace_lit_Id) + else if (tile == Tile::lit_furnace_Id) { return true; } diff --git a/Minecraft.World/OreRecipies.cpp b/Minecraft.World/OreRecipies.cpp index 387d059b..d408f3af 100644 --- a/Minecraft.World/OreRecipies.cpp +++ b/Minecraft.World/OreRecipies.cpp @@ -9,10 +9,10 @@ void OreRecipies::_init() { ADD_OBJECT(map[0],Tile::goldBlock); - ADD_OBJECT(map[0],new ItemInstance(Item::goldIngot, 9)); + ADD_OBJECT(map[0],new ItemInstance(Item::gold_ingot, 9)); ADD_OBJECT(map[1],Tile::ironBlock); - ADD_OBJECT(map[1],new ItemInstance(Item::ironIngot, 9)); + ADD_OBJECT(map[1],new ItemInstance(Item::iron_ingot, 9)); ADD_OBJECT(map[2],Tile::diamondBlock); ADD_OBJECT(map[2],new ItemInstance(Item::diamond, 9)); @@ -21,16 +21,19 @@ void OreRecipies::_init() ADD_OBJECT(map[3],new ItemInstance(Item::emerald, 9)); ADD_OBJECT(map[4],Tile::lapisBlock); - ADD_OBJECT(map[4],new ItemInstance(Item::dye_powder, 9, DyePowderItem::BLUE)); + ADD_OBJECT(map[4],new ItemInstance(Item::dye, 9, DyePowderItem::BLUE)); ADD_OBJECT(map[5],Tile::redstoneBlock); - ADD_OBJECT(map[5],new ItemInstance(Item::redStone, 9)); + ADD_OBJECT(map[5],new ItemInstance(Item::redstone, 9)); ADD_OBJECT(map[6],Tile::coalBlock); ADD_OBJECT(map[6],new ItemInstance(Item::coal, 9, CoalItem::STONE_COAL)); ADD_OBJECT(map[7],Tile::hayBlock); ADD_OBJECT(map[7],new ItemInstance(Item::wheat, 9)); + + ADD_OBJECT(map[8],Tile::slimeBlock); + ADD_OBJECT(map[8],new ItemInstance(Item::slime_ball, 9)); } void OreRecipies::addRecipes(Recipes *r) { diff --git a/Minecraft.World/OreRecipies.h b/Minecraft.World/OreRecipies.h index f2bef1f7..0c675f3f 100644 --- a/Minecraft.World/OreRecipies.h +++ b/Minecraft.World/OreRecipies.h @@ -1,6 +1,6 @@ #pragma once -#define MAX_ORE_RECIPES 8 +#define MAX_ORE_RECIPES 9 class OreRecipies { diff --git a/Minecraft.World/OreTile.cpp b/Minecraft.World/OreTile.cpp index bd656541..25e7c7c0 100644 --- a/Minecraft.World/OreTile.cpp +++ b/Minecraft.World/OreTile.cpp @@ -9,17 +9,17 @@ OreTile::OreTile(int id) : Tile(id, Material::stone) int OreTile::getResource(int data, Random *random, int playerBonusLevel) { - if (id == Tile::coalOre_Id) return Item::coal_Id; - if (id == Tile::diamondOre_Id) return Item::diamond_Id; - if (id == Tile::lapisOre_Id) return Item::dye_powder_Id; - if (id == Tile::emeraldOre_Id) return Item::emerald_Id; - if (id == Tile::netherQuartz_Id) return Item::netherQuartz_Id; + if (id == Tile::coal_ore_Id) return Item::coal_Id; + if (id == Tile::diamond_ore_Id) return Item::diamond_Id; + if (id == Tile::lapis_ore_Id) return Item::dye_Id; + if (id == Tile::emerald_ore_Id) return Item::emerald_Id; + if (id == Tile::quartz_ore_Id) return Item::quartz_Id; return id; } int OreTile::getResourceCount(Random *random) { - if (id == Tile::lapisOre_Id) return 4 + random->nextInt(5); + if (id == Tile::lapis_ore_Id) return 4 + random->nextInt(5); return 1; } @@ -45,23 +45,23 @@ void OreTile::spawnResources(Level *level, int x, int y, int z, int data, float if (getResource(data, level->random, playerBonusLevel) != id) { int magicCount = 0; - if (id == Tile::coalOre_Id) + if (id == Tile::coal_ore_Id) { magicCount = Mth::nextInt(level->random, 0, 2); } - else if (id == Tile::diamondOre_Id) + else if (id == Tile::diamond_ore_Id) { magicCount = Mth::nextInt(level->random, 3, 7); } - else if (id == Tile::emeraldOre_Id) + else if (id == Tile::emerald_ore_Id) { magicCount = Mth::nextInt(level->random, 3, 7); } - else if (id == Tile::lapisOre_Id) + else if (id == Tile::lapis_ore_Id) { magicCount = Mth::nextInt(level->random, 2, 5); } - else if (id == Tile::netherQuartz_Id) + else if (id == Tile::quartz_ore_Id) { magicCount = Mth::nextInt(level->random, 2, 5); } @@ -72,6 +72,6 @@ void OreTile::spawnResources(Level *level, int x, int y, int z, int data, float int OreTile::getSpawnResourcesAuxValue(int data) { // lapis spawns blue dye - if (id == Tile::lapisOre_Id) return DyePowderItem::BLUE; + if (id == Tile::lapis_ore_Id) return DyePowderItem::BLUE; return 0; } \ No newline at end of file diff --git a/Minecraft.World/Ozelot.cpp b/Minecraft.World/Ozelot.cpp index a57917e0..147366e3 100644 --- a/Minecraft.World/Ozelot.cpp +++ b/Minecraft.World/Ozelot.cpp @@ -43,7 +43,7 @@ Ozelot::Ozelot(Level *level) : TamableAnimal(level) getNavigation()->setAvoidWater(true); goalSelector.addGoal(1, new FloatGoal(this)); goalSelector.addGoal(2, sitGoal, false); - goalSelector.addGoal(3, temptGoal = new TemptGoal(this, SNEAK_SPEED, Item::fish_raw_Id, true), false); + goalSelector.addGoal(3, temptGoal = new TemptGoal(this, SNEAK_SPEED, Item::fish_Id, true), false); goalSelector.addGoal(4, new AvoidPlayerGoal(this, typeid(Player), 16, WALK_SPEED, SPRINT_SPEED)); goalSelector.addGoal(5, new FollowOwnerGoal(this, FOLLOW_SPEED, 10, 5)); goalSelector.addGoal(6, new OcelotSitOnTileGoal(this, SPRINT_SPEED)); @@ -214,7 +214,7 @@ bool Ozelot::interact(shared_ptr player) } else { - if (temptGoal->isRunning() && item != NULL && item->id == Item::fish_raw_Id && player->distanceToSqr(shared_from_this()) < 3 * 3) + if (temptGoal->isRunning() && item != NULL && item->id == Item::fish_Id && player->distanceToSqr(shared_from_this()) < 3 * 3) { // 4J-PB - don't lose the fish in creative mode if (!player->abilities.instabuild) item->count--; @@ -272,7 +272,7 @@ shared_ptr Ozelot::getBreedOffspring(shared_ptr target) bool Ozelot::isFood(shared_ptr itemInstance) { - return itemInstance != NULL && itemInstance->id == Item::fish_raw_Id; + return itemInstance != NULL && itemInstance->id == Item::fish_Id; } bool Ozelot::canMate(shared_ptr animal) diff --git a/Minecraft.World/PathFinder.cpp b/Minecraft.World/PathFinder.cpp index eb3bd45e..f4983a58 100644 --- a/Minecraft.World/PathFinder.cpp +++ b/Minecraft.World/PathFinder.cpp @@ -53,7 +53,7 @@ Path *PathFinder::findPath(Entity *e, double xt, double yt, double zt, float max { startY = static_cast(e->bb->y0); int tileId = level->getTile((int) Mth::floor(e->x), startY, (int) Mth::floor(e->z)); - while (tileId == Tile::water_Id || tileId == Tile::calmWater_Id) + while (tileId == Tile::flowing_water_Id || tileId == Tile::water_Id) { ++startY; tileId = level->getTile((int) Mth::floor(e->x), startY, (int) Mth::floor(e->z)); @@ -217,12 +217,12 @@ int PathFinder::isFree(Entity *entity, int x, int y, int z, Node *size, bool avo int tileId = entity->level->getTile(xx, yy, zz); if(tileId <= 0) continue; if (tileId == Tile::trapdoor_Id) walkable = true; - else if (tileId == Tile::water_Id || tileId == Tile::calmWater_Id) + else if (tileId == Tile::flowing_water_Id || tileId == Tile::water_Id) { if (avoidWater) return TYPE_WATER; else walkable = true; } - else if (!canPassDoors && tileId == Tile::door_wood_Id) + else if (!canPassDoors && tileId == Tile::wooden_door_Id) { return TYPE_BLOCKED; } @@ -246,11 +246,12 @@ int PathFinder::isFree(Entity *entity, int x, int y, int z, Node *size, bool avo } } + if (tile == nullptr) continue; // tu31 tutorial world fix if (tile->isPathfindable(entity->level, xx, yy, zz)) continue; - if (canOpenDoors && tileId == Tile::door_wood_Id) continue; + if (canOpenDoors && tileId == Tile::wooden_door_Id) continue; int renderShape = tile->getRenderShape(); - if (renderShape == Tile::SHAPE_FENCE || tileId == Tile::fenceGate_Id || renderShape == Tile::SHAPE_WALL) return TYPE_FENCE; + if (renderShape == Tile::SHAPE_FENCE || tileId == Tile::fence_gate_Id || renderShape == Tile::SHAPE_WALL) return TYPE_FENCE; if (tileId == Tile::trapdoor_Id) return TYPE_TRAP; Material *m = tile->material; if (m == Material::lava) diff --git a/Minecraft.World/PathNavigation.cpp b/Minecraft.World/PathNavigation.cpp index 51d08d1e..06d142cc 100644 --- a/Minecraft.World/PathNavigation.cpp +++ b/Minecraft.World/PathNavigation.cpp @@ -237,7 +237,7 @@ int PathNavigation::getSurfaceY() int surface = static_cast(mob->bb->y0); int tileId = level->getTile(Mth::floor(mob->x), surface, Mth::floor(mob->z)); int steps = 0; - while (tileId == Tile::water_Id || tileId == Tile::calmWater_Id) + while (tileId == Tile::flowing_water_Id || tileId == Tile::water_Id) { ++surface; tileId = level->getTile(Mth::floor(mob->x), surface, Mth::floor(mob->z)); @@ -346,7 +346,9 @@ bool PathNavigation::canWalkOn(int x, int y, int z, int sx, int sy, int sz, Vec3 if (dirX * goalDirX + dirZ * goalDirZ < 0) continue; int tile = level->getTile(xx, y - 1, zz); if (tile <= 0) return false; - Material *m = Tile::tiles[tile]->material; + Tile *tileObj = Tile::tiles[tile]; + if (tileObj == nullptr) continue; // tu31 tutorial world fix + Material *m = tileObj->material; if (m == Material::water && !mob->isInWater()) return false; if (m == Material::lava) return false; } @@ -370,7 +372,9 @@ bool PathNavigation::canWalkAbove(int startX, int startY, int startZ, int sx, in if (dirX * goalDirX + dirZ * goalDirZ < 0) continue; int tile = level->getTile(xx, yy, zz); if (tile <= 0) continue; - if (!Tile::tiles[tile]->isPathfindable(level, xx, yy, zz)) return false; + Tile *tileObj = Tile::tiles[tile]; + if (tileObj == nullptr) continue; // tu31 tutorial world fix + if (!tileObj->isPathfindable(level, xx, yy, zz)) return false; } } } diff --git a/Minecraft.World/PickaxeItem.cpp b/Minecraft.World/PickaxeItem.cpp index 1bcee6e0..1a19c0a9 100644 --- a/Minecraft.World/PickaxeItem.cpp +++ b/Minecraft.World/PickaxeItem.cpp @@ -25,7 +25,7 @@ void PickaxeItem::staticCtor() diggables.data[15] = Tile::lapisOre; diggables.data[16] = Tile::lapisBlock; diggables.data[17] = Tile::redStoneOre; - diggables.data[18] = Tile::redStoneOre_lit; + diggables.data[18] = Tile::lit_redstone_ore; diggables.data[19] = Tile::rail; diggables.data[20] = Tile::detectorRail; diggables.data[21] = Tile::goldenRail; @@ -44,7 +44,7 @@ bool PickaxeItem::canDestroySpecial(Tile *tile) if (tile == Tile::goldBlock || tile == Tile::goldOre) return tier->getLevel() >= 2; if (tile == Tile::ironBlock || tile == Tile::ironOre) return tier->getLevel() >= 1; if (tile == Tile::lapisBlock || tile == Tile::lapisOre) return tier->getLevel() >= 1; - if (tile == Tile::redStoneOre || tile == Tile::redStoneOre_lit) return tier->getLevel() >= 2; + if (tile == Tile::redStoneOre || tile == Tile::lit_redstone_ore) return tier->getLevel() >= 2; if (tile->material == Material::stone) return true; if (tile->material == Material::metal) return true; if (tile->material == Material::heavyMetal) return true; diff --git a/Minecraft.World/Pig.cpp b/Minecraft.World/Pig.cpp index 2e1d1715..38af8cab 100644 --- a/Minecraft.World/Pig.cpp +++ b/Minecraft.World/Pig.cpp @@ -34,8 +34,8 @@ Pig::Pig(Level *level) : Animal( level ) goalSelector.addGoal(1, new PanicGoal(this, 1.25)); goalSelector.addGoal(2, controlGoal = new ControlledByPlayerGoal(this, 0.3f, 0.25f)); goalSelector.addGoal(3, new BreedGoal(this, 1.0)); - goalSelector.addGoal(4, new TemptGoal(this, 1.2, Item::carrotOnAStick_Id, false)); - goalSelector.addGoal(4, new TemptGoal(this, 1.2, Item::carrots_Id, false)); + goalSelector.addGoal(4, new TemptGoal(this, 1.2, Item::carrot_on_a_stick_Id, false)); + goalSelector.addGoal(4, new TemptGoal(this, 1.2, Item::carrot_Id, false)); goalSelector.addGoal(5, new FollowParentGoal(this, 1.1)); goalSelector.addGoal(6, new RandomStrollGoal(this, 1.0)); goalSelector.addGoal(7, new LookAtPlayerGoal(this, typeid(Player), 6)); @@ -69,7 +69,7 @@ bool Pig::canBeControlledByRider() { shared_ptr item = dynamic_pointer_cast(rider.lock())->getCarriedItem(); - return item != nullptr && item->id == Item::carrotOnAStick_Id; + return item != nullptr && item->id == Item::carrot_on_a_stick_Id; } void Pig::defineSynchedData() @@ -127,8 +127,8 @@ bool Pig::mobInteract(shared_ptr player) int Pig::getDeathLoot() { - if (this->isOnFire() ) return Item::porkChop_cooked->id; - return Item::porkChop_raw_Id; + if (this->isOnFire() ) return Item::cooked_porkchop->id; + return Item::porkchop_Id; } void Pig::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) @@ -139,11 +139,11 @@ void Pig::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) { if (isOnFire()) { - spawnAtLocation(Item::porkChop_cooked_Id, 1); + spawnAtLocation(Item::cooked_porkchop_Id, 1); } else { - spawnAtLocation(Item::porkChop_raw_Id, 1); + spawnAtLocation(Item::porkchop_Id, 1); } } if (hasSaddle()) spawnAtLocation(Item::saddle_Id, 1); @@ -199,7 +199,7 @@ shared_ptr Pig::getBreedOffspring(shared_ptr target) bool Pig::isFood(shared_ptr itemInstance) { - return itemInstance != nullptr && itemInstance->id == Item::carrots_Id; + return itemInstance != nullptr && itemInstance->id == Item::carrot_Id; } ControlledByPlayerGoal *Pig::getControlGoal() diff --git a/Minecraft.World/PigZombie.cpp b/Minecraft.World/PigZombie.cpp index e87d028a..b294e9a3 100644 --- a/Minecraft.World/PigZombie.cpp +++ b/Minecraft.World/PigZombie.cpp @@ -153,7 +153,7 @@ void PigZombie::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) count = random->nextInt(2 + playerBonusLevel); for (int i = 0; i < count; i++) { - spawnAtLocation(Item::goldNugget_Id, 1); + spawnAtLocation(Item::gold_nugget_Id, 1); } } @@ -164,7 +164,7 @@ bool PigZombie::mobInteract(shared_ptr player) void PigZombie::dropRareDeathLoot(int rareLootLevel) { - spawnAtLocation(Item::goldIngot_Id, 1); + spawnAtLocation(Item::gold_ingot_Id, 1); } int PigZombie::getDeathLoot() @@ -174,7 +174,7 @@ int PigZombie::getDeathLoot() void PigZombie::populateDefaultEquipmentSlots() { - setEquippedSlot(SLOT_WEAPON, std::make_shared(Item::sword_gold)); + setEquippedSlot(SLOT_WEAPON, std::make_shared(Item::golden_sword)); } MobGroupData *PigZombie::finalizeMobSpawn(MobGroupData *groupData, int extraData /*= 0*/) // 4J Added extraData param diff --git a/Minecraft.World/PineFeature.cpp b/Minecraft.World/PineFeature.cpp index 6ee6fd7c..4d05ef65 100644 --- a/Minecraft.World/PineFeature.cpp +++ b/Minecraft.World/PineFeature.cpp @@ -95,7 +95,7 @@ bool PineFeature::place(Level *level, Random *random, int x, int y, int z) for (int hh = 0; hh < treeHeight - 1; hh++) { int t = level->getTile(x, y + hh, z); - if (t == 0 || t == Tile::leaves_Id) placeBlock(level, x, y + hh, z, Tile::treeTrunk_Id, TreeTile::SPRUCE_TRUNK); + if (t == 0 || t == Tile::leaves_Id) placeBlock(level, x, y + hh, z, Tile::log_Id, TreeTile::SPRUCE_TRUNK); } return true; diff --git a/Minecraft.World/PistonBaseTile.cpp b/Minecraft.World/PistonBaseTile.cpp index 24749a89..f708c9e0 100644 --- a/Minecraft.World/PistonBaseTile.cpp +++ b/Minecraft.World/PistonBaseTile.cpp @@ -1,677 +1,802 @@ -#include "stdafx.h" -#include "PistonBaseTile.h" -#include "PistonMovingPiece.h" -#include "PistonPieceEntity.h" -#include "PistonExtensionTile.h" -#include "Facing.h" -#include "net.minecraft.world.level.h" -#include "../Minecraft.Client/Minecraft.h" -#include "../Minecraft.Client/MultiPlayerLevel.h" -#include "net.minecraft.world.h" -#include "LevelChunk.h" -#include "Dimension.h" -#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) -#include "../Minecraft.Server/FourKitBridge.h" -#endif - -const wstring PistonBaseTile::EDGE_TEX = L"piston_side"; -const wstring PistonBaseTile::PLATFORM_TEX = L"piston_top"; -const wstring PistonBaseTile::PLATFORM_STICKY_TEX = L"piston_top_sticky"; -const wstring PistonBaseTile::BACK_TEX = L"piston_bottom"; -const wstring PistonBaseTile::INSIDE_TEX = L"piston_inner_top"; - -const float PistonBaseTile::PLATFORM_THICKNESS = 4.0f; - -DWORD PistonBaseTile::tlsIdx = TlsAlloc(); - -// 4J - NOTE - this ignoreUpdate stuff has been removed from the java version, but I'm not currently sure how the java version does without it... there must be -// some other mechanism that we don't have that stops the event from one piston being processed, from causing neighbours to have extra events created for them. -// For us, that means that if we create a piston next to another one, then one of them gets two events to createPush, the second of which fails, leaving the -// piston in a bad (simultaneously extended & not extended) state. -// 4J - ignoreUpdate is a static in java, implementing as TLS here to make thread safe - -//I removed the code for ignoreUpdate so the above comment no longer applies ^.^ - -PistonBaseTile::PistonBaseTile(int id, bool isSticky) : Tile(id, Material::piston, isSolidRender() ) -{ - // 4J - added initialiser - this->isSticky = isSticky; - setSoundType(SOUND_STONE); - setDestroyTime(0.5f); - - iconInside = nullptr; - iconBack = nullptr; - iconPlatform = nullptr; -} - -Icon *PistonBaseTile::getPlatformTexture() -{ - return iconPlatform; -} - -void PistonBaseTile::updateShape(float x0, float y0, float z0, float x1, float y1, float z1) -{ - setShape(x0, y0, z0, x1, y1, z1); -} - -Icon *PistonBaseTile::getTexture(int face, int data) -{ - int facing = getFacing(data); - - if (facing > 5) - { - return iconPlatform; - } - - if (face == facing) - { - // sorry about this mess... - // when the piston is extended, either normally - // or because a piston arm animation, the top - // texture is the furnace bottom - ThreadStorage *tls = static_cast(TlsGetValue(Tile::tlsIdxShape)); - if (isExtended(data) || tls->xx0 > 0 || tls->yy0 > 0 || tls->zz0 > 0 || tls->xx1 < 1 || tls->yy1 < 1 || tls->zz1 < 1) - { - return iconInside; - } - return iconPlatform; - } - if (face == Facing::OPPOSITE_FACING[facing]) - { - return iconBack; - } - - return icon; -} - -Icon *PistonBaseTile::getTexture(const wstring &name) -{ - if (name.compare(EDGE_TEX) == 0) return Tile::pistonBase->icon; - if (name.compare(PLATFORM_TEX) == 0) return Tile::pistonBase->iconPlatform; - if (name.compare(PLATFORM_STICKY_TEX) == 0) return Tile::pistonStickyBase->iconPlatform; - if (name.compare(INSIDE_TEX) == 0) return Tile::pistonBase->iconInside; - - return nullptr; -} - -//@Override -void PistonBaseTile::registerIcons(IconRegister *iconRegister) -{ - icon = iconRegister->registerIcon(EDGE_TEX); - iconPlatform = iconRegister->registerIcon(isSticky ? PLATFORM_STICKY_TEX : PLATFORM_TEX); - iconInside = iconRegister->registerIcon(INSIDE_TEX); - iconBack = iconRegister->registerIcon(BACK_TEX); -} - -int PistonBaseTile::getRenderShape() -{ - return SHAPE_PISTON_BASE; -} - -bool PistonBaseTile::isSolidRender(bool isServerLevel) -{ - return false; -} - -bool PistonBaseTile::use(Level *level, int x, int y, int z, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly/*=false*/) // 4J added soundOnly param -{ - return false; -} - -void PistonBaseTile::setPlacedBy(Level *level, int x, int y, int z, shared_ptr by, shared_ptr itemInstance) -{ - int targetData = getNewFacing(level, x, y, z, dynamic_pointer_cast(by) ); - level->setData(x, y, z, targetData, Tile::UPDATE_CLIENTS); - if (!level->isClientSide) - { - checkIfExtend(level, x, y, z); - } -} - -void PistonBaseTile::neighborChanged(Level *level, int x, int y, int z, int type) -{ - if (!level->isClientSide) - { - checkIfExtend(level, x, y, z); - } -} - -void PistonBaseTile::onPlace(Level *level, int x, int y, int z) -{ - if (!level->isClientSide && level->getTileEntity(x, y, z) == nullptr) - { - checkIfExtend(level, x, y, z); - } -} - -void PistonBaseTile::checkIfExtend(Level *level, int x, int y, int z) -{ - int data = level->getData(x, y, z); - int facing = getFacing(data); - - if (facing == UNDEFINED_FACING) - { - return; - } - bool extend = getNeighborSignal(level, x, y, z, facing); - - if (extend && !isExtended(data)) - { - if (canPush(level, x, y, z, facing)) - { - level->tileEvent(x, y, z, id, TRIGGER_EXTEND, facing); - } - } - else if (!extend && isExtended(data)) - { - level->setData(x, y, z, facing, UPDATE_CLIENTS); - level->tileEvent(x, y, z, id, TRIGGER_CONTRACT, facing); - } -} - -/** -* This method checks neighbor signals for this block and the block above, -* and directly beneath. However, it avoids checking blocks that would be -* pushed by this block. -* -* @param level -* @param x -* @param y -* @param z -* @return -*/ -bool PistonBaseTile::getNeighborSignal(Level *level, int x, int y, int z, int facing) -{ - // check adjacent neighbors, but not in push direction - if (facing != Facing::DOWN && level->hasSignal(x, y - 1, z, Facing::DOWN)) return true; - if (facing != Facing::UP && level->hasSignal(x, y + 1, z, Facing::UP)) return true; - if (facing != Facing::NORTH && level->hasSignal(x, y, z - 1, Facing::NORTH)) return true; - if (facing != Facing::SOUTH && level->hasSignal(x, y, z + 1, Facing::SOUTH)) return true; - if (facing != Facing::EAST && level->hasSignal(x + 1, y, z, Facing::EAST)) return true; - if (facing != Facing::WEST && level->hasSignal(x - 1, y, z, Facing::WEST)) return true; - - // check signals above - if (level->hasSignal(x, y, z, 0)) return true; - if (level->hasSignal(x, y + 2, z, 1)) return true; - if (level->hasSignal(x, y + 1, z - 1, 2)) return true; - if (level->hasSignal(x, y + 1, z + 1, 3)) return true; - if (level->hasSignal(x - 1, y + 1, z, 4)) return true; - if (level->hasSignal(x + 1, y + 1, z, 5)) return true; - - return false; -} - -bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1, int facing) -{ - - if (!level->isClientSide) - { - bool extend = getNeighborSignal(level, x, y, z, facing); - - if (extend && param1 == TRIGGER_CONTRACT) - { - level->setData(x, y, z, facing | EXTENDED_BIT, UPDATE_CLIENTS); - return false; - } - else if (!extend && param1 == TRIGGER_EXTEND) - { - return false; - } - } - - if (param1 == TRIGGER_EXTEND) - { -#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) - { - int pushLength = 0; - int cx = x + Facing::STEP_X[facing]; - int cy = y + Facing::STEP_Y[facing]; - int cz = z + Facing::STEP_Z[facing]; - for (int i = 0; i < MAX_PUSH_DEPTH + 1; i++) - { - int block = level->getTile(cx, cy, cz); - if (block == 0) break; - if (!isPushable(block, level, cx, cy, cz, true)) break; - if (Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_DESTROY) { pushLength++; break; } - pushLength++; - if (i == MAX_PUSH_DEPTH) break; - cx += Facing::STEP_X[facing]; - cy += Facing::STEP_Y[facing]; - cz += Facing::STEP_Z[facing]; - } - if (FourKitBridge::FirePistonExtend(level->dimension->id, x, y, z, facing, pushLength)) - { - return false; - } - } -#endif - PIXBeginNamedEvent(0,"Create push\n"); - if (createPush(level, x, y, z, facing)) - { - // 4J - it is (currently) critical that this setData sends data to the client, so have added a bool to the method so that it sends data even if the data was already set to the same value - // as before, which was actually its behaviour until a change in 1.0.1 meant that setData only conditionally sent updates to listeners. If the data update Isn't sent, then what - // can happen is: - // (1) the host sends the tile event to the client - // (2) the client gets the tile event, and sets the tile/data value locally. - // (3) just before setting the tile/data locally, the client will put the old value in the vector of things to be restored should an update not be received back from the host - // (4) we don't get any update of the tile from the host, and so the old value gets restored on the client - // (5) the piston base ends up being restored to its retracted state whilst the piston arm is extended - // We really need to spend some time investigating a better way for pistons to work as it all seems a bit scary how the host/client interact, but forcing this to send should at least - // restore the behaviour of the pistons to something closer to what they were before the 1.0.1 update. By sending this data update, then (4) in the list above doesn't happen - // because the client does actually receive an update for this tile from the host after the event has been processed on the cient. - level->setData(x, y, z, facing | EXTENDED_BIT, Tile::UPDATE_CLIENTS, true); - level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_TILE_PISTON_OUT, 0.5f, level->random->nextFloat() * 0.25f + 0.6f); - } - else - { - return false; - } - PIXEndNamedEvent(); - } - else if (param1 == TRIGGER_CONTRACT) - { -#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) - if (FourKitBridge::FirePistonRetract(level->dimension->id, x, y, z, facing)) - { - level->setData(x, y, z, facing | EXTENDED_BIT, UPDATE_CLIENTS); - return false; - } -#endif - PIXBeginNamedEvent(0,"Contract phase A\n"); - shared_ptr prevTileEntity = level->getTileEntity(x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]); - if (prevTileEntity != nullptr && dynamic_pointer_cast(prevTileEntity) != nullptr) - { - dynamic_pointer_cast(prevTileEntity)->finalTick(); - } - - stopSharingIfServer(level, x, y, z); // 4J added - level->setTileAndData(x, y, z, Tile::pistonMovingPiece_Id, facing, Tile::UPDATE_ALL); - level->setTileEntity(x, y, z, PistonMovingPiece::newMovingPieceEntity(id, facing, facing, false, true)); - - PIXEndNamedEvent(); - - // sticky movement - if (isSticky) - { - PIXBeginNamedEvent(0,"Contract sticky phase A\n"); - int twoX = x + Facing::STEP_X[facing] * 2; - int twoY = y + Facing::STEP_Y[facing] * 2; - int twoZ = z + Facing::STEP_Z[facing] * 2; - int block = level->getTile(twoX, twoY, twoZ); - int blockData = level->getData(twoX, twoY, twoZ); - bool pistonPiece = false; - - PIXEndNamedEvent(); - - if (block == Tile::pistonMovingPiece_Id) - { - PIXBeginNamedEvent(0,"Contract sticky phase B\n"); - // the block two steps away is a moving piston block piece, so replace it with the real data, - // since it's probably this piston which is changing too fast - shared_ptr tileEntity = level->getTileEntity(twoX, twoY, twoZ); - if (tileEntity != nullptr && dynamic_pointer_cast(tileEntity) != nullptr ) - { - shared_ptr ppe = dynamic_pointer_cast(tileEntity); - - if (ppe->getFacing() == facing && ppe->isExtending()) - { - // force the tile to air before pushing - ppe->finalTick(); - block = ppe->getId(); - blockData = ppe->getData(); - pistonPiece = true; - } - } - PIXEndNamedEvent(); - } - - PIXBeginNamedEvent(0,"Contract sticky phase C\n"); - if (!pistonPiece && block > 0 && (isPushable(block, level, twoX, twoY, twoZ, false)) - && (Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_NORMAL || block == Tile::pistonBase_Id || block == Tile::pistonStickyBase_Id)) - { - stopSharingIfServer(level, twoX, twoY, twoZ); // 4J added - - x += Facing::STEP_X[facing]; - y += Facing::STEP_Y[facing]; - z += Facing::STEP_Z[facing]; - - level->setTileAndData(x, y, z, Tile::pistonMovingPiece_Id, blockData, Tile::UPDATE_ALL); - level->setTileEntity(x, y, z, PistonMovingPiece::newMovingPieceEntity(block, blockData, facing, false, false)); - - level->removeTile(twoX, twoY, twoZ); - } - else if (!pistonPiece) - { - stopSharingIfServer(level, x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]); // 4J added - level->removeTile(x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]); - } - PIXEndNamedEvent(); - } - else - { - stopSharingIfServer(level, x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]); // 4J added - level->removeTile(x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]); - } - - level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_TILE_PISTON_IN, 0.5f, level->random->nextFloat() * 0.15f + 0.6f); - } - - return true; -} - -void PistonBaseTile::updateShape(LevelSource *level, int x, int y, int z, int forceData, shared_ptr forceEntity) // 4J added forceData, forceEntity param -{ - int data = (forceData == -1 ) ? level->getData(x, y, z) : forceData; - - if (isExtended(data)) - { - const float thickness = PLATFORM_THICKNESS / 16.0f; - switch (getFacing(data)) - { - case Facing::DOWN: - setShape(0, thickness, 0, 1, 1, 1); - break; - case Facing::UP: - setShape(0, 0, 0, 1, 1 - thickness, 1); - break; - case Facing::NORTH: - setShape(0, 0, thickness, 1, 1, 1); - break; - case Facing::SOUTH: - setShape(0, 0, 0, 1, 1, 1 - thickness); - break; - case Facing::WEST: - setShape(thickness, 0, 0, 1, 1, 1); - break; - case Facing::EAST: - setShape(0, 0, 0, 1 - thickness, 1, 1); - break; - } - } - else - { - setShape(0, 0, 0, 1, 1, 1); - } -} - -void PistonBaseTile::updateDefaultShape() -{ - setShape(0, 0, 0, 1, 1, 1); -} - -void PistonBaseTile::addAABBs(Level *level, int x, int y, int z, AABB *box, AABBList *boxes, shared_ptr source) -{ - setShape(0, 0, 0, 1, 1, 1); - Tile::addAABBs(level, x, y, z, box, boxes, source); -} - -AABB *PistonBaseTile::getAABB(Level *level, int x, int y, int z) -{ - updateShape(level, x, y, z); - return Tile::getAABB(level, x, y, z); -} - -bool PistonBaseTile::isCubeShaped() -{ - return false; -} - -int PistonBaseTile::getFacing(int data) -{ - return data & 0x7; -} - -bool PistonBaseTile::isExtended(int data) -{ - return (data & EXTENDED_BIT) != 0; -} - -int PistonBaseTile::getNewFacing(Level *level, int x, int y, int z, shared_ptr player) -{ - if (Mth::abs(static_cast(player->x) - x) < 2 && Mth::abs(static_cast(player->z) - z) < 2) - { - // If the player is above the block, the slot is on the top - double py = player->y + 1.82 - player->heightOffset; - if (py - y > 2) - { - return Facing::UP; - } - // If the player is below the block, the slot is on the bottom - if (y - py > 0) - { - return Facing::DOWN; - } - } - // The slot is on the side - int i = Mth::floor(player->yRot * 4.0f / 360.0f + 0.5) & 0x3; - if (i == 0) return Facing::NORTH; - if (i == 1) return Facing::EAST; - if (i == 2) return Facing::SOUTH; - if (i == 3) return Facing::WEST; - return 0; -} - -bool PistonBaseTile::isPushable(int block, Level *level, int cx, int cy, int cz, bool allowDestroyable) -{ - // special case for obsidian - if (block == Tile::obsidian_Id) - { - return false; - } - - if (block == Tile::pistonBase_Id || block == Tile::pistonStickyBase_Id) - { - // special case for piston bases - if (isExtended(level->getData(cx, cy, cz))) - { - return false; - } - } - else - { - if (Tile::tiles[block]->getDestroySpeed(level, cx, cy, cz) == Tile::INDESTRUCTIBLE_DESTROY_TIME) - { - return false; - } - - if (Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_BLOCK) - { - return false; - } - - if (Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_DESTROY) - { - if(!allowDestroyable) - { - return false; - } - return true; - } - } - - if( Tile::tiles[block]->isEntityTile() ) // 4J - java uses instanceof EntityTile here - { - // may not push tile entities - return false; - } - - return true; -} - -bool PistonBaseTile::canPush(Level *level, int sx, int sy, int sz, int facing) -{ - int cx = sx + Facing::STEP_X[facing]; - int cy = sy + Facing::STEP_Y[facing]; - int cz = sz + Facing::STEP_Z[facing]; - - for (int i = 0; i < MAX_PUSH_DEPTH + 1; i++) - { - - if (cy <= 0 || cy >= (Level::maxBuildHeight - 1)) - { - // out of bounds - return false; - } - - // 4J - added to also check for out of bounds in x/z for our finite world - int minXZ = - (level->dimension->getXZSize() * 16 ) / 2; - int maxXZ = (level->dimension->getXZSize() * 16 ) / 2 - 1; - if( ( cx <= minXZ ) || ( cx >= maxXZ ) || ( cz <= minXZ ) || ( cz >= maxXZ ) ) - { - return false; - } - int block = level->getTile(cx, cy, cz); - if (block == 0) - { - break; - } - - if (!isPushable(block, level, cx, cy, cz, true)) - { - return false; - } - - if (Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_DESTROY) - { - break; - } - - if (i == MAX_PUSH_DEPTH) - { - // we've reached the maximum push depth - // without finding air or a breakable block - return false; - } - - cx += Facing::STEP_X[facing]; - cy += Facing::STEP_Y[facing]; - cz += Facing::STEP_Z[facing]; - } - - return true; - -} - -void PistonBaseTile::stopSharingIfServer(Level *level, int x, int y, int z) -{ - if( !level->isClientSide ) - { - MultiPlayerLevel *clientLevel = Minecraft::GetInstance()->getLevel(level->dimension->id); - if( clientLevel ) - { - LevelChunk *lc = clientLevel->getChunkAt( x, z ); - lc->stopSharingTilesAndData(); - } - } -} - -bool PistonBaseTile::createPush(Level *level, int sx, int sy, int sz, int facing) -{ - int cx = sx + Facing::STEP_X[facing]; - int cy = sy + Facing::STEP_Y[facing]; - int cz = sz + Facing::STEP_Z[facing]; - - for (int i = 0; i < MAX_PUSH_DEPTH + 1; i++) - { - if (cy <= 0 || cy >= (Level::maxBuildHeight - 1)) - { - // out of bounds - return false; - } - - // 4J - added to also check for out of bounds in x/z for our finite world - int minXZ = - (level->dimension->getXZSize() * 16 ) / 2; - int maxXZ = (level->dimension->getXZSize() * 16 ) / 2 - 1; - if( ( cx <= minXZ ) || ( cx >= maxXZ ) || ( cz <= minXZ ) || ( cz >= maxXZ ) ) - { - return false; - } - - int block = level->getTile(cx, cy, cz); - if (block == 0) - { - break; - } - - if (!isPushable(block, level, cx, cy, cz, true)) - { - return false; - } - - if (Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_DESTROY) - { - // this block is destroyed when pushed - Tile::tiles[block]->spawnResources(level, cx, cy, cz, level->getData(cx, cy, cz), 0); - // setting the tile to air is actually superflous, but helps vs multiplayer problems - stopSharingIfServer(level, cx, cy, cz); // 4J added - level->removeTile(cx, cy, cz); - break; - } - - if (i == MAX_PUSH_DEPTH) - { - // we've reached the maximum push depth without finding air or a breakable block - return false; - } - - cx += Facing::STEP_X[facing]; - cy += Facing::STEP_Y[facing]; - cz += Facing::STEP_Z[facing]; - } - - int ex = cx; - int ey = cy; - int ez = cz; - int count = 0; - int tiles[MAX_PUSH_DEPTH + 1]; - - while (cx != sx || cy != sy || cz != sz) - { - - int nx = cx - Facing::STEP_X[facing]; - int ny = cy - Facing::STEP_Y[facing]; - int nz = cz - Facing::STEP_Z[facing]; - - int block = level->getTile(nx, ny, nz); - int data = level->getData(nx, ny, nz); - - stopSharingIfServer(level, cx, cy, cz); // 4J added - - if (block == id && nx == sx && ny == sy && nz == sz) - { - level->setTileAndData(cx, cy, cz, Tile::pistonMovingPiece_Id, facing | (isSticky ? PistonExtensionTile::STICKY_BIT : 0), Tile::UPDATE_NONE); - level->setTileEntity(cx, cy, cz, PistonMovingPiece::newMovingPieceEntity(Tile::pistonExtensionPiece_Id, facing | (isSticky ? PistonExtensionTile::STICKY_BIT : 0), facing, true, false)); - } - else - { - level->setTileAndData(cx, cy, cz, Tile::pistonMovingPiece_Id, data, Tile::UPDATE_NONE); - level->setTileEntity(cx, cy, cz, PistonMovingPiece::newMovingPieceEntity(block, data, facing, true, false)); - } - tiles[count++] = block; - - cx = nx; - cy = ny; - cz = nz; - } - - cx = ex; - cy = ey; - cz = ez; - count = 0; - - while (cx != sx || cy != sy || cz != sz) - { - int nx = cx - Facing::STEP_X[facing]; - int ny = cy - Facing::STEP_Y[facing]; - int nz = cz - Facing::STEP_Z[facing]; - - level->updateNeighborsAt(nx, ny, nz, tiles[count++]); - - cx = nx; - cy = ny; - cz = nz; - } - - return true; - -} +#include "stdafx.h" +#include "PistonBaseTile.h" +#include "PistonMovingPiece.h" +#include "PistonPieceEntity.h" +#include "PistonExtensionTile.h" +#include "Facing.h" +#include "net.minecraft.world.level.h" +#include "../Minecraft.Client/Minecraft.h" +#include "../Minecraft.Client/MultiPlayerLevel.h" +#include "net.minecraft.world.h" +#include "LevelChunk.h" +#include "Dimension.h" +#include +#include +#include +#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) +#include "../Minecraft.Server/FourKitBridge.h" +#endif + +const wstring PistonBaseTile::EDGE_TEX = L"piston_side"; +const wstring PistonBaseTile::PLATFORM_TEX = L"piston_top"; +const wstring PistonBaseTile::PLATFORM_STICKY_TEX = L"piston_top_sticky"; +const wstring PistonBaseTile::BACK_TEX = L"piston_bottom"; +const wstring PistonBaseTile::INSIDE_TEX = L"piston_inner_top"; + +const float PistonBaseTile::PLATFORM_THICKNESS = 4.0f; + +DWORD PistonBaseTile::tlsIdx = TlsAlloc(); + +// 4J - NOTE - this ignoreUpdate stuff has been removed from the java version, but I'm not currently sure how the java version does without it... there must be +// some other mechanism that we don't have that stops the event from one piston being processed, from causing neighbours to have extra events created for them. +// For us, that means that if we create a piston next to another one, then one of them gets two events to createPush, the second of which fails, leaving the +// piston in a bad (simultaneously extended & not extended) state. +// 4J - ignoreUpdate is a static in java, implementing as TLS here to make thread safe + +//I removed the code for ignoreUpdate so the above comment no longer applies ^.^ + +PistonBaseTile::PistonBaseTile(int id, bool isSticky) : Tile(id, Material::piston, isSolidRender() ) +{ + this->isSticky = isSticky; + setSoundType(SOUND_STONE); + setDestroyTime(0.5f); + + iconInside = nullptr; + iconBack = nullptr; + iconPlatform = nullptr; +} + +void PistonBaseTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int PistonBaseTile::defaultBlockState() +{ + return 0; +} + +int PistonBaseTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState PistonBaseTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState PistonBaseTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + +Icon *PistonBaseTile::getPlatformTexture() +{ + return iconPlatform; +} + +void PistonBaseTile::updateShape(float x0, float y0, float z0, float x1, float y1, float z1) +{ + setShape(x0, y0, z0, x1, y1, z1); +} + +Icon *PistonBaseTile::getTexture(int face, int data) +{ + int facing = getFacing(data); + + if (facing > 5) + { + return iconPlatform; + } + + if (face == facing) + { + // sorry about this mess... + // when the piston is extended, either normally + // or because a piston arm animation, the top + // texture is the furnace bottom + ThreadStorage *tls = static_cast(TlsGetValue(Tile::tlsIdxShape)); + if (isExtended(data) || tls->xx0 > 0 || tls->yy0 > 0 || tls->zz0 > 0 || tls->xx1 < 1 || tls->yy1 < 1 || tls->zz1 < 1) + { + return iconInside; + } + return iconPlatform; + } + if (face == Facing::OPPOSITE_FACING[facing]) + { + return iconBack; + } + + return icon; +} + +Icon *PistonBaseTile::getTexture(const wstring &name) +{ + if (name.compare(EDGE_TEX) == 0) return Tile::pistonBase->icon; + if (name.compare(PLATFORM_TEX) == 0) return Tile::pistonBase->iconPlatform; + if (name.compare(PLATFORM_STICKY_TEX) == 0) return Tile::sticky_piston->iconPlatform; + if (name.compare(INSIDE_TEX) == 0) return Tile::pistonBase->iconInside; + + return nullptr; +} + +//@Override +void PistonBaseTile::registerIcons(IconRegister *iconRegister) +{ + icon = iconRegister->registerIcon(EDGE_TEX); + iconPlatform = iconRegister->registerIcon(isSticky ? PLATFORM_STICKY_TEX : PLATFORM_TEX); + iconInside = iconRegister->registerIcon(INSIDE_TEX); + iconBack = iconRegister->registerIcon(BACK_TEX); +} + +int PistonBaseTile::getRenderShape() +{ + return SHAPE_PISTON_BASE; +} + +bool PistonBaseTile::isSolidRender(bool isServerLevel) +{ + return false; +} + +bool PistonBaseTile::use(Level *level, int x, int y, int z, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly/*=false*/) // 4J added soundOnly param +{ + return false; +} + +void PistonBaseTile::setPlacedBy(Level *level, int x, int y, int z, shared_ptr by, shared_ptr itemInstance) +{ + int targetData = getNewFacing(level, x, y, z, dynamic_pointer_cast(by) ); + level->setData(x, y, z, targetData, Tile::UPDATE_CLIENTS); + if (!level->isClientSide) + { + checkIfExtend(level, x, y, z); + } +} + +void PistonBaseTile::neighborChanged(Level *level, int x, int y, int z, int type) +{ + if (!level->isClientSide) + { + checkIfExtend(level, x, y, z); + } +} + +void PistonBaseTile::onPlace(Level *level, int x, int y, int z) +{ + if (!level->isClientSide && level->getTileEntity(x, y, z) == nullptr) + { + checkIfExtend(level, x, y, z); + } +} + +void PistonBaseTile::checkIfExtend(Level *level, int x, int y, int z) +{ + int data = level->getData(x, y, z); + int facing = getFacing(data); + + if (facing == UNDEFINED_FACING) + { + return; + } + bool extend = getNeighborSignal(level, x, y, z, facing); + + if (extend && !isExtended(data)) + { + if (canPush(level, x, y, z, facing)) + { + level->tileEvent(x, y, z, id, TRIGGER_EXTEND, facing); + } + } + else if (!extend && isExtended(data)) + { + // level->setData(x, y, z, facing, UPDATE_CLIENTS); + level->tileEvent(x, y, z, id, TRIGGER_CONTRACT, facing); + } +} + +/** +* This method checks neighbor signals for this block and the block above, +* and directly beneath. However, it avoids checking blocks that would be +* pushed by this block. +* +* @param level +* @param x +* @param y +* @param z +* @return +*/ +bool PistonBaseTile::getNeighborSignal(Level *level, int x, int y, int z, int facing) +{ + // check adjacent neighbors, but not in push direction + if (facing != Facing::DOWN && level->hasSignal(x, y - 1, z, Facing::DOWN)) return true; + if (facing != Facing::UP && level->hasSignal(x, y + 1, z, Facing::UP)) return true; + if (facing != Facing::NORTH && level->hasSignal(x, y, z - 1, Facing::NORTH)) return true; + if (facing != Facing::SOUTH && level->hasSignal(x, y, z + 1, Facing::SOUTH)) return true; + if (facing != Facing::EAST && level->hasSignal(x + 1, y, z, Facing::EAST)) return true; + if (facing != Facing::WEST && level->hasSignal(x - 1, y, z, Facing::WEST)) return true; + + // check signals above + if (level->hasSignal(x, y, z, 0)) return true; + if (level->hasSignal(x, y + 2, z, 1)) return true; + if (level->hasSignal(x, y + 1, z - 1, 2)) return true; + if (level->hasSignal(x, y + 1, z + 1, 3)) return true; + if (level->hasSignal(x - 1, y + 1, z, 4)) return true; + if (level->hasSignal(x + 1, y + 1, z, 5)) return true; + + return false; +} + +bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1, int facing) +{ + + if (!level->isClientSide) + { + bool extend = getNeighborSignal(level, x, y, z, facing); + + if (extend && param1 == TRIGGER_CONTRACT) + { + level->setData(x, y, z, facing | EXTENDED_BIT, UPDATE_CLIENTS); + return false; + } + else if (!extend && param1 == TRIGGER_EXTEND) + { + return false; + } + } + + if (param1 == TRIGGER_EXTEND) + { +#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) + { + int pushLength = 0; + int cx = x + Facing::STEP_X[facing]; + int cy = y + Facing::STEP_Y[facing]; + int cz = z + Facing::STEP_Z[facing]; + for (int i = 0; i < MAX_PUSH_DEPTH + 1; i++) + { + int block = level->getTile(cx, cy, cz); + if (block == 0) break; + if (!isPushable(block, level, cx, cy, cz, true)) break; + if (Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_DESTROY) { pushLength++; break; } + pushLength++; + if (i == MAX_PUSH_DEPTH) break; + cx += Facing::STEP_X[facing]; + cy += Facing::STEP_Y[facing]; + cz += Facing::STEP_Z[facing]; + } + if (FourKitBridge::FirePistonExtend(level->dimension->id, x, y, z, facing, pushLength)) + { + return false; + } + } +#endif + PIXBeginNamedEvent(0,"Create push\n"); + if (createPush(level, x, y, z, facing)) + { + // 4J - it is (currently) critical that this setData sends data to the client, so have added a bool to the method so that it sends data even if the data was already set to the same value + // as before, which was actually its behaviour until a change in 1.0.1 meant that setData only conditionally sent updates to listeners. If the data update Isn't sent, then what + // can happen is: + // (1) the host sends the tile event to the client + // (2) the client gets the tile event, and sets the tile/data value locally. + // (3) just before setting the tile/data locally, the client will put the old value in the vector of things to be restored should an update not be received back from the host + // (4) we don't get any update of the tile from the host, and so the old value gets restored on the client + // (5) the piston base ends up being restored to its retracted state whilst the piston arm is extended + // We really need to spend some time investigating a better way for pistons to work as it all seems a bit scary how the host/client interact, but forcing this to send should at least + // restore the behaviour of the pistons to something closer to what they were before the 1.0.1 update. By sending this data update, then (4) in the list above doesn't happen + // because the client does actually receive an update for this tile from the host after the event has been processed on the cient. + level->setData(x, y, z, facing | EXTENDED_BIT, Tile::UPDATE_CLIENTS, true); + level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_TILE_PISTON_OUT, 0.5f, level->random->nextFloat() * 0.25f + 0.6f); + } + else + { + return false; + } + PIXEndNamedEvent(); + } + else if (param1 == TRIGGER_CONTRACT) + { +#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) + if (FourKitBridge::FirePistonRetract(level->dimension->id, x, y, z, facing)) + { + level->setData(x, y, z, facing | EXTENDED_BIT, UPDATE_CLIENTS); + return false; + } +#endif + PIXBeginNamedEvent(0,"Contract phase A\n"); + shared_ptr prevTileEntity = level->getTileEntity(x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]); + if (prevTileEntity != nullptr && dynamic_pointer_cast(prevTileEntity) != nullptr) + { + dynamic_pointer_cast(prevTileEntity)->finalTick(); + } + + stopSharingIfServer(level, x, y, z); // 4J added + level->setTileAndData(x, y, z, Tile::piston_extension_Id, facing, Tile::UPDATE_ALL); + level->setTileEntity(x, y, z, PistonMovingPiece::newMovingPieceEntity(id, facing, facing, false, true)); + + PIXEndNamedEvent(); + + // sticky movement + if (isSticky) + { + PIXBeginNamedEvent(0,"Contract sticky phase A\n"); + int twoX = x + Facing::STEP_X[facing] * 2; + int twoY = y + Facing::STEP_Y[facing] * 2; + int twoZ = z + Facing::STEP_Z[facing] * 2; + int block = level->getTile(twoX, twoY, twoZ); + int blockData = level->getData(twoX, twoY, twoZ); + bool pistonPiece = false; + + PIXEndNamedEvent(); + + if (block == Tile::piston_extension_Id) + { + PIXBeginNamedEvent(0,"Contract sticky phase B\n"); + // the block two steps away is a moving piston block piece, so replace it with the real data, + // since it's probably this piston which is changing too fast + shared_ptr tileEntity = level->getTileEntity(twoX, twoY, twoZ); + if (tileEntity != nullptr && dynamic_pointer_cast(tileEntity) != nullptr ) + { + shared_ptr ppe = dynamic_pointer_cast(tileEntity); + + if (ppe->getFacing() == facing && ppe->isExtending()) + { + // force the tile to air before pushing + ppe->finalTick(); + block = ppe->getId(); + blockData = ppe->getData(); + pistonPiece = true; + } + } + PIXEndNamedEvent(); + } + + PIXBeginNamedEvent(0,"Contract sticky phase C\n"); + { + int pullDir = Facing::OPPOSITE_FACING[facing]; + int armX = x + Facing::STEP_X[facing]; + int armY = y + Facing::STEP_Y[facing]; + int armZ = z + Facing::STEP_Z[facing]; + + bool canPull = block > 0 + && isPushable(block, level, twoX, twoY, twoZ, false) + && (Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_NORMAL + || Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_SLIME + || block == Tile::piston_Id + || block == Tile::sticky_piston_Id); + + if (canPull) + { + std::vector toMove, toDestroy; + bool ok = collectStructure(level, pullDir, + twoX, twoY, twoZ, + x, y, z, + armX, armY, armZ, + false, + toMove, toDestroy); + + if (ok && !toMove.empty()) + { + applyStructureMove(level, x, y, z, facing, pullDir, isSticky, + toMove, toDestroy, false); + } + else if (block > 0 && Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_SLIME) + { + std::vector fallbackMove; + std::vector fallbackDestroy; + bool fallbackOk = collectStructure(level, pullDir, + twoX, twoY, twoZ, + x, y, z, + armX, armY, armZ, + true, + fallbackMove, fallbackDestroy); + if (fallbackOk && !fallbackMove.empty()) + { + applyStructureMove(level, x, y, z, facing, pullDir, isSticky, + fallbackMove, fallbackDestroy, false); + } + else + { + stopSharingIfServer(level, armX, armY, armZ); + level->removeTile(armX, armY, armZ); + } + } + else + { + stopSharingIfServer(level, armX, armY, armZ); + level->removeTile(armX, armY, armZ); + } + } + else + { + stopSharingIfServer(level, armX, armY, armZ); + level->removeTile(armX, armY, armZ); + } + } + PIXEndNamedEvent(); + } + else + { + stopSharingIfServer(level, x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]); // 4J added + level->removeTile(x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]); + } + + level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_TILE_PISTON_IN, 0.5f, level->random->nextFloat() * 0.15f + 0.6f); + } + + return true; +} + +void PistonBaseTile::updateShape(LevelSource *level, int x, int y, int z, int forceData, shared_ptr forceEntity) // 4J added forceData, forceEntity param +{ + int data = (forceData == -1 ) ? level->getData(x, y, z) : forceData; + + if (isExtended(data)) + { + const float thickness = PLATFORM_THICKNESS / 16.0f; + switch (getFacing(data)) + { + case Facing::DOWN: + setShape(0, thickness, 0, 1, 1, 1); + break; + case Facing::UP: + setShape(0, 0, 0, 1, 1 - thickness, 1); + break; + case Facing::NORTH: + setShape(0, 0, thickness, 1, 1, 1); + break; + case Facing::SOUTH: + setShape(0, 0, 0, 1, 1, 1 - thickness); + break; + case Facing::WEST: + setShape(thickness, 0, 0, 1, 1, 1); + break; + case Facing::EAST: + setShape(0, 0, 0, 1 - thickness, 1, 1); + break; + } + } + else + { + setShape(0, 0, 0, 1, 1, 1); + } +} + +void PistonBaseTile::updateDefaultShape() +{ + setShape(0, 0, 0, 1, 1, 1); +} + +void PistonBaseTile::addAABBs(Level *level, int x, int y, int z, AABB *box, AABBList *boxes, shared_ptr source) +{ + setShape(0, 0, 0, 1, 1, 1); + Tile::addAABBs(level, x, y, z, box, boxes, source); +} + +AABB *PistonBaseTile::getAABB(Level *level, int x, int y, int z) +{ + updateShape(level, x, y, z); + return Tile::getAABB(level, x, y, z); +} + +bool PistonBaseTile::isCubeShaped() +{ + return false; +} + +int PistonBaseTile::getFacing(int data) +{ + return data & 0x7; +} + +bool PistonBaseTile::isExtended(int data) +{ + return (data & EXTENDED_BIT) != 0; +} + +int PistonBaseTile::getNewFacing(Level *level, int x, int y, int z, shared_ptr player) +{ + if (Mth::abs(static_cast(player->x) - x) < 2 && Mth::abs(static_cast(player->z) - z) < 2) + { + // If the player is above the block, the slot is on the top + double py = player->y + 1.82 - player->heightOffset; + if (py - y > 2) + { + return Facing::UP; + } + // If the player is below the block, the slot is on the bottom + if (y - py > 0) + { + return Facing::DOWN; + } + } + // The slot is on the side + int i = Mth::floor(player->yRot * 4.0f / 360.0f + 0.5) & 0x3; + if (i == 0) return Facing::NORTH; + if (i == 1) return Facing::EAST; + if (i == 2) return Facing::SOUTH; + if (i == 3) return Facing::WEST; + return 0; +} + +bool PistonBaseTile::isPushable(int block, Level *level, int cx, int cy, int cz, bool allowDestroyable) +{ + Tile *tile = Tile::tiles[block]; + if (tile == nullptr) return false; // tu31 tutorial world fix + + // special case for obsidian + if (block == Tile::obsidian_Id) + { + return false; + } + + if (block == Tile::piston_Id || block == Tile::sticky_piston_Id) + { + // special case for piston bases + if (isExtended(level->getData(cx, cy, cz))) + { + return false; + } + } + else + { + if (tile->getDestroySpeed(level, cx, cy, cz) == Tile::INDESTRUCTIBLE_DESTROY_TIME) + { + return false; + } + + if (tile->getPistonPushReaction() == Material::PUSH_BLOCK) + { + return false; + } + + if (tile->getPistonPushReaction() == Material::PUSH_DESTROY) + { + if(!allowDestroyable) + { + return false; + } + return true; + } + } + + if( tile->isEntityTile() ) // 4J - java uses instanceof EntityTile here + { + // may not push tile entities + return false; + } + + return true; +} + +bool PistonBaseTile::canPush(Level *level, int sx, int sy, int sz, int facing) +{ + std::vector toMove, toDestroy; + return collectStructure(level, facing, + sx + Facing::STEP_X[facing], sy + Facing::STEP_Y[facing], sz + Facing::STEP_Z[facing], + sx, sy, sz, + INT_MIN, 0, 0, + true, + toMove, toDestroy); +} + +bool PistonBaseTile::collectStructure(Level *level, int moveDir, + int startX, int startY, int startZ, + int skipX, int skipY, int skipZ, + int skip2X, int skip2Y, int skip2Z, + bool allowDestroy, + std::vector &toMove, + std::vector &toDestroy) +{ + std::deque queue; + std::vector visited; + + auto hasVisited = [&](int x, int y, int z) -> bool { + for (auto &v : visited) if (v.x == x && v.y == y && v.z == z) return true; + return false; + }; + auto isSkipped = [&](int x, int y, int z) -> bool { + if (x == skipX && y == skipY && z == skipZ) return true; + if (x == skip2X && y == skip2Y && z == skip2Z) return true; + return false; + }; + + queue.push_back({startX, startY, startZ}); + + while (!queue.empty()) + { + BlockPos3 pos = queue.front(); + queue.pop_front(); + + if (hasVisited(pos.x, pos.y, pos.z)) continue; + if (isSkipped(pos.x, pos.y, pos.z)) continue; + visited.push_back(pos); + + if (pos.y <= 0 || pos.y >= (Level::maxBuildHeight - 1)) return false; + int minXZ = -(level->dimension->getXZSize() * 16) / 2; + int maxXZ = (level->dimension->getXZSize() * 16) / 2 - 1; + if (pos.x <= minXZ || pos.x >= maxXZ || pos.z <= minXZ || pos.z >= maxXZ) return false; + + int block = level->getTile(pos.x, pos.y, pos.z); + if (block == 0) continue; + + if (!isPushable(block, level, pos.x, pos.y, pos.z, allowDestroy)) return false; + + int reaction = Tile::tiles[block]->getPistonPushReaction(); + + if (reaction == Material::PUSH_DESTROY) + { + toDestroy.push_back(pos); + continue; + } + + if ((int)toMove.size() >= MAX_PUSH_DEPTH) return false; + toMove.push_back(pos); + + queue.push_back({pos.x + Facing::STEP_X[moveDir], + pos.y + Facing::STEP_Y[moveDir], + pos.z + Facing::STEP_Z[moveDir]}); + + if (reaction == Material::PUSH_SLIME) + { + for (int d = 0; d < 6; d++) + { + if (d == moveDir) continue; + int nx = pos.x + Facing::STEP_X[d]; + int ny = pos.y + Facing::STEP_Y[d]; + int nz = pos.z + Facing::STEP_Z[d]; + int neighborBlock = level->getTile(nx, ny, nz); + if (neighborBlock == 0) continue; + if (!isPushable(neighborBlock, level, nx, ny, nz, false)) continue; + queue.push_back({nx, ny, nz}); + } + } + } + + return true; +} + +void PistonBaseTile::applyStructureMove(Level *level, + int pistonX, int pistonY, int pistonZ, + int facing, int moveDir, bool sticky, + std::vector &toMove, + std::vector &toDestroy, + bool isExtension) +{ + for (auto &dpos : toDestroy) + { + int block = level->getTile(dpos.x, dpos.y, dpos.z); + if (block > 0) + { + Tile::tiles[block]->spawnResources(level, dpos.x, dpos.y, dpos.z, level->getData(dpos.x, dpos.y, dpos.z), 0); + stopSharingIfServer(level, dpos.x, dpos.y, dpos.z); + level->removeTile(dpos.x, dpos.y, dpos.z); + } + } + + int n = (int)toMove.size(); + int armX = pistonX + Facing::STEP_X[facing]; + int armY = pistonY + Facing::STEP_Y[facing]; + int armZ = pistonZ + Facing::STEP_Z[facing]; + + if (n == 0) + { + if (isExtension) + { + int armData = facing | (sticky ? PistonExtensionTile::STICKY_BIT : 0); + stopSharingIfServer(level, armX, armY, armZ); + level->setTileAndData(armX, armY, armZ, Tile::piston_extension_Id, armData, Tile::UPDATE_NONE); + level->setTileEntity(armX, armY, armZ, + PistonMovingPiece::newMovingPieceEntity(Tile::piston_head_Id, armData, facing, true, false)); + } + return; + } + + std::vector savedBlocks(n), savedDatas(n); + for (int i = 0; i < n; i++) + { + savedBlocks[i] = level->getTile(toMove[i].x, toMove[i].y, toMove[i].z); + savedDatas[i] = level->getData(toMove[i].x, toMove[i].y, toMove[i].z); + } + + std::sort(toMove.begin(), toMove.end(), + [&](const BlockPos3 &a, const BlockPos3 &b) { + int da = a.x * Facing::STEP_X[moveDir] + a.y * Facing::STEP_Y[moveDir] + a.z * Facing::STEP_Z[moveDir]; + int db = b.x * Facing::STEP_X[moveDir] + b.y * Facing::STEP_Y[moveDir] + b.z * Facing::STEP_Z[moveDir]; + return da > db; + }); + + for (int i = 0; i < n; i++) + { + savedBlocks[i] = level->getTile(toMove[i].x, toMove[i].y, toMove[i].z); + savedDatas[i] = level->getData(toMove[i].x, toMove[i].y, toMove[i].z); + } + + for (int i = 0; i < n; i++) + { + auto &pos = toMove[i]; + int destX = pos.x + Facing::STEP_X[moveDir]; + int destY = pos.y + Facing::STEP_Y[moveDir]; + int destZ = pos.z + Facing::STEP_Z[moveDir]; + + stopSharingIfServer(level, destX, destY, destZ); + level->setTileAndData(destX, destY, destZ, Tile::piston_extension_Id, savedDatas[i], Tile::UPDATE_NONE); + level->setTileEntity(destX, destY, destZ, + PistonMovingPiece::newMovingPieceEntity(savedBlocks[i], savedDatas[i], facing, isExtension, false)); + } + + if (isExtension) + { + int armData = facing | (sticky ? PistonExtensionTile::STICKY_BIT : 0); + stopSharingIfServer(level, armX, armY, armZ); + level->setTileAndData(armX, armY, armZ, Tile::piston_extension_Id, armData, Tile::UPDATE_NONE); + level->setTileEntity(armX, armY, armZ, + PistonMovingPiece::newMovingPieceEntity(Tile::piston_head_Id, armData, facing, true, false)); + } + + for (int i = 0; i < n; i++) + { + auto &pos = toMove[i]; + + if (isExtension && pos.x == armX && pos.y == armY && pos.z == armZ) + continue; + + int srcX = pos.x - Facing::STEP_X[moveDir]; + int srcY = pos.y - Facing::STEP_Y[moveDir]; + int srcZ = pos.z - Facing::STEP_Z[moveDir]; + bool receivesBlock = false; + for (auto &src : toMove) + { + if (src.x == srcX && src.y == srcY && src.z == srcZ) + { + receivesBlock = true; + break; + } + } + if (!receivesBlock) + { + stopSharingIfServer(level, pos.x, pos.y, pos.z); + level->setTileAndData(pos.x, pos.y, pos.z, 0, 0, Tile::UPDATE_CLIENTS); + } + } + + for (int i = 0; i < n; i++) + { + level->updateNeighborsAt(toMove[i].x, toMove[i].y, toMove[i].z, savedBlocks[i]); + } +} + +void PistonBaseTile::stopSharingIfServer(Level *level, int x, int y, int z) +{ + if( !level->isClientSide ) + { + MultiPlayerLevel *clientLevel = Minecraft::GetInstance()->getLevel(level->dimension->id); + if( clientLevel ) + { + LevelChunk *lc = clientLevel->getChunkAt( x, z ); + lc->stopSharingTilesAndData(); + } + } +} + +bool PistonBaseTile::createPush(Level *level, int sx, int sy, int sz, int facing) +{ + std::vector toMove, toDestroy; + + if (!collectStructure(level, facing, + sx + Facing::STEP_X[facing], sy + Facing::STEP_Y[facing], sz + Facing::STEP_Z[facing], + sx, sy, sz, + INT_MIN, 0, 0, + true, + toMove, toDestroy)) + { + return false; + } + + applyStructureMove(level, sx, sy, sz, facing, facing, isSticky, + toMove, toDestroy, true); + + return true; +} diff --git a/Minecraft.World/PistonBaseTile.h b/Minecraft.World/PistonBaseTile.h index b307c7b4..ee535bce 100644 --- a/Minecraft.World/PistonBaseTile.h +++ b/Minecraft.World/PistonBaseTile.h @@ -1,70 +1,93 @@ -#pragma once -#include "Tile.h" - -class PistonBaseTile : public Tile -{ -public: - static const int EXTENDED_BIT = 8; - static const int UNDEFINED_FACING = 7; - - static const float PLATFORM_THICKNESS; - static const int MAX_PUSH_DEPTH = 12; - static const int TRIGGER_EXTEND = 0; - static const int TRIGGER_CONTRACT = 1; - - static const wstring EDGE_TEX; - static const wstring PLATFORM_TEX; - static const wstring PLATFORM_STICKY_TEX; - static const wstring BACK_TEX; - static const wstring INSIDE_TEX; - -private: - bool isSticky; - - Icon *iconInside; - Icon *iconBack; - Icon *iconPlatform; - - static DWORD tlsIdx; - // 4J - was just a static but implemented with TLS for our version - //code removed so the above comment no longer applies - -public: - PistonBaseTile(int id, bool isSticky); - - Icon *getPlatformTexture(); - virtual void updateShape(float x0, float y0, float z0, float x1, float y1, float z1); - - virtual Icon *getTexture(int face, int data); - static Icon *getTexture(const wstring &name); - void registerIcons(IconRegister *iconRegister); - - virtual int getRenderShape(); - virtual bool isSolidRender(bool isServerLevel = false); - virtual bool use(Level *level, int x, int y, int z, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false); // 4J added soundOnly param - virtual void setPlacedBy(Level *level, int x, int y, int z, shared_ptr by, shared_ptr itemInstance); - virtual void neighborChanged(Level *level, int x, int y, int z, int type); - virtual void onPlace(Level *level, int x, int y, int z); - -private: - void checkIfExtend(Level *level, int x, int y, int z); - bool getNeighborSignal(Level *level, int x, int y, int z, int facing); - -public: - virtual bool triggerEvent(Level *level, int x, int y, int z, int param1, int facing); - virtual void updateShape(LevelSource *level, int x, int y, int z, int forceData = -1, shared_ptr forceEntity = shared_ptr()); // 4J added forceData, forceEntity param - virtual void updateDefaultShape(); - virtual void addAABBs(Level *level, int x, int y, int z, AABB *box, AABBList *boxes, shared_ptr source); - virtual AABB *getAABB(Level *level, int x, int y, int z); - virtual bool isCubeShaped(); - - static int getFacing(int data); - static bool isExtended(int data); - static int getNewFacing(Level *level, int x, int y, int z, shared_ptr player); -private: - static bool isPushable(int block, Level *level, int cx, int cy, int cz, bool allowDestroyable); - static bool canPush(Level *level, int sx, int sy, int sz, int facing); - static void stopSharingIfServer(Level *level, int x, int y, int z); // 4J added - - bool createPush(Level *level, int sx, int sy, int sz, int facing); -}; +#pragma once +#include "Tile.h" +#include + +struct BlockPos3 +{ + int x, y, z; + bool operator==(const BlockPos3 &o) const { return x == o.x && y == o.y && z == o.z; } +}; + +class PistonBaseTile : public Tile +{ +public: + static const int EXTENDED_BIT = 8; + static const int UNDEFINED_FACING = 7; + + static const float PLATFORM_THICKNESS; + static const int MAX_PUSH_DEPTH = 12; + static const int TRIGGER_EXTEND = 0; + static const int TRIGGER_CONTRACT = 1; + + static const wstring EDGE_TEX; + static const wstring PLATFORM_TEX; + static const wstring PLATFORM_STICKY_TEX; + static const wstring BACK_TEX; + static const wstring INSIDE_TEX; + +private: + bool isSticky; + + Icon *iconInside; + Icon *iconBack; + Icon *iconPlatform; + + static DWORD tlsIdx; + //code removed so the above comment no longer applies + +public: + PistonBaseTile(int id, bool isSticky); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + + Icon *getPlatformTexture(); + virtual void updateShape(float x0, float y0, float z0, float x1, float y1, float z1); + + virtual Icon *getTexture(int face, int data); + static Icon *getTexture(const wstring &name); + void registerIcons(IconRegister *iconRegister); + + virtual int getRenderShape(); + virtual bool isSolidRender(bool isServerLevel = false); + virtual bool use(Level *level, int x, int y, int z, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false); // 4J added soundOnly param + virtual void setPlacedBy(Level *level, int x, int y, int z, shared_ptr by, shared_ptr itemInstance); + virtual void neighborChanged(Level *level, int x, int y, int z, int type); + virtual void onPlace(Level *level, int x, int y, int z); + +private: + void checkIfExtend(Level *level, int x, int y, int z); + bool getNeighborSignal(Level *level, int x, int y, int z, int facing); + +public: + virtual bool triggerEvent(Level *level, int x, int y, int z, int param1, int facing); + virtual void updateShape(LevelSource *level, int x, int y, int z, int forceData = -1, shared_ptr forceEntity = shared_ptr()); // 4J added forceData, forceEntity param + virtual void updateDefaultShape(); + virtual void addAABBs(Level *level, int x, int y, int z, AABB *box, AABBList *boxes, shared_ptr source); + virtual AABB *getAABB(Level *level, int x, int y, int z); + virtual bool isCubeShaped(); + + static int getFacing(int data); + static bool isExtended(int data); + static int getNewFacing(Level *level, int x, int y, int z, shared_ptr player); +private: + static bool isPushable(int block, Level *level, int cx, int cy, int cz, bool allowDestroyable); + static bool canPush(Level *level, int sx, int sy, int sz, int facing); + static bool collectStructure(Level *level, int moveDir, + int startX, int startY, int startZ, + int skipX, int skipY, int skipZ, + int skip2X, int skip2Y, int skip2Z, + bool allowDestroy, + std::vector &toMove, + std::vector &toDestroy); + static void applyStructureMove(Level *level, int pistonX, int pistonY, int pistonZ, + int facing, int moveDir, bool isSticky, + std::vector &toMove, + std::vector &toDestroy, + bool isExtension); + static void stopSharingIfServer(Level *level, int x, int y, int z); // 4J added + + bool createPush(Level *level, int sx, int sy, int sz, int facing); +}; diff --git a/Minecraft.World/PistonExtensionTile.cpp b/Minecraft.World/PistonExtensionTile.cpp index bf5e6e60..c5798c5c 100644 --- a/Minecraft.World/PistonExtensionTile.cpp +++ b/Minecraft.World/PistonExtensionTile.cpp @@ -13,6 +13,32 @@ PistonExtensionTile::PistonExtensionTile(int id) : Tile(id, Material::piston,isS setDestroyTime(0.5f); } +void PistonExtensionTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int PistonExtensionTile::defaultBlockState() +{ + return 0; +} + +int PistonExtensionTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState PistonExtensionTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState PistonExtensionTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + void PistonExtensionTile::setOverrideTopTexture(Icon *overrideTopTexture) { this->overrideTopTexture = overrideTopTexture; @@ -29,7 +55,7 @@ void PistonExtensionTile::playerWillDestroy(Level *level, int x, int y, int z, i { int facing = getFacing(data); int tile = level->getTile(x - Facing::STEP_X[facing], y - Facing::STEP_Y[facing], z - Facing::STEP_Z[facing]); - if (tile == Tile::pistonBase_Id || tile == Tile::pistonStickyBase_Id) + if (tile == Tile::piston_Id || tile == Tile::sticky_piston_Id) { level->removeTile(x - Facing::STEP_X[facing], y - Facing::STEP_Y[facing], z - Facing::STEP_Z[facing]); } @@ -47,7 +73,7 @@ void PistonExtensionTile::onRemove(Level *level, int x, int y, int z, int id, in int t = level->getTile(x, y, z); - if (t == Tile::pistonBase_Id || t == Tile::pistonStickyBase_Id) + if (t == Tile::piston_Id || t == Tile::sticky_piston_Id) { data = level->getData(x, y, z); if (PistonBaseTile::isExtended(data)) @@ -203,7 +229,7 @@ void PistonExtensionTile::neighborChanged(Level *level, int x, int y, int z, int { int facing = getFacing(level->getData(x, y, z)); int tile = level->getTile(x - Facing::STEP_X[facing], y - Facing::STEP_Y[facing], z - Facing::STEP_Z[facing]); - if (tile != Tile::pistonBase_Id && tile != Tile::pistonStickyBase_Id) + if (tile != Tile::piston_Id && tile != Tile::sticky_piston_Id) { level->removeTile(x, y, z); } @@ -223,8 +249,8 @@ int PistonExtensionTile::cloneTileId(Level *level, int x, int y, int z) int data = level->getData(x, y, z); if ((data & STICKY_BIT) != 0) { - return Tile::pistonStickyBase_Id; + return Tile::sticky_piston_Id; } - return Tile::pistonBase_Id; + return Tile::piston_Id; return 0; } \ No newline at end of file diff --git a/Minecraft.World/PistonExtensionTile.h b/Minecraft.World/PistonExtensionTile.h index bd00b8e2..7725707f 100644 --- a/Minecraft.World/PistonExtensionTile.h +++ b/Minecraft.World/PistonExtensionTile.h @@ -12,6 +12,11 @@ private: public: PistonExtensionTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; virtual void setOverrideTopTexture(Icon *overrideTopTexture); virtual void clearOverrideTopTexture(); virtual void playerWillDestroy(Level *level, int x, int y, int z, int data, shared_ptr player); diff --git a/Minecraft.World/PistonPieceEntity.cpp b/Minecraft.World/PistonPieceEntity.cpp index 08e18cbb..6faa0daa 100644 --- a/Minecraft.World/PistonPieceEntity.cpp +++ b/Minecraft.World/PistonPieceEntity.cpp @@ -2,6 +2,7 @@ #include "com.mojang.nbt.h" #include "PistonPieceEntity.h" #include "PistonMovingPiece.h" +#include "net.minecraft.world.phys.h" #include "net.minecraft.world.level.h" #include "Facing.h" #include "Tile.h" @@ -119,7 +120,13 @@ void PistonPieceEntity::moveCollidedEntities(float progress, float amount) AABB *aabb = Tile::pistonMovingPiece->getAABB(level, x, y, z, id, progress, facing); if (aabb != nullptr) { - vector > *entities = level->getEntities(nullptr, aabb); + AABB *queryBox = aabb; + if (id == Tile::slimeBlock->id && Facing::STEP_Y[facing] > 0) + { + queryBox = AABB::newTemp(aabb->x0, aabb->y0, aabb->z0, aabb->x1, aabb->y1 + 1.0f, aabb->z1); + } + + vector > *entities = level->getEntities(nullptr, queryBox); if (!entities->empty()) { vector< shared_ptr > collisionHolder; @@ -133,6 +140,18 @@ void PistonPieceEntity::moveCollidedEntities(float progress, float amount) it->move(amount * Facing::STEP_X[facing], amount * Facing::STEP_Y[facing], amount * Facing::STEP_Z[facing]); + + if (id == Tile::slimeBlock->id && Facing::STEP_Y[facing] > 0) + { + if (it->yd < amount) + { + it->yd = amount; + } + it->yd = it->yd * 1.25f; + it->onGround = false; + it->fallDistance = 0.0f; + it->hasImpulse = true; + } } } } @@ -145,7 +164,7 @@ void PistonPieceEntity::finalTick() progressO = progress = 1; level->removeTileEntity(x, y, z); setRemoved(); - if (level->getTile(x, y, z) == Tile::pistonMovingPiece_Id) + if (level->getTile(x, y, z) == Tile::piston_extension_Id) { level->setTileAndData(x, y, z, id, data, Tile::UPDATE_ALL); level->neighborChanged(x, y, z, id); @@ -162,7 +181,7 @@ void PistonPieceEntity::tick() moveCollidedEntities(1, 4 / 16.f); level->removeTileEntity(x, y, z); setRemoved(); - if (level->getTile(x, y, z) == Tile::pistonMovingPiece_Id) + if (level->getTile(x, y, z) == Tile::piston_extension_Id) { level->setTileAndData(x, y, z, id, data, Tile::UPDATE_ALL); level->neighborChanged(x, y, z, id); diff --git a/Minecraft.World/PlainsBiome.cpp b/Minecraft.World/PlainsBiome.cpp index 4e562099..c55df71d 100644 --- a/Minecraft.World/PlainsBiome.cpp +++ b/Minecraft.World/PlainsBiome.cpp @@ -22,25 +22,25 @@ Feature* PlainsBiome::getFlowerFeature(Random* random, int x, int y, int z) { int j = random->nextInt(4); switch (j) { - case 0: return new FlowerFeature(Tile::rose_Id, Rose::ORANGE_TULIP); - case 1: return new FlowerFeature(Tile::rose_Id, Rose::RED_TULIP); - case 2: return new FlowerFeature(Tile::rose_Id, Rose::PINK_TULIP); - case 3: return new FlowerFeature(Tile::rose_Id, Rose::WHITE_TULIP); + case 0: return new FlowerFeature(Tile::red_flower_Id, Rose::ORANGE_TULIP); + case 1: return new FlowerFeature(Tile::red_flower_Id, Rose::RED_TULIP); + case 2: return new FlowerFeature(Tile::red_flower_Id, Rose::PINK_TULIP); + case 3: return new FlowerFeature(Tile::red_flower_Id, Rose::WHITE_TULIP); } }else if (random->nextInt(3) > 0) { int i = random->nextInt(3); if (i == 1) { - return new FlowerFeature(Tile::rose_Id,Rose::AZURE_BLUET); + return new FlowerFeature(Tile::red_flower_Id,Rose::AZURE_BLUET); } else - return new FlowerFeature(Tile::rose_Id,Rose::OXEYE_DAISY); + return new FlowerFeature(Tile::red_flower_Id,Rose::OXEYE_DAISY); } else { - return new FlowerFeature(Tile::flower_Id); + return new FlowerFeature(Tile::yellow_flower_Id); } return Biome::getFlowerFeature(random, x, y, z); @@ -58,12 +58,8 @@ void PlainsBiome::decorate(Level* level, Random* rand, int xo, int zo) decorator->flowerCount = 4; decorator->grassCount = 10; + DOUBLE_PLANT_GENERATOR->setPlantType(TallGrass2::TALL_GRASS); - - - - - for (int i = 0; i < 7; ++i) { int x = xo + rand->nextInt(16) + 8; @@ -76,11 +72,10 @@ void PlainsBiome::decorate(Level* level, Random* rand, int xo, int zo) if (_plains) { DOUBLE_PLANT_GENERATOR->setPlantType(TallGrass2::SUNFLOWER); - for (int i1 = 0; i1 < 10; ++i1) { - int j1 = rand->nextInt(16) + 8; - int k1 = rand->nextInt(16) + 8; + int j1 = xo + rand->nextInt(16) + 8; + int k1 = zo + rand->nextInt(16) + 8; int l1 = rand->nextInt(level->getHeightmap(j1, k1) + 32); DOUBLE_PLANT_GENERATOR->place(level, rand, j1, l1, k1); } diff --git a/Minecraft.World/Player.cpp b/Minecraft.World/Player.cpp index 01d45328..df1f8bd6 100644 --- a/Minecraft.World/Player.cpp +++ b/Minecraft.World/Player.cpp @@ -388,7 +388,7 @@ void Player::tick() this->drop( shared_ptr( new ItemInstance(Item::map) ) ); this->drop( shared_ptr( new ItemInstance(Item::record_01) ) ); this->drop( shared_ptr( new ItemInstance(Item::record_02) ) ); - this->drop( shared_ptr(new ItemInstance( Item::pickAxe_diamond, 1 )) ); + this->drop( shared_ptr(new ItemInstance( Item::diamond_pickaxe, 1 )) ); #endif #ifdef __PS3__ @@ -398,7 +398,7 @@ void Player::tick() // this->drop( shared_ptr( new ItemInstance(Item::map) ) ); // this->drop( shared_ptr( new ItemInstance(Item::record_01) ) ); // this->drop( shared_ptr( new ItemInstance(Item::record_02) ) ); - // this->drop( shared_ptr(new ItemInstance( Item::pickAxe_diamond, 1 )) ); + // this->drop( shared_ptr(new ItemInstance( Item::diamond_pickaxe, 1 )) ); // #endif #endif @@ -408,11 +408,11 @@ void Player::tick() this->drop( shared_ptr( new ItemInstance(Item::map) ) ); this->drop( shared_ptr( new ItemInstance(Item::record_01) ) ); this->drop( shared_ptr( new ItemInstance(Item::record_02) ) ); - this->drop( shared_ptr(new ItemInstance( Item::pickAxe_diamond, 1 )) ); + this->drop( shared_ptr(new ItemInstance( Item::diamond_pickaxe, 1 )) ); #endif #endif // 4J-PB - Throw items out at the start of the level - //this->drop( new ItemInstance( Item::pickAxe_diamond, 1 ) ); + //this->drop( new ItemInstance( Item::diamond_pickaxe, 1 ) ); //this->drop( new ItemInstance( Tile::workBench, 1 ) ); //this->drop( new ItemInstance( Tile::treeTrunk, 8 ) ); //this->drop( shared_ptr( new ItemInstance( Item::milk, 3 ) ) ); @@ -460,7 +460,7 @@ void Player::tick() // increaseXp(10); { - // ItemInstance itemInstance = new ItemInstance(Item.pickAxe_diamond); + // ItemInstance itemInstance = new ItemInstance(Item.diamond_pickaxe); // itemInstance.enchant(Enchantment.diggingBonus, 3); // inventory.add(itemInstance); } @@ -479,16 +479,16 @@ void Player::tick() int poweredCount = 0; for(int i = 10; i < 2800; ++i) { - level->setTileAndData(x+i,y-1,z-2,Tile::quartzBlock_Id,0,Tile::UPDATE_CLIENTS); - level->setTileAndData(x+i,y,z-2,Tile::quartzBlock_Id,0,Tile::UPDATE_CLIENTS); - level->setTileAndData(x+i,y+1,z-2,Tile::quartzBlock_Id,0,Tile::UPDATE_CLIENTS); + level->setTileAndData(x+i,y-1,z-2,Tile::quartz_block_Id,0,Tile::UPDATE_CLIENTS); + level->setTileAndData(x+i,y,z-2,Tile::quartz_block_Id,0,Tile::UPDATE_CLIENTS); + level->setTileAndData(x+i,y+1,z-2,Tile::quartz_block_Id,0,Tile::UPDATE_CLIENTS); level->setTileAndData(x+i,y+2,z-2,Tile::glowstone_Id,0,Tile::UPDATE_CLIENTS); - level->setTileAndData(x+i,y+3,z-2,Tile::quartzBlock_Id,0,Tile::UPDATE_CLIENTS); + level->setTileAndData(x+i,y+3,z-2,Tile::quartz_block_Id,0,Tile::UPDATE_CLIENTS); - level->setTileAndData(x+i,y-1,z-1,Tile::stoneBrick_Id,0,Tile::UPDATE_CLIENTS); + level->setTileAndData(x+i,y-1,z-1,Tile::stonebrick_Id,0,Tile::UPDATE_CLIENTS); if(i%20 == 0) { - level->setTileAndData(x+i,y,z-1,Tile::redstoneTorch_on_Id,0,Tile::UPDATE_CLIENTS); + level->setTileAndData(x+i,y,z-1,Tile::redstone_torch_Id,0,Tile::UPDATE_CLIENTS); poweredCount = 4; } else @@ -499,10 +499,10 @@ void Player::tick() level->setTileAndData(x+i,y+2,z-1,0,0,Tile::UPDATE_CLIENTS); level->setTileAndData(x+i,y+3,z-1,0,0,Tile::UPDATE_CLIENTS); - level->setTileAndData(x+i,y-1,z,Tile::stoneBrick_Id,0,Tile::UPDATE_CLIENTS); + level->setTileAndData(x+i,y-1,z,Tile::stonebrick_Id,0,Tile::UPDATE_CLIENTS); if(poweredCount>0) { - level->setTileAndData(x+i,y,z,Tile::goldenRail_Id,0,Tile::UPDATE_CLIENTS); + level->setTileAndData(x+i,y,z,Tile::golden_rail_Id,0,Tile::UPDATE_CLIENTS); --poweredCount; } else @@ -513,7 +513,7 @@ void Player::tick() level->setTileAndData(x+i,y+2,z,0,0,Tile::UPDATE_CLIENTS); level->setTileAndData(x+i,y+3,z,0,0,Tile::UPDATE_CLIENTS); - level->setTileAndData(x+i,y-1,z+1,Tile::stoneBrick_Id,0,Tile::UPDATE_CLIENTS); + level->setTileAndData(x+i,y-1,z+1,Tile::stonebrick_Id,0,Tile::UPDATE_CLIENTS); if((i+5)%20 == 0) { level->setTileAndData(x+i,y,z+1,Tile::torch_Id,0,Tile::UPDATE_CLIENTS); @@ -526,11 +526,11 @@ void Player::tick() level->setTileAndData(x+i,y+2,z+1,0,0,Tile::UPDATE_CLIENTS); level->setTileAndData(x+i,y+3,z+1,0,0,Tile::UPDATE_CLIENTS); - level->setTileAndData(x+i,y-1,z+2,Tile::quartzBlock_Id,0,Tile::UPDATE_CLIENTS); - level->setTileAndData(x+i,y,z+2,Tile::quartzBlock_Id,0,Tile::UPDATE_CLIENTS); - level->setTileAndData(x+i,y+1,z+2,Tile::quartzBlock_Id,0,Tile::UPDATE_CLIENTS); + level->setTileAndData(x+i,y-1,z+2,Tile::quartz_block_Id,0,Tile::UPDATE_CLIENTS); + level->setTileAndData(x+i,y,z+2,Tile::quartz_block_Id,0,Tile::UPDATE_CLIENTS); + level->setTileAndData(x+i,y+1,z+2,Tile::quartz_block_Id,0,Tile::UPDATE_CLIENTS); level->setTileAndData(x+i,y+2,z+2,Tile::glowstone_Id,0,Tile::UPDATE_CLIENTS); - level->setTileAndData(x+i,y+3,z+2,Tile::quartzBlock_Id,0,Tile::UPDATE_CLIENTS); + level->setTileAndData(x+i,y+3,z+2,Tile::quartz_block_Id,0,Tile::UPDATE_CLIENTS); } madeTrack = true; } @@ -1554,7 +1554,7 @@ void Player::openTextEdit(shared_ptr sign) { } -bool Player::openBrewingStand(shared_ptr brewingStand) +bool Player::openBrewingStand(shared_ptr brewing_stand) { return true; } @@ -2500,9 +2500,9 @@ void Player::makeStuckInWeb() Icon *Player::getItemInHandIcon(shared_ptr item, int layer) { Icon *icon = LivingEntity::getItemInHandIcon(item, layer); - if (item->id == Item::fishingRod->id && fishing != nullptr) + if (item->id == Item::fishing_rod->id && fishing != nullptr) { - icon = Item::fishingRod->getEmptyIcon(); + icon = Item::fishing_rod->getEmptyIcon(); } else if (item->getItem()->hasMultipleSpriteLayers()) { @@ -3081,11 +3081,11 @@ bool Player::isAllowedToUse(Tile *tile) { switch(tile->id) { - case Tile::door_wood_Id: - case Tile::button_stone_Id: - case Tile::button_wood_Id: + case Tile::wooden_door_Id: + case Tile::stone_button_Id: + case Tile::wooden_button_Id: case Tile::lever_Id: - case Tile::fenceGate_Id: + case Tile::fence_gate_Id: case Tile::trapdoor_Id: allowed = true; break; @@ -3098,13 +3098,13 @@ bool Player::isAllowedToUse(Tile *tile) { case Tile::chest_Id: case Tile::furnace_Id: - case Tile::furnace_lit_Id: + case Tile::lit_furnace_Id: case Tile::dispenser_Id: - case Tile::brewingStand_Id: - case Tile::enchantTable_Id: - case Tile::workBench_Id: + case Tile::brewing_stand_Id: + case Tile::enchanting_table_Id: + case Tile::crafting_table_Id: case Tile::anvil_Id: - case Tile::enderChest_Id: + case Tile::ender_chest_Id: allowed = true; break; } @@ -3114,21 +3114,21 @@ bool Player::isAllowedToUse(Tile *tile) { switch(tile->id) { - case Tile::door_wood_Id: - case Tile::button_stone_Id: - case Tile::button_wood_Id: + case Tile::wooden_door_Id: + case Tile::stone_button_Id: + case Tile::wooden_button_Id: case Tile::lever_Id: - case Tile::fenceGate_Id: + case Tile::fence_gate_Id: case Tile::trapdoor_Id: case Tile::chest_Id: case Tile::furnace_Id: - case Tile::furnace_lit_Id: + case Tile::lit_furnace_Id: case Tile::dispenser_Id: - case Tile::brewingStand_Id: - case Tile::enchantTable_Id: - case Tile::workBench_Id: + case Tile::brewing_stand_Id: + case Tile::enchanting_table_Id: + case Tile::crafting_table_Id: case Tile::anvil_Id: - case Tile::enderChest_Id: + case Tile::ender_chest_Id: allowed = false; break; default: @@ -3155,28 +3155,28 @@ bool Player::isAllowedToUse(shared_ptr item) switch(item->id) { // food - case Item::mushroomStew_Id: + case Item::mushroom_stew_Id: case Item::apple_Id: case Item::bread_Id: - case Item::porkChop_raw_Id: - case Item::porkChop_cooked_Id: - case Item::apple_gold_Id: - case Item::fish_raw_Id: - case Item::fish_cooked_Id: + case Item::porkchop_Id: + case Item::cooked_porkchop_Id: + case Item::golden_apple_Id: + case Item::fish_Id: + case Item::cooked_fish_Id: case Item::cookie_Id: - case Item::beef_cooked_Id: - case Item::beef_raw_Id: - case Item::chicken_cooked_Id: - case Item::chicken_raw_Id: - case Item::melon_Id: + case Item::cooked_beef_Id: + case Item::beef_Id: + case Item::cooked_chicken_Id: + case Item::chicken_Id: + case Item::melon_block_Id: case Item::rotten_flesh_Id: // bow case Item::bow_Id: - case Item::sword_diamond_Id: - case Item::sword_gold_Id: - case Item::sword_iron_Id: - case Item::sword_stone_Id: - case Item::sword_wood_Id: + case Item::diamond_sword_Id: + case Item::golden_sword_Id: + case Item::iron_sword_Id: + case Item::stone_sword_Id: + case Item::wooden_sword_Id: allowed = true; break; } diff --git a/Minecraft.World/Player.h b/Minecraft.World/Player.h index 6b25bc2d..59979f9a 100644 --- a/Minecraft.World/Player.h +++ b/Minecraft.World/Player.h @@ -279,7 +279,7 @@ public: virtual bool openFurnace(shared_ptr container); // 4J - added bool return virtual bool openTrap(shared_ptr container); // 4J - added bool return virtual void openTextEdit(shared_ptr sign); - virtual bool openBrewingStand(shared_ptr brewingStand); // 4J - added bool return + virtual bool openBrewingStand(shared_ptr brewing_stand); // 4J - added bool return virtual bool openBeacon(shared_ptr beacon); virtual bool openTrading(shared_ptr traderTarget, const wstring &name); // 4J - added bool return virtual void openItemInstanceGui(shared_ptr itemInstance, shared_ptr player); diff --git a/Minecraft.World/PortalForcer.cpp b/Minecraft.World/PortalForcer.cpp index 049e2d36..9c23fb75 100644 --- a/Minecraft.World/PortalForcer.cpp +++ b/Minecraft.World/PortalForcer.cpp @@ -101,14 +101,77 @@ bool PortalForcer::findPortal(shared_ptr e, double xOriginal, double yOr { PortalPosition *pos = it->second; - closest = 0; - xTarget = pos->x; - yTarget = pos->y; - zTarget = pos->z; - pos->lastUsed = level->getGameTime(); - updateCache = false; + if (level->getTile(pos->x, pos->y, pos->z) == Tile::portal_Id) + { + closest = 0; + xTarget = pos->x; + yTarget = pos->y; + zTarget = pos->z; + pos->lastUsed = level->getGameTime(); + updateCache = false; + } + else + { + delete pos; + cachedPortals.erase(it); + for (auto keyIt = cachedPortalKeys.begin(); keyIt != cachedPortalKeys.end(); ++keyIt) + { + if (*keyIt == hash) + { + cachedPortalKeys.erase(keyIt); + break; + } + } + } } - else + + if (updateCache) + { + const int localRadius = 16; + double localClosest = -1; + int localX = 0; + int localY = 0; + int localZ = 0; + + for (int x = xc - localRadius; x <= xc + localRadius; x++) + { + double xd = (x + 0.5) - e->x; + for (int z = zc - localRadius; z <= zc + localRadius; z++) + { + double zd = (z + 0.5) - e->z; + for (int y = level->getHeight() - 1; y >= 0; y--) + { + if (level->getTile(x, y, z) == Tile::portal_Id) + { + while (level->getTile(x, y - 1, z) == Tile::portal_Id) + { + y--; + } + + double yd = (y + 0.5) - e->y; + double dist = xd * xd + yd * yd + zd * zd; + if (localClosest < 0 || dist < localClosest) + { + localClosest = dist; + localX = x; + localY = y; + localZ = z; + } + } + } + } + } + + if (localClosest >= 0) + { + closest = localClosest; + xTarget = localX; + yTarget = localY; + zTarget = localZ; + } + } + + if (closest < 0) { for (int x = xc - r; x <= xc + r; x++) { @@ -118,9 +181,9 @@ bool PortalForcer::findPortal(shared_ptr e, double xOriginal, double yOr double zd = (z + 0.5) - e->z; for (int y = level->getHeight() - 1; y >= 0; y--) { - if (level->getTile(x, y, z) == Tile::portalTile_Id) + if (level->getTile(x, y, z) == Tile::portal_Id) { - while (level->getTile(x, y - 1, z) == Tile::portalTile_Id) + while (level->getTile(x, y - 1, z) == Tile::portal_Id) { y--; } @@ -166,10 +229,10 @@ bool PortalForcer::findPortal(shared_ptr e, double xOriginal, double yOr double zt = z + 0.5; int dir = Direction::UNDEFINED; - if (level->getTile(x - 1, y, z) == Tile::portalTile_Id) dir = Direction::NORTH; - if (level->getTile(x + 1, y, z) == Tile::portalTile_Id) dir = Direction::SOUTH; - if (level->getTile(x, y, z - 1) == Tile::portalTile_Id) dir = Direction::EAST; - if (level->getTile(x, y, z + 1) == Tile::portalTile_Id) dir = Direction::WEST; + if (level->getTile(x - 1, y, z) == Tile::portal_Id) dir = Direction::NORTH; + if (level->getTile(x + 1, y, z) == Tile::portal_Id) dir = Direction::SOUTH; + if (level->getTile(x, y, z - 1) == Tile::portal_Id) dir = Direction::EAST; + if (level->getTile(x, y, z + 1) == Tile::portal_Id) dir = Direction::WEST; int originalDir = e->getPortalEntranceDir(); @@ -491,7 +554,7 @@ next_second: continue; int zt = z + (s - 1) * za; bool border = s == 0 || s == 3 || h == -1 || h == 3; - level->setTileAndData(xt, yt, zt, border ? Tile::obsidian_Id : Tile::portalTile_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(xt, yt, zt, border ? Tile::obsidian_Id : Tile::portal_Id, 0, Tile::UPDATE_CLIENTS); } } diff --git a/Minecraft.World/PortalTile.cpp b/Minecraft.World/PortalTile.cpp index e7e76a08..0e3925ef 100644 --- a/Minecraft.World/PortalTile.cpp +++ b/Minecraft.World/PortalTile.cpp @@ -94,7 +94,7 @@ bool PortalTile::validPortalFrame(Level* level, int x, int y, int z, int xd, int { for (int yy = 0; yy < 3; yy++) { - level->setTileAndData(x + xd * xx, y + yy, z + zd * xx, Tile::portalTile_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x + xd * xx, y + yy, z + zd * xx, Tile::portal_Id, 0, Tile::UPDATE_CLIENTS); } } diff --git a/Minecraft.World/PotatoTile.cpp b/Minecraft.World/PotatoTile.cpp index 351c8c98..77eed3c6 100644 --- a/Minecraft.World/PotatoTile.cpp +++ b/Minecraft.World/PotatoTile.cpp @@ -46,7 +46,7 @@ void PotatoTile::spawnResources(Level *level, int x, int y, int z, int data, flo { if (level->random->nextInt(50) == 0) { - popResource(level, x, y, z, std::make_shared(Item::potatoPoisonous)); + popResource(level, x, y, z, std::make_shared(Item::poisonous_potato)); } } } diff --git a/Minecraft.World/PumpkinTile.cpp b/Minecraft.World/PumpkinTile.cpp index da11001d..ac159fb0 100644 --- a/Minecraft.World/PumpkinTile.cpp +++ b/Minecraft.World/PumpkinTile.cpp @@ -69,10 +69,10 @@ void PumpkinTile::onPlace(Level *level, int x, int y, int z) level->addParticle(eParticleType_snowshovel, x + level->random->nextDouble(), y - 2 + level->random->nextDouble() * 2.5, z + level->random->nextDouble(), 0, 0, 0); } } - else if (level->getTile(x, y - 1, z) == Tile::ironBlock_Id && level->getTile(x, y - 2, z) == Tile::ironBlock_Id) + else if (level->getTile(x, y - 1, z) == Tile::iron_block_Id && level->getTile(x, y - 2, z) == Tile::iron_block_Id) { - bool xArms = level->getTile(x - 1, y - 1, z) == Tile::ironBlock_Id && level->getTile(x + 1, y - 1, z) == Tile::ironBlock_Id; - bool zArms = level->getTile(x, y - 1, z - 1) == Tile::ironBlock_Id && level->getTile(x, y - 1, z + 1) == Tile::ironBlock_Id; + bool xArms = level->getTile(x - 1, y - 1, z) == Tile::iron_block_Id && level->getTile(x + 1, y - 1, z) == Tile::iron_block_Id; + bool zArms = level->getTile(x, y - 1, z - 1) == Tile::iron_block_Id && level->getTile(x, y - 1, z + 1) == Tile::iron_block_Id; if (xArms || zArms) { if (!level->isClientSide) @@ -122,23 +122,23 @@ void PumpkinTile::onPlace(Level *level, int x, int y, int z) { // If we can't spawn it, at least give the resources back Tile::spawnResources(level, x, y, z, level->getData(x, y, z), 0); - Tile::tiles[Tile::ironBlock_Id]->spawnResources(level, x, y - 1, z, level->getData(x, y - 1, z), 0); - Tile::tiles[Tile::ironBlock_Id]->spawnResources(level, x, y - 2, z, level->getData(x, y - 2, z), 0); + Tile::tiles[Tile::iron_block_Id]->spawnResources(level, x, y - 1, z, level->getData(x, y - 1, z), 0); + Tile::tiles[Tile::iron_block_Id]->spawnResources(level, x, y - 2, z, level->getData(x, y - 2, z), 0); level->setTileAndData(x, y, z, 0, 0, Tile::UPDATE_CLIENTS); level->setTileAndData(x, y - 1, z, 0, 0, Tile::UPDATE_CLIENTS); level->setTileAndData(x, y - 2, z, 0, 0, Tile::UPDATE_CLIENTS); if(xArms) { - Tile::tiles[Tile::ironBlock_Id]->spawnResources(level, x - 1, y - 1, z, level->getData(x - 1, y - 1, z), 0); - Tile::tiles[Tile::ironBlock_Id]->spawnResources(level, x + 1, y - 1, z, level->getData(x + 1, y - 1, z), 0); + Tile::tiles[Tile::iron_block_Id]->spawnResources(level, x - 1, y - 1, z, level->getData(x - 1, y - 1, z), 0); + Tile::tiles[Tile::iron_block_Id]->spawnResources(level, x + 1, y - 1, z, level->getData(x + 1, y - 1, z), 0); level->setTileAndData(x - 1, y - 1, z, 0, 0, Tile::UPDATE_CLIENTS); level->setTileAndData(x + 1, y - 1, z, 0, 0, Tile::UPDATE_CLIENTS); } else { - Tile::tiles[Tile::ironBlock_Id]->spawnResources(level, x, y - 1, z - 1, level->getData(x, y - 1, z - 1), 0); - Tile::tiles[Tile::ironBlock_Id]->spawnResources(level, x, y - 1, z + 1, level->getData(x, y - 1, z + 1), 0); + Tile::tiles[Tile::iron_block_Id]->spawnResources(level, x, y - 1, z - 1, level->getData(x, y - 1, z - 1), 0); + Tile::tiles[Tile::iron_block_Id]->spawnResources(level, x, y - 1, z + 1, level->getData(x, y - 1, z + 1), 0); level->setTileAndData(x, y - 1, z - 1, 0, 0, Tile::UPDATE_CLIENTS); level->setTileAndData(x, y - 1, z + 1, 0, 0, Tile::UPDATE_CLIENTS); } diff --git a/Minecraft.World/Rabbit.cpp b/Minecraft.World/Rabbit.cpp index 19d6fabd..6505a860 100644 --- a/Minecraft.World/Rabbit.cpp +++ b/Minecraft.World/Rabbit.cpp @@ -35,7 +35,7 @@ Rabbit::Rabbit(Level *level) : Animal(level) goalSelector.addGoal(1, new FloatGoal(this)); goalSelector.addGoal(2, new PanicGoal(this, 1.2f)); goalSelector.addGoal(3, new BreedGoal(this, 0.8f)); - goalSelector.addGoal(4, new TemptGoal(this, 1.0f, Item::carrots_Id, false)); + goalSelector.addGoal(4, new TemptGoal(this, 1.0f, Item::carrot_Id, false)); goalSelector.addGoal(5, new FollowParentGoal(this, 1.1f)); goalSelector.addGoal(6, new RandomStrollGoal(this, 0.6f)); goalSelector.addGoal(7, new LookAtPlayerGoal(this, typeid(Player), 10.0f)); @@ -73,7 +73,7 @@ bool Rabbit::useNewAi() { void Rabbit::dropDeathLoot(bool wasKilledByPlayer, int lootingLevel) { int meatCount = random->nextInt(2) + random->nextInt(lootingLevel + 1); - int meatId = isOnFire() ? Item::rabbit_cooked_Id : Item::rabbit_raw_Id; + int meatId = isOnFire() ? Item::cooked_rabbit_Id : Item::rabbit_Id; spawnAtLocation(meatId, meatCount); @@ -83,7 +83,7 @@ void Rabbit::dropDeathLoot(bool wasKilledByPlayer, int lootingLevel) { float footChance = 0.10f + (0.03f * lootingLevel); if (wasKilledByPlayer && random->nextFloat() < footChance) { - spawnAtLocation(Item::rabbits_foot_Id, 1); + spawnAtLocation(Item::rabbit_foot_Id, 1); } } @@ -121,7 +121,7 @@ bool Rabbit::isFood(shared_ptr item) { int id = item->getItem()->id; - return id == Item::carrots_Id || id == Item::carrots_Id || id == Item::carrotGolden_Id; + return id == Item::carrot_Id || id == Item::carrot_Id || id == Item::golden_carrot_Id; } shared_ptr Rabbit::getBreedOffspring(shared_ptr target) { diff --git a/Minecraft.World/RandomLevelSource.cpp b/Minecraft.World/RandomLevelSource.cpp index 1a24ad06..aa6ae9e0 100644 --- a/Minecraft.World/RandomLevelSource.cpp +++ b/Minecraft.World/RandomLevelSource.cpp @@ -326,7 +326,7 @@ void RandomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) } else if (yc * CHUNK_HEIGHT + y < waterHeight) { - tileId = static_cast(Tile::calmWater_Id); + tileId = static_cast(Tile::water_Id); } // 4J - more extra code to make sure that the column at the edge of the world is just water & rock, to match the infinite sea that @@ -336,7 +336,7 @@ void RandomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) { // This matches code in MultiPlayerChunkCache that makes the geometry which continues at the edge of the world if( yc * CHUNK_HEIGHT + y <= ( level->getSeaLevel() - 10 ) ) tileId = Tile::stone_Id; - else if( yc * CHUNK_HEIGHT + y < level->getSeaLevel() ) tileId = Tile::calmWater_Id; + else if( yc * CHUNK_HEIGHT + y < level->getSeaLevel() ) tileId = Tile::water_Id; } blocks[offs += step] = tileId; @@ -668,10 +668,10 @@ void RandomLevelSource::calcWaterDepths(ChunkSource *parent, int xt, int zt) if (level->getHeightmap(xp - 1, zp) > 0 || level->getHeightmap(xp + 1, zp) > 0 || level->getHeightmap(xp, zp - 1) > 0 || level->getHeightmap(xp, zp + 1) > 0) { bool hadWater = false; - if (hadWater || (level->getTile(xp - 1, y, zp) == Tile::calmWater_Id && level->getData(xp - 1, y, zp) < 7)) hadWater = true; - if (hadWater || (level->getTile(xp + 1, y, zp) == Tile::calmWater_Id && level->getData(xp + 1, y, zp) < 7)) hadWater = true; - if (hadWater || (level->getTile(xp, y, zp - 1) == Tile::calmWater_Id && level->getData(xp, y, zp - 1) < 7)) hadWater = true; - if (hadWater || (level->getTile(xp, y, zp + 1) == Tile::calmWater_Id && level->getData(xp, y, zp + 1) < 7)) hadWater = true; + if (hadWater || (level->getTile(xp - 1, y, zp) == Tile::water_Id && level->getData(xp - 1, y, zp) < 7)) hadWater = true; + if (hadWater || (level->getTile(xp + 1, y, zp) == Tile::water_Id && level->getData(xp + 1, y, zp) < 7)) hadWater = true; + if (hadWater || (level->getTile(xp, y, zp - 1) == Tile::water_Id && level->getData(xp, y, zp - 1) < 7)) hadWater = true; + if (hadWater || (level->getTile(xp, y, zp + 1) == Tile::water_Id && level->getData(xp, y, zp + 1) < 7)) hadWater = true; if (hadWater) { for (int x2 = -5; x2 <= 5; x2++) @@ -683,7 +683,7 @@ void RandomLevelSource::calcWaterDepths(ChunkSource *parent, int xt, int zt) if (d <= 5) { d = 6 - d; - if (level->getTile(xp + x2, y, zp + z2) == Tile::calmWater_Id) + if (level->getTile(xp + x2, y, zp + z2) == Tile::water_Id) { int od = level->getData(xp + x2, y, zp + z2); if (od < 7 && od < d) @@ -696,10 +696,10 @@ void RandomLevelSource::calcWaterDepths(ChunkSource *parent, int xt, int zt) } if (hadWater) { - level->setTileAndData(xp, y, zp, Tile::calmWater_Id, 7, Tile::UPDATE_CLIENTS); + level->setTileAndData(xp, y, zp, Tile::water_Id, 7, Tile::UPDATE_CLIENTS); for (int y2 = 0; y2 < y; y2++) { - level->setTileAndData(xp, y2, zp, Tile::calmWater_Id, 8, Tile::UPDATE_CLIENTS); + level->setTileAndData(xp, y2, zp, Tile::water_Id, 8, Tile::UPDATE_CLIENTS); } } } @@ -751,7 +751,7 @@ void RandomLevelSource::postProcess(ChunkSource *parent, int xt, int zt) int y = pprandom->nextInt(Level::genDepth); int z = zo + pprandom->nextInt(16) + 8; - LakeFeature calmWater(Tile::calmWater_Id); + LakeFeature calmWater(Tile::water_Id); calmWater.place(level, pprandom, x, y, z); } } @@ -765,7 +765,7 @@ void RandomLevelSource::postProcess(ChunkSource *parent, int xt, int zt) int z = zo + pprandom->nextInt(16) + 8; if (y < level->seaLevel || pprandom->nextInt(10) == 0) { - LakeFeature calmLava(Tile::calmLava_Id); + LakeFeature calmLava(Tile::lava_Id); calmLava.place(level, pprandom, x, y, z); } } @@ -810,7 +810,7 @@ void RandomLevelSource::postProcess(ChunkSource *parent, int xt, int zt) } if (level->shouldSnow(x + xo, y, z + zo)) { - level->setTileAndData(x + xo, y, z + zo, Tile::topSnow_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x + xo, y, z + zo, Tile::snow_layer_Id, 0, Tile::UPDATE_CLIENTS); } } } diff --git a/Minecraft.World/Recipes.cpp b/Minecraft.World/Recipes.cpp index f8c1ef41..b2eb70e2 100644 --- a/Minecraft.World/Recipes.cpp +++ b/Minecraft.World/Recipes.cpp @@ -81,14 +81,14 @@ void Recipes::_compileRecipes() L"sczg", L"#", // - L'#', new ItemInstance(Tile::tree2Trunk, 1, TreeTile2::ACACIA_TRUNK), + L'#', new ItemInstance(Tile::log2, 1, TreeTile2::ACACIA_TRUNK), L'S'); addShapedRecipy(new ItemInstance(Tile::wood, 4, TreeTile::DARK_TRUNK), // L"sczg", L"#", // - L'#', new ItemInstance(Tile::tree2Trunk, 1, TreeTile2::DARK_TRUNK), + L'#', new ItemInstance(Tile::log2, 1, TreeTile2::DARK_TRUNK), L'S'); addShapedRecipy(new ItemInstance(Item::stick, 4), // @@ -128,7 +128,7 @@ void Recipes::_compileRecipes() L" i ", // L"iii", // - L'I', Tile::ironBlock, L'i', Item::ironIngot, + L'I', Tile::ironBlock, L'i', Item::iron_ingot, L'S'); // 4J Stu - Reordered for crafting menu @@ -219,12 +219,12 @@ void Recipes::_compileRecipes() L'#', Tile::netherBrick, L'S'); - addShapedRecipy(new ItemInstance(Tile::ironFence, 16), // + addShapedRecipy(new ItemInstance(Tile::iron_bars, 16), // L"sscig", L"###", // L"###", // - L'#', Item::ironIngot, + L'#', Item::iron_ingot, L'S'); addShapedRecipy(new ItemInstance(Tile::fenceGate, 1), // @@ -275,7 +275,7 @@ void Recipes::_compileRecipes() L'#', Item::stick, L'W', new ItemInstance(Tile::wood, 1, TreeTile::DARK_TRUNK), L'S'); - addShapedRecipy(new ItemInstance(Item::door_wood, 3), // + addShapedRecipy(new ItemInstance(Item::wooden_door, 3), // L"sssczg", L"##", // L"##", // @@ -284,7 +284,7 @@ void Recipes::_compileRecipes() L'#', new ItemInstance(Tile::wood, 1, 0), L'S'); - addShapedRecipy(new ItemInstance(Item::door_birch, 3), // + addShapedRecipy(new ItemInstance(Item::birch_door, 3), // L"sssczg", L"##", // L"##", // @@ -293,7 +293,7 @@ void Recipes::_compileRecipes() L'#', new ItemInstance(Tile::wood, 1, TreeTile::BIRCH_TRUNK), L'S'); - addShapedRecipy(new ItemInstance(Item::door_spruce, 3), // + addShapedRecipy(new ItemInstance(Item::spruce_door, 3), // L"sssczg", L"##", // L"##", // @@ -302,7 +302,7 @@ void Recipes::_compileRecipes() L'#', new ItemInstance(Tile::wood, 1, TreeTile::SPRUCE_TRUNK), L'S'); - addShapedRecipy(new ItemInstance(Item::door_jungle, 3), // + addShapedRecipy(new ItemInstance(Item::jungle_door, 3), // L"sssczg", L"##", // L"##", // @@ -311,7 +311,7 @@ void Recipes::_compileRecipes() L'#', new ItemInstance(Tile::wood, 1, TreeTile::JUNGLE_TRUNK), L'S'); - addShapedRecipy(new ItemInstance(Item::door_acacia, 3), // + addShapedRecipy(new ItemInstance(Item::acacia_door, 3), // L"sssczg", L"##", // L"##", // @@ -320,7 +320,7 @@ void Recipes::_compileRecipes() L'#', new ItemInstance(Tile::wood, 1, TreeTile::ACACIA_TRUNK), L'S'); - addShapedRecipy(new ItemInstance(Item::door_dark, 3), // + addShapedRecipy(new ItemInstance(Item::dark_oak_door, 3), // L"sssczg", L"##", // L"##", // @@ -329,13 +329,13 @@ void Recipes::_compileRecipes() L'#', new ItemInstance(Tile::wood, 1, TreeTile::DARK_TRUNK), L'S'); - addShapedRecipy(new ItemInstance(Item::door_iron, 3), // + addShapedRecipy(new ItemInstance(Item::iron_door, 3), // L"ssscig", L"##", // L"##", // L"##", // - L'#', Item::ironIngot, + L'#', Item::iron_ingot, L'S'); addShapedRecipy(new ItemInstance(Tile::trapdoor, 2), // @@ -351,7 +351,7 @@ void Recipes::_compileRecipes() L"##", // L"##", // - L'#', Item::ironIngot, + L'#', Item::iron_ingot, L'S'); addShapedRecipy(new ItemInstance(Tile::stairs_wood, 4), // @@ -381,7 +381,7 @@ void Recipes::_compileRecipes() L'#', Tile::redBrick, L'S'); - addShapedRecipy(new ItemInstance(Tile::stairs_stoneBrickSmooth, 4), // + addShapedRecipy(new ItemInstance(Tile::stone_brick_stairsSmooth, 4), // L"sssctg", L"# ", // L"## ", // @@ -390,7 +390,7 @@ void Recipes::_compileRecipes() L'#', Tile::stoneBrick, L'S'); - addShapedRecipy(new ItemInstance(Tile::stairs_netherBricks, 4), // + addShapedRecipy(new ItemInstance(Tile::nether_brick_stairs, 4), // L"sssctg", L"# ", // L"## ", // @@ -480,7 +480,7 @@ void Recipes::_compileRecipes() L"##", // L"##", // - L'#', Item::snowBall, + L'#', Item::snowball, L'S'); addShapedRecipy(new ItemInstance(Tile::prismarine, 1), // @@ -507,7 +507,7 @@ void Recipes::_compileRecipes() L"#X#", // L"###", // - L'#', Item::prismarine_shard, L'X', new ItemInstance(Item::dye_powder, 1, DyePowderItem::BLACK), + L'#', Item::prismarine_shard, L'X', new ItemInstance(Item::dye, 1, DyePowderItem::BLACK), L'S'); addShapedRecipy(new ItemInstance(Tile::topSnow, 6), // @@ -657,7 +657,7 @@ void Recipes::_compileRecipes() L"BEB", // L"CCC", // - L'A', Item::bucket_milk,// + L'A', Item::milk_bucket,// L'B', Item::sugar,// L'C', Item::wheat, L'E', Item::egg, L'F'); @@ -675,7 +675,7 @@ void Recipes::_compileRecipes() L"X#X", // L"X X", // - L'X', Item::ironIngot,// + L'X', Item::iron_ingot,// L'#', Item::stick, L'V'); @@ -685,8 +685,8 @@ void Recipes::_compileRecipes() L"X#X", // L"XRX", // - L'X', Item::goldIngot,// - L'R', Item::redStone,// + L'X', Item::gold_ingot,// + L'R', Item::redstone,// L'#', Item::stick, L'V'); @@ -696,7 +696,7 @@ void Recipes::_compileRecipes() L"X#X", // L"XSX", // - L'X', Item::ironIngot,// + L'X', Item::iron_ingot,// L'#', Tile::redstoneTorch_on,// L'S', Item::stick, L'V'); @@ -707,8 +707,8 @@ void Recipes::_compileRecipes() L"X#X", // L"XRX", // - L'X', Item::ironIngot,// - L'R', Item::redStone,// + L'X', Item::iron_ingot,// + L'R', Item::redstone,// L'#', Tile::pressurePlate_stone, L'V'); @@ -717,10 +717,10 @@ void Recipes::_compileRecipes() L"# #", // L"###", // - L'#', Item::ironIngot, + L'#', Item::iron_ingot, L'V'); - addShapedRecipy(new ItemInstance(Item::minecart_chest, 1), // + addShapedRecipy(new ItemInstance(Item::chest_minecart, 1), // L"ssctcig", L"A", // L"B", // @@ -728,7 +728,7 @@ void Recipes::_compileRecipes() L'A', Tile::chest, L'B', Item::minecart, L'V'); - addShapedRecipy(new ItemInstance(Item::minecart_furnace, 1), // + addShapedRecipy(new ItemInstance(Item::furnace_minecart, 1), // L"ssctcig", L"A", // L"B", // @@ -736,7 +736,7 @@ void Recipes::_compileRecipes() L'A', Tile::furnace, L'B', Item::minecart, L'V'); - addShapedRecipy(new ItemInstance(Item::minecart_tnt, 1), // + addShapedRecipy(new ItemInstance(Item::tnt_minecart, 1), // L"ssctcig", L"A", // L"B", // @@ -744,7 +744,7 @@ void Recipes::_compileRecipes() L'A', Tile::tnt, L'B', Item::minecart, L'V'); - addShapedRecipy(new ItemInstance(Item::minecart_hopper, 1), // + addShapedRecipy(new ItemInstance(Item::hopper_minecart, 1), // L"ssctcig", L"A", // L"B", // @@ -760,7 +760,7 @@ void Recipes::_compileRecipes() L'#', Tile::wood, L'V'); - addShapedRecipy(new ItemInstance((Item*)Item::fishingRod, 1), // + addShapedRecipy(new ItemInstance((Item *)Item::fishing_rod, 1), // L"ssscicig", L" #", // L" #X", // @@ -769,20 +769,20 @@ void Recipes::_compileRecipes() L'#', Item::stick, L'X', Item::string, L'T'); - addShapedRecipy(new ItemInstance(Item::carrotOnAStick, 1), // + addShapedRecipy(new ItemInstance(Item::carrot_on_a_stick, 1), // L"sscicig", L"# ", // L" X", // - L'#', Item::fishingRod, L'X', Item::carrots, + L'#', Item::fishing_rod, L'X', Item::carrots, L'T')->keepTag(); - addShapedRecipy(new ItemInstance(Item::flintAndSteel, 1), // + addShapedRecipy(new ItemInstance(Item::flint_and_steel, 1), // L"sscicig", L"A ", // L" B", // - L'A', Item::ironIngot, L'B', Item::flint, + L'A', Item::iron_ingot, L'B', Item::flint, L'T'); addShapedRecipy(new ItemInstance(Item::bread, 1), // @@ -816,12 +816,12 @@ void Recipes::_compileRecipes() pWeaponRecipies->addRecipes(this); - addShapedRecipy(new ItemInstance(Item::bucket_empty, 1), // + addShapedRecipy(new ItemInstance(Item::bucket, 1), // L"sscig", L"# #", // L" # ", // - L'#', Item::ironIngot, + L'#', Item::iron_ingot, L'T'); addShapedRecipy(new ItemInstance(Item::bowl, 4), // @@ -865,7 +865,7 @@ void Recipes::_compileRecipes() L"##", // L"##", // - L'#', Item::yellowDust, + L'#', Item::glowstone_dust, L'T'); addShapedRecipy(new ItemInstance(Tile::quartzBlock, 1), // @@ -873,7 +873,7 @@ void Recipes::_compileRecipes() L"##", // L"##", // - L'#', Item::netherQuartz, + L'#', Item::nether_quartz, L'S'); addShapedRecipy(new ItemInstance(Tile::lever, 1), // @@ -890,7 +890,7 @@ void Recipes::_compileRecipes() L"S", // L"#", // - L'#', Tile::wood, L'S', Item::stick, L'I', Item::ironIngot, + L'#', Tile::wood, L'S', Item::stick, L'I', Item::iron_ingot, L'M'); addShapedRecipy(new ItemInstance(Tile::redstoneTorch_on, 1), // @@ -898,7 +898,7 @@ void Recipes::_compileRecipes() L"X", // L"#", // - L'#', Item::stick, L'X', Item::redStone, + L'#', Item::stick, L'X', Item::redstone, L'M'); addShapedRecipy(new ItemInstance(Item::repeater, 1), // @@ -906,7 +906,7 @@ void Recipes::_compileRecipes() L"#X#", // L"III", // - L'#', Tile::redstoneTorch_on, L'X', Item::redStone, L'I', new ItemInstance(Tile::stone, 1, 0), + L'#', Tile::redstoneTorch_on, L'X', Item::redstone, L'I', new ItemInstance(Tile::stone, 1, 0), L'M'); addShapedRecipy(new ItemInstance(Item::comparator, 1), // @@ -915,7 +915,7 @@ void Recipes::_compileRecipes() L"#X#", // L"III", // - L'#', Tile::redstoneTorch_on, L'X', Item::netherQuartz, L'I', new ItemInstance(Tile::stone, 1, 0), + L'#', Tile::redstoneTorch_on, L'X', Item::nether_quartz, L'I', new ItemInstance(Tile::stone, 1, 0), L'M'); addShapedRecipy(new ItemInstance(Tile::daylightDetector), @@ -924,7 +924,7 @@ void Recipes::_compileRecipes() L"QQQ", L"WWW", - L'G', Tile::glass, L'Q', Item::netherQuartz, L'W', Tile::woodSlabHalf, + L'G', Tile::glass, L'Q', Item::nether_quartz, L'W', Tile::woodSlabHalf, L'M'); addShapedRecipy(new ItemInstance(Tile::hopper), @@ -933,7 +933,7 @@ void Recipes::_compileRecipes() L"ICI", // L" I ", // - L'I', Item::ironIngot, L'C', Tile::chest, + L'I', Item::iron_ingot, L'C', Tile::chest, L'M'); addShapedRecipy(new ItemInstance(Item::clock, 1), // @@ -941,22 +941,22 @@ void Recipes::_compileRecipes() L" # ", // L"#X#", // L" # ", // - L'#', Item::goldIngot, L'X', Item::redStone, + L'#', Item::gold_ingot, L'X', Item::redstone, L'T'); - addShapelessRecipy(new ItemInstance(Item::eyeOfEnder, 1), // + addShapelessRecipy(new ItemInstance(Item::eye_of_ender, 1), // L"iig", - Item::enderPearl, Item::blazePowder, + Item::ender_pearl, Item::blaze_powder, L'T'); addShapelessRecipy(new ItemInstance(Item::fireball, 3), // L"iiig", - Item::gunpowder, Item::blazePowder, Item::coal, + Item::gunpowder, Item::blaze_powder,Item::coal, L'T'); addShapelessRecipy(new ItemInstance(Item::fireball, 3), // L"iizg", - Item::gunpowder, Item::blazePowder, new ItemInstance(Item::coal, 1, CoalItem::CHAR_COAL), + Item::gunpowder, Item::blaze_powder,new ItemInstance(Item::coal, 1, CoalItem::CHAR_COAL), L'T'); addShapedRecipy(new ItemInstance(Item::lead, 2), // @@ -965,7 +965,7 @@ void Recipes::_compileRecipes() L"~O ", // L" ~", // - L'~', Item::string, L'O', Item::slimeBall, + L'~', Item::string, L'O', Item::slime_ball, L'T'); @@ -975,10 +975,10 @@ void Recipes::_compileRecipes() L"#X#", // L" # ", // - L'#', Item::ironIngot, L'X', Item::redStone, + L'#', Item::iron_ingot, L'X', Item::redstone, L'T'); - addShapedRecipy(new ItemInstance((Item*)Item::emptyMap, 1), // + addShapedRecipy(new ItemInstance((Item*)Item::empty_map, 1), // L"ssscicig", L"###", // L"#X#", // @@ -1013,18 +1013,18 @@ void Recipes::_compileRecipes() L'#', new ItemInstance(Tile::stone, 1, 0), L'M'); - addShapedRecipy(new ItemInstance(Tile::weightedPlate_heavy, 1), // + addShapedRecipy(new ItemInstance(Tile::heavy_weighted_pressure_plate, 1), // L"scig", L"##", // - L'#', Item::ironIngot, + L'#', Item::iron_ingot, L'M'); - addShapedRecipy(new ItemInstance(Tile::weightedPlate_light, 1), // + addShapedRecipy(new ItemInstance(Tile::light_weighted_pressure_plate, 1), // L"scig", L"##", // - L'#', Item::goldIngot, + L'#', Item::gold_ingot, L'M'); addShapedRecipy(new ItemInstance(Tile::dispenser, 1), // @@ -1032,7 +1032,7 @@ void Recipes::_compileRecipes() L"###", // L"#X#", // L"#R#", // - L'#', Tile::cobblestone, L'X', Item::bow, L'R', Item::redStone, + L'#', Tile::cobblestone, L'X', Item::bow, L'R', Item::redstone, L'M'); addShapedRecipy(new ItemInstance(Tile::dropper, 1), // @@ -1041,7 +1041,7 @@ void Recipes::_compileRecipes() L"# #", // L"#R#", // - L'#', Tile::cobblestone, L'R', Item::redStone, + L'#', Tile::cobblestone, L'R', Item::redstone, L'M'); addShapedRecipy(new ItemInstance(Item::cauldron, 1), // @@ -1050,15 +1050,15 @@ void Recipes::_compileRecipes() L"# #", // L"###", // - L'#', Item::ironIngot, + L'#', Item::iron_ingot, L'T'); - addShapedRecipy(new ItemInstance(Item::brewingStand, 1), // + addShapedRecipy(new ItemInstance(Item::brewing_stand, 1), // L"ssctcig", L" B ", // L"###", // - L'#', Tile::cobblestone, L'B', Item::blazeRod, + L'#', Tile::cobblestone, L'B', Item::blaze_rod, L'S'); @@ -1070,7 +1070,7 @@ void Recipes::_compileRecipes() L'A', Tile::pumpkin, L'B', Tile::torch, L'T'); - addShapedRecipy(new ItemInstance(Item::flowerPot, 1), // + addShapedRecipy(new ItemInstance(Item::flower_pot, 1), // L"sscig", L"# #", // L" # ", // @@ -1121,15 +1121,15 @@ void Recipes::_compileRecipes() Item::leather, L'D'); - addShapelessRecipy(new ItemInstance(Item::writingBook, 1), + addShapelessRecipy(new ItemInstance(Item::writable_book, 1), L"iiig", Item::book, Item::feather, - ItemInstance(Item::dye_powder, 1, DyePowderItem::BLACK), + ItemInstance(Item::dye, 1, DyePowderItem::BLACK), L'D'); - //addShapelessRecipy(new ItemInstance(Item.writingBook, 1), // - // Item.book, new ItemInstance(Item.dye_powder, 1, DyePowderItem.BLACK), Item.feather); + //addShapelessRecipy(new ItemInstance(Item.writable_book, 1), // + // Item.book, new ItemInstance(Item.dye, 1, DyePowderItem.BLACK), Item.feather); addShapedRecipy(new ItemInstance(Tile::noteblock, 1), // L"sssctcig", @@ -1137,7 +1137,7 @@ void Recipes::_compileRecipes() L"#X#", // L"###", // - L'#', Tile::wood, L'X', Item::redStone, + L'#', Tile::wood, L'X', Item::redstone, L'M'); addShapedRecipy(new ItemInstance(Tile::bookshelf, 1), // @@ -1170,19 +1170,19 @@ void Recipes::_compileRecipes() pOreRecipies->addRecipes(this); - addShapedRecipy(new ItemInstance(Item::goldIngot), // + addShapedRecipy(new ItemInstance(Item::gold_ingot), // L"ssscig", L"###", // L"###", // L"###", // - L'#', Item::goldNugget, + L'#', Item::gold_nugget, L'D'); - addShapedRecipy(new ItemInstance(Item::goldNugget, 9), // + addShapedRecipy(new ItemInstance(Item::gold_nugget, 9), // L"scig", L"#", // - L'#', Item::goldIngot, + L'#', Item::gold_ingot, L'D'); // 4J-PB - moving into decorations to make the structures list smaller @@ -1202,15 +1202,15 @@ void Recipes::_compileRecipes() L"#X#", // L"#R#", // - L'#', Tile::cobblestone, L'X', Item::ironIngot, L'R', Item::redStone, L'T', Tile::wood, + L'#', Tile::cobblestone, L'X', Item::iron_ingot, L'R', Item::redstone, L'T', Tile::wood, L'M'); - addShapedRecipy(new ItemInstance(static_cast(Tile::pistonStickyBase), 1), // + addShapedRecipy(new ItemInstance(static_cast(Tile::sticky_piston), 1), // L"sscictg", L"S", // L"P", // - L'S', Item::slimeBall, L'P', Tile::pistonBase, + L'S', Item::slime_ball, L'P', Tile::pistonBase, L'M'); @@ -1223,20 +1223,20 @@ void Recipes::_compileRecipes() L'P', Item::paper, L'G', Item::gunpowder, L'D'); - addShapedRecipy(new ItemInstance(Item::fireworksCharge, 1), // + addShapedRecipy(new ItemInstance(Item::firework_charge,1), // L"sscicig", L" D ", // L" G ", // - L'D', Item::dye_powder, L'G', Item::gunpowder, + L'D', Item::dye, L'G', Item::gunpowder, L'D'); - addShapedRecipy(new ItemInstance(Item::fireworksCharge, 1), // + addShapedRecipy(new ItemInstance(Item::firework_charge,1), // L"sscicig", L" D ", // L" C ", // - L'D', Item::dye_powder, L'C', Item::fireworksCharge, + L'D', Item::dye, L'C', Item::firework_charge, L'D'); buildRecipeIngredientsArray(); diff --git a/Minecraft.World/RedStoneDustTile.cpp b/Minecraft.World/RedStoneDustTile.cpp index f81cf303..d849d77b 100644 --- a/Minecraft.World/RedStoneDustTile.cpp +++ b/Minecraft.World/RedStoneDustTile.cpp @@ -22,7 +22,8 @@ const wstring RedStoneDustTile::TEXTURE_LINE_OVERLAY = L"_line_overlay"; RedStoneDustTile::RedStoneDustTile(int id) : Tile(id, Material::decoration,isSolidRender()) { shouldSignal = true; - + setLightBlock(0); + updateDefaultShape(); iconCross = nullptr; @@ -31,6 +32,32 @@ RedStoneDustTile::RedStoneDustTile(int id) : Tile(id, Material::decoration,isSol iconLineOver = nullptr; } +void RedStoneDustTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int RedStoneDustTile::defaultBlockState() +{ + return 0; +} + +int RedStoneDustTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState RedStoneDustTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState RedStoneDustTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + // 4J Added override void RedStoneDustTile::updateDefaultShape() { @@ -251,7 +278,7 @@ void RedStoneDustTile::neighborChanged(Level *level, int x, int y, int z, int ty int RedStoneDustTile::getResource(int data, Random *random, int playerBonusLevel) { - return Item::redStone->id; + return Item::redstone->id; } int RedStoneDustTile::getDirectSignal(LevelSource *level, int x, int y, int z, int dir) @@ -354,14 +381,15 @@ void RedStoneDustTile::animateTick(Level *level, int x, int y, int z, Random *ra bool RedStoneDustTile::shouldConnectTo(LevelSource *level, int x, int y, int z, int direction) { int t = level->getTile(x, y, z); - if (t == Tile::redStoneDust_Id) return true; + if (t == Tile::redstone_wire_Id) return true; if (t == 0) return false; - if (Tile::diode_off->isSameDiode(t)) + Tile *tile = Tile::tiles[t]; + if (Tile::unpowered_repeater->isSameDiode(t)) { int data = level->getData(x, y, z); return direction == (data & DiodeTile::DIRECTION_MASK) || direction == Direction::DIRECTION_OPPOSITE[data & DiodeTile::DIRECTION_MASK]; } - else if (Tile::tiles[t]->isSignalSource() && direction != Direction::UNDEFINED) return true; + else if (tile != nullptr && tile->isSignalSource() && direction != Direction::UNDEFINED) return true; return false; } @@ -374,7 +402,7 @@ bool RedStoneDustTile::shouldReceivePowerFrom(LevelSource *level, int x, int y, } int t = level->getTile(x, y, z); - if (t == Tile::diode_on_Id) + if (t == Tile::powered_repeater_Id) { int data = level->getData(x, y, z); return direction == (data & DiodeTile::DIRECTION_MASK); @@ -384,7 +412,7 @@ bool RedStoneDustTile::shouldReceivePowerFrom(LevelSource *level, int x, int y, int RedStoneDustTile::cloneTileId(Level *level, int x, int y, int z) { - return Item::redStone_Id; + return Item::redstone_Id; } void RedStoneDustTile::registerIcons(IconRegister *iconRegister) diff --git a/Minecraft.World/RedStoneDustTile.h b/Minecraft.World/RedStoneDustTile.h index 2a647658..edd80a95 100644 --- a/Minecraft.World/RedStoneDustTile.h +++ b/Minecraft.World/RedStoneDustTile.h @@ -25,6 +25,11 @@ private: public: RedStoneDustTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void updateDefaultShape(); // 4J Added override virtual AABB *getAABB(Level *level, int x, int y, int z); virtual bool isSolidRender(bool isServerLevel = false); diff --git a/Minecraft.World/RedStoneItem.cpp b/Minecraft.World/RedStoneItem.cpp index 6e12842a..8b34a245 100644 --- a/Minecraft.World/RedStoneItem.cpp +++ b/Minecraft.World/RedStoneItem.cpp @@ -13,7 +13,7 @@ RedStoneItem::RedStoneItem(int id) : Item(id) bool RedStoneItem::useOn(shared_ptr itemInstance, shared_ptr player, Level *level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, bool bTestUseOnOnly) { // 4J-PB - Adding a test only version to allow tooltips to be displayed - if (level->getTile(x, y, z) != Tile::topSnow_Id) + if (level->getTile(x, y, z) != Tile::snow_layer_Id) { if (face == 0) y--; if (face == 1) y++; @@ -29,10 +29,10 @@ bool RedStoneItem::useOn(shared_ptr itemInstance, shared_ptrawardStat(GenericStats::blocksPlaced(Tile::redStoneDust_Id), GenericStats::param_blocksPlaced(Tile::redStoneDust_Id,itemInstance->getAuxValue(),1)); + player->awardStat(GenericStats::blocksPlaced(Tile::redstone_wire_Id), GenericStats::param_blocksPlaced(Tile::redstone_wire_Id,itemInstance->getAuxValue(),1)); itemInstance->count--; - level->setTileAndUpdate(x, y, z, Tile::redStoneDust_Id); + level->setTileAndUpdate(x, y, z, Tile::redstone_wire_Id); } } diff --git a/Minecraft.World/RedStoneOreTile.cpp b/Minecraft.World/RedStoneOreTile.cpp index 407da2cc..411bc474 100644 --- a/Minecraft.World/RedStoneOreTile.cpp +++ b/Minecraft.World/RedStoneOreTile.cpp @@ -32,7 +32,7 @@ void RedStoneOreTile::stepOn(Level *level, int x, int y, int z, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly/*=false*/) // 4J added soundOnly param @@ -46,23 +46,23 @@ void RedStoneOreTile::interact(Level *level, int x, int y, int z) { poofParticles(level, x, y, z); if (level->isClientSide) return; // 4J added - if (id == Tile::redStoneOre_Id) + if (id == Tile::redstone_ore_Id) { - level->setTileAndUpdate(x, y, z, Tile::redStoneOre_lit_Id); + level->setTileAndUpdate(x, y, z, Tile::lit_redstone_ore_Id); } } void RedStoneOreTile::tick(Level *level, int x, int y, int z, Random* random) { - if (id == Tile::redStoneOre_lit_Id) + if (id == Tile::lit_redstone_ore_Id) { - level->setTileAndUpdate(x, y, z, Tile::redStoneOre_Id); + level->setTileAndUpdate(x, y, z, Tile::redstone_ore_Id); } } int RedStoneOreTile::getResource(int data, Random *random, int playerBonusLevel) { - return Item::redStone->id; + return Item::redstone->id; } int RedStoneOreTile::getResourceCountForLootBonus(int bonusLevel, Random *random) @@ -119,7 +119,7 @@ void RedStoneOreTile::poofParticles(Level *level, int x, int y, int z) bool RedStoneOreTile::shouldTileTick(Level *level, int x,int y,int z) { - return id == Tile::redStoneOre_lit_Id; + return id == Tile::lit_redstone_ore_Id; } shared_ptr RedStoneOreTile::getSilkTouchItemInstance(int data) diff --git a/Minecraft.World/RedlightTile.cpp b/Minecraft.World/RedlightTile.cpp index bf4cc01f..516353c9 100644 --- a/Minecraft.World/RedlightTile.cpp +++ b/Minecraft.World/RedlightTile.cpp @@ -36,7 +36,7 @@ void RedlightTile::onPlace(Level *level, int x, int y, int z) } else if (!isLit && level->hasNeighborSignal(x, y, z)) { - level->setTileAndData(x, y, z, Tile::redstoneLight_lit_Id, 0, UPDATE_CLIENTS); + level->setTileAndData(x, y, z, Tile::lit_redstone_lamp_Id, 0, UPDATE_CLIENTS); } } } @@ -51,7 +51,7 @@ void RedlightTile::neighborChanged(Level *level, int x, int y, int z, int type) } else if (!isLit && level->hasNeighborSignal(x, y, z)) { - level->setTileAndData(x, y, z, Tile::redstoneLight_lit_Id, 0, UPDATE_CLIENTS); + level->setTileAndData(x, y, z, Tile::lit_redstone_lamp_Id, 0, UPDATE_CLIENTS); } } } @@ -62,17 +62,17 @@ void RedlightTile::tick(Level *level, int x, int y, int z, Random *random) { if (isLit && !level->hasNeighborSignal(x, y, z)) { - level->setTileAndData(x, y, z, Tile::redstoneLight_Id, 0, UPDATE_CLIENTS); + level->setTileAndData(x, y, z, Tile::redstone_lamp_Id, 0, UPDATE_CLIENTS); } } } int RedlightTile::getResource(int data, Random *random, int playerBonusLevel) { - return Tile::redstoneLight_Id; + return Tile::redstone_lamp_Id; } int RedlightTile::cloneTileId(Level *level, int x, int y, int z) { - return Tile::redstoneLight_Id; + return Tile::redstone_lamp_Id; } \ No newline at end of file diff --git a/Minecraft.World/ReedTile.cpp b/Minecraft.World/ReedTile.cpp index b67c4874..db56c9bc 100644 --- a/Minecraft.World/ReedTile.cpp +++ b/Minecraft.World/ReedTile.cpp @@ -16,6 +16,32 @@ ReedTile::ReedTile(int id) : Tile( id, Material::plant,isSolidRender() ) this->setTicking(true); } +void ReedTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int ReedTile::defaultBlockState() +{ + return 0; +} + +int ReedTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState ReedTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState ReedTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + // 4J Added override void ReedTile::updateDefaultShape() { diff --git a/Minecraft.World/ReedTile.h b/Minecraft.World/ReedTile.h index bc2a0366..16bc4494 100644 --- a/Minecraft.World/ReedTile.h +++ b/Minecraft.World/ReedTile.h @@ -14,6 +14,11 @@ protected: public: virtual void updateDefaultShape(); // 4J Added override + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); void tick(Level *level, int x, int y, int z, Random* random); public: diff --git a/Minecraft.World/Region.cpp b/Minecraft.World/Region.cpp index 1e8acaf3..40bac832 100644 --- a/Minecraft.World/Region.cpp +++ b/Minecraft.World/Region.cpp @@ -196,11 +196,11 @@ int Region::getRawBrightness(int x, int y, int z, bool propagate) int id = getTile(x, y, z); switch(id) { - case Tile::stoneSlabHalf_Id: - case Tile::woodSlabHalf_Id: + case Tile::stone_slab_Id: + case Tile::wooden_slab_Id: case Tile::farmland_Id: - case Tile::stairs_stone_Id: - case Tile::stairs_wood_Id: + case Tile::stone_stairs_Id: + case Tile::oak_stairs_Id: { int br = getRawBrightness(x, y + 1, z, false); int br1 = getRawBrightness(x + 1, y, z, false); @@ -246,7 +246,9 @@ Material *Region::getMaterial(int x, int y, int z) { int t = getTile(x, y, z); if (t == 0) return Material::air; - return Tile::tiles[t]->material; + Tile *tile = Tile::tiles[t]; + if (tile == nullptr) return Material::air; + return tile->material; } diff --git a/Minecraft.World/RegionHillsLayer.cpp b/Minecraft.World/RegionHillsLayer.cpp index 81b3a49e..ff05cf09 100644 --- a/Minecraft.World/RegionHillsLayer.cpp +++ b/Minecraft.World/RegionHillsLayer.cpp @@ -3,8 +3,6 @@ #include "IntCache.h" #include "RegionHillsLayer.h" - - RegionHillsLayer::RegionHillsLayer(int64_t seed, shared_ptr parent) : Layer(seed) { this->parent = parent; @@ -27,7 +25,7 @@ void RegionHillsLayer::init(int64_t seed) bool RegionHillsLayer::biomesEqualOrMesaPlateau(int a, int b) { - return a == b; + return isSame(a, b); // was: a == b } @@ -125,7 +123,7 @@ intArray RegionHillsLayer::getArea(int xo, int yo, int w, int h) } else if (k == Biome::extremeHills->id) { - i1 = Biome::smallerExtremeHills->id; + i1 = Biome::extremeHills_plus->id; // NOT smallerExtremeHills } else if (k == Biome::savanna->id) { @@ -133,6 +131,10 @@ intArray RegionHillsLayer::getArea(int xo, int yo, int w, int h) i1 = Biome::savannaPlateau->id; } + else if (Layer::isSame(k, Biome::mesaPlateauF->id)) + { + i1 = Biome::mesa->id; + } else if (k == Biome::deepOcean->id && nextRandom(3) == 0) { diff --git a/Minecraft.World/RepairMenu.cpp b/Minecraft.World/RepairMenu.cpp index a4c48edf..695ea0b2 100644 --- a/Minecraft.World/RepairMenu.cpp +++ b/Minecraft.World/RepairMenu.cpp @@ -78,7 +78,7 @@ void RepairMenu::createResult() if (addition != NULL) { - usingBook = addition->id == Item::enchantedBook_Id && Item::enchantedBook->getEnchantments(addition)->size() > 0; + usingBook = addition->id == Item::enchanted_book_Id && Item::enchanted_book->getEnchantments(addition)->size() > 0; if (result->isDamageableItem() && Item::items[result->id]->isValidRepairItem(input, addition)) { diff --git a/Minecraft.World/RepeaterTile.cpp b/Minecraft.World/RepeaterTile.cpp index 23a9e12f..b5f4c743 100644 --- a/Minecraft.World/RepeaterTile.cpp +++ b/Minecraft.World/RepeaterTile.cpp @@ -12,6 +12,32 @@ RepeaterTile::RepeaterTile(int id, bool on) : DiodeTile(id, on) { } +void RepeaterTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int RepeaterTile::defaultBlockState() +{ + return 0; +} + +int RepeaterTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState RepeaterTile::getBlockState(int data) +{ + return Tile::BlockState((data & 0xF) | ((on ? 1 : 0) << 4)); +} + +Tile::BlockState RepeaterTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return getBlockState(level->getData(x, y, z)); +} + bool RepeaterTile::use(Level *level, int x, int y, int z, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly) { if (soundOnly) return false; @@ -31,12 +57,12 @@ int RepeaterTile::getTurnOnDelay(int data) DiodeTile *RepeaterTile::getOnTile() { - return Tile::diode_on; + return Tile::powered_repeater; } DiodeTile *RepeaterTile::getOffTile() { - return Tile::diode_off; + return Tile::unpowered_repeater; } int RepeaterTile::getResource(int data, Random *random, int playerBonusLevel) diff --git a/Minecraft.World/RepeaterTile.h b/Minecraft.World/RepeaterTile.h index 048e4de0..0c7091f1 100644 --- a/Minecraft.World/RepeaterTile.h +++ b/Minecraft.World/RepeaterTile.h @@ -16,6 +16,12 @@ private: public: RepeaterTile(int id, bool on); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual bool use(Level *level, int x, int y, int z, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false); protected: diff --git a/Minecraft.World/ResultSlot.cpp b/Minecraft.World/ResultSlot.cpp index bed4d2d8..27cd83ec 100644 --- a/Minecraft.World/ResultSlot.cpp +++ b/Minecraft.World/ResultSlot.cpp @@ -38,16 +38,16 @@ void ResultSlot::checkTakeAchievements(shared_ptr carried) carried->onCraftedBy(player->level, dynamic_pointer_cast( player->shared_from_this() ), removeCount); removeCount = 0; - if (carried->id == Tile::workBench_Id) player->awardStat(GenericStats::buildWorkbench(), GenericStats::param_buildWorkbench()); - else if (carried->id == Item::pickAxe_wood_Id) player->awardStat(GenericStats::buildPickaxe(), GenericStats::param_buildPickaxe()); + if (carried->id == Tile::crafting_table_Id) player->awardStat(GenericStats::buildWorkbench(), GenericStats::param_buildWorkbench()); + else if (carried->id == Item::wooden_pickaxe_Id) player->awardStat(GenericStats::buildPickaxe(), GenericStats::param_buildPickaxe()); else if (carried->id == Tile::furnace_Id) player->awardStat(GenericStats::buildFurnace(), GenericStats::param_buildFurnace()); else if (carried->getItem()->getBaseItemType() == Item::eBaseItemType_hoe) player->awardStat(GenericStats::buildHoe(), GenericStats::param_buildHoe()); else if (carried->id == Item::bread_Id) player->awardStat(GenericStats::makeBread(), GenericStats::param_makeBread()); else if (carried->id == Item::cake_Id) player->awardStat(GenericStats::bakeCake(), GenericStats::param_bakeCake()); - else if (carried->id == Item::pickAxe_stone_Id) player->awardStat(GenericStats::buildBetterPickaxe(), GenericStats::param_buildBetterPickaxe()); + else if (carried->id == Item::stone_pickaxe_Id) player->awardStat(GenericStats::buildBetterPickaxe(), GenericStats::param_buildBetterPickaxe()); // The description is technically wrong but that's accurate else if (carried->getItem()->getBaseItemType() == Item::eBaseItemType_sword) player->awardStat(GenericStats::buildSword(), GenericStats::param_buildSword()); - //else if (carried->id == Tile::enchantTable_Id) player->awardStat(GenericStats::enchantments(), GenericStats::param_achievement(eAward_)); + //else if (carried->id == Tile::enchanting_table_Id) player->awardStat(GenericStats::enchantments(), GenericStats::param_achievement(eAward_)); else if (carried->id == Tile::bookshelf_Id) player->awardStat(GenericStats::bookcase(), GenericStats::param_bookcase()); // 4J : WESTY : Added new acheivements. diff --git a/Minecraft.World/RoofTreeFeature.cpp b/Minecraft.World/RoofTreeFeature.cpp index 8b548442..4025cf1a 100644 --- a/Minecraft.World/RoofTreeFeature.cpp +++ b/Minecraft.World/RoofTreeFeature.cpp @@ -41,7 +41,7 @@ bool RoofTreeFeature::checkSpace(Level *worldIn, int x, int y, int z, int height return false; } - if (tile == Tile::water_Id) { + if (tile == Tile::flowing_water_Id) { return false; } } @@ -55,7 +55,7 @@ bool RoofTreeFeature::checkSpace(Level *worldIn, int x, int y, int z, int height void RoofTreeFeature::placeLog(Level *worldIn, int x, int y, int z) { int tile = worldIn->getTile(x, y, z); if (tile == 0 || tile == Tile::leaves_Id || tile == Tile::leaves2_Id || tile == Tile::tallgrass_Id) { - placeBlock(worldIn, x, y, z, Tile::tree2Trunk_Id, TreeTile2::DARK_TRUNK); + placeBlock(worldIn, x, y, z, Tile::log2_Id, TreeTile2::DARK_TRUNK); } } diff --git a/Minecraft.World/RotatedPillarTile.cpp b/Minecraft.World/RotatedPillarTile.cpp index 6475cd72..fbfc00d2 100644 --- a/Minecraft.World/RotatedPillarTile.cpp +++ b/Minecraft.World/RotatedPillarTile.cpp @@ -6,6 +6,32 @@ RotatedPillarTile::RotatedPillarTile(int id, Material *material) : Tile(id, mate { } +void RotatedPillarTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int RotatedPillarTile::defaultBlockState() +{ + return 0; +} + +int RotatedPillarTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & MASK_FACING) : 0; +} + +Tile::BlockState RotatedPillarTile::getBlockState(int data) +{ + return Tile::BlockState(data & MASK_FACING); +} + +Tile::BlockState RotatedPillarTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & MASK_FACING); +} + int RotatedPillarTile::getRenderShape() { return Tile::SHAPE_TREE; diff --git a/Minecraft.World/RotatedPillarTile.h b/Minecraft.World/RotatedPillarTile.h index 76e52997..a01f3560 100644 --- a/Minecraft.World/RotatedPillarTile.h +++ b/Minecraft.World/RotatedPillarTile.h @@ -17,6 +17,11 @@ protected: RotatedPillarTile(int id, Material *material); public: + virtual void createBlockStateDefinition(); + virtual int defaultBlockState(); + virtual int convertBlockStateToLegacyData(BlockState *state); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z); + virtual Tile::BlockState getBlockState(int data); virtual int getRenderShape(); virtual int getPlacedOnFaceDataValue(Level *level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue); virtual Icon *getTexture(int face, int data); diff --git a/Minecraft.World/Sapling.cpp b/Minecraft.World/Sapling.cpp index 93b15039..5c76d3fa 100644 --- a/Minecraft.World/Sapling.cpp +++ b/Minecraft.World/Sapling.cpp @@ -38,6 +38,32 @@ Sapling::Sapling(int id) : Bush(id) icons = nullptr; } +void Sapling::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int Sapling::defaultBlockState() +{ + return 0; +} + +int Sapling::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & (TYPE_MASK | AGE_BIT)) : 0; +} + +Tile::BlockState Sapling::getBlockState(int data) +{ + return Tile::BlockState(data & (TYPE_MASK | AGE_BIT)); +} + +Tile::BlockState Sapling::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & (TYPE_MASK | AGE_BIT)); +} + void Sapling::updateDefaultShape() { float ss = 0.4f; diff --git a/Minecraft.World/Sapling.h b/Minecraft.World/Sapling.h index 7d1e287b..cfeac0f3 100644 --- a/Minecraft.World/Sapling.h +++ b/Minecraft.World/Sapling.h @@ -37,6 +37,11 @@ protected: Sapling(int id); public: + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void updateDefaultShape(); // 4J Added override virtual void tick(Level *level, int x, int y, int z, Random *random); diff --git a/Minecraft.World/SavannaTreeFeature.cpp b/Minecraft.World/SavannaTreeFeature.cpp index 48457f21..b00c1c4f 100644 --- a/Minecraft.World/SavannaTreeFeature.cpp +++ b/Minecraft.World/SavannaTreeFeature.cpp @@ -11,7 +11,7 @@ SavannaTreeFeature::SavannaTreeFeature(bool doUpdate) : AbstractTreeFeature(doUp void SavannaTreeFeature::placeLog(Level* level, int x, int y, int z) { - placeBlock(level, x, y, z, Tile::tree2Trunk_Id, 0); + placeBlock(level, x, y, z, Tile::log2_Id, 0); } void SavannaTreeFeature::placeLeafAt(Level* level, int x, int y, int z) diff --git a/Minecraft.World/ScatteredFeaturePieces.cpp b/Minecraft.World/ScatteredFeaturePieces.cpp index 18082e46..6b955eae 100644 --- a/Minecraft.World/ScatteredFeaturePieces.cpp +++ b/Minecraft.World/ScatteredFeaturePieces.cpp @@ -105,16 +105,16 @@ bool ScatteredFeaturePieces::ScatteredFeaturePiece::updateAverageGroundHeight(Le WeighedTreasure *ScatteredFeaturePieces::DesertPyramidPiece::treasureItems[ScatteredFeaturePieces::DesertPyramidPiece::TREASURE_ITEMS_COUNT] = { new WeighedTreasure(Item::diamond_Id, 0, 1, 3, 3), - new WeighedTreasure(Item::ironIngot_Id, 0, 1, 5, 10), - new WeighedTreasure(Item::goldIngot_Id, 0, 2, 7, 15), + new WeighedTreasure(Item::iron_ingot_Id, 0, 1, 5, 10), + new WeighedTreasure(Item::gold_ingot_Id, 0, 2, 7, 15), new WeighedTreasure(Item::emerald_Id, 0, 1, 3, 2), new WeighedTreasure(Item::bone_Id, 0, 4, 6, 20), new WeighedTreasure(Item::rotten_flesh_Id, 0, 3, 7, 16), // very rare for pyramids ... new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 3), - new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 1), - new WeighedTreasure(Item::horseArmorGold_Id, 0, 1, 1, 1), - new WeighedTreasure(Item::horseArmorDiamond_Id, 0, 1, 1, 1), + new WeighedTreasure(Item::iron_horse_armor_Id, 0, 1, 1, 1), + new WeighedTreasure(Item::golden_horse_armor_Id, 0, 1, 1, 1), + new WeighedTreasure(Item::diamond_horse_armor_Id, 0, 1, 1, 1), // ... }; @@ -156,73 +156,73 @@ void ScatteredFeaturePieces::DesertPyramidPiece::readAdditonalSaveData(CompoundT bool ScatteredFeaturePieces::DesertPyramidPiece::postProcess(Level *level, Random *random, BoundingBox *chunkBB) { // pyramid - generateBox(level, chunkBB, 0, -4, 0, width - 1, 0, depth - 1, Tile::sandStone_Id, Tile::sandStone_Id, false); + generateBox(level, chunkBB, 0, -4, 0, width - 1, 0, depth - 1, Tile::sandstone_Id, Tile::sandstone_Id, false); for (int pos = 1; pos <= 9; pos++) { - generateBox(level, chunkBB, pos, pos, pos, width - 1 - pos, pos, depth - 1 - pos, Tile::sandStone_Id, Tile::sandStone_Id, false); + generateBox(level, chunkBB, pos, pos, pos, width - 1 - pos, pos, depth - 1 - pos, Tile::sandstone_Id, Tile::sandstone_Id, false); generateBox(level, chunkBB, pos + 1, pos, pos + 1, width - 2 - pos, pos, depth - 2 - pos, 0, 0, false); } for (int x = 0; x < width; x++) { for (int z = 0; z < depth; z++) { - fillColumnDown(level, Tile::sandStone_Id, 0, x, -5, z, chunkBB); + fillColumnDown(level, Tile::sandstone_Id, 0, x, -5, z, chunkBB); } } - int stairsNorth = getOrientationData(Tile::stairs_sandstone_Id, 3); - int stairsSouth = getOrientationData(Tile::stairs_sandstone_Id, 2); - int stairsEast = getOrientationData(Tile::stairs_sandstone_Id, 0); - int stairsWest = getOrientationData(Tile::stairs_sandstone_Id, 1); + int stairsNorth = getOrientationData(Tile::sandstone_stairs_Id, 3); + int stairsSouth = getOrientationData(Tile::sandstone_stairs_Id, 2); + int stairsEast = getOrientationData(Tile::sandstone_stairs_Id, 0); + int stairsWest = getOrientationData(Tile::sandstone_stairs_Id, 1); int baseDecoColor = ~DyePowderItem::ORANGE & 0xf; int blue = ~DyePowderItem::BLUE & 0xf; // towers - generateBox(level, chunkBB, 0, 0, 0, 4, 9, 4, Tile::sandStone_Id, 0, false); - generateBox(level, chunkBB, 1, 10, 1, 3, 10, 3, Tile::sandStone_Id, Tile::sandStone_Id, false); - placeBlock(level, Tile::stairs_sandstone_Id, stairsNorth, 2, 10, 0, chunkBB); - placeBlock(level, Tile::stairs_sandstone_Id, stairsSouth, 2, 10, 4, chunkBB); - placeBlock(level, Tile::stairs_sandstone_Id, stairsEast, 0, 10, 2, chunkBB); - placeBlock(level, Tile::stairs_sandstone_Id, stairsWest, 4, 10, 2, chunkBB); - generateBox(level, chunkBB, width - 5, 0, 0, width - 1, 9, 4, Tile::sandStone_Id, 0, false); - generateBox(level, chunkBB, width - 4, 10, 1, width - 2, 10, 3, Tile::sandStone_Id, Tile::sandStone_Id, false); - placeBlock(level, Tile::stairs_sandstone_Id, stairsNorth, width - 3, 10, 0, chunkBB); - placeBlock(level, Tile::stairs_sandstone_Id, stairsSouth, width - 3, 10, 4, chunkBB); - placeBlock(level, Tile::stairs_sandstone_Id, stairsEast, width - 5, 10, 2, chunkBB); - placeBlock(level, Tile::stairs_sandstone_Id, stairsWest, width - 1, 10, 2, chunkBB); + generateBox(level, chunkBB, 0, 0, 0, 4, 9, 4, Tile::sandstone_Id, 0, false); + generateBox(level, chunkBB, 1, 10, 1, 3, 10, 3, Tile::sandstone_Id, Tile::sandstone_Id, false); + placeBlock(level, Tile::sandstone_stairs_Id, stairsNorth, 2, 10, 0, chunkBB); + placeBlock(level, Tile::sandstone_stairs_Id, stairsSouth, 2, 10, 4, chunkBB); + placeBlock(level, Tile::sandstone_stairs_Id, stairsEast, 0, 10, 2, chunkBB); + placeBlock(level, Tile::sandstone_stairs_Id, stairsWest, 4, 10, 2, chunkBB); + generateBox(level, chunkBB, width - 5, 0, 0, width - 1, 9, 4, Tile::sandstone_Id, 0, false); + generateBox(level, chunkBB, width - 4, 10, 1, width - 2, 10, 3, Tile::sandstone_Id, Tile::sandstone_Id, false); + placeBlock(level, Tile::sandstone_stairs_Id, stairsNorth, width - 3, 10, 0, chunkBB); + placeBlock(level, Tile::sandstone_stairs_Id, stairsSouth, width - 3, 10, 4, chunkBB); + placeBlock(level, Tile::sandstone_stairs_Id, stairsEast, width - 5, 10, 2, chunkBB); + placeBlock(level, Tile::sandstone_stairs_Id, stairsWest, width - 1, 10, 2, chunkBB); // entrance - generateBox(level, chunkBB, 8, 0, 0, 12, 4, 4, Tile::sandStone_Id, 0, false); + generateBox(level, chunkBB, 8, 0, 0, 12, 4, 4, Tile::sandstone_Id, 0, false); generateBox(level, chunkBB, 9, 1, 0, 11, 3, 4, 0, 0, false); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 9, 1, 1, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 9, 2, 1, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 9, 3, 1, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 10, 3, 1, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 11, 3, 1, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 11, 2, 1, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 11, 1, 1, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 9, 1, 1, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 9, 2, 1, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 9, 3, 1, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 10, 3, 1, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 11, 3, 1, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 11, 2, 1, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 11, 1, 1, chunkBB); // tower pathways - generateBox(level, chunkBB, 4, 1, 1, 8, 3, 3, Tile::sandStone_Id, 0, false); + generateBox(level, chunkBB, 4, 1, 1, 8, 3, 3, Tile::sandstone_Id, 0, false); generateBox(level, chunkBB, 4, 1, 2, 8, 2, 2, 0, 0, false); - generateBox(level, chunkBB, 12, 1, 1, 16, 3, 3, Tile::sandStone_Id, 0, false); + generateBox(level, chunkBB, 12, 1, 1, 16, 3, 3, Tile::sandstone_Id, 0, false); generateBox(level, chunkBB, 12, 1, 2, 16, 2, 2, 0, 0, false); // hall floor and pillars - generateBox(level, chunkBB, 5, 4, 5, width - 6, 4, depth - 6, Tile::sandStone_Id, Tile::sandStone_Id, false); + generateBox(level, chunkBB, 5, 4, 5, width - 6, 4, depth - 6, Tile::sandstone_Id, Tile::sandstone_Id, false); generateBox(level, chunkBB, 9, 4, 9, 11, 4, 11, 0, 0, false); - generateBox(level, chunkBB, 8, 1, 8, 8, 3, 8, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); - generateBox(level, chunkBB, 12, 1, 8, 12, 3, 8, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); - generateBox(level, chunkBB, 8, 1, 12, 8, 3, 12, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); - generateBox(level, chunkBB, 12, 1, 12, 12, 3, 12, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); + generateBox(level, chunkBB, 8, 1, 8, 8, 3, 8, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); + generateBox(level, chunkBB, 12, 1, 8, 12, 3, 8, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); + generateBox(level, chunkBB, 8, 1, 12, 8, 3, 12, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); + generateBox(level, chunkBB, 12, 1, 12, 12, 3, 12, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); // catwalks - generateBox(level, chunkBB, 1, 1, 5, 4, 4, 11, Tile::sandStone_Id, Tile::sandStone_Id, false); - generateBox(level, chunkBB, width - 5, 1, 5, width - 2, 4, 11, Tile::sandStone_Id, Tile::sandStone_Id, false); - generateBox(level, chunkBB, 6, 7, 9, 6, 7, 11, Tile::sandStone_Id, Tile::sandStone_Id, false); - generateBox(level, chunkBB, width - 7, 7, 9, width - 7, 7, 11, Tile::sandStone_Id, Tile::sandStone_Id, false); - generateBox(level, chunkBB, 5, 5, 9, 5, 7, 11, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); - generateBox(level, chunkBB, width - 6, 5, 9, width - 6, 7, 11, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); + generateBox(level, chunkBB, 1, 1, 5, 4, 4, 11, Tile::sandstone_Id, Tile::sandstone_Id, false); + generateBox(level, chunkBB, width - 5, 1, 5, width - 2, 4, 11, Tile::sandstone_Id, Tile::sandstone_Id, false); + generateBox(level, chunkBB, 6, 7, 9, 6, 7, 11, Tile::sandstone_Id, Tile::sandstone_Id, false); + generateBox(level, chunkBB, width - 7, 7, 9, width - 7, 7, 11, Tile::sandstone_Id, Tile::sandstone_Id, false); + generateBox(level, chunkBB, 5, 5, 9, 5, 7, 11, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); + generateBox(level, chunkBB, width - 6, 5, 9, width - 6, 7, 11, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); placeBlock(level, 0, 0, 5, 5, 10, chunkBB); placeBlock(level, 0, 0, 5, 6, 10, chunkBB); placeBlock(level, 0, 0, 6, 6, 10, chunkBB); @@ -233,125 +233,125 @@ bool ScatteredFeaturePieces::DesertPyramidPiece::postProcess(Level *level, Rando // tower stairs generateBox(level, chunkBB, 2, 4, 4, 2, 6, 4, 0, 0, false); generateBox(level, chunkBB, width - 3, 4, 4, width - 3, 6, 4, 0, 0, false); - placeBlock(level, Tile::stairs_sandstone_Id, stairsNorth, 2, 4, 5, chunkBB); - placeBlock(level, Tile::stairs_sandstone_Id, stairsNorth, 2, 3, 4, chunkBB); - placeBlock(level, Tile::stairs_sandstone_Id, stairsNorth, width - 3, 4, 5, chunkBB); - placeBlock(level, Tile::stairs_sandstone_Id, stairsNorth, width - 3, 3, 4, chunkBB); - generateBox(level, chunkBB, 1, 1, 3, 2, 2, 3, Tile::sandStone_Id, Tile::sandStone_Id, false); - generateBox(level, chunkBB, width - 3, 1, 3, width - 2, 2, 3, Tile::sandStone_Id, Tile::sandStone_Id, false); - placeBlock(level, Tile::stairs_sandstone_Id, 0, 1, 1, 2, chunkBB); - placeBlock(level, Tile::stairs_sandstone_Id, 0, width - 2, 1, 2, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SAND_SLAB, 1, 2, 2, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SAND_SLAB, width - 2, 2, 2, chunkBB); - placeBlock(level, Tile::stairs_sandstone_Id, stairsWest, 2, 1, 2, chunkBB); - placeBlock(level, Tile::stairs_sandstone_Id, stairsEast, width - 3, 1, 2, chunkBB); + placeBlock(level, Tile::sandstone_stairs_Id, stairsNorth, 2, 4, 5, chunkBB); + placeBlock(level, Tile::sandstone_stairs_Id, stairsNorth, 2, 3, 4, chunkBB); + placeBlock(level, Tile::sandstone_stairs_Id, stairsNorth, width - 3, 4, 5, chunkBB); + placeBlock(level, Tile::sandstone_stairs_Id, stairsNorth, width - 3, 3, 4, chunkBB); + generateBox(level, chunkBB, 1, 1, 3, 2, 2, 3, Tile::sandstone_Id, Tile::sandstone_Id, false); + generateBox(level, chunkBB, width - 3, 1, 3, width - 2, 2, 3, Tile::sandstone_Id, Tile::sandstone_Id, false); + placeBlock(level, Tile::sandstone_stairs_Id, 0, 1, 1, 2, chunkBB); + placeBlock(level, Tile::sandstone_stairs_Id, 0, width - 2, 1, 2, chunkBB); + placeBlock(level, Tile::stone_slab_Id, StoneSlabTile::SAND_SLAB, 1, 2, 2, chunkBB); + placeBlock(level, Tile::stone_slab_Id, StoneSlabTile::SAND_SLAB, width - 2, 2, 2, chunkBB); + placeBlock(level, Tile::sandstone_stairs_Id, stairsWest, 2, 1, 2, chunkBB); + placeBlock(level, Tile::sandstone_stairs_Id, stairsEast, width - 3, 1, 2, chunkBB); // indoor decoration - generateBox(level, chunkBB, 4, 3, 5, 4, 3, 18, Tile::sandStone_Id, Tile::sandStone_Id, false); - generateBox(level, chunkBB, width - 5, 3, 5, width - 5, 3, 17, Tile::sandStone_Id, Tile::sandStone_Id, false); + generateBox(level, chunkBB, 4, 3, 5, 4, 3, 18, Tile::sandstone_Id, Tile::sandstone_Id, false); + generateBox(level, chunkBB, width - 5, 3, 5, width - 5, 3, 17, Tile::sandstone_Id, Tile::sandstone_Id, false); generateBox(level, chunkBB, 3, 1, 5, 4, 2, 16, 0, 0, false); generateBox(level, chunkBB, width - 6, 1, 5, width - 5, 2, 16, 0, 0, false); for (int z = 5; z <= 17; z += 2) { - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 4, 1, z, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, 4, 2, z, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, width - 5, 1, z, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, width - 5, 2, z, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 4, 1, z, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_HEIROGLYPHS, 4, 2, z, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, width - 5, 1, z, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_HEIROGLYPHS, width - 5, 2, z, chunkBB); } - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, 10, 0, 7, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, 10, 0, 8, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, 9, 0, 9, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, 11, 0, 9, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, 8, 0, 10, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, 12, 0, 10, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, 7, 0, 10, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, 13, 0, 10, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, 9, 0, 11, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, 11, 0, 11, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, 10, 0, 12, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, 10, 0, 13, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, blue, 10, 0, 10, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, 10, 0, 7, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, 10, 0, 8, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, 9, 0, 9, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, 11, 0, 9, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, 8, 0, 10, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, 12, 0, 10, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, 7, 0, 10, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, 13, 0, 10, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, 9, 0, 11, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, 11, 0, 11, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, 10, 0, 12, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, 10, 0, 13, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, blue, 10, 0, 10, chunkBB); // outdoor decoration for (int x = 0; x <= width - 1; x += width - 1) { - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 2, 1, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x, 2, 2, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 2, 3, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 3, 1, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x, 3, 2, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 3, 3, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x, 4, 1, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, x, 4, 2, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x, 4, 3, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 5, 1, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x, 5, 2, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 5, 3, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x, 6, 1, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, x, 6, 2, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x, 6, 3, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x, 7, 1, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x, 7, 2, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x, 7, 3, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 8, 1, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 8, 2, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 8, 3, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 2, 1, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x, 2, 2, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 2, 3, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 3, 1, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x, 3, 2, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 3, 3, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x, 4, 1, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_HEIROGLYPHS, x, 4, 2, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x, 4, 3, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 5, 1, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x, 5, 2, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 5, 3, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x, 6, 1, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_HEIROGLYPHS, x, 6, 2, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x, 6, 3, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x, 7, 1, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x, 7, 2, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x, 7, 3, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 8, 1, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 8, 2, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 8, 3, chunkBB); } for (int x = 2; x <= width - 3; x += width - 3 - 2) { - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x - 1, 2, 0, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x, 2, 0, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x + 1, 2, 0, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x - 1, 3, 0, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x, 3, 0, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x + 1, 3, 0, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x - 1, 4, 0, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, x, 4, 0, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x + 1, 4, 0, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x - 1, 5, 0, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x, 5, 0, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x + 1, 5, 0, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x - 1, 6, 0, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, x, 6, 0, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x + 1, 6, 00, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x - 1, 7, 0, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x, 7, 0, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, x + 1, 7, 0, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x - 1, 8, 0, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 8, 0, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x + 1, 8, 0, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x - 1, 2, 0, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x, 2, 0, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x + 1, 2, 0, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x - 1, 3, 0, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x, 3, 0, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x + 1, 3, 0, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x - 1, 4, 0, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_HEIROGLYPHS, x, 4, 0, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x + 1, 4, 0, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x - 1, 5, 0, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x, 5, 0, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x + 1, 5, 0, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x - 1, 6, 0, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_HEIROGLYPHS, x, 6, 0, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x + 1, 6, 00, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x - 1, 7, 0, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x, 7, 0, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, x + 1, 7, 0, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x - 1, 8, 0, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 8, 0, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x + 1, 8, 0, chunkBB); } - generateBox(level, chunkBB, 8, 4, 0, 12, 6, 0, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); + generateBox(level, chunkBB, 8, 4, 0, 12, 6, 0, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); placeBlock(level, 0, 0, 8, 6, 0, chunkBB); placeBlock(level, 0, 0, 12, 6, 0, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, 9, 5, 0, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, 10, 5, 0, chunkBB); - placeBlock(level, Tile::clayHardened_colored_Id, baseDecoColor, 11, 5, 0, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, 9, 5, 0, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_HEIROGLYPHS, 10, 5, 0, chunkBB); + placeBlock(level, Tile::stained_hardened_clay_Id, baseDecoColor, 11, 5, 0, chunkBB); // tombs - generateBox(level, chunkBB, 8, -14, 8, 12, -11, 12, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); - generateBox(level, chunkBB, 8, -10, 8, 12, -10, 12, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, false); - generateBox(level, chunkBB, 8, -9, 8, 12, -9, 12, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); - generateBox(level, chunkBB, 8, -8, 8, 12, -1, 12, Tile::sandStone_Id, Tile::sandStone_Id, false); + generateBox(level, chunkBB, 8, -14, 8, 12, -11, 12, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); + generateBox(level, chunkBB, 8, -10, 8, 12, -10, 12, Tile::sandstone_Id, SandStoneTile::TYPE_HEIROGLYPHS, Tile::sandstone_Id, SandStoneTile::TYPE_HEIROGLYPHS, false); + generateBox(level, chunkBB, 8, -9, 8, 12, -9, 12, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, false); + generateBox(level, chunkBB, 8, -8, 8, 12, -1, 12, Tile::sandstone_Id, Tile::sandstone_Id, false); generateBox(level, chunkBB, 9, -11, 9, 11, -1, 11, 0, 0, false); - placeBlock(level, Tile::pressurePlate_stone_Id, 0, 10, -11, 10, chunkBB); + placeBlock(level, Tile::stone_pressure_plate_Id, 0, 10, -11, 10, chunkBB); generateBox(level, chunkBB, 9, -13, 9, 11, -13, 11, Tile::tnt_Id, 0, false); placeBlock(level, 0, 0, 8, -11, 10, chunkBB); placeBlock(level, 0, 0, 8, -10, 10, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, 7, -10, 10, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 7, -11, 10, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_HEIROGLYPHS, 7, -10, 10, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 7, -11, 10, chunkBB); placeBlock(level, 0, 0, 12, -11, 10, chunkBB); placeBlock(level, 0, 0, 12, -10, 10, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, 13, -10, 10, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 13, -11, 10, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_HEIROGLYPHS, 13, -10, 10, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 13, -11, 10, chunkBB); placeBlock(level, 0, 0, 10, -11, 8, chunkBB); placeBlock(level, 0, 0, 10, -10, 8, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, 10, -10, 7, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 10, -11, 7, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_HEIROGLYPHS, 10, -10, 7, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 10, -11, 7, chunkBB); placeBlock(level, 0, 0, 10, -11, 12, chunkBB); placeBlock(level, 0, 0, 10, -10, 12, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, 10, -10, 13, chunkBB); - placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 10, -11, 13, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_HEIROGLYPHS, 10, -10, 13, chunkBB); + placeBlock(level, Tile::sandstone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 10, -11, 13, chunkBB); // chests! for (int i = 0; i < 4; i++) @@ -360,7 +360,7 @@ bool ScatteredFeaturePieces::DesertPyramidPiece::postProcess(Level *level, Rando { int xo = Direction::STEP_X[i] * 2; int zo = Direction::STEP_Z[i] * 2; - hasPlacedChest[i] = createChest(level, chunkBB, random, 10 + xo, -11, 10 + zo, WeighedTreasure::addToTreasure(WeighedTreasureArray(treasureItems,TREASURE_ITEMS_COUNT), Item::enchantedBook->createForRandomTreasure(random)), 2 + random->nextInt(5)); + hasPlacedChest[i] = createChest(level, chunkBB, random, 10 + xo, -11, 10 + zo, WeighedTreasure::addToTreasure(WeighedTreasureArray(treasureItems,TREASURE_ITEMS_COUNT), Item::enchanted_book->createForRandomTreasure(random)), 2 + random->nextInt(5)); } } @@ -370,16 +370,16 @@ bool ScatteredFeaturePieces::DesertPyramidPiece::postProcess(Level *level, Rando WeighedTreasure *ScatteredFeaturePieces::JunglePyramidPiece::treasureItems[ScatteredFeaturePieces::JunglePyramidPiece::TREASURE_ITEMS_COUNT] = { new WeighedTreasure(Item::diamond_Id, 0, 1, 3, 3), - new WeighedTreasure(Item::ironIngot_Id, 0, 1, 5, 10), - new WeighedTreasure(Item::goldIngot_Id, 0, 2, 7, 15), + new WeighedTreasure(Item::iron_ingot_Id, 0, 1, 5, 10), + new WeighedTreasure(Item::gold_ingot_Id, 0, 2, 7, 15), new WeighedTreasure(Item::emerald_Id, 0, 1, 3, 2), new WeighedTreasure(Item::bone_Id, 0, 4, 6, 20), new WeighedTreasure(Item::rotten_flesh_Id, 0, 3, 7, 16), // very rare for pyramids ... new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 3), - new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 1), - new WeighedTreasure(Item::horseArmorGold_Id, 0, 1, 1, 1), - new WeighedTreasure(Item::horseArmorDiamond_Id, 0, 1, 1, 1), + new WeighedTreasure(Item::iron_horse_armor_Id, 0, 1, 1, 1), + new WeighedTreasure(Item::golden_horse_armor_Id, 0, 1, 1, 1), + new WeighedTreasure(Item::diamond_horse_armor_Id, 0, 1, 1, 1), // ... }; @@ -428,10 +428,10 @@ bool ScatteredFeaturePieces::JunglePyramidPiece::postProcess(Level *level, Rando return false; } - int stairsNorth = getOrientationData(Tile::stairs_stone_Id, 3); - int stairsSouth = getOrientationData(Tile::stairs_stone_Id, 2); - int stairsEast = getOrientationData(Tile::stairs_stone_Id, 0); - int stairsWest = getOrientationData(Tile::stairs_stone_Id, 1); + int stairsNorth = getOrientationData(Tile::stone_stairs_Id, 3); + int stairsSouth = getOrientationData(Tile::stone_stairs_Id, 2); + int stairsEast = getOrientationData(Tile::stone_stairs_Id, 0); + int stairsWest = getOrientationData(Tile::stone_stairs_Id, 1); // floor generateBox(level, chunkBB, 0, -4, 0, width - 1, 0, depth - 1, false, random, &stoneSelector); @@ -498,38 +498,38 @@ bool ScatteredFeaturePieces::JunglePyramidPiece::postProcess(Level *level, Rando generateBox(level, chunkBB, 4, 9, 10, 4, 9, 10, false, random, &stoneSelector); generateBox(level, chunkBB, 7, 9, 10, 7, 9, 10, false, random, &stoneSelector); generateBox(level, chunkBB, 5, 9, 7, 6, 9, 7, false, random, &stoneSelector); - placeBlock(level, Tile::stairs_stone_Id, stairsNorth, 5, 9, 6, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, stairsNorth, 6, 9, 6, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, stairsSouth, 5, 9, 8, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, stairsSouth, 6, 9, 8, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsNorth, 5, 9, 6, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsNorth, 6, 9, 6, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsSouth, 5, 9, 8, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsSouth, 6, 9, 8, chunkBB); // front stairs - placeBlock(level, Tile::stairs_stone_Id, stairsNorth, 4, 0, 0, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, stairsNorth, 5, 0, 0, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, stairsNorth, 6, 0, 0, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, stairsNorth, 7, 0, 0, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsNorth, 4, 0, 0, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsNorth, 5, 0, 0, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsNorth, 6, 0, 0, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsNorth, 7, 0, 0, chunkBB); // indoor stairs up - placeBlock(level, Tile::stairs_stone_Id, stairsNorth, 4, 1, 8, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, stairsNorth, 4, 2, 9, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, stairsNorth, 4, 3, 10, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, stairsNorth, 7, 1, 8, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, stairsNorth, 7, 2, 9, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, stairsNorth, 7, 3, 10, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsNorth, 4, 1, 8, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsNorth, 4, 2, 9, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsNorth, 4, 3, 10, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsNorth, 7, 1, 8, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsNorth, 7, 2, 9, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsNorth, 7, 3, 10, chunkBB); generateBox(level, chunkBB, 4, 1, 9, 4, 1, 9, false, random, &stoneSelector); generateBox(level, chunkBB, 7, 1, 9, 7, 1, 9, false, random, &stoneSelector); generateBox(level, chunkBB, 4, 1, 10, 7, 2, 10, false, random, &stoneSelector); // indoor hand rail generateBox(level, chunkBB, 5, 4, 5, 6, 4, 5, false, random, &stoneSelector); - placeBlock(level, Tile::stairs_stone_Id, stairsEast, 4, 4, 5, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, stairsWest, 7, 4, 5, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsEast, 4, 4, 5, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsWest, 7, 4, 5, chunkBB); // indoor stairs down for (int i = 0; i < 4; i++) { - placeBlock(level, Tile::stairs_stone_Id, stairsSouth, 5, 0 - i, 6 + i, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, stairsSouth, 6, 0 - i, 6 + i, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsSouth, 5, 0 - i, 6 + i, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, stairsSouth, 6, 0 - i, 6 + i, chunkBB); generateAirBox(level, chunkBB, 5, 0 - i, 7 + i, 6, 0 - i, 9 + i); } @@ -551,19 +551,19 @@ bool ScatteredFeaturePieces::JunglePyramidPiece::postProcess(Level *level, Rando generateBox(level, chunkBB, 6, -1, 1, 6, -1, 1, false, random, &stoneSelector); // trip wire trap 1 - placeBlock(level, Tile::tripWireSource_Id, getOrientationData(Tile::tripWireSource_Id, Direction::EAST) | TripWireSourceTile::MASK_ATTACHED, 1, -3, 8, chunkBB); - placeBlock(level, Tile::tripWireSource_Id, getOrientationData(Tile::tripWireSource_Id, Direction::WEST) | TripWireSourceTile::MASK_ATTACHED, 4, -3, 8, chunkBB); - placeBlock(level, Tile::tripWire_Id, TripWireTile::MASK_ATTACHED, 2, -3, 8, chunkBB); - placeBlock(level, Tile::tripWire_Id, TripWireTile::MASK_ATTACHED, 3, -3, 8, chunkBB); - placeBlock(level, Tile::redStoneDust_Id, 0, 5, -3, 7, chunkBB); - placeBlock(level, Tile::redStoneDust_Id, 0, 5, -3, 6, chunkBB); - placeBlock(level, Tile::redStoneDust_Id, 0, 5, -3, 5, chunkBB); - placeBlock(level, Tile::redStoneDust_Id, 0, 5, -3, 4, chunkBB); - placeBlock(level, Tile::redStoneDust_Id, 0, 5, -3, 3, chunkBB); - placeBlock(level, Tile::redStoneDust_Id, 0, 5, -3, 2, chunkBB); - placeBlock(level, Tile::redStoneDust_Id, 0, 5, -3, 1, chunkBB); - placeBlock(level, Tile::redStoneDust_Id, 0, 4, -3, 1, chunkBB); - placeBlock(level, Tile::mossyCobblestone_Id, 0, 3, -3, 1, chunkBB); + placeBlock(level, Tile::tripwire_hook_Id, getOrientationData(Tile::tripwire_hook_Id, Direction::EAST) | TripWireSourceTile::MASK_ATTACHED, 1, -3, 8, chunkBB); + placeBlock(level, Tile::tripwire_hook_Id, getOrientationData(Tile::tripwire_hook_Id, Direction::WEST) | TripWireSourceTile::MASK_ATTACHED, 4, -3, 8, chunkBB); + placeBlock(level, Tile::tripwire_Id, TripWireTile::MASK_ATTACHED, 2, -3, 8, chunkBB); + placeBlock(level, Tile::tripwire_Id, TripWireTile::MASK_ATTACHED, 3, -3, 8, chunkBB); + placeBlock(level, Tile::redstone_wire_Id, 0, 5, -3, 7, chunkBB); + placeBlock(level, Tile::redstone_wire_Id, 0, 5, -3, 6, chunkBB); + placeBlock(level, Tile::redstone_wire_Id, 0, 5, -3, 5, chunkBB); + placeBlock(level, Tile::redstone_wire_Id, 0, 5, -3, 4, chunkBB); + placeBlock(level, Tile::redstone_wire_Id, 0, 5, -3, 3, chunkBB); + placeBlock(level, Tile::redstone_wire_Id, 0, 5, -3, 2, chunkBB); + placeBlock(level, Tile::redstone_wire_Id, 0, 5, -3, 1, chunkBB); + placeBlock(level, Tile::redstone_wire_Id, 0, 4, -3, 1, chunkBB); + placeBlock(level, Tile::mossy_cobblestone_Id, 0, 3, -3, 1, chunkBB); if (!placedTrap1) { placedTrap1 = createDispenser(level, chunkBB, random, 3, -2, 1, Facing::NORTH, WeighedTreasureArray(dispenserItems,DISPENSER_ITEMS_COUNT), 2); @@ -571,16 +571,16 @@ bool ScatteredFeaturePieces::JunglePyramidPiece::postProcess(Level *level, Rando placeBlock(level, Tile::vine_Id, 0xf, 3, -2, 2, chunkBB); // trip wire trap 2 - placeBlock(level, Tile::tripWireSource_Id, getOrientationData(Tile::tripWireSource_Id, Direction::NORTH) | TripWireSourceTile::MASK_ATTACHED, 7, -3, 1, chunkBB); - placeBlock(level, Tile::tripWireSource_Id, getOrientationData(Tile::tripWireSource_Id, Direction::SOUTH) | TripWireSourceTile::MASK_ATTACHED, 7, -3, 5, chunkBB); - placeBlock(level, Tile::tripWire_Id, TripWireTile::MASK_ATTACHED, 7, -3, 2, chunkBB); - placeBlock(level, Tile::tripWire_Id, TripWireTile::MASK_ATTACHED, 7, -3, 3, chunkBB); - placeBlock(level, Tile::tripWire_Id, TripWireTile::MASK_ATTACHED, 7, -3, 4, chunkBB); - placeBlock(level, Tile::redStoneDust_Id, 0, 8, -3, 6, chunkBB); - placeBlock(level, Tile::redStoneDust_Id, 0, 9, -3, 6, chunkBB); - placeBlock(level, Tile::redStoneDust_Id, 0, 9, -3, 5, chunkBB); - placeBlock(level, Tile::mossyCobblestone_Id, 0, 9, -3, 4, chunkBB); - placeBlock(level, Tile::redStoneDust_Id, 0, 9, -2, 4, chunkBB); + placeBlock(level, Tile::tripwire_hook_Id, getOrientationData(Tile::tripwire_hook_Id, Direction::NORTH) | TripWireSourceTile::MASK_ATTACHED, 7, -3, 1, chunkBB); + placeBlock(level, Tile::tripwire_hook_Id, getOrientationData(Tile::tripwire_hook_Id, Direction::SOUTH) | TripWireSourceTile::MASK_ATTACHED, 7, -3, 5, chunkBB); + placeBlock(level, Tile::tripwire_Id, TripWireTile::MASK_ATTACHED, 7, -3, 2, chunkBB); + placeBlock(level, Tile::tripwire_Id, TripWireTile::MASK_ATTACHED, 7, -3, 3, chunkBB); + placeBlock(level, Tile::tripwire_Id, TripWireTile::MASK_ATTACHED, 7, -3, 4, chunkBB); + placeBlock(level, Tile::redstone_wire_Id, 0, 8, -3, 6, chunkBB); + placeBlock(level, Tile::redstone_wire_Id, 0, 9, -3, 6, chunkBB); + placeBlock(level, Tile::redstone_wire_Id, 0, 9, -3, 5, chunkBB); + placeBlock(level, Tile::mossy_cobblestone_Id, 0, 9, -3, 4, chunkBB); + placeBlock(level, Tile::redstone_wire_Id, 0, 9, -2, 4, chunkBB); if (!placedTrap2) { placedTrap2 = createDispenser(level, chunkBB, random, 9, -2, 3, Facing::WEST, WeighedTreasureArray(dispenserItems,DISPENSER_ITEMS_COUNT), 2); @@ -589,40 +589,40 @@ bool ScatteredFeaturePieces::JunglePyramidPiece::postProcess(Level *level, Rando placeBlock(level, Tile::vine_Id, 0xf, 8, -2, 3, chunkBB); if (!placedMainChest) { - placedMainChest = createChest(level, chunkBB, random, 8, -3, 3, WeighedTreasure::addToTreasure(WeighedTreasureArray(treasureItems,TREASURE_ITEMS_COUNT), Item::enchantedBook->createForRandomTreasure(random)), 2 + random->nextInt(5)); + placedMainChest = createChest(level, chunkBB, random, 8, -3, 3, WeighedTreasure::addToTreasure(WeighedTreasureArray(treasureItems,TREASURE_ITEMS_COUNT), Item::enchanted_book->createForRandomTreasure(random)), 2 + random->nextInt(5)); } - placeBlock(level, Tile::mossyCobblestone_Id, 0, 9, -3, 2, chunkBB); - placeBlock(level, Tile::mossyCobblestone_Id, 0, 8, -3, 1, chunkBB); - placeBlock(level, Tile::mossyCobblestone_Id, 0, 4, -3, 5, chunkBB); - placeBlock(level, Tile::mossyCobblestone_Id, 0, 5, -2, 5, chunkBB); - placeBlock(level, Tile::mossyCobblestone_Id, 0, 5, -1, 5, chunkBB); - placeBlock(level, Tile::mossyCobblestone_Id, 0, 6, -3, 5, chunkBB); - placeBlock(level, Tile::mossyCobblestone_Id, 0, 7, -2, 5, chunkBB); - placeBlock(level, Tile::mossyCobblestone_Id, 0, 7, -1, 5, chunkBB); - placeBlock(level, Tile::mossyCobblestone_Id, 0, 8, -3, 5, chunkBB); + placeBlock(level, Tile::mossy_cobblestone_Id, 0, 9, -3, 2, chunkBB); + placeBlock(level, Tile::mossy_cobblestone_Id, 0, 8, -3, 1, chunkBB); + placeBlock(level, Tile::mossy_cobblestone_Id, 0, 4, -3, 5, chunkBB); + placeBlock(level, Tile::mossy_cobblestone_Id, 0, 5, -2, 5, chunkBB); + placeBlock(level, Tile::mossy_cobblestone_Id, 0, 5, -1, 5, chunkBB); + placeBlock(level, Tile::mossy_cobblestone_Id, 0, 6, -3, 5, chunkBB); + placeBlock(level, Tile::mossy_cobblestone_Id, 0, 7, -2, 5, chunkBB); + placeBlock(level, Tile::mossy_cobblestone_Id, 0, 7, -1, 5, chunkBB); + placeBlock(level, Tile::mossy_cobblestone_Id, 0, 8, -3, 5, chunkBB); generateBox(level, chunkBB, 9, -1, 1, 9, -1, 5, false, random, &stoneSelector); // hidden room generateAirBox(level, chunkBB, 8, -3, 8, 10, -1, 10); - placeBlock(level, Tile::stoneBrick_Id, SmoothStoneBrickTile::TYPE_DETAIL, 8, -2, 11, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, SmoothStoneBrickTile::TYPE_DETAIL, 9, -2, 11, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, SmoothStoneBrickTile::TYPE_DETAIL, 10, -2, 11, chunkBB); + placeBlock(level, Tile::stonebrick_Id, SmoothStoneBrickTile::TYPE_DETAIL, 8, -2, 11, chunkBB); + placeBlock(level, Tile::stonebrick_Id, SmoothStoneBrickTile::TYPE_DETAIL, 9, -2, 11, chunkBB); + placeBlock(level, Tile::stonebrick_Id, SmoothStoneBrickTile::TYPE_DETAIL, 10, -2, 11, chunkBB); placeBlock(level, Tile::lever_Id, LeverTile::getLeverFacing(getOrientationData(Tile::lever_Id, Facing::NORTH)), 8, -2, 12, chunkBB); placeBlock(level, Tile::lever_Id, LeverTile::getLeverFacing(getOrientationData(Tile::lever_Id, Facing::NORTH)), 9, -2, 12, chunkBB); placeBlock(level, Tile::lever_Id, LeverTile::getLeverFacing(getOrientationData(Tile::lever_Id, Facing::NORTH)), 10, -2, 12, chunkBB); generateBox(level, chunkBB, 8, -3, 8, 8, -3, 10, false, random, &stoneSelector); generateBox(level, chunkBB, 10, -3, 8, 10, -3, 10, false, random, &stoneSelector); - placeBlock(level, Tile::mossyCobblestone_Id, 0, 10, -2, 9, chunkBB); - placeBlock(level, Tile::redStoneDust_Id, 0, 8, -2, 9, chunkBB); - placeBlock(level, Tile::redStoneDust_Id, 0, 8, -2, 10, chunkBB); - placeBlock(level, Tile::redStoneDust_Id, 0, 10, -1, 9, chunkBB); - placeBlock(level, Tile::pistonStickyBase_Id, Facing::UP, 9, -2, 8, chunkBB); - placeBlock(level, Tile::pistonStickyBase_Id, getOrientationData(Tile::pistonStickyBase_Id, Facing::WEST), 10, -2, 8, chunkBB); - placeBlock(level, Tile::pistonStickyBase_Id, getOrientationData(Tile::pistonStickyBase_Id, Facing::WEST), 10, -1, 8, chunkBB); - placeBlock(level, Tile::diode_off_Id, getOrientationData(Tile::diode_off_Id, Direction::NORTH), 10, -2, 10, chunkBB); + placeBlock(level, Tile::mossy_cobblestone_Id, 0, 10, -2, 9, chunkBB); + placeBlock(level, Tile::redstone_wire_Id, 0, 8, -2, 9, chunkBB); + placeBlock(level, Tile::redstone_wire_Id, 0, 8, -2, 10, chunkBB); + placeBlock(level, Tile::redstone_wire_Id, 0, 10, -1, 9, chunkBB); + placeBlock(level, Tile::sticky_piston_Id, Facing::UP, 9, -2, 8, chunkBB); + placeBlock(level, Tile::sticky_piston_Id, getOrientationData(Tile::sticky_piston_Id, Facing::WEST), 10, -2, 8, chunkBB); + placeBlock(level, Tile::sticky_piston_Id, getOrientationData(Tile::sticky_piston_Id, Facing::WEST), 10, -1, 8, chunkBB); + placeBlock(level, Tile::unpowered_repeater_Id, getOrientationData(Tile::unpowered_repeater_Id, Direction::NORTH), 10, -2, 10, chunkBB); if (!placedHiddenChest) { - placedHiddenChest = createChest(level, chunkBB, random, 9, -3, 10, WeighedTreasure::addToTreasure(WeighedTreasureArray(treasureItems,TREASURE_ITEMS_COUNT), Item::enchantedBook->createForRandomTreasure(random)), 2 + random->nextInt(5)); + placedHiddenChest = createChest(level, chunkBB, random, 9, -3, 10, WeighedTreasure::addToTreasure(WeighedTreasureArray(treasureItems,TREASURE_ITEMS_COUNT), Item::enchanted_book->createForRandomTreasure(random)), 2 + random->nextInt(5)); } return true; @@ -636,7 +636,7 @@ void ScatteredFeaturePieces::JunglePyramidPiece::MossStoneSelector::next(Random } else { - nextId = Tile::mossyCobblestone_Id; + nextId = Tile::mossy_cobblestone_Id; } } @@ -673,21 +673,21 @@ bool ScatteredFeaturePieces::SwamplandHut::postProcess(Level *level, Random *ran } // floor and ceiling - generateBox(level, chunkBB, 1, 1, 1, 5, 1, 7, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, false); - generateBox(level, chunkBB, 1, 4, 2, 5, 4, 7, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, false); - generateBox(level, chunkBB, 2, 1, 0, 4, 1, 0, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, false); + generateBox(level, chunkBB, 1, 1, 1, 5, 1, 7, Tile::planks_Id, TreeTile::SPRUCE_TRUNK, Tile::planks_Id, TreeTile::SPRUCE_TRUNK, false); + generateBox(level, chunkBB, 1, 4, 2, 5, 4, 7, Tile::planks_Id, TreeTile::SPRUCE_TRUNK, Tile::planks_Id, TreeTile::SPRUCE_TRUNK, false); + generateBox(level, chunkBB, 2, 1, 0, 4, 1, 0, Tile::planks_Id, TreeTile::SPRUCE_TRUNK, Tile::planks_Id, TreeTile::SPRUCE_TRUNK, false); // walls - generateBox(level, chunkBB, 2, 2, 2, 3, 3, 2, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, false); - generateBox(level, chunkBB, 1, 2, 3, 1, 3, 6, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, false); - generateBox(level, chunkBB, 5, 2, 3, 5, 3, 6, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, false); - generateBox(level, chunkBB, 2, 2, 7, 4, 3, 7, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, false); + generateBox(level, chunkBB, 2, 2, 2, 3, 3, 2, Tile::planks_Id, TreeTile::SPRUCE_TRUNK, Tile::planks_Id, TreeTile::SPRUCE_TRUNK, false); + generateBox(level, chunkBB, 1, 2, 3, 1, 3, 6, Tile::planks_Id, TreeTile::SPRUCE_TRUNK, Tile::planks_Id, TreeTile::SPRUCE_TRUNK, false); + generateBox(level, chunkBB, 5, 2, 3, 5, 3, 6, Tile::planks_Id, TreeTile::SPRUCE_TRUNK, Tile::planks_Id, TreeTile::SPRUCE_TRUNK, false); + generateBox(level, chunkBB, 2, 2, 7, 4, 3, 7, Tile::planks_Id, TreeTile::SPRUCE_TRUNK, Tile::planks_Id, TreeTile::SPRUCE_TRUNK, false); // pillars - generateBox(level, chunkBB, 1, 0, 2, 1, 3, 2, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - generateBox(level, chunkBB, 5, 0, 2, 5, 3, 2, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - generateBox(level, chunkBB, 1, 0, 7, 1, 3, 7, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - generateBox(level, chunkBB, 5, 0, 7, 5, 3, 7, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); + generateBox(level, chunkBB, 1, 0, 2, 1, 3, 2, Tile::log_Id, Tile::log_Id, false); + generateBox(level, chunkBB, 5, 0, 2, 5, 3, 2, Tile::log_Id, Tile::log_Id, false); + generateBox(level, chunkBB, 1, 0, 7, 1, 3, 7, Tile::log_Id, Tile::log_Id, false); + generateBox(level, chunkBB, 5, 0, 7, 5, 3, 7, Tile::log_Id, Tile::log_Id, false); // windows placeBlock(level, Tile::fence_Id, 0, 2, 3, 2, chunkBB); @@ -695,10 +695,10 @@ bool ScatteredFeaturePieces::SwamplandHut::postProcess(Level *level, Random *ran placeBlock(level, 0, 0, 1, 3, 4, chunkBB); placeBlock(level, 0, 0, 5, 3, 4, chunkBB); placeBlock(level, 0, 0, 5, 3, 5, chunkBB); - placeBlock(level, Tile::flowerPot_Id, FlowerPotTile::TYPE_MUSHROOM_RED, 1, 3, 5, chunkBB); + placeBlock(level, Tile::flower_pot_Id, FlowerPotTile::TYPE_MUSHROOM_RED, 1, 3, 5, chunkBB); // decoration - placeBlock(level, Tile::workBench_Id, 0, 3, 2, 6, chunkBB); + placeBlock(level, Tile::crafting_table_Id, 0, 3, 2, 6, chunkBB); placeBlock(level, Tile::cauldron_Id, 0, 4, 2, 6, chunkBB); // front railings @@ -708,22 +708,22 @@ bool ScatteredFeaturePieces::SwamplandHut::postProcess(Level *level, Random *ran // placeBlock(level, Tile.torch.id, 0, 5, 3, 1, chunkBB); // ceiling edges - int south = getOrientationData(Tile::stairs_wood_Id, StairTile::DIR_NORTH); - int east = getOrientationData(Tile::stairs_wood_Id, StairTile::DIR_WEST); - int west = getOrientationData(Tile::stairs_wood_Id, StairTile::DIR_EAST); - int north = getOrientationData(Tile::stairs_wood_Id, StairTile::DIR_SOUTH); + int south = getOrientationData(Tile::oak_stairs_Id, StairTile::DIR_NORTH); + int east = getOrientationData(Tile::oak_stairs_Id, StairTile::DIR_WEST); + int west = getOrientationData(Tile::oak_stairs_Id, StairTile::DIR_EAST); + int north = getOrientationData(Tile::oak_stairs_Id, StairTile::DIR_SOUTH); - generateBox(level, chunkBB, 0, 4, 1, 6, 4, 1, Tile::stairs_sprucewood_Id, south, Tile::stairs_sprucewood_Id, south, false); - generateBox(level, chunkBB, 0, 4, 2, 0, 4, 7, Tile::stairs_sprucewood_Id, west, Tile::stairs_sprucewood_Id, west, false); - generateBox(level, chunkBB, 6, 4, 2, 6, 4, 7, Tile::stairs_sprucewood_Id, east, Tile::stairs_sprucewood_Id, east, false); - generateBox(level, chunkBB, 0, 4, 8, 6, 4, 8, Tile::stairs_sprucewood_Id, north, Tile::stairs_sprucewood_Id, north, false); + generateBox(level, chunkBB, 0, 4, 1, 6, 4, 1, Tile::spruce_stairs_Id, south, Tile::spruce_stairs_Id, south, false); + generateBox(level, chunkBB, 0, 4, 2, 0, 4, 7, Tile::spruce_stairs_Id, west, Tile::spruce_stairs_Id, west, false); + generateBox(level, chunkBB, 6, 4, 2, 6, 4, 7, Tile::spruce_stairs_Id, east, Tile::spruce_stairs_Id, east, false); + generateBox(level, chunkBB, 0, 4, 8, 6, 4, 8, Tile::spruce_stairs_Id, north, Tile::spruce_stairs_Id, north, false); // fill pillars down to solid ground for (int z = 2; z <= 7; z += 5) { for (int x = 1; x <= 5; x += 4) { - fillColumnDown(level, Tile::treeTrunk_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::log_Id, 0, x, -1, z, chunkBB); } } diff --git a/Minecraft.World/ShearsItem.cpp b/Minecraft.World/ShearsItem.cpp index dd0c2ac7..4d047b1e 100644 --- a/Minecraft.World/ShearsItem.cpp +++ b/Minecraft.World/ShearsItem.cpp @@ -11,7 +11,7 @@ ShearsItem::ShearsItem(int itemId) : Item(itemId) bool ShearsItem::mineBlock(shared_ptr itemInstance, Level *level, int tile, int x, int y, int z, shared_ptr owner) { - if (tile == Tile::leaves_Id || tile == Tile::web_Id || tile == Tile::tallgrass_Id || tile == Tile::vine_Id || tile == Tile::tripWire_Id) + if (tile == Tile::leaves_Id || tile == Tile::web_Id || tile == Tile::tallgrass_Id || tile == Tile::vine_Id || tile == Tile::tripwire_Id) { itemInstance->hurtAndBreak(1, owner); return true; @@ -21,7 +21,7 @@ bool ShearsItem::mineBlock(shared_ptr itemInstance, Level *level, bool ShearsItem::canDestroySpecial(Tile *tile) { - return tile->id == Tile::web_Id || tile->id == Tile::redStoneDust_Id || tile->id == Tile::tripWire_Id; + return tile->id == Tile::web_Id || tile->id == Tile::redstone_wire_Id || tile->id == Tile::tripwire_Id; } float ShearsItem::getDestroySpeed(shared_ptr itemInstance, Tile *tile) diff --git a/Minecraft.World/Sheep.cpp b/Minecraft.World/Sheep.cpp index d49c5a5c..3a9ae6a5 100644 --- a/Minecraft.World/Sheep.cpp +++ b/Minecraft.World/Sheep.cpp @@ -66,8 +66,8 @@ Sheep::Sheep(Level *level) : Animal( level ) goalSelector.addGoal(8, new RandomLookAroundGoal(this)); container = std::make_shared(new SheepContainer(), 2, 1); - container->setItem(0, std::make_shared(Item::dye_powder, 1, 0)); - container->setItem(1, std::make_shared(Item::dye_powder, 1, 0)); + container->setItem(0, std::make_shared(Item::dye, 1, 0)); + container->setItem(1, std::make_shared(Item::dye, 1, 0)); } bool Sheep::useNewAi() @@ -117,11 +117,11 @@ void Sheep::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) { if (isOnFire()) { - spawnAtLocation(Item::mutton_cooked_Id, 1); + spawnAtLocation(Item::cooked_mutton_Id, 1); } else { - spawnAtLocation(Item::mutton_raw_Id, 1); + spawnAtLocation(Item::mutton_Id, 1); } } } @@ -338,7 +338,7 @@ int Sheep::getOffspringColor(shared_ptr animal, shared_ptr partn shared_ptr instance = Recipes::getInstance()->getItemFor(container, animal->level); int color = 0; - if (instance != nullptr && instance->getItem()->id == Item::dye_powder_Id) + if (instance != nullptr && instance->getItem()->id == Item::dye_Id) { color = instance->getAuxValue(); } diff --git a/Minecraft.World/ShoreLayer.cpp b/Minecraft.World/ShoreLayer.cpp index 511b2f70..08f5183a 100644 --- a/Minecraft.World/ShoreLayer.cpp +++ b/Minecraft.World/ShoreLayer.cpp @@ -4,78 +4,127 @@ ShoreLayer::ShoreLayer(int64_t seed, shared_ptr parent, int64_t seedMixup) : Layer(seedMixup) { - this->parent = parent; + this->parent = parent; +} + +bool ShoreLayer::isJungleCompatible(int id) +{ + if (id == Biome::jungle->id || id == Biome::jungleHills->id || id == Biome::jungleEdge->id || + id == Biome::jungleM->id || id == Biome::jungleEdgeM->id) + return true; + if (id == Biome::forest->id || id == Biome::taiga->id) + return true; + if (isOcean(id)) + return true; + return false; +} + +bool ShoreLayer::isMesaBiome(int id) +{ + return id == Biome::mesa->id || id == Biome::mesaPlateauF->id || id == Biome::mesaPlateau->id || + id == Biome::mesaBryce->id || id == Biome::mesaPlateauFM->id || id == Biome::mesaPlateauM->id; +} + +void ShoreLayer::replaceIfNeighborOcean(intArray& b, intArray& result, int x, int y, int w, int stride, int center, int target) +{ + if (!isOcean(center)) + { + int n = b[(x + 1) + (y + 0) * stride]; + int e = b[(x + 2) + (y + 1) * stride]; + int w1 = b[(x + 0) + (y + 1) * stride]; + int s = b[(x + 1) + (y + 2) * stride]; + if (isOcean(n) || isOcean(e) || isOcean(w1) || isOcean(s)) + { + result[x + y * w] = target; + return; + } + } + result[x + y * w] = center; } intArray ShoreLayer::getArea(int xo, int yo, int w, int h) { intArray b = parent->getArea(xo - 1, yo - 1, w + 2, h + 2); - intArray result = IntCache::allocate(w * h); + int stride = w + 2; + for (int y = 0; y < h; y++) - { + { for (int x = 0; x < w; x++) - { + { initRandom(x + xo, y + yo); - int old = b[(x + 1) + (y + 1) * (w + 2)]; + int old = b[(x + 1) + (y + 1) * stride]; + + int n = b[(x + 1) + (y + 0) * stride]; + int e = b[(x + 2) + (y + 1) * stride]; + int w1 = b[(x + 0) + (y + 1) * stride]; + int s = b[(x + 1) + (y + 2) * stride]; + if (old == Biome::mushroomIsland->id) - { - int _n = b[(x + 1) + (y + 1 - 1) * (w + 2)]; - int _e = b[(x + 1 + 1) + (y + 1) * (w + 2)]; - int _w = b[(x + 1 - 1) + (y + 1) * (w + 2)]; - int _s = b[(x + 1) + (y + 1 + 1) * (w + 2)]; - if (_n == Biome::ocean->id || _e == Biome::ocean->id || _w == Biome::ocean->id || _s == Biome::ocean->id || _n == Biome::deepOcean->id || _e == Biome::deepOcean->id || _w == Biome::deepOcean->id || _s == Biome::deepOcean->id) - { - result[x + y * w] = Biome::mushroomIslandShore->id; - } - else - { - result[x + y * w] = old; - } - } - else if (old != Biome::ocean->id && old != Biome::deepOcean->id && old != Biome::river->id && old != Biome::swampland->id && old != Biome::extremeHills->id) - { - int _n = b[(x + 1) + (y + 1 - 1) * (w + 2)]; - int _e = b[(x + 1 + 1) + (y + 1) * (w + 2)]; - int _w = b[(x + 1 - 1) + (y + 1) * (w + 2)]; - int _s = b[(x + 1) + (y + 1 + 1) * (w + 2)]; - if (_n == Biome::ocean->id || _e == Biome::ocean->id || _w == Biome::ocean->id || _s == Biome::ocean->id || _n == Biome::deepOcean->id || _e == Biome::deepOcean->id || _w == Biome::deepOcean->id || _s == Biome::deepOcean->id) - { - if (old == Biome::taiga->id || old == Biome::taigaHills->id || old == Biome::megaTaiga->id || old == Biome::megaTaigaHills->id || old == Biome::coldTaiga->id || old == Biome::coldTaigaHills->id) - { - result[x + y * w] = Biome::coldBeach->id; - } - else - { - result[x + y * w] = Biome::beaches->id; - } - } - else - { - result[x + y * w] = old; - } - } - else if (old == Biome::extremeHills->id) - { - int _n = b[(x + 1) + (y + 1 - 1) * (w + 2)]; - int _e = b[(x + 1 + 1) + (y + 1) * (w + 2)]; - int _w = b[(x + 1 - 1) + (y + 1) * (w + 2)]; - int _s = b[(x + 1) + (y + 1 + 1) * (w + 2)]; - if (_n != Biome::extremeHills->id || _e != Biome::extremeHills->id || _w != Biome::extremeHills->id || _s != Biome::extremeHills->id) - { - result[x + y * w] = Biome::smallerExtremeHills->id; - } - else - { - result[x + y * w] = old; - } - } - else - { - result[x + y * w] = old; + { + // decompile checks plain ocean only, NOT deepOcean, for this branch + bool nearOcean = (n == Biome::ocean->id || e == Biome::ocean->id || + w1 == Biome::ocean->id || s == Biome::ocean->id); + result[x + y * w] = nearOcean ? Biome::mushroomIslandShore->id : old; + continue; } + + if (old == Biome::jungle->id || old == Biome::jungleHills->id || + old == Biome::jungleM->id) + { + bool allCompatible = isJungleCompatible(n) && isJungleCompatible(e) && + isJungleCompatible(w1) && isJungleCompatible(s); + if (!allCompatible) + { + result[x + y * w] = Biome::jungleEdge->id; + } + else + { + bool nearOcean = (isOcean(n) || isOcean(e) || isOcean(w1) || isOcean(s)); + result[x + y * w] = nearOcean ? Biome::beaches->id : old; + } + continue; + } + + if (old == Biome::extremeHills->id || old == Biome::extremeHills_plus->id || + old == Biome::smallerExtremeHills->id) + { + replaceIfNeighborOcean(b, result, x, y, w, stride, old, Biome::stoneBeach->id); + continue; + } + + Biome* biome = Biome::getBiome(old); + if (biome != nullptr && biome->hasSnow()) + { + replaceIfNeighborOcean(b, result, x, y, w, stride, old, Biome::coldBeach->id); + continue; + } + + if (old == Biome::mesa->id || old == Biome::mesaPlateauF->id) + { + bool nearOcean = (isOcean(n) || isOcean(e) || isOcean(w1) || isOcean(s)); + if (nearOcean) + { + result[x + y * w] = Biome::beaches->id; + } + else + { + bool allMesa = isMesaBiome(n) && isMesaBiome(e) && isMesaBiome(w1) && isMesaBiome(s); + result[x + y * w] = allMesa ? old : Biome::desert->id; + } + continue; + } + + if (old != Biome::ocean->id && old != Biome::deepOcean->id && + old != Biome::river->id && old != Biome::swampland->id) + { + bool nearOcean = (isOcean(n) || isOcean(e) || isOcean(w1) || isOcean(s)); + result[x + y * w] = nearOcean ? Biome::beaches->id : old; + continue; + } + + result[x + y * w] = old; } } - return result; -} \ No newline at end of file +} diff --git a/Minecraft.World/ShoreLayer.h b/Minecraft.World/ShoreLayer.h index cbae390f..75140a42 100644 --- a/Minecraft.World/ShoreLayer.h +++ b/Minecraft.World/ShoreLayer.h @@ -3,6 +3,10 @@ class ShoreLayer : public Layer { +private: + static bool isJungleCompatible(int id); + static bool isMesaBiome(int id); + void replaceIfNeighborOcean(intArray& b, intArray& result, int x, int y, int w, int stride, int center, int target); public: ShoreLayer(int64_t seed, shared_ptr parent, int64_t seedMixup); virtual intArray getArea(int xo, int yo, int w, int h); diff --git a/Minecraft.World/SignItem.cpp b/Minecraft.World/SignItem.cpp index a418fd34..2fbda494 100644 --- a/Minecraft.World/SignItem.cpp +++ b/Minecraft.World/SignItem.cpp @@ -40,11 +40,11 @@ bool SignItem::useOn(shared_ptr instance, shared_ptr playe if (face == 1) { int rot = Mth::floor(((player->yRot + 180) * 16) / 360 + 0.5) & 15; - level->setTileAndData(x, y, z, Tile::sign_Id, rot, Tile::UPDATE_ALL); + level->setTileAndData(x, y, z, Tile::standing_sign_Id, rot, Tile::UPDATE_ALL); } else { - level->setTileAndData(x, y, z, Tile::wallSign_Id, face, Tile::UPDATE_ALL); + level->setTileAndData(x, y, z, Tile::wall_standing_sign_Id, face, Tile::UPDATE_ALL); } instance->count--; @@ -53,9 +53,9 @@ bool SignItem::useOn(shared_ptr instance, shared_ptr playe // 4J-JEV: Hook for durango 'BlockPlaced' event. player->awardStat( - GenericStats::blocksPlaced((face==1) ? Tile::sign_Id : Tile::wallSign_Id), + GenericStats::blocksPlaced((face==1) ? Tile::standing_sign_Id : Tile::wall_standing_sign_Id), GenericStats::param_blocksPlaced( - (face==1) ? Tile::sign_Id : Tile::wallSign_Id, + (face==1) ? Tile::standing_sign_Id : Tile::wall_standing_sign_Id, instance->getAuxValue(), 1) ); diff --git a/Minecraft.World/SignTile.cpp b/Minecraft.World/SignTile.cpp index 15be23db..81be3505 100644 --- a/Minecraft.World/SignTile.cpp +++ b/Minecraft.World/SignTile.cpp @@ -120,7 +120,7 @@ void SignTile::neighborChanged(Level *level, int x, int y, int z, int type) int SignTile::cloneTileId(Level *level, int x, int y, int z) { - return Item::sign_Id; + return Item::standing_sign_Id; } void SignTile::registerIcons(IconRegister *iconRegister) diff --git a/Minecraft.World/Silverfish.cpp b/Minecraft.World/Silverfish.cpp index fd7e2d2b..ac97d982 100644 --- a/Minecraft.World/Silverfish.cpp +++ b/Minecraft.World/Silverfish.cpp @@ -137,7 +137,7 @@ void Silverfish::serverAiStep() for (int zOff = 0; !doBreak && zOff <= 10 && zOff >= -10; zOff = (zOff <= 0) ? 1 - zOff : 0 - zOff) { int tile = level->getTile(baseX + xOff, baseY + yOff, baseZ + zOff); - if (tile == Tile::monsterStoneEgg_Id) + if (tile == Tile::monster_egg_Id) { if (!level->getGameRules()->getBoolean(GameRules::RULE_MOBGRIEFING)) { @@ -159,7 +159,7 @@ void Silverfish::serverAiStep() { level->destroyTile(baseX + xOff, baseY + yOff, baseZ + zOff, false); } - Tile::monsterStoneEgg->destroy(level, baseX + xOff, baseY + yOff, baseZ + zOff, 0); + Tile::monster_egg->destroy(level, baseX + xOff, baseY + yOff, baseZ + zOff, 0); if (random->nextBoolean()) { @@ -183,7 +183,7 @@ void Silverfish::serverAiStep() int tile = level->getTile(tileX + Facing::STEP_X[facing], tileY + Facing::STEP_Y[facing], tileZ + Facing::STEP_Z[facing]); if (StoneMonsterTile::isCompatibleHostBlock(tile)) { - level->setTileAndData(tileX + Facing::STEP_X[facing], tileY + Facing::STEP_Y[facing], tileZ + Facing::STEP_Z[facing], Tile::monsterStoneEgg_Id, StoneMonsterTile::getDataForHostBlock(tile), Tile::UPDATE_ALL); + level->setTileAndData(tileX + Facing::STEP_X[facing], tileY + Facing::STEP_Y[facing], tileZ + Facing::STEP_Z[facing], Tile::monster_egg_Id, StoneMonsterTile::getDataForHostBlock(tile), Tile::UPDATE_ALL); spawnAnim(); remove(); } diff --git a/Minecraft.World/Skeleton.cpp b/Minecraft.World/Skeleton.cpp index 8285441d..dfbbc11c 100644 --- a/Minecraft.World/Skeleton.cpp +++ b/Minecraft.World/Skeleton.cpp @@ -237,7 +237,7 @@ MobGroupData *Skeleton::finalizeMobSpawn(MobGroupData *groupData, int extraData goalSelector.addGoal(4, meleeGoal, false); setSkeletonType(TYPE_WITHER); - setEquippedSlot(SLOT_WEAPON, std::make_shared(Item::sword_stone)); + setEquippedSlot(SLOT_WEAPON, std::make_shared(Item::stone_sword)); getAttribute(SharedMonsterAttributes::ATTACK_DAMAGE)->setBaseValue(4); } else diff --git a/Minecraft.World/SkullItem.cpp b/Minecraft.World/SkullItem.cpp index 383f226f..5b9ae68c 100644 --- a/Minecraft.World/SkullItem.cpp +++ b/Minecraft.World/SkullItem.cpp @@ -68,11 +68,11 @@ bool SkullItem::useOn(shared_ptr instance, shared_ptr play bool SkullItem::mayPlace(Level *level, int x, int y, int z, int face, shared_ptr player, shared_ptr item) { int currentTile = level->getTile(x, y, z); - if (currentTile == Tile::topSnow_Id) + if (currentTile == Tile::snow_layer_Id) { face = Facing::UP; } - else if (currentTile != Tile::vine_Id && currentTile != Tile::tallgrass_Id && currentTile != Tile::deadBush_Id) + else if (currentTile != Tile::vine_Id && currentTile != Tile::tallgrass_Id && currentTile != Tile::deadbush_Id) { if (face == 0) y--; if (face == 1) y++; diff --git a/Minecraft.World/SkullTile.cpp b/Minecraft.World/SkullTile.cpp index b5eca373..261b549a 100644 --- a/Minecraft.World/SkullTile.cpp +++ b/Minecraft.World/SkullTile.cpp @@ -137,7 +137,7 @@ void SkullTile::checkMobSpawn(Level *level, int x, int y, int z, shared_ptrgetSkullType() == SkullTileEntity::TYPE_WITHER && y >= 2 && level->difficulty > Difficulty::PEACEFUL && !level->isClientSide) { // Check wither boss spawn - int ss = Tile::soulsand_Id; + int ss = Tile::soul_sand_Id; // North-south alignment for (int zo = -2; zo <= 0; zo++) @@ -175,10 +175,10 @@ void SkullTile::checkMobSpawn(Level *level, int x, int y, int z, shared_ptrspawnResources(level, x, y - 1, z + zo, 0, 0); - Tile::tiles[Tile::soulsand_Id]->spawnResources(level, x, y - 1, z + zo + 1, 0, 0); - Tile::tiles[Tile::soulsand_Id]->spawnResources(level, x, y - 2, z + zo + 1, 0, 0); - Tile::tiles[Tile::soulsand_Id]->spawnResources(level, x, y - 1, z + zo + 2, 0, 0); + Tile::tiles[Tile::soul_sand_Id]->spawnResources(level, x, y - 1, z + zo, 0, 0); + Tile::tiles[Tile::soul_sand_Id]->spawnResources(level, x, y - 1, z + zo + 1, 0, 0); + Tile::tiles[Tile::soul_sand_Id]->spawnResources(level, x, y - 2, z + zo + 1, 0, 0); + Tile::tiles[Tile::soul_sand_Id]->spawnResources(level, x, y - 1, z + zo + 2, 0, 0); shared_ptr itemInstance = std::make_shared(Item::skull_Id, 3, SkullTileEntity::TYPE_WITHER); shared_ptr itemEntity = std::make_shared(level, x, y, z + zo + 1, itemInstance); @@ -237,10 +237,10 @@ void SkullTile::checkMobSpawn(Level *level, int x, int y, int z, shared_ptrspawnResources(level, x + xo, y - 1, z, 0, 0); - Tile::tiles[Tile::soulsand_Id]->spawnResources(level, x + xo + 1, y - 1, z, 0, 0); - Tile::tiles[Tile::soulsand_Id]->spawnResources(level, x + xo + 1, y - 2, z, 0, 0); - Tile::tiles[Tile::soulsand_Id]->spawnResources(level, x + xo + 2, y - 1, z, 0, 0); + Tile::tiles[Tile::soul_sand_Id]->spawnResources(level, x + xo, y - 1, z, 0, 0); + Tile::tiles[Tile::soul_sand_Id]->spawnResources(level, x + xo + 1, y - 1, z, 0, 0); + Tile::tiles[Tile::soul_sand_Id]->spawnResources(level, x + xo + 1, y - 2, z, 0, 0); + Tile::tiles[Tile::soul_sand_Id]->spawnResources(level, x + xo + 2, y - 1, z, 0, 0); shared_ptr itemInstance = std::make_shared(Item::skull_Id, 3, SkullTileEntity::TYPE_WITHER); shared_ptr itemEntity = std::make_shared(level, x + xo + 1, y, z, itemInstance); diff --git a/Minecraft.World/Slime.cpp b/Minecraft.World/Slime.cpp index 563455d6..54043995 100644 --- a/Minecraft.World/Slime.cpp +++ b/Minecraft.World/Slime.cpp @@ -246,7 +246,7 @@ int Slime::getDeathSound() int Slime::getDeathLoot() { - if (getSize() == 1) return Item::slimeBall->id; + if (getSize() == 1) return Item::slime_ball->id; return 0; } diff --git a/Minecraft.World/SlimeTile.cpp b/Minecraft.World/SlimeTile.cpp new file mode 100644 index 00000000..b7a9b0d6 --- /dev/null +++ b/Minecraft.World/SlimeTile.cpp @@ -0,0 +1,93 @@ +#include "stdafx.h" +#include "net.minecraft.world.level.h" +#include "net.minecraft.world.level.dimension.h" +#include "net.minecraft.world.item.enchantment.h" +#include "net.minecraft.world.food.h" +#include "net.minecraft.stats.h" +#include "SlimeTile.h" +#include "Entity.h" + +SlimeTile::SlimeTile(int id) : HalfTransparentTile(id, L"slime", Material::clay, false) +{ + friction = 0.8f; +} + +int SlimeTile::getRenderLayer() +{ + return 2; +} + +int SlimeTile::getRenderShape() +{ + return Tile::SHAPE_SLIME; +} + +bool SlimeTile::shouldRenderFace(LevelSource *level, int x, int y, int z, int face) +{ + return true; +} + +bool SlimeTile::isSolidRender() +{ + return false; +} + +int SlimeTile::getPistonPushReaction() +{ + return Material::PUSH_SLIME; +} + +void SlimeTile::fallOn(Level *level, int x, int y, int z, + shared_ptr entity, float distance) +{ + HalfTransparentTile::fallOn(level, x, y, z, entity, distance); + + if (entity == nullptr) + return; + + entity->clearFallDamageQueue(); + + entity->fallDistance = 0.0f; + + if (entity->isSneaking() || std::abs(entity->yd) < 0.1f) + { + entity->yd = 0.0f; + return; + } + + if (entity->yd < 0.0f) + { + entity->yd = -entity->yd; + + if (!(entity->instanceof(eTYPE_LIVINGENTITY))) + { + entity->yd *= 0.8f; + } + } +} + +void SlimeTile::stepOn(Level *level, int x, int y, int z, shared_ptr entity) +{ + if (entity != nullptr) + { + entity->clearFallDamageQueue(); + } + + if (entity != nullptr && + std::abs(entity->yd) < 0.1f && + !entity->isSneaking()) + { + double d0 = 0.4 + std::abs(entity->yd) * 0.2; + + entity->xd *= d0; + entity->zd *= d0; + level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_MOB_SLIME_SMALL, 0.4f, 0.8f + level->random->nextFloat() * 0.4f); + } + + HalfTransparentTile::stepOn(level, x, y, z, entity); +} + +void SlimeTile::updateEntityAfterFallOn(Level* level, shared_ptr entity) +{ + // stub +} diff --git a/Minecraft.World/SlimeTile.h b/Minecraft.World/SlimeTile.h new file mode 100644 index 00000000..9747d18d --- /dev/null +++ b/Minecraft.World/SlimeTile.h @@ -0,0 +1,20 @@ +#pragma once +#include "HalfTransparentTile.h" + +class Random; + +class SlimeTile : public HalfTransparentTile +{ +public: + SlimeTile(int id); + virtual int getRenderLayer(); + virtual bool shouldRenderFace(LevelSource *level, int x, int y, int z, int face); + virtual int getRenderShape(); + virtual bool isSolidRender(); + virtual int getPistonPushReaction(); + + // slime block logic + virtual void fallOn(Level *level, int x, int y, int z, shared_ptr entity, float fallDistance); + virtual void updateEntityAfterFallOn(Level *level, shared_ptr entity); + virtual void stepOn(Level *level, int x, int y, int z, shared_ptr entity); +}; diff --git a/Minecraft.World/Slot.cpp b/Minecraft.World/Slot.cpp index 2f42a27d..ab0cbcdf 100644 --- a/Minecraft.World/Slot.cpp +++ b/Minecraft.World/Slot.cpp @@ -131,7 +131,7 @@ bool Slot::mayCombine(shared_ptr second) if(thisItem) { bool thisIsDyableArmor = thisItem->getMaterial() == ArmorItem::ArmorMaterial::CLOTH; - bool itemIsDye = second->id == Item::dye_powder_Id; + bool itemIsDye = second->id == Item::dye_Id; return thisIsDyableArmor && itemIsDye; } // 4J Stu - This condition taken from Recipes::getItemFor to repair items, but added the damaged check to skip when the result is pointless diff --git a/Minecraft.World/SnowItem.cpp b/Minecraft.World/SnowItem.cpp index 73cb57ad..2e2857d9 100644 --- a/Minecraft.World/SnowItem.cpp +++ b/Minecraft.World/SnowItem.cpp @@ -16,7 +16,7 @@ bool SnowItem::useOn(shared_ptr instance, shared_ptr playe int currentTile = level->getTile(x, y, z); // Are we adding extra snow to an existing tile? - if (currentTile == Tile::topSnow_Id) + if (currentTile == Tile::snow_layer_Id) { Tile *snowTile = Tile::tiles[getTileId()]; int currentData = level->getData(x, y, z); diff --git a/Minecraft.World/SnowMan.cpp b/Minecraft.World/SnowMan.cpp index 8a6561bf..c166bdde 100644 --- a/Minecraft.World/SnowMan.cpp +++ b/Minecraft.World/SnowMan.cpp @@ -76,7 +76,7 @@ void SnowMan::aiStep() { if (Tile::topSnow->mayPlace(level, xx, yy, zz)) { - level->setTileAndUpdate(xx, yy, zz, Tile::topSnow_Id); + level->setTileAndUpdate(xx, yy, zz, Tile::snow_layer_Id); } } } @@ -85,7 +85,7 @@ void SnowMan::aiStep() int SnowMan::getDeathLoot() { - return Item::snowBall_Id; + return Item::snowball_Id; } @@ -94,7 +94,7 @@ void SnowMan::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) // drop some feathers int count = random->nextInt(16); for (int i = 0; i < count; i++) { - spawnAtLocation(Item::snowBall_Id, 1); + spawnAtLocation(Item::snowball_Id, 1); } } diff --git a/Minecraft.World/SnowTile.cpp b/Minecraft.World/SnowTile.cpp index e73f5ceb..4c1c4343 100644 --- a/Minecraft.World/SnowTile.cpp +++ b/Minecraft.World/SnowTile.cpp @@ -12,7 +12,7 @@ SnowTile::SnowTile(int id) : Tile(id, Material::snow) int SnowTile::getResource(int data, Random *random, int playerBonusLevel) { - return Item::snowBall->id; + return Item::snowball->id; } int SnowTile::getResourceCount(Random *random) diff --git a/Minecraft.World/SpawnEggItem.cpp b/Minecraft.World/SpawnEggItem.cpp index a4de941f..4266af19 100644 --- a/Minecraft.World/SpawnEggItem.cpp +++ b/Minecraft.World/SpawnEggItem.cpp @@ -194,7 +194,7 @@ bool SpawnEggItem::useOn(shared_ptr itemInstance, shared_ptrgetTile(x, y, z); - if (tile == Tile::mobSpawner_Id) + if (tile == Tile::mob_spawner_Id) { shared_ptr spawnerTile = dynamic_pointer_cast(level->getTileEntity(x, y, z)); diff --git a/Minecraft.World/Spider.cpp b/Minecraft.World/Spider.cpp index 63b4d9aa..0ad2bec8 100644 --- a/Minecraft.World/Spider.cpp +++ b/Minecraft.World/Spider.cpp @@ -132,7 +132,7 @@ void Spider::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) if (wasKilledByPlayer && (random->nextInt(3) == 0 || random->nextInt(1 + playerBonusLevel) > 0)) { - spawnAtLocation(Item::spiderEye_Id, 1); + spawnAtLocation(Item::spider_eye_Id, 1); } } diff --git a/Minecraft.World/SpikeFeature.cpp b/Minecraft.World/SpikeFeature.cpp index 912e3aff..7d805727 100644 --- a/Minecraft.World/SpikeFeature.cpp +++ b/Minecraft.World/SpikeFeature.cpp @@ -53,7 +53,7 @@ bool SpikeFeature::place(Level *level, Random *random, int x, int y, int z) shared_ptr enderCrystal = std::make_shared(level); enderCrystal->moveTo(x + 0.5f, y + hh, z + 0.5f, random->nextFloat() * 360, 0); level->addEntity(enderCrystal); - level->setTileAndData(x, y + hh, z, Tile::unbreakable_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y + hh, z, Tile::bedrock_Id, 0, Tile::UPDATE_CLIENTS); return true; } @@ -138,9 +138,9 @@ bool SpikeFeature::placeWithIndex(Level *level, Random *random, int x, int y, in { if(yy==(y + hh - 1)) { - placeBlock(level, xx, y + hh, zz, Tile::ironFence_Id, 0); - placeBlock(level, xx, y + hh +1, zz, Tile::ironFence_Id, 0); - placeBlock(level, xx, y + hh +2, zz, Tile::ironFence_Id, 0); + placeBlock(level, xx, y + hh, zz, Tile::iron_bars_Id, 0); + placeBlock(level, xx, y + hh +1, zz, Tile::iron_bars_Id, 0); + placeBlock(level, xx, y + hh +2, zz, Tile::iron_bars_Id, 0); } } } @@ -162,7 +162,7 @@ bool SpikeFeature::placeWithIndex(Level *level, Random *random, int x, int y, in { for (int zz = z - 2; zz <= z + 2; zz++) { - placeBlock(level, xx, yy, zz, Tile::ironFence_Id, 0); + placeBlock(level, xx, yy, zz, Tile::iron_bars_Id, 0); } } } @@ -171,8 +171,8 @@ bool SpikeFeature::placeWithIndex(Level *level, Random *random, int x, int y, in shared_ptr enderCrystal = std::make_shared(level); enderCrystal->moveTo(x + 0.5f, y + hh, z + 0.5f, random->nextFloat() * 360, 0); level->addEntity(enderCrystal); - placeBlock(level, x, y + hh, z, Tile::unbreakable_Id, 0); - //level->setTile(x, y + hh, z, Tile::unbreakable_Id); + placeBlock(level, x, y + hh, z, Tile::bedrock_Id, 0); + //level->setTile(x, y + hh, z, Tile::bedrock_Id); return true; } diff --git a/Minecraft.World/SpruceFeature.cpp b/Minecraft.World/SpruceFeature.cpp index 11bbc984..8664745c 100644 --- a/Minecraft.World/SpruceFeature.cpp +++ b/Minecraft.World/SpruceFeature.cpp @@ -110,7 +110,7 @@ bool SpruceFeature::place(Level *level, Random *random, int x, int y, int z) for (int hh = 0; hh < treeHeight - topOffset; hh++) { int t = level->getTile(x, y + hh, z); - if (t == 0 || t == Tile::leaves_Id) placeBlock(level, x, y + hh, z, Tile::treeTrunk_Id, TreeTile::SPRUCE_TRUNK); + if (t == 0 || t == Tile::leaves_Id) placeBlock(level, x, y + hh, z, Tile::log_Id, TreeTile::SPRUCE_TRUNK); } return true; } diff --git a/Minecraft.World/Squid.cpp b/Minecraft.World/Squid.cpp index c6a5e9a7..57d43347 100644 --- a/Minecraft.World/Squid.cpp +++ b/Minecraft.World/Squid.cpp @@ -81,7 +81,7 @@ void Squid::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) int count = random->nextInt(3 + playerBonusLevel) + 1; for (int i = 0; i < count; i++) { - spawnAtLocation(std::make_shared(Item::dye_powder, 1, DyePowderItem::BLACK), 0.0f); + spawnAtLocation(std::make_shared(Item::dye, 1, DyePowderItem::BLACK), 0.0f); } } diff --git a/Minecraft.World/StainedGlassBlock.cpp b/Minecraft.World/StainedGlassBlock.cpp index dcf4e401..e1aa67e2 100644 --- a/Minecraft.World/StainedGlassBlock.cpp +++ b/Minecraft.World/StainedGlassBlock.cpp @@ -27,7 +27,7 @@ int StainedGlassBlock::getItemAuxValueForBlockData(int data) int StainedGlassBlock::getRenderLayer() { - return 2; + return 3; } void StainedGlassBlock::registerIcons(IconRegister *iconRegister) diff --git a/Minecraft.World/StainedGlassPaneBlock.cpp b/Minecraft.World/StainedGlassPaneBlock.cpp index a73be08b..7d075150 100644 --- a/Minecraft.World/StainedGlassPaneBlock.cpp +++ b/Minecraft.World/StainedGlassPaneBlock.cpp @@ -38,7 +38,7 @@ int StainedGlassPaneBlock::getItemAuxValueForBlockData(int data) int StainedGlassPaneBlock::getRenderLayer() { - return 2; + return 3; } void StainedGlassPaneBlock::registerIcons(IconRegister *iconRegister) diff --git a/Minecraft.World/StairTile.cpp b/Minecraft.World/StairTile.cpp index 00607736..f3a622f6 100644 --- a/Minecraft.World/StairTile.cpp +++ b/Minecraft.World/StairTile.cpp @@ -529,3 +529,189 @@ void StairTile::registerIcons(IconRegister *iconRegister) { // None } + +void StairTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int StairTile::defaultBlockState() +{ + return 0; // default state +} + +Tile::BlockState StairTile::getBlockState(int data) +{ + int composite = data & 0x3; + if ((data & UPSIDEDOWN_BIT) != 0) composite |= UPSIDEDOWN_BIT; + return Tile::BlockState(composite); +} + +Tile::BlockState StairTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + int data = level->getData(x, y, z); + int dir = data & 0x3; + bool upsideDown = (data & UPSIDEDOWN_BIT) != 0; + + int shape = 0; + + bool checkInnerPiece = true; + if (dir == DIR_EAST) + { + int backTile = level->getTile(x + 1, y, z); + int backData = level->getData(x + 1, y, z); + if (isStairs(backTile) && ((backData & UPSIDEDOWN_BIT) == (data & UPSIDEDOWN_BIT))) + { + int backDir = backData & 0x3; + if (backDir == DIR_NORTH && !isLockAttached(level, x, y, z + 1, data)) + { + checkInnerPiece = false; + } + else if (backDir == DIR_SOUTH && !isLockAttached(level, x, y, z - 1, data)) + { + checkInnerPiece = false; + } + } + } + else if (dir == DIR_WEST) + { + int backTile = level->getTile(x - 1, y, z); + int backData = level->getData(x - 1, y, z); + if (isStairs(backTile) && ((backData & UPSIDEDOWN_BIT) == (data & UPSIDEDOWN_BIT))) + { + int backDir = backData & 0x3; + if (backDir == DIR_NORTH && !isLockAttached(level, x, y, z + 1, data)) + { + checkInnerPiece = false; + } + else if (backDir == DIR_SOUTH && !isLockAttached(level, x, y, z - 1, data)) + { + checkInnerPiece = false; + } + } + } + else if (dir == DIR_SOUTH) + { + int backTile = level->getTile(x, y, z + 1); + int backData = level->getData(x, y, z + 1); + if (isStairs(backTile) && ((backData & UPSIDEDOWN_BIT) == (data & UPSIDEDOWN_BIT))) + { + int backDir = backData & 0x3; + if (backDir == DIR_WEST && !isLockAttached(level, x + 1, y, z, data)) + { + checkInnerPiece = false; + } + else if (backDir == DIR_EAST && !isLockAttached(level, x - 1, y, z, data)) + { + checkInnerPiece = false; + } + } + } + else if (dir == DIR_NORTH) + { + int backTile = level->getTile(x, y, z - 1); + int backData = level->getData(x, y, z - 1); + if (isStairs(backTile) && ((backData & UPSIDEDOWN_BIT) == (data & UPSIDEDOWN_BIT))) + { + int backDir = backData & 0x3; + if (backDir == DIR_WEST && !isLockAttached(level, x + 1, y, z, data)) + { + checkInnerPiece = false; + } + else if (backDir == DIR_EAST && !isLockAttached(level, x - 1, y, z, data)) + { + checkInnerPiece = false; + } + } + } + + if (!checkInnerPiece) + { + shape = 2; + } + else + { + bool hasInnerPiece = false; + if (dir == DIR_EAST) + { + int frontTile = level->getTile(x - 1, y, z); + int frontData = level->getData(x - 1, y, z); + if (isStairs(frontTile) && ((frontData & UPSIDEDOWN_BIT) == (data & UPSIDEDOWN_BIT))) + { + int frontDir = frontData & 0x3; + if ((frontDir == DIR_NORTH && !isLockAttached(level, x, y, z - 1, data)) || + (frontDir == DIR_SOUTH && !isLockAttached(level, x, y, z + 1, data))) + { + hasInnerPiece = true; + } + } + } + else if (dir == DIR_WEST) + { + int frontTile = level->getTile(x + 1, y, z); + int frontData = level->getData(x + 1, y, z); + if (isStairs(frontTile) && ((frontData & UPSIDEDOWN_BIT) == (data & UPSIDEDOWN_BIT))) + { + int frontDir = frontData & 0x3; + if ((frontDir == DIR_NORTH && !isLockAttached(level, x, y, z - 1, data)) || + (frontDir == DIR_SOUTH && !isLockAttached(level, x, y, z + 1, data))) + { + hasInnerPiece = true; + } + } + } + else if (dir == DIR_SOUTH) + { + int frontTile = level->getTile(x, y, z - 1); + int frontData = level->getData(x, y, z - 1); + if (isStairs(frontTile) && ((frontData & UPSIDEDOWN_BIT) == (data & UPSIDEDOWN_BIT))) + { + int frontDir = frontData & 0x3; + if ((frontDir == DIR_WEST && !isLockAttached(level, x - 1, y, z, data)) || + (frontDir == DIR_EAST && !isLockAttached(level, x + 1, y, z, data))) + { + hasInnerPiece = true; + } + } + } + else if (dir == DIR_NORTH) + { + int frontTile = level->getTile(x, y, z + 1); + int frontData = level->getData(x, y, z + 1); + if (isStairs(frontTile) && ((frontData & UPSIDEDOWN_BIT) == (data & UPSIDEDOWN_BIT))) + { + int frontDir = frontData & 0x3; + if ((frontDir == DIR_WEST && !isLockAttached(level, x - 1, y, z, data)) || + (frontDir == DIR_EAST && !isLockAttached(level, x + 1, y, z, data))) + { + hasInnerPiece = true; + } + } + } + + if (hasInnerPiece) + { + shape = 1; + } + } + + int composite = (dir & 0x3) | (upsideDown ? UPSIDEDOWN_BIT : 0) | ((shape & 0x7) << 3); + return Tile::BlockState(composite); +} + +int StairTile::convertBlockStateToLegacyData(BlockState *state) +{ + if (!state) return 0; + int composite = state->value; + int data = composite & 0x3; + if (composite & UPSIDEDOWN_BIT) data |= UPSIDEDOWN_BIT; + return data; +} + +void StairTile::fillVirtualBlockStateProperties(Tile::BlockState *state, LevelSource *level, const BlockPos &pos) +{ + if (!state) return; + Tile::BlockState s = getBlockState(level, pos.getX(), pos.getY(), pos.getZ()); + state->value = s.value; +} diff --git a/Minecraft.World/StairTile.h b/Minecraft.World/StairTile.h index ff5d57ff..6e502887 100644 --- a/Minecraft.World/StairTile.h +++ b/Minecraft.World/StairTile.h @@ -76,4 +76,13 @@ public: virtual int getPlacedOnFaceDataValue(Level *level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue); virtual HitResult *clip(Level *level, int xt, int yt, int zt, Vec3 *a, Vec3 *b); virtual void registerIcons(IconRegister *iconRegister); + + virtual void createBlockStateDefinition() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual int defaultBlockState() override; + + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + Tile::BlockState getBlockState(int data); + + void fillVirtualBlockStateProperties(Tile::BlockState *state, LevelSource *level, const BlockPos &pos); }; diff --git a/Minecraft.World/Stats.cpp b/Minecraft.World/Stats.cpp index 662621da..33d9a48e 100644 --- a/Minecraft.World/Stats.cpp +++ b/Minecraft.World/Stats.cpp @@ -178,7 +178,7 @@ void Stats::buildBlockStats() newStat = new ItemStat(BLOCKS_MINED_OFFSET + 11, L"mineBlock.redstone", Tile::redStoneOre->id); blocksMinedStats->push_back(newStat); blocksMined[Tile::redStoneOre->id] = newStat; - blocksMined[Tile::redStoneOre_lit->id] = newStat; + blocksMined[Tile::lit_redstone_ore->id] = newStat; newStat->postConstruct(); newStat = new ItemStat(BLOCKS_MINED_OFFSET + 12, L"mineBlock.lapisLazuli", Tile::lapisOre->id); @@ -306,105 +306,105 @@ void Stats::buildCraftableStats() itemsCrafted[Item::stick->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 3, L"craftItem.woodenShovel", Item::shovel_wood->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 3, L"craftItem.woodenShovel", Item::wooden_shovel->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::shovel_wood->id] = newStat; + itemsCrafted[Item::wooden_shovel->id] = newStat; newStat->postConstruct(); // 4J : WESTY : Added for new achievements. - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 4, L"craftItem.woodenPickAxe", Item::pickAxe_wood->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 4, L"craftItem.woodenPickAxe", Item::wooden_pickaxe->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::pickAxe_wood->id] = newStat; + itemsCrafted[Item::wooden_pickaxe->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 5, L"craftItem.stonePickAxe", Item::pickAxe_stone->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 5, L"craftItem.stonePickAxe", Item::stone_pickaxe->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::pickAxe_stone->id] = newStat; + itemsCrafted[Item::stone_pickaxe->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 6, L"craftItem.ironPickAxe", Item::pickAxe_iron->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 6, L"craftItem.ironPickAxe", Item::iron_pickaxe->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::pickAxe_iron->id] = newStat; + itemsCrafted[Item::iron_pickaxe->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 7, L"craftItem.diamondPickAxe", Item::pickAxe_diamond->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 7, L"craftItem.diamondPickAxe", Item::diamond_pickaxe->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::pickAxe_diamond->id] = newStat; + itemsCrafted[Item::diamond_pickaxe->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 8, L"craftItem.goldPickAxe", Item::pickAxe_gold->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 8, L"craftItem.goldPickAxe", Item::golden_pickaxe->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::pickAxe_gold->id] = newStat; + itemsCrafted[Item::golden_pickaxe->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 9, L"craftItem.stoneShovel", Item::shovel_stone->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 9, L"craftItem.stoneShovel", Item::stone_shovel->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::shovel_stone->id] = newStat; + itemsCrafted[Item::stone_shovel->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 10, L"craftItem.ironShovel", Item::shovel_iron->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 10, L"craftItem.ironShovel", Item::iron_shovel->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::shovel_iron->id] = newStat; + itemsCrafted[Item::iron_shovel->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 11, L"craftItem.diamondShovel", Item::shovel_diamond->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 11, L"craftItem.diamondShovel", Item::diamond_shovel->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::shovel_diamond->id] = newStat; + itemsCrafted[Item::diamond_shovel->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 12, L"craftItem.goldShovel", Item::shovel_gold->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 12, L"craftItem.goldShovel", Item::golden_shovel->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::shovel_gold->id] = newStat; + itemsCrafted[Item::golden_shovel->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 13, L"craftItem.woodenAxe", Item::hatchet_wood->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 13, L"craftItem.woodenAxe", Item::wooden_axe->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::hatchet_wood->id] = newStat; + itemsCrafted[Item::wooden_axe->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 14, L"craftItem.stoneAxe", Item::hatchet_stone->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 14, L"craftItem.stoneAxe", Item::stone_axe->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::hatchet_stone->id] = newStat; + itemsCrafted[Item::stone_axe->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 15, L"craftItem.ironAxe", Item::hatchet_iron->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 15, L"craftItem.ironAxe", Item::iron_axe->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::hatchet_iron->id] = newStat; + itemsCrafted[Item::iron_axe->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 16, L"craftItem.diamondAxe", Item::hatchet_diamond->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 16, L"craftItem.diamondAxe", Item::diamond_axe->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::hatchet_diamond->id] = newStat; + itemsCrafted[Item::diamond_axe->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 17, L"craftItem.goldAxe", Item::hatchet_gold->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 17, L"craftItem.goldAxe", Item::golden_axe->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::hatchet_gold->id] = newStat; + itemsCrafted[Item::golden_axe->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 18, L"craftItem.woodenHoe", Item::hoe_wood->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 18, L"craftItem.woodenHoe", Item::wooden_hoe->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::hoe_wood->id] = newStat; + itemsCrafted[Item::wooden_hoe->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 19, L"craftItem.stoneHoe", Item::hoe_stone->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 19, L"craftItem.stoneHoe", Item::stone_hoe->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::hoe_stone->id] = newStat; + itemsCrafted[Item::stone_hoe->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 20, L"craftItem.ironHoe", Item::hoe_iron->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 20, L"craftItem.ironHoe", Item::iron_hoe->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::hoe_iron->id] = newStat; + itemsCrafted[Item::iron_hoe->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 21, L"craftItem.diamondHoe", Item::hoe_diamond->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 21, L"craftItem.diamondHoe", Item::diamond_hoe->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::hoe_diamond->id] = newStat; + itemsCrafted[Item::diamond_hoe->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 22, L"craftItem.goldHoe", Item::hoe_gold->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 22, L"craftItem.goldHoe", Item::golden_hoe->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::hoe_gold->id] = newStat; + itemsCrafted[Item::golden_hoe->id] = newStat; newStat->postConstruct(); newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 23, L"craftItem.glowstone", Tile::glowstone_Id); @@ -422,19 +422,19 @@ void Stats::buildCraftableStats() itemsCrafted[Item::bowl->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 26, L"craftItem.bucket", Item::bucket_empty->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 26, L"craftItem.bucket", Item::bucket->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::bucket_empty->id] = newStat; + itemsCrafted[Item::bucket->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 27, L"craftItem.flintAndSteel", Item::flintAndSteel->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 27, L"craftItem.flint_and_steel", Item::flint_and_steel->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::flintAndSteel->id] = newStat; + itemsCrafted[Item::flint_and_steel->id] = newStat; newStat->postConstruct(); - newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 28, L"craftItem.fishingRod", Item::fishingRod->id); + newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 28, L"craftItem.fishing_rod", Item::fishing_rod->id); itemsCraftedStats->push_back(newStat); - itemsCrafted[Item::fishingRod->id] = newStat; + itemsCrafted[Item::fishing_rod->id] = newStat; newStat->postConstruct(); newStat = new ItemStat(ITEMS_CRAFTED_OFFSET + 29, L"craftItem.clock", Item::clock->id); @@ -475,17 +475,17 @@ void Stats::buildAdditionalStats() { - ItemStat *itemStat = new ItemStat(offset++, L"craftItem.flowerPot", Item::flowerPot_Id); + ItemStat *itemStat = new ItemStat(offset++, L"craftItem.flower_pot", Item::flower_pot_Id); itemsCraftedStats->push_back(itemStat); itemsCrafted[itemStat->getItemId()] = itemStat; itemStat->postConstruct(); - itemStat = new ItemStat(offset++, L"craftItem.sign", Item::sign_Id); + itemStat = new ItemStat(offset++, L"craftItem.sign", Item::standing_sign_Id); itemsCraftedStats->push_back(itemStat); itemsCrafted[itemStat->getItemId()] = itemStat; itemStat->postConstruct(); - itemStat = new ItemStat(offset++, L"mineBlock.emerald", Tile::emeraldOre_Id); + itemStat = new ItemStat(offset++, L"mineBlock.emerald", Tile::emerald_ore_Id); blocksMinedStats->push_back(itemStat); blocksMined[itemStat->getItemId()] = itemStat; itemStat->postConstruct(); @@ -502,17 +502,17 @@ void Stats::buildAdditionalStats() // Either way, I'm making this one smaller because we don't need those record items (and we only need 2). blocksPlaced = StatArray(1000); - itemStat = new ItemStat(offset++, L"blockPlaced.flowerPot", Tile::flowerPot_Id); + itemStat = new ItemStat(offset++, L"blockPlaced.flower_pot", Tile::flower_pot_Id); blocksPlacedStats->push_back(itemStat); blocksPlaced[itemStat->getItemId()] = itemStat; itemStat->postConstruct(); - itemStat = new ItemStat(offset++, L"blockPlaced.sign", Tile::sign_Id); + itemStat = new ItemStat(offset++, L"blockPlaced.sign", Tile::standing_sign_Id); blocksPlacedStats->push_back(itemStat); blocksPlaced[itemStat->getItemId()] = itemStat; itemStat->postConstruct(); - itemStat = new ItemStat(offset++, L"blockPlaced.wallsign", Tile::wallSign_Id); + itemStat = new ItemStat(offset++, L"blockPlaced.wallsign", Tile::wall_standing_sign_Id); blocksPlacedStats->push_back(itemStat); blocksPlaced[itemStat->getItemId()] = itemStat; itemStat->postConstruct(); @@ -537,12 +537,12 @@ void Stats::buildAdditionalStats() generalStat->postConstruct(); } - itemStat = new ItemStat(offset++, L"itemCrafted.porkchop", Item::porkChop_cooked_Id); + itemStat = new ItemStat(offset++, L"itemCrafted.porkchop", Item::cooked_porkchop_Id); itemsCraftedStats->push_back(itemStat); itemsCrafted[itemStat->getItemId()] = itemStat; itemStat->postConstruct(); - itemStat = new ItemStat(offset++, L"itemEaten.porkchop", Item::porkChop_cooked_Id); + itemStat = new ItemStat(offset++, L"itemEaten.porkchop", Item::cooked_porkchop_Id); blocksPlacedStats->push_back(itemStat); blocksPlaced[itemStat->getItemId()] = itemStat; itemStat->postConstruct(); diff --git a/Minecraft.World/StemTile.cpp b/Minecraft.World/StemTile.cpp index 66980f58..06a9f192 100644 --- a/Minecraft.World/StemTile.cpp +++ b/Minecraft.World/StemTile.cpp @@ -24,6 +24,35 @@ StemTile::StemTile(int id, Tile *fruit) : Bush(id) iconAngled = nullptr; } +void StemTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int StemTile::defaultBlockState() +{ + return 0; +} + +int StemTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x7) : 0; +} + +Tile::BlockState StemTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x7); +} + +Tile::BlockState StemTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + int age = level->getData(x, y, z) & 0x7; + int connectDir = getConnectDir(level, x, y, z); + int facingCode = connectDir >= 0 ? connectDir + 1 : 0; + return Tile::BlockState(age | ((facingCode & 0x7) << 3)); +} + bool StemTile::mayPlaceOn(int tile) { return tile == Tile::farmland_Id; @@ -214,11 +243,11 @@ int StemTile::cloneTileId(Level *level, int x, int y, int z) { if (fruit == Tile::pumpkin) { - return Item::seeds_pumpkin_Id; + return Item::pumpkin_seeds_Id; } else if (fruit == Tile::melon) { - return Item::seeds_melon_Id; + return Item::melon_seeds_Id; } return 0; diff --git a/Minecraft.World/StemTile.h b/Minecraft.World/StemTile.h index 4685e0a5..c8caf938 100644 --- a/Minecraft.World/StemTile.h +++ b/Minecraft.World/StemTile.h @@ -15,6 +15,11 @@ private: public: StemTile(int id, Tile *fruit); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual bool mayPlaceOn(int tile); public: diff --git a/Minecraft.World/StoneBeachBiome.cpp b/Minecraft.World/StoneBeachBiome.cpp new file mode 100644 index 00000000..fcd08c57 --- /dev/null +++ b/Minecraft.World/StoneBeachBiome.cpp @@ -0,0 +1,19 @@ +#include "stdafx.h" +#include "StoneBeachBiome.h" +#include "net.minecraft.world.level.tile.h" +#include "BiomeDecorator.h" + +StoneBeachBiome::StoneBeachBiome(int id) : Biome(id) +{ + this->topMaterial = static_cast(Tile::stone_Id); + this->topMaterialData = 0; + this->material = static_cast(Tile::stone_Id); + this->materialData = 0; + + if (decorator != nullptr) + { + decorator->treeCount = 0; + decorator->grassCount = 0; + decorator->flowerCount = 0; + } +} \ No newline at end of file diff --git a/Minecraft.World/StoneBeachBiome.h b/Minecraft.World/StoneBeachBiome.h new file mode 100644 index 00000000..c4302bb1 --- /dev/null +++ b/Minecraft.World/StoneBeachBiome.h @@ -0,0 +1,10 @@ +#pragma once +#include "Biome.h" + +class StoneBeachBiome : public Biome +{ +public: + StoneBeachBiome(int id); + virtual bool isFoggy() const { return false; } + virtual bool isNatural() const { return true; } +}; \ No newline at end of file diff --git a/Minecraft.World/StoneMonsterTile.cpp b/Minecraft.World/StoneMonsterTile.cpp index fd3f1b90..e99769c3 100644 --- a/Minecraft.World/StoneMonsterTile.cpp +++ b/Minecraft.World/StoneMonsterTile.cpp @@ -66,7 +66,7 @@ int StoneMonsterTile::getResourceCount(Random *random) bool StoneMonsterTile::isCompatibleHostBlock(int block) { - return block == Tile::stone_Id || block == Tile::cobblestone_Id || block == Tile::stoneBrick_Id; + return block == Tile::stone_Id || block == Tile::cobblestone_Id || block == Tile::stonebrick_Id; } int StoneMonsterTile::getDataForHostBlock(int block) @@ -75,7 +75,7 @@ int StoneMonsterTile::getDataForHostBlock(int block) { return HOST_COBBLE; } - if (block == Tile::stoneBrick_Id) + if (block == Tile::stonebrick_Id) { return HOST_STONEBRICK; } diff --git a/Minecraft.World/StoneMonsterTileItem.cpp b/Minecraft.World/StoneMonsterTileItem.cpp index 4ecdf627..7691875a 100644 --- a/Minecraft.World/StoneMonsterTileItem.cpp +++ b/Minecraft.World/StoneMonsterTileItem.cpp @@ -16,7 +16,7 @@ int StoneMonsterTileItem::getLevelDataForAuxValue(int auxValue) Icon *StoneMonsterTileItem::getIcon(int itemAuxValue) { - return Tile::monsterStoneEgg->getTexture(0, itemAuxValue); + return Tile::monster_egg->getTexture(0, itemAuxValue); } unsigned int StoneMonsterTileItem::getDescriptionId(shared_ptr instance) diff --git a/Minecraft.World/StoneSlabTile.cpp b/Minecraft.World/StoneSlabTile.cpp index 37f09404..802be2d8 100644 --- a/Minecraft.World/StoneSlabTile.cpp +++ b/Minecraft.World/StoneSlabTile.cpp @@ -60,7 +60,7 @@ void StoneSlabTile::registerIcons(IconRegister *iconRegister) int StoneSlabTile::getResource(int data, Random *random, int playerBonusLevel) { - return Tile::stoneSlabHalf_Id; + return Tile::stone_slab_Id; } unsigned int StoneSlabTile::getDescriptionId(int iData) @@ -78,5 +78,5 @@ int StoneSlabTile::getAuxName(int auxValue) shared_ptr StoneSlabTile::getSilkTouchItemInstance(int data) { - return make_shared(Tile::stoneSlabHalf_Id, 2, data & TYPE_MASK); + return make_shared(Tile::stone_slab_Id, 2, data & TYPE_MASK); } \ No newline at end of file diff --git a/Minecraft.World/StrongholdPieces.cpp b/Minecraft.World/StrongholdPieces.cpp index d98d9488..eb454b6c 100644 --- a/Minecraft.World/StrongholdPieces.cpp +++ b/Minecraft.World/StrongholdPieces.cpp @@ -280,39 +280,39 @@ void StrongholdPieces::StrongholdPiece::generateSmallDoor(Level *level, Random * generateBox(level, chunkBB, footX, footY, footZ, footX + SMALL_DOOR_WIDTH - 1, footY + SMALL_DOOR_HEIGHT - 1, footZ, 0, 0, false); break; case WOOD_DOOR: - placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY, footZ, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY + 1, footZ, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY + 2, footZ, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, footX + 1, footY + 2, footZ, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY + 2, footZ, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY + 1, footZ, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY, footZ, chunkBB); - placeBlock(level, Tile::door_wood_Id, 0, footX + 1, footY, footZ, chunkBB); - placeBlock(level, Tile::door_wood_Id, DoorTile::UPPER_BIT, footX + 1, footY + 1, footZ, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, footX, footY, footZ, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, footX, footY + 1, footZ, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, footX, footY + 2, footZ, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, footX + 1, footY + 2, footZ, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, footX + 2, footY + 2, footZ, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, footX + 2, footY + 1, footZ, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, footX + 2, footY, footZ, chunkBB); + placeBlock(level, Tile::wooden_door_Id, 0, footX + 1, footY, footZ, chunkBB); + placeBlock(level, Tile::wooden_door_Id, DoorTile::UPPER_BIT, footX + 1, footY + 1, footZ, chunkBB); break; case GRATES: placeBlock(level, 0, 0, footX + 1, footY, footZ, chunkBB); placeBlock(level, 0, 0, footX + 1, footY + 1, footZ, chunkBB); - placeBlock(level, Tile::ironFence_Id, 0, footX, footY, footZ, chunkBB); - placeBlock(level, Tile::ironFence_Id, 0, footX, footY + 1, footZ, chunkBB); - placeBlock(level, Tile::ironFence_Id, 0, footX, footY + 2, footZ, chunkBB); - placeBlock(level, Tile::ironFence_Id, 0, footX + 1, footY + 2, footZ, chunkBB); - placeBlock(level, Tile::ironFence_Id, 0, footX + 2, footY + 2, footZ, chunkBB); - placeBlock(level, Tile::ironFence_Id, 0, footX + 2, footY + 1, footZ, chunkBB); - placeBlock(level, Tile::ironFence_Id, 0, footX + 2, footY, footZ, chunkBB); + placeBlock(level, Tile::iron_bars_Id, 0, footX, footY, footZ, chunkBB); + placeBlock(level, Tile::iron_bars_Id, 0, footX, footY + 1, footZ, chunkBB); + placeBlock(level, Tile::iron_bars_Id, 0, footX, footY + 2, footZ, chunkBB); + placeBlock(level, Tile::iron_bars_Id, 0, footX + 1, footY + 2, footZ, chunkBB); + placeBlock(level, Tile::iron_bars_Id, 0, footX + 2, footY + 2, footZ, chunkBB); + placeBlock(level, Tile::iron_bars_Id, 0, footX + 2, footY + 1, footZ, chunkBB); + placeBlock(level, Tile::iron_bars_Id, 0, footX + 2, footY, footZ, chunkBB); break; case IRON_DOOR: - placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY, footZ, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY + 1, footZ, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY + 2, footZ, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, footX + 1, footY + 2, footZ, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY + 2, footZ, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY + 1, footZ, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY, footZ, chunkBB); - placeBlock(level, Tile::door_iron_Id, 0, footX + 1, footY, footZ, chunkBB); - placeBlock(level, Tile::door_iron_Id, DoorTile::UPPER_BIT, footX + 1, footY + 1, footZ, chunkBB); - placeBlock(level, Tile::button_stone_Id, getOrientationData(Tile::button_stone_Id, 4), footX + 2, footY + 1, footZ + 1, chunkBB); - placeBlock(level, Tile::button_stone_Id, getOrientationData(Tile::button_stone_Id, 3), footX + 2, footY + 1, footZ - 1, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, footX, footY, footZ, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, footX, footY + 1, footZ, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, footX, footY + 2, footZ, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, footX + 1, footY + 2, footZ, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, footX + 2, footY + 2, footZ, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, footX + 2, footY + 1, footZ, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, footX + 2, footY, footZ, chunkBB); + placeBlock(level, Tile::iron_door_Id, 0, footX + 1, footY, footZ, chunkBB); + placeBlock(level, Tile::iron_door_Id, DoorTile::UPPER_BIT, footX + 1, footY + 1, footZ, chunkBB); + placeBlock(level, Tile::stone_button_Id, getOrientationData(Tile::stone_button_Id, 4), footX + 2, footY + 1, footZ + 1, chunkBB); + placeBlock(level, Tile::stone_button_Id, getOrientationData(Tile::stone_button_Id, 3), footX + 2, footY + 1, footZ - 1, chunkBB); break; } @@ -482,26 +482,26 @@ bool StrongholdPieces::FillerCorridor::postProcess(Level *level, Random *random, for (int i = 0; i < steps; i++) { // row 0 - placeBlock(level, Tile::stoneBrick_Id, 0, 0, 0, i, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 1, 0, i, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 2, 0, i, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 3, 0, i, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 4, 0, i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 0, 0, i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 1, 0, i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 2, 0, i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 3, 0, i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 4, 0, i, chunkBB); // row 1-3 for (int y = 1; y <= 3; y++) { - placeBlock(level, Tile::stoneBrick_Id, 0, 0, y, i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 0, y, i, chunkBB); placeBlock(level, 0, 0, 1, y, i, chunkBB); placeBlock(level, 0, 0, 2, y, i, chunkBB); placeBlock(level, 0, 0, 3, y, i, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 4, y, i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 4, y, i, chunkBB); } // row 4 - placeBlock(level, Tile::stoneBrick_Id, 0, 0, 4, i, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 1, 4, i, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 2, 4, i, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 3, 4, i, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 4, 4, i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 0, 4, i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 1, 4, i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 2, 4, i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 3, 4, i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 4, 4, i, chunkBB); } return true; @@ -588,23 +588,23 @@ bool StrongholdPieces::StairsDown::postProcess(Level *level, Random *random, Bou generateSmallDoor(level, random, chunkBB, OPENING, 1, 1, depth - 1); // stair steps - placeBlock(level, Tile::stoneBrick_Id, 0, 2, 6, 1, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 1, 5, 1, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 6, 1, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 1, 5, 2, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 1, 4, 3, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 5, 3, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 2, 4, 3, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 3, 3, 3, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 3, 4, 3, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 3, 3, 2, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 3, 2, 1, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 3, 3, 1, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 2, 2, 1, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 1, 1, 1, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 2, 1, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 1, 1, 2, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 1, 3, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 2, 6, 1, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 1, 5, 1, chunkBB); + placeBlock(level, Tile::stone_slab_Id, StoneSlabTile::STONE_SLAB, 1, 6, 1, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 1, 5, 2, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 1, 4, 3, chunkBB); + placeBlock(level, Tile::stone_slab_Id, StoneSlabTile::STONE_SLAB, 1, 5, 3, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 2, 4, 3, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 3, 3, 3, chunkBB); + placeBlock(level, Tile::stone_slab_Id, StoneSlabTile::STONE_SLAB, 3, 4, 3, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 3, 3, 2, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 3, 2, 1, chunkBB); + placeBlock(level, Tile::stone_slab_Id, StoneSlabTile::STONE_SLAB, 3, 3, 1, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 2, 2, 1, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 1, 1, 1, chunkBB); + placeBlock(level, Tile::stone_slab_Id, StoneSlabTile::STONE_SLAB, 1, 2, 1, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 1, 1, 2, chunkBB); + placeBlock(level, Tile::stone_slab_Id, StoneSlabTile::STONE_SLAB, 1, 1, 3, chunkBB); return true; } @@ -717,25 +717,25 @@ bool StrongholdPieces::Straight::postProcess(Level *level, Random *random, Bound WeighedTreasure *StrongholdPieces::ChestCorridor::treasureItems[TREASURE_ITEMS_COUNT] = { - new WeighedTreasure(Item::enderPearl_Id, 0, 1, 1, 10), + new WeighedTreasure(Item::ender_pearl_Id, 0, 1, 1, 10), new WeighedTreasure(Item::diamond_Id, 0, 1, 3, 3), - new WeighedTreasure(Item::ironIngot_Id, 0, 1, 5, 10), - new WeighedTreasure(Item::goldIngot_Id, 0, 1, 3, 5), - new WeighedTreasure(Item::redStone_Id, 0, 4, 9, 5), + new WeighedTreasure(Item::iron_ingot_Id, 0, 1, 5, 10), + new WeighedTreasure(Item::gold_ingot_Id, 0, 1, 3, 5), + new WeighedTreasure(Item::redstone_Id, 0, 4, 9, 5), new WeighedTreasure(Item::bread_Id, 0, 1, 3, 15), new WeighedTreasure(Item::apple_Id, 0, 1, 3, 15), - new WeighedTreasure(Item::pickAxe_iron_Id, 0, 1, 1, 5), - new WeighedTreasure(Item::sword_iron_Id, 0, 1, 1, 5), - new WeighedTreasure(Item::chestplate_iron_Id, 0, 1, 1, 5), - new WeighedTreasure(Item::helmet_iron_Id, 0, 1, 1, 5), - new WeighedTreasure(Item::leggings_iron_Id, 0, 1, 1, 5), - new WeighedTreasure(Item::boots_iron_Id, 0, 1, 1, 5), - new WeighedTreasure(Item::apple_gold_Id, 0, 1, 1, 1), + new WeighedTreasure(Item::iron_pickaxe_Id, 0, 1, 1, 5), + new WeighedTreasure(Item::iron_sword_Id, 0, 1, 1, 5), + new WeighedTreasure(Item::iron_chestplate_Id, 0, 1, 1, 5), + new WeighedTreasure(Item::iron_helmet_Id, 0, 1, 1, 5), + new WeighedTreasure(Item::iron_leggings_Id, 0, 1, 1, 5), + new WeighedTreasure(Item::iron_boots_Id, 0, 1, 1, 5), + new WeighedTreasure(Item::golden_apple_Id, 0, 1, 1, 1), // very rare for strongholds ... new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 1), - new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 1), - new WeighedTreasure(Item::horseArmorGold_Id, 0, 1, 1, 1), - new WeighedTreasure(Item::horseArmorDiamond_Id, 0, 1, 1, 1), + new WeighedTreasure(Item::iron_horse_armor_Id, 0, 1, 1, 1), + new WeighedTreasure(Item::golden_horse_armor_Id, 0, 1, 1, 1), + new WeighedTreasure(Item::diamond_horse_armor_Id, 0, 1, 1, 1), // ... }; @@ -799,14 +799,14 @@ bool StrongholdPieces::ChestCorridor::postProcess(Level *level, Random *random, generateSmallDoor(level, random, chunkBB, OPENING, 1, 1, depth - 1); // chest placement - generateBox(level, chunkBB, 3, 1, 2, 3, 1, 4, Tile::stoneBrick_Id, Tile::stoneBrick_Id, false); - placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SMOOTHBRICK_SLAB, 3, 1, 1, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SMOOTHBRICK_SLAB, 3, 1, 5, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SMOOTHBRICK_SLAB, 3, 2, 2, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SMOOTHBRICK_SLAB, 3, 2, 4, chunkBB); + generateBox(level, chunkBB, 3, 1, 2, 3, 1, 4, Tile::stonebrick_Id, Tile::stonebrick_Id, false); + placeBlock(level, Tile::stone_slab_Id, StoneSlabTile::SMOOTHBRICK_SLAB, 3, 1, 1, chunkBB); + placeBlock(level, Tile::stone_slab_Id, StoneSlabTile::SMOOTHBRICK_SLAB, 3, 1, 5, chunkBB); + placeBlock(level, Tile::stone_slab_Id, StoneSlabTile::SMOOTHBRICK_SLAB, 3, 2, 2, chunkBB); + placeBlock(level, Tile::stone_slab_Id, StoneSlabTile::SMOOTHBRICK_SLAB, 3, 2, 4, chunkBB); for (int z = 2; z <= 4; z++) { - placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SMOOTHBRICK_SLAB, 2, 1, z, chunkBB); + placeBlock(level, Tile::stone_slab_Id, StoneSlabTile::SMOOTHBRICK_SLAB, 2, 1, z, chunkBB); } if (!hasPlacedChest) @@ -816,7 +816,7 @@ bool StrongholdPieces::ChestCorridor::postProcess(Level *level, Random *random, if (chunkBB->isInside(x, y, z)) { hasPlacedChest = true; - createChest(level, chunkBB, random, 3, 2, 3, WeighedTreasure::addToTreasure(WeighedTreasureArray(treasureItems,TREASURE_ITEMS_COUNT), Item::enchantedBook->createForRandomTreasure(random)), 2 + random->nextInt(2)); + createChest(level, chunkBB, random, 3, 2, 3, WeighedTreasure::addToTreasure(WeighedTreasureArray(treasureItems,TREASURE_ITEMS_COUNT), Item::enchanted_book->createForRandomTreasure(random)), 2 + random->nextInt(2)); } } @@ -871,17 +871,17 @@ bool StrongholdPieces::StraightStairsDown::postProcess(Level *level, Random *ran generateSmallDoor(level, random, chunkBB, OPENING, 1, 1, depth - 1); // stairs - int orientationData = getOrientationData(Tile::stairs_stone_Id, 2); + int orientationData = getOrientationData(Tile::stone_stairs_Id, 2); for (int i = 0; i < 6; i++) { - placeBlock(level, Tile::stairs_stone_Id, orientationData, 1, height - 5 - i, 1 + i, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, orientationData, 2, height - 5 - i, 1 + i, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, orientationData, 3, height - 5 - i, 1 + i, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, orientationData, 1, height - 5 - i, 1 + i, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, orientationData, 2, height - 5 - i, 1 + i, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, orientationData, 3, height - 5 - i, 1 + i, chunkBB); if (i < 5) { - placeBlock(level, Tile::stoneBrick_Id, 0, 1, height - 6 - i, 1 + i, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 2, height - 6 - i, 1 + i, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 3, height - 6 - i, 1 + i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 1, height - 6 - i, 1 + i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 2, height - 6 - i, 1 + i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 3, height - 6 - i, 1 + i, chunkBB); } } @@ -1046,13 +1046,13 @@ StrongholdPieces::RoomCrossing *StrongholdPieces::RoomCrossing::createPiece(list WeighedTreasure *StrongholdPieces::RoomCrossing::smallTreasureItems[SMALL_TREASURE_ITEMS_COUNT] = { - new WeighedTreasure(Item::ironIngot_Id, 0, 1, 5, 10), - new WeighedTreasure(Item::goldIngot_Id, 0, 1, 3, 5), - new WeighedTreasure(Item::redStone_Id, 0, 4, 9, 5), + new WeighedTreasure(Item::iron_ingot_Id, 0, 1, 5, 10), + new WeighedTreasure(Item::gold_ingot_Id, 0, 1, 3, 5), + new WeighedTreasure(Item::redstone_Id, 0, 4, 9, 5), new WeighedTreasure(Item::coal_Id, CoalItem::STONE_COAL, 3, 8, 10), new WeighedTreasure(Item::bread_Id, 0, 1, 3, 15), new WeighedTreasure(Item::apple_Id, 0, 1, 3, 15), - new WeighedTreasure(Item::pickAxe_iron_Id, 0, 1, 1, 1), + new WeighedTreasure(Item::iron_pickaxe_Id, 0, 1, 1, 1), }; bool StrongholdPieces::RoomCrossing::postProcess(Level *level, Random *random, BoundingBox *chunkBB) @@ -1077,35 +1077,35 @@ bool StrongholdPieces::RoomCrossing::postProcess(Level *level, Random *random, B break; case 0: // middle torch pillar - placeBlock(level, Tile::stoneBrick_Id, 0, 5, 1, 5, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 5, 2, 5, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 5, 3, 5, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 5, 1, 5, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 5, 2, 5, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 5, 3, 5, chunkBB); placeBlock(level, Tile::torch_Id, 0, 4, 3, 5, chunkBB); placeBlock(level, Tile::torch_Id, 0, 6, 3, 5, chunkBB); placeBlock(level, Tile::torch_Id, 0, 5, 3, 4, chunkBB); placeBlock(level, Tile::torch_Id, 0, 5, 3, 6, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, 0, 4, 1, 4, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, 0, 4, 1, 5, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, 0, 4, 1, 6, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, 0, 6, 1, 4, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, 0, 6, 1, 5, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, 0, 6, 1, 6, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, 0, 5, 1, 4, chunkBB); - placeBlock(level, Tile::stoneSlabHalf_Id, 0, 5, 1, 6, chunkBB); + placeBlock(level, Tile::stone_slab_Id, 0, 4, 1, 4, chunkBB); + placeBlock(level, Tile::stone_slab_Id, 0, 4, 1, 5, chunkBB); + placeBlock(level, Tile::stone_slab_Id, 0, 4, 1, 6, chunkBB); + placeBlock(level, Tile::stone_slab_Id, 0, 6, 1, 4, chunkBB); + placeBlock(level, Tile::stone_slab_Id, 0, 6, 1, 5, chunkBB); + placeBlock(level, Tile::stone_slab_Id, 0, 6, 1, 6, chunkBB); + placeBlock(level, Tile::stone_slab_Id, 0, 5, 1, 4, chunkBB); + placeBlock(level, Tile::stone_slab_Id, 0, 5, 1, 6, chunkBB); break; case 1: { for (int i = 0; i < 5; i++) { - placeBlock(level, Tile::stoneBrick_Id, 0, 3, 1, 3 + i, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 7, 1, 3 + i, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 3 + i, 1, 3, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 3 + i, 1, 7, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 3, 1, 3 + i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 7, 1, 3 + i, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 3 + i, 1, 3, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 3 + i, 1, 7, chunkBB); } - placeBlock(level, Tile::stoneBrick_Id, 0, 5, 1, 5, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 5, 2, 5, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 5, 3, 5, chunkBB); - placeBlock(level, Tile::water_Id, 0, 5, 4, 5, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 5, 1, 5, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 5, 2, 5, chunkBB); + placeBlock(level, Tile::stonebrick_Id, 0, 5, 3, 5, chunkBB); + placeBlock(level, Tile::flowing_water_Id, 0, 5, 4, 5, chunkBB); } break; case 2: @@ -1138,22 +1138,22 @@ bool StrongholdPieces::RoomCrossing::postProcess(Level *level, Random *random, B placeBlock(level, Tile::torch_Id, 0, 5, 3, 5, chunkBB); for (int z = 2; z <= 8; z++) { - placeBlock(level, Tile::wood_Id, 0, 2, 3, z, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 3, 3, z, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 2, 3, z, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 3, 3, z, chunkBB); if (z <= 3 || z >= 7) { - placeBlock(level, Tile::wood_Id, 0, 4, 3, z, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 5, 3, z, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 6, 3, z, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 4, 3, z, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 5, 3, z, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 6, 3, z, chunkBB); } - placeBlock(level, Tile::wood_Id, 0, 7, 3, z, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 8, 3, z, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 7, 3, z, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 8, 3, z, chunkBB); } placeBlock(level, Tile::ladder_Id, getOrientationData(Tile::ladder_Id, Facing::WEST), 9, 1, 3, chunkBB); placeBlock(level, Tile::ladder_Id, getOrientationData(Tile::ladder_Id, Facing::WEST), 9, 2, 3, chunkBB); placeBlock(level, Tile::ladder_Id, getOrientationData(Tile::ladder_Id, Facing::WEST), 9, 3, 3, chunkBB); - createChest(level, chunkBB, random, 3, 4, 8, WeighedTreasure::addToTreasure(WeighedTreasureArray(smallTreasureItems,SMALL_TREASURE_ITEMS_COUNT), Item::enchantedBook->createForRandomTreasure(random)), 1 + random->nextInt(4)); + createChest(level, chunkBB, random, 3, 4, 8, WeighedTreasure::addToTreasure(WeighedTreasureArray(smallTreasureItems,SMALL_TREASURE_ITEMS_COUNT), Item::enchanted_book->createForRandomTreasure(random)), 1 + random->nextInt(4)); // System.out.println("Created chest at " + getWorldX(3, 8) + // "," + getWorldY(4) + "," + getWorldZ(3, 8)); @@ -1217,16 +1217,16 @@ bool StrongholdPieces::PrisonHall::postProcess(Level *level, Random *random, Bou generateBox(level, chunkBB, 4, 1, 9, 4, 3, 9, false, random, (BlockSelector *)smoothStoneSelector); // grates - generateBox(level, chunkBB, 4, 1, 4, 4, 3, 6, Tile::ironFence_Id, Tile::ironFence_Id, false); - generateBox(level, chunkBB, 5, 1, 5, 7, 3, 5, Tile::ironFence_Id, Tile::ironFence_Id, false); + generateBox(level, chunkBB, 4, 1, 4, 4, 3, 6, Tile::iron_bars_Id, Tile::iron_bars_Id, false); + generateBox(level, chunkBB, 5, 1, 5, 7, 3, 5, Tile::iron_bars_Id, Tile::iron_bars_Id, false); // doors - placeBlock(level, Tile::ironFence_Id, 0, 4, 3, 2, chunkBB); - placeBlock(level, Tile::ironFence_Id, 0, 4, 3, 8, chunkBB); - placeBlock(level, Tile::door_iron_Id, getOrientationData(Tile::door_iron_Id, 3), 4, 1, 2, chunkBB); - placeBlock(level, Tile::door_iron_Id, getOrientationData(Tile::door_iron_Id, 3) + DoorTile::UPPER_BIT, 4, 2, 2, chunkBB); - placeBlock(level, Tile::door_iron_Id, getOrientationData(Tile::door_iron_Id, 3), 4, 1, 8, chunkBB); - placeBlock(level, Tile::door_iron_Id, getOrientationData(Tile::door_iron_Id, 3) + DoorTile::UPPER_BIT, 4, 2, 8, chunkBB); + placeBlock(level, Tile::iron_bars_Id, 0, 4, 3, 2, chunkBB); + placeBlock(level, Tile::iron_bars_Id, 0, 4, 3, 8, chunkBB); + placeBlock(level, Tile::iron_door_Id, getOrientationData(Tile::iron_door_Id, 3), 4, 1, 2, chunkBB); + placeBlock(level, Tile::iron_door_Id, getOrientationData(Tile::iron_door_Id, 3) + DoorTile::UPPER_BIT, 4, 2, 2, chunkBB); + placeBlock(level, Tile::iron_door_Id, getOrientationData(Tile::iron_door_Id, 3), 4, 1, 8, chunkBB); + placeBlock(level, Tile::iron_door_Id, getOrientationData(Tile::iron_door_Id, 3) + DoorTile::UPPER_BIT, 4, 2, 8, chunkBB); return true; @@ -1317,16 +1317,16 @@ bool StrongholdPieces::Library::postProcess(Level *level, Random *random, Boundi // place library walls for (int d = 1; d <= depth - 2; d++) { if (((d - 1) % 4) == 0) { - generateBox(level, chunkBB, bookLeft, 1, d, bookLeft, 4, d, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, bookRight, 1, d, bookRight, 4, d, Tile::wood_Id, Tile::wood_Id, false); + generateBox(level, chunkBB, bookLeft, 1, d, bookLeft, 4, d, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, bookRight, 1, d, bookRight, 4, d, Tile::planks_Id, Tile::planks_Id, false); placeBlock(level, Tile::torch_Id, 0, 2, 3, d, chunkBB); placeBlock(level, Tile::torch_Id, 0, width - 3, 3, d, chunkBB); if (isTall) { - generateBox(level, chunkBB, bookLeft, 6, d, bookLeft, 9, d, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, bookRight, 6, d, bookRight, 9, d, Tile::wood_Id, Tile::wood_Id, false); + generateBox(level, chunkBB, bookLeft, 6, d, bookLeft, 9, d, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, bookRight, 6, d, bookRight, 9, d, Tile::planks_Id, Tile::planks_Id, false); } } else @@ -1353,14 +1353,14 @@ bool StrongholdPieces::Library::postProcess(Level *level, Random *random, Boundi if (isTall) { // create balcony - generateBox(level, chunkBB, 1, 5, 1, 3, 5, depth - 2, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, width - 4, 5, 1, width - 2, 5, depth - 2, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 4, 5, 1, width - 5, 5, 2, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 4, 5, depth - 3, width - 5, 5, depth - 2, Tile::wood_Id, Tile::wood_Id, false); + generateBox(level, chunkBB, 1, 5, 1, 3, 5, depth - 2, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, width - 4, 5, 1, width - 2, 5, depth - 2, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 4, 5, 1, width - 5, 5, 2, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 4, 5, depth - 3, width - 5, 5, depth - 2, Tile::planks_Id, Tile::planks_Id, false); - placeBlock(level, Tile::wood_Id, 0, width - 5, 5, depth - 4, chunkBB); - placeBlock(level, Tile::wood_Id, 0, width - 6, 5, depth - 4, chunkBB); - placeBlock(level, Tile::wood_Id, 0, width - 5, 5, depth - 5, chunkBB); + placeBlock(level, Tile::planks_Id, 0, width - 5, 5, depth - 4, chunkBB); + placeBlock(level, Tile::planks_Id, 0, width - 6, 5, depth - 4, chunkBB); + placeBlock(level, Tile::planks_Id, 0, width - 5, 5, depth - 5, chunkBB); // balcony fences generateBox(level, chunkBB, 3, 6, 2, 3, 6, depth - 3, Tile::fence_Id, Tile::fence_Id, false); @@ -1407,11 +1407,11 @@ bool StrongholdPieces::Library::postProcess(Level *level, Random *random, Boundi } // place chests - createChest(level, chunkBB, random, 3, 3, 5, WeighedTreasure::addToTreasure(WeighedTreasureArray(libraryTreasureItems,LIBRARY_TREASURE_ITEMS_COUNT), Item::enchantedBook->createForRandomTreasure(random, 1, 5, 2)), 1 + random->nextInt(4)); + createChest(level, chunkBB, random, 3, 3, 5, WeighedTreasure::addToTreasure(WeighedTreasureArray(libraryTreasureItems,LIBRARY_TREASURE_ITEMS_COUNT), Item::enchanted_book->createForRandomTreasure(random, 1, 5, 2)), 1 + random->nextInt(4)); if (isTall) { placeBlock(level, 0, 0, width - 2, tallHeight - 2, 1, chunkBB); - createChest(level, chunkBB, random, width - 2, tallHeight - 3, 1, WeighedTreasure::addToTreasure(WeighedTreasureArray(libraryTreasureItems,LIBRARY_TREASURE_ITEMS_COUNT), Item::enchantedBook->createForRandomTreasure(random, 1, 5, 2)), 1 + random->nextInt(4)); + createChest(level, chunkBB, random, width - 2, tallHeight - 3, 1, WeighedTreasure::addToTreasure(WeighedTreasureArray(libraryTreasureItems,LIBRARY_TREASURE_ITEMS_COUNT), Item::enchanted_book->createForRandomTreasure(random, 1, 5, 2)), 1 + random->nextInt(4)); } return true; @@ -1517,18 +1517,18 @@ bool StrongholdPieces::FiveCrossing::postProcess(Level *level, Random *random, B // left stairs generateBox(level, chunkBB, 1, 3, 5, 3, 3, 6, false, random, (BlockSelector *)smoothStoneSelector); - generateBox(level, chunkBB, 1, 3, 4, 3, 3, 4, Tile::stoneSlabHalf_Id, Tile::stoneSlabHalf_Id, false); - generateBox(level, chunkBB, 1, 4, 6, 3, 4, 6, Tile::stoneSlabHalf_Id, Tile::stoneSlabHalf_Id, false); + generateBox(level, chunkBB, 1, 3, 4, 3, 3, 4, Tile::stone_slab_Id, Tile::stone_slab_Id, false); + generateBox(level, chunkBB, 1, 4, 6, 3, 4, 6, Tile::stone_slab_Id, Tile::stone_slab_Id, false); // lower stairs generateBox(level, chunkBB, 5, 1, 7, 7, 1, 8, false, random, (BlockSelector *)smoothStoneSelector); - generateBox(level, chunkBB, 5, 1, 9, 7, 1, 9, Tile::stoneSlabHalf_Id, Tile::stoneSlabHalf_Id, false); - generateBox(level, chunkBB, 5, 2, 7, 7, 2, 7, Tile::stoneSlabHalf_Id, Tile::stoneSlabHalf_Id, false); + generateBox(level, chunkBB, 5, 1, 9, 7, 1, 9, Tile::stone_slab_Id, Tile::stone_slab_Id, false); + generateBox(level, chunkBB, 5, 2, 7, 7, 2, 7, Tile::stone_slab_Id, Tile::stone_slab_Id, false); // bridge - generateBox(level, chunkBB, 4, 5, 7, 4, 5, 9, Tile::stoneSlabHalf_Id, Tile::stoneSlabHalf_Id, false); - generateBox(level, chunkBB, 8, 5, 7, 8, 5, 9, Tile::stoneSlabHalf_Id, Tile::stoneSlabHalf_Id, false); - generateBox(level, chunkBB, 5, 5, 7, 7, 5, 9, Tile::stoneSlab_Id, Tile::stoneSlab_Id, false); + generateBox(level, chunkBB, 4, 5, 7, 4, 5, 9, Tile::stone_slab_Id, Tile::stone_slab_Id, false); + generateBox(level, chunkBB, 8, 5, 7, 8, 5, 9, Tile::stone_slab_Id, Tile::stone_slab_Id, false); + generateBox(level, chunkBB, 5, 5, 7, 7, 5, 9, Tile::double_stone_slab_Id, Tile::double_stone_slab_Id, false); placeBlock(level, Tile::torch_Id, 0, 6, 5, 6, chunkBB); return true; @@ -1601,34 +1601,34 @@ bool StrongholdPieces::PortalRoom::postProcess(Level *level, Random *random, Bou // entrance lava pools generateBox(level, chunkBB, 1, 1, 1, 2, 1, 4, false, random, (BlockSelector *)smoothStoneSelector); generateBox(level, chunkBB, width - 3, 1, 1, width - 2, 1, 4, false, random, (BlockSelector *)smoothStoneSelector); - generateBox(level, chunkBB, 1, 1, 1, 1, 1, 3, Tile::lava_Id, Tile::lava_Id, false); - generateBox(level, chunkBB, width - 2, 1, 1, width - 2, 1, 3, Tile::lava_Id, Tile::lava_Id, false); + generateBox(level, chunkBB, 1, 1, 1, 1, 1, 3, Tile::flowing_lava_Id, Tile::flowing_lava_Id, false); + generateBox(level, chunkBB, width - 2, 1, 1, width - 2, 1, 3, Tile::flowing_lava_Id, Tile::flowing_lava_Id, false); // portal lava pool generateBox(level, chunkBB, 3, 1, 8, 7, 1, 12, false, random, (BlockSelector *)smoothStoneSelector); - generateBox(level, chunkBB, 4, 1, 9, 6, 1, 11, Tile::lava_Id, Tile::lava_Id, false); + generateBox(level, chunkBB, 4, 1, 9, 6, 1, 11, Tile::flowing_lava_Id, Tile::flowing_lava_Id, false); // wall decorations for (int z = 3; z < depth - 2; z += 2) { - generateBox(level, chunkBB, 0, 3, z, 0, 4, z, Tile::ironFence_Id, Tile::ironFence_Id, false); - generateBox(level, chunkBB, width - 1, 3, z, width - 1, 4, z, Tile::ironFence_Id, Tile::ironFence_Id, false); + generateBox(level, chunkBB, 0, 3, z, 0, 4, z, Tile::iron_bars_Id, Tile::iron_bars_Id, false); + generateBox(level, chunkBB, width - 1, 3, z, width - 1, 4, z, Tile::iron_bars_Id, Tile::iron_bars_Id, false); } for (int x = 2; x < width - 2; x += 2) { - generateBox(level, chunkBB, x, 3, depth - 1, x, 4, depth - 1, Tile::ironFence_Id, Tile::ironFence_Id, false); + generateBox(level, chunkBB, x, 3, depth - 1, x, 4, depth - 1, Tile::iron_bars_Id, Tile::iron_bars_Id, false); } // stair - int orientationData = getOrientationData(Tile::stairs_stoneBrick_Id, 3); + int orientationData = getOrientationData(Tile::stone_brick_stairs_Id, 3); generateBox(level, chunkBB, 4, 1, 5, 6, 1, 7, false, random, (BlockSelector *)smoothStoneSelector); generateBox(level, chunkBB, 4, 2, 6, 6, 2, 7, false, random, (BlockSelector *)smoothStoneSelector); generateBox(level, chunkBB, 4, 3, 7, 6, 3, 7, false, random, (BlockSelector *)smoothStoneSelector); for (int x = 4; x <= 6; x++) { - placeBlock(level, Tile::stairs_stoneBrick_Id, orientationData, x, 1, 4, chunkBB); - placeBlock(level, Tile::stairs_stoneBrick_Id, orientationData, x, 2, 5, chunkBB); - placeBlock(level, Tile::stairs_stoneBrick_Id, orientationData, x, 3, 6, chunkBB); + placeBlock(level, Tile::stone_brick_stairs_Id, orientationData, x, 1, 4, chunkBB); + placeBlock(level, Tile::stone_brick_stairs_Id, orientationData, x, 2, 5, chunkBB); + placeBlock(level, Tile::stone_brick_stairs_Id, orientationData, x, 3, 6, chunkBB); } int north = Direction::NORTH; @@ -1659,18 +1659,18 @@ bool StrongholdPieces::PortalRoom::postProcess(Level *level, Random *random, Bou // 4J-PB - Removed for Christmas update since we don't have The End // 4J-PB - not going to remove it, so that maps generated will have it in, but it can't be activated - placeBlock(level, Tile::endPortalFrameTile_Id, north + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 4, 3, 8, chunkBB); - placeBlock(level, Tile::endPortalFrameTile_Id, north + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 5, 3, 8, chunkBB); - placeBlock(level, Tile::endPortalFrameTile_Id, north + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 6, 3, 8, chunkBB); - placeBlock(level, Tile::endPortalFrameTile_Id, south + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 4, 3, 12, chunkBB); - placeBlock(level, Tile::endPortalFrameTile_Id, south + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 5, 3, 12, chunkBB); - placeBlock(level, Tile::endPortalFrameTile_Id, south + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 6, 3, 12, chunkBB); - placeBlock(level, Tile::endPortalFrameTile_Id, east + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 3, 3, 9, chunkBB); - placeBlock(level, Tile::endPortalFrameTile_Id, east + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 3, 3, 10, chunkBB); - placeBlock(level, Tile::endPortalFrameTile_Id, east + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 3, 3, 11, chunkBB); - placeBlock(level, Tile::endPortalFrameTile_Id, west + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 7, 3, 9, chunkBB); - placeBlock(level, Tile::endPortalFrameTile_Id, west + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 7, 3, 10, chunkBB); - placeBlock(level, Tile::endPortalFrameTile_Id, west + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 7, 3, 11, chunkBB); + placeBlock(level, Tile::end_portal_frame_Id, north + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 4, 3, 8, chunkBB); + placeBlock(level, Tile::end_portal_frame_Id, north + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 5, 3, 8, chunkBB); + placeBlock(level, Tile::end_portal_frame_Id, north + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 6, 3, 8, chunkBB); + placeBlock(level, Tile::end_portal_frame_Id, south + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 4, 3, 12, chunkBB); + placeBlock(level, Tile::end_portal_frame_Id, south + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 5, 3, 12, chunkBB); + placeBlock(level, Tile::end_portal_frame_Id, south + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 6, 3, 12, chunkBB); + placeBlock(level, Tile::end_portal_frame_Id, east + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 3, 3, 9, chunkBB); + placeBlock(level, Tile::end_portal_frame_Id, east + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 3, 3, 10, chunkBB); + placeBlock(level, Tile::end_portal_frame_Id, east + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 3, 3, 11, chunkBB); + placeBlock(level, Tile::end_portal_frame_Id, west + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 7, 3, 9, chunkBB); + placeBlock(level, Tile::end_portal_frame_Id, west + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 7, 3, 10, chunkBB); + placeBlock(level, Tile::end_portal_frame_Id, west + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 7, 3, 11, chunkBB); if (!hasPlacedMobSpawner) @@ -1686,7 +1686,7 @@ bool StrongholdPieces::PortalRoom::postProcess(Level *level, Random *random, Bou level->getLevelData()->setHasStrongholdEndPortal(); hasPlacedMobSpawner = true; - level->setTileAndData(x, y, z, Tile::mobSpawner_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y, z, Tile::mob_spawner_Id, 0, Tile::UPDATE_CLIENTS); shared_ptr entity = dynamic_pointer_cast(level->getTileEntity(x, y, z)); if (entity != nullptr) entity->getSpawner()->setEntityId(L"Silverfish"); } @@ -1700,7 +1700,7 @@ void StrongholdPieces::SmoothStoneSelector::next(Random *random, int worldX, int { if (isEdge) { - nextId = Tile::stoneBrick_Id; + nextId = Tile::stonebrick_Id; float selection = random->nextFloat(); if (selection < 0.2f) @@ -1713,7 +1713,7 @@ void StrongholdPieces::SmoothStoneSelector::next(Random *random, int worldX, int } else if (selection < 0.55f) { - nextId = Tile::monsterStoneEgg_Id; + nextId = Tile::monster_egg_Id; nextData = StoneMonsterTile::HOST_STONEBRICK; } else diff --git a/Minecraft.World/StructurePiece.cpp b/Minecraft.World/StructurePiece.cpp index bb3887c0..d50b951f 100644 --- a/Minecraft.World/StructurePiece.cpp +++ b/Minecraft.World/StructurePiece.cpp @@ -250,7 +250,7 @@ int StructurePiece::getOrientationData( int tile, int data ) } } } - else if ( tile == Tile::door_wood_Id || tile == Tile::door_iron_Id ) + else if ( tile == Tile::wooden_door_Id || tile == Tile::iron_door_Id ) { if ( orientation == Direction::SOUTH ) { @@ -280,7 +280,7 @@ int StructurePiece::getOrientationData( int tile, int data ) return ( data + 3 ) & 3; } } - else if ( tile == Tile::stairs_stone_Id || tile == Tile::stairs_wood_Id || tile == Tile::stairs_netherBricks_Id || tile == Tile::stairs_stoneBrick_Id || tile == Tile::stairs_sandstone_Id) + else if ( tile == Tile::stone_stairs_Id || tile == Tile::oak_stairs_Id || tile == Tile::nether_brick_stairs_Id || tile == Tile::stone_brick_stairs_Id || tile == Tile::sandstone_stairs_Id) { if ( orientation == Direction::SOUTH ) { @@ -437,7 +437,7 @@ int StructurePiece::getOrientationData( int tile, int data ) } } } - else if (tile == Tile::tripWireSource_Id || (Tile::tiles[tile] != nullptr && dynamic_cast(Tile::tiles[tile]))) + else if (tile == Tile::tripwire_hook_Id || (Tile::tiles[tile] != nullptr && dynamic_cast(Tile::tiles[tile]))) { if (orientation == Direction::SOUTH) { @@ -485,7 +485,7 @@ int StructurePiece::getOrientationData( int tile, int data ) } } } - else if (tile == Tile::pistonBase_Id || tile == Tile::pistonStickyBase_Id || tile == Tile::lever_Id || tile == Tile::dispenser_Id) + else if (tile == Tile::piston_Id || tile == Tile::sticky_piston_Id || tile == Tile::lever_Id || tile == Tile::dispenser_Id) { if (orientation == Direction::SOUTH) { @@ -851,6 +851,6 @@ void StructurePiece::createDoor( Level* level, BoundingBox* chunkBB, Random* ran if ( chunkBB->isInside( worldX, worldY, worldZ ) ) { - DoorItem::place( level, worldX, worldY, worldZ, orientation, Tile::door_wood ); + DoorItem::place( level, worldX, worldY, worldZ, orientation, Tile::wooden_door ); } } diff --git a/Minecraft.World/StructureRecipies.cpp b/Minecraft.World/StructureRecipies.cpp index 78454512..54e29580 100644 --- a/Minecraft.World/StructureRecipies.cpp +++ b/Minecraft.World/StructureRecipies.cpp @@ -82,14 +82,14 @@ void StructureRecipies::addRecipes(Recipes *r) L"#Q", // L"Q#", // - L'#', Tile::cobblestone, L'Q', Item::netherQuartz, + L'#', Tile::cobblestone, L'Q', Item::nether_quartz, L'S'); r->addShapedRecipy(new ItemInstance(Tile::stone_Id, 1, StoneTile::GRANITE), // L"sczcig", L"#Q", // - L'#', new ItemInstance(Tile::stone_Id, 1, StoneTile::DIORITE), L'Q', Item::netherQuartz, + L'#', new ItemInstance(Tile::stone_Id, 1, StoneTile::DIORITE), L'Q', Item::nether_quartz, L'S'); r->addShapedRecipy(new ItemInstance(Tile::stone_Id, 2, StoneTile::ANDESITE), // @@ -164,7 +164,7 @@ void StructureRecipies::addRecipes(Recipes *r) L"#E#", // L"###", // - L'#', Tile::obsidian, L'E', Item::eyeOfEnder, + L'#', Tile::obsidian, L'E', Item::eye_of_ender, L'S'); r->addShapedRecipy(new ItemInstance(Tile::stoneBrick, 4), // @@ -197,15 +197,15 @@ void StructureRecipies::addRecipes(Recipes *r) L'S'); // 4J Stu - Move this into "Recipes" to change the order things are displayed on the crafting menu - //r->addShapedRecipy(new ItemInstance(Tile::ironFence, 16), // + //r->addShapedRecipy(new ItemInstance(Tile::iron_bars, 16), // // L"sscig", // L"###", // // L"###", // - // L'#', Item::ironIngot, + // L'#', Item::iron_ingot, // L'S'); - r->addShapedRecipy(new ItemInstance(Tile::thinGlass, 16), // + r->addShapedRecipy(new ItemInstance(Tile::glass_pane, 16), // L"ssctg", L"###", // L"###", // @@ -225,7 +225,7 @@ for (int i = 0; i < 16; i++) L"#X#", L"###", L'#', new ItemInstance(Tile::glass), - L'X', new ItemInstance(Item::dye_powder, 1, i), + L'X', new ItemInstance(Item::dye, 1, i), L'D'); r->addShapedRecipy(new ItemInstance(Tile::stained_glass_pane, 16, ColoredTile::getItemAuxValueForTileData(i)), L"ssczg", @@ -243,7 +243,7 @@ for (int i = 0; i < 16; i++) L"#X#", L"###", L'#', new ItemInstance(Tile::glass), - L'X', new ItemInstance(Item::dye_powder, 1, i), + L'X', new ItemInstance(Item::dye, 1, i), L'D'); r->addShapedRecipy(new ItemInstance(Tile::stained_glass_pane, 16, ColoredTile::getItemAuxValueForTileData(i)), L"ssczg", @@ -266,7 +266,7 @@ for (int i = 0; i < 16; i++) L" R ", // L"RGR", // L" R ", // - L'R', Item::redStone, 'G', Tile::glowstone, + L'R', Item::redstone, 'G', Tile::glowstone, L'M'); r->addShapedRecipy(new ItemInstance(Tile::beacon, 1), // @@ -275,6 +275,6 @@ for (int i = 0; i < 16; i++) L"GSG", // L"OOO", // - L'G', Tile::glass, L'S', Item::netherStar, L'O', Tile::obsidian, + L'G', Tile::glass, L'S', Item::nether_star, L'O', Tile::obsidian, L'M'); } \ No newline at end of file diff --git a/Minecraft.World/SwampBiome.cpp b/Minecraft.World/SwampBiome.cpp index a7a0f489..be7580c4 100644 --- a/Minecraft.World/SwampBiome.cpp +++ b/Minecraft.World/SwampBiome.cpp @@ -40,12 +40,12 @@ void SwampBiome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunk int index = (localZ * 16 + localX) * Level::genDepth + y; if (chunkBlocks[index] != 0) { - if (y == 62 && chunkBlocks[index] != static_cast(Tile::water_Id)) + if (y == 62 && chunkBlocks[index] != static_cast(Tile::flowing_water_Id)) { - chunkBlocks[index] = static_cast(Tile::water_Id); + chunkBlocks[index] = static_cast(Tile::flowing_water_Id); if (d0 < 0.12) { - chunkBlocks[index + 1] = static_cast(Tile::waterLily_Id); + chunkBlocks[index + 1] = static_cast(Tile::waterlily_Id); } } break; diff --git a/Minecraft.World/SwampBiome.h b/Minecraft.World/SwampBiome.h index 7108602c..90befc2e 100644 --- a/Minecraft.World/SwampBiome.h +++ b/Minecraft.World/SwampBiome.h @@ -15,7 +15,7 @@ public: public: virtual Feature *getTreeFeature(Random *random); virtual void buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, int x, int z, double noiseVal) override; - virtual Feature* getFlowerFeature(Random* random, int x, int y, int z) override{return new FlowerFeature(Tile::rose_Id, Rose::BLUE_ORCHID);} + virtual Feature* getFlowerFeature(Random* random, int x, int y, int z) override{return new FlowerFeature(Tile::red_flower_Id, Rose::BLUE_ORCHID);} // 4J Stu - Not using these any more //virtual int getGrassColor(); //virtual int getFolageColor(); diff --git a/Minecraft.World/SwampTreeFeature.cpp b/Minecraft.World/SwampTreeFeature.cpp index 5b94767a..f0b7270a 100644 --- a/Minecraft.World/SwampTreeFeature.cpp +++ b/Minecraft.World/SwampTreeFeature.cpp @@ -39,7 +39,7 @@ bool SwampTreeFeature::place(Level *level, Random *random, int x, int y, int z) int tt = level->getTile(xx, yy, zz); if (tt != 0 && tt != Tile::leaves_Id) { - if (tt == Tile::calmWater_Id || tt == Tile::water_Id) + if (tt == Tile::water_Id || tt == Tile::flowing_water_Id) { if (yy > y) free = false; } @@ -83,7 +83,7 @@ bool SwampTreeFeature::place(Level *level, Random *random, int x, int y, int z) for (int hh = 0; hh < treeHeight; hh++) { int t = level->getTile(x, y + hh, z); - if (t == 0 || t == Tile::leaves_Id || t == Tile::water_Id || t == Tile::calmWater_Id) placeBlock(level, x, y + hh, z, Tile::treeTrunk_Id); + if (t == 0 || t == Tile::leaves_Id || t == Tile::flowing_water_Id || t == Tile::water_Id) placeBlock(level, x, y + hh, z, Tile::log_Id); } for (int yy = y - 3 + treeHeight; yy <= y + treeHeight; yy++) diff --git a/Minecraft.World/TaigaBiome.cpp b/Minecraft.World/TaigaBiome.cpp index 7e9d9e58..5db734e0 100644 --- a/Minecraft.World/TaigaBiome.cpp +++ b/Minecraft.World/TaigaBiome.cpp @@ -53,7 +53,7 @@ void TaigaBiome::decorate(Level *level, Random *random, int xo, int zo) { if (type == 1 || type == 2) { - BlockBlobFeature mossyBoulder(Tile::mossyCobblestone_Id, 0); + BlockBlobFeature mossyBoulder(Tile::mossy_cobblestone_Id, 0); int count = random->nextInt(3); for (int i = 0; i < count; ++i) { diff --git a/Minecraft.World/TallGrass.cpp b/Minecraft.World/TallGrass.cpp index 943d9e1d..88e9a7a9 100644 --- a/Minecraft.World/TallGrass.cpp +++ b/Minecraft.World/TallGrass.cpp @@ -19,6 +19,32 @@ TallGrass::TallGrass(int id) : Bush(id, Material::replaceable_plant) this->updateDefaultShape(); } +void TallGrass::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TallGrass::defaultBlockState() +{ + return 0; +} + +int TallGrass::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x3) : 0; +} + +Tile::BlockState TallGrass::getBlockState(int data) +{ + return Tile::BlockState(data & 0x3); +} + +Tile::BlockState TallGrass::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x3); +} + // 4J Added override void TallGrass::updateDefaultShape() { @@ -68,7 +94,7 @@ int TallGrass::getColor(LevelSource *level, int x, int y, int z, int data) int TallGrass::getResource(int data, Random *random, int playerBonusLevel) { if (random->nextInt(8) == 0) { - return Item::seeds_wheat->id; + return Item::wheat_seeds->id; } return -1; diff --git a/Minecraft.World/TallGrass.h b/Minecraft.World/TallGrass.h index 9b4c5515..53583e9e 100644 --- a/Minecraft.World/TallGrass.h +++ b/Minecraft.World/TallGrass.h @@ -25,6 +25,11 @@ protected: public: virtual void updateDefaultShape(); // 4J Added override + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual Icon *getTexture(int face, int data); virtual int getColor(int auxData); diff --git a/Minecraft.World/TallGrass2.cpp b/Minecraft.World/TallGrass2.cpp index e9998c21..3a9c2aae 100644 --- a/Minecraft.World/TallGrass2.cpp +++ b/Minecraft.World/TallGrass2.cpp @@ -7,11 +7,18 @@ #include "net.minecraft.h" #include "../Minecraft.Client/Minecraft.h" #include "net.minecraft.stats.h" +#include "net.minecraft.world.item.enchantment.h" +#include "net.minecraft.world.food.h" +#include +#include +// fireblade: somewhat of a hacky way to fix the tutorial world sunflowers +// but essentially the sunflowers are incredibly glitchy and i have no way to fix them except by doing this +static std::map, int> s_tallGrass2DestroyCache; // tranq please i beg you make sure the ids are correct so we dont get corrupted worlds from people static const int TILE_IDS[TallGrass2::VARIANT_COUNT] = { - IDS_TILE_SUNFLOWER, // 0 - Sunflower, not implemented yet + IDS_TILE_SUNFLOWER, // 0 - Sunflower IDS_TILE_LILAC, // 1 - Lilac IDS_TILE_DOUBLE_TALL_GRASS, // 2 - Tall Grass IDS_TILE_LARGE_FERN, // 3 - Large Fern @@ -20,7 +27,7 @@ static const int TILE_IDS[TallGrass2::VARIANT_COUNT] = { }; static const int DESCRIPTION_IDS[TallGrass2::VARIANT_COUNT] = { - IDS_DESC_SUNFLOWER, // 0 - Sunflower, not implemented yet + IDS_DESC_SUNFLOWER, // 0 - Sunflower IDS_DESC_LILAC, // 1 - Lilac IDS_DESC_DOUBLE_TALL_GRASS, // 2 - Tall Grass IDS_DESC_LARGE_FERN, // 3 - Large Fern @@ -30,7 +37,7 @@ static const int DESCRIPTION_IDS[TallGrass2::VARIANT_COUNT] = { static const wstring TEXTURE_BOTTOM[TallGrass2::VARIANT_COUNT] = { - L"tallgrass2_tall_grass_lower", // Sunflower, not implemented yet + L"tallgrass2_sunflower_lower", L"tallgrass2_lilac_lower", L"tallgrass2_tall_grass_lower", L"tallgrass2_large_fern_lower", @@ -39,7 +46,25 @@ static const wstring TEXTURE_BOTTOM[TallGrass2::VARIANT_COUNT] = { }; static const wstring TEXTURE_TOP[TallGrass2::VARIANT_COUNT] = { - L"tallgrass2_tall_grass_upper", // Sunflower, not implemented yet + L"tallgrass2_sunflower_upper", + L"tallgrass2_lilac_upper", + L"tallgrass2_tall_grass_upper", + L"tallgrass2_large_fern_upper", + L"tallgrass2_rose_bush_upper", + L"tallgrass2_peony_upper" +}; + +static const wstring TEXTURE_HEAD_FRONT[TallGrass2::VARIANT_COUNT] = { + L"tallgrass2_sunflower_head_front", + L"tallgrass2_lilac_upper", + L"tallgrass2_tall_grass_upper", + L"tallgrass2_large_fern_upper", + L"tallgrass2_rose_bush_upper", + L"tallgrass2_peony_upper" +}; + +static const wstring TEXTURE_HEAD_BACK[TallGrass2::VARIANT_COUNT] = { + L"tallgrass2_sunflower_head_back", L"tallgrass2_lilac_upper", L"tallgrass2_tall_grass_upper", L"tallgrass2_large_fern_upper", @@ -53,6 +78,37 @@ TallGrass2::TallGrass2(int id) : Bush(id, Material::replaceable_plant) this->updateDefaultShape(); } +void TallGrass2::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TallGrass2::defaultBlockState() +{ + return 0; +} + +int TallGrass2::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState TallGrass2::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState TallGrass2::getBlockState(LevelSource* level, int x, int y, int z) +{ + int data = level->getData(x, y, z) & 0xF; + if ((data & UPPER_BIT) != 0 && level->getTile(x, y - 1, z) == id) + { + data = (level->getData(x, y - 1, z) & ~UPPER_BIT) | UPPER_BIT; + } + return Tile::BlockState(data); +} + void TallGrass2::updateDefaultShape() { @@ -79,9 +135,12 @@ void TallGrass2::registerIcons(IconRegister* iconRegister) { iconBottom[i] = iconRegister->registerIcon(TEXTURE_BOTTOM[i]); iconTop[i] = iconRegister->registerIcon(TEXTURE_TOP[i]); + iconHeadFront[i] = iconRegister->registerIcon(TEXTURE_HEAD_FRONT[i]); + iconHeadBack[i] = iconRegister->registerIcon(TEXTURE_HEAD_BACK[i]); } - icon = iconTop[TALL_GRASS]; + // sunflower item + icon = iconHeadFront[SUNFLOWER] != nullptr ? iconHeadFront[SUNFLOWER] : iconTop[SUNFLOWER]; } @@ -100,7 +159,12 @@ Icon* TallGrass2::getTexture(LevelSource* level, int x, int y, int z, int face) { int data = level->getData(x, y, z); bool isUpper = (data & UPPER_BIT) != 0; - int variant = data & ~UPPER_BIT; + int variantData = data; + if (isUpper && level->getTile(x, y - 1, z) == id) + { + variantData = level->getData(x, y - 1, z); + } + int variant = variantData & ~UPPER_BIT; if (variant < 0 || variant >= VARIANT_COUNT) variant = 0; return isUpper ? iconTop[variant] : iconBottom[variant]; } @@ -109,11 +173,14 @@ Icon* TallGrass2::getTexture(LevelSource* level, int x, int y, int z, int face) int TallGrass2::getVariant(LevelSource* level, int x, int y, int z) { int data = level->getData(x, y, z); - bool isUpper = (data & UPPER_BIT) != 0; - int lowerData = isUpper ? level->getData(x, y - 1, z) : data; - int variant = lowerData & ~UPPER_BIT; - if (variant < 0 || variant >= VARIANT_COUNT) variant = 0; - return variant; + int variantData = data; + + if ((data & UPPER_BIT) != 0 && level->getTile(x, y - 1, z) == id) + { + variantData = level->getData(x, y - 1, z); + } + + return variantData & 0xF; } @@ -137,7 +204,12 @@ int TallGrass2::getColor(LevelSource* level, int x, int y, int z) int TallGrass2::getColor(LevelSource* level, int x, int y, int z, int data) { - int variant = data & ~UPPER_BIT; + int variantData = data; + if ((data & UPPER_BIT) != 0 && level->getTile(x, y - 1, z) == id) + { + variantData = level->getData(x, y - 1, z); + } + int variant = variantData & ~UPPER_BIT; if (variant < 0 || variant >= VARIANT_COUNT) variant = 0; if (!isGrassColored(variant)) return 0xFFFFFF; return level->getBiome(x, z)->getGrassColor(); @@ -151,6 +223,7 @@ bool TallGrass2::mayPlace(Level* level, int x, int y, int z) && level->getTile(x, y, z) == 0 && level->getTile(x, y + 1, z) == 0; } + void TallGrass2::finalizePlacement(Level* level, int x, int y, int z, int data) { if ((data & UPPER_BIT) != 0) return; @@ -169,7 +242,6 @@ void TallGrass2::onPlace(Level* level, int x, int y, int z) level->setTilesDirty(x - 1, y - 1, z - 1, x + 1, y + 2, z + 1); } - bool TallGrass2::canSurvive(Level* level, int x, int y, int z) { int data = level->getData(x, y, z); @@ -186,22 +258,44 @@ void TallGrass2::neighborChanged(Level* level, int x, int y, int z, int type) { int data = level->getData(x, y, z); bool isUpper = (data & UPPER_BIT) != 0; + int variant = data & ~UPPER_BIT; if (!isUpper) { int upperTileId = level->getTile(x, y + 1, z); if (!canSurvive(level, x, y, z) || (upperTileId != id)) { - spawnResources(level, x, y, z, data, 0); + if (variant != SUNFLOWER) + { + spawnResources(level, x, y, z, data, 0); + } level->setTileAndData(x, y, z, 0, 0, Tile::UPDATE_CLIENTS); if (upperTileId == id) level->removeTile(x, y + 1, z); } + else + { + int expectedUpperData = variant | UPPER_BIT; + int upperData = level->getData(x, y + 1, z) & 0xF; + if (upperData != expectedUpperData) + { + level->setData(x, y + 1, z, expectedUpperData, Tile::UPDATE_CLIENTS, true); + } + } } else { if (level->getTile(x, y - 1, z) != id) level->removeTile(x, y, z); + else + { + int expectedUpperData = (level->getData(x, y - 1, z) & ~UPPER_BIT) | UPPER_BIT; + int selfData = data & 0xF; + if (selfData != expectedUpperData) + { + level->setData(x, y, z, expectedUpperData, Tile::UPDATE_CLIENTS, true); + } + } } } @@ -220,13 +314,37 @@ void TallGrass2::tick(Level* level, int x, int y, int z, Random* random) if (upperTileId == id) level->removeTile(x, y + 1, z); } + else + { + int expectedUpperData = (data & ~UPPER_BIT) | UPPER_BIT; + int upperData = level->getData(x, y + 1, z) & 0xF; + if (upperData != expectedUpperData) + { + level->setData(x, y + 1, z, expectedUpperData, Tile::UPDATE_CLIENTS, true); + } + } } } int TallGrass2::getResource(int data, Random* random, int playerBonusLevel) { - return -1; + (void)playerBonusLevel; + if ((data & UPPER_BIT) != 0) return -1; + + int variant = data & ~UPPER_BIT; + if (variant < 0 || variant >= VARIANT_COUNT) variant = 0; + + if (variant == TALL_GRASS || variant == LARGE_FERN) + { + if (random->nextInt(8) == 0) + { + return Item::wheat_seeds->id; + } + return -1; + } + + return Tile::double_plant_Id; } int TallGrass2::getResourceCountForLootBonus(int bonusLevel, Random* random) @@ -234,6 +352,11 @@ int TallGrass2::getResourceCountForLootBonus(int bonusLevel, Random* random) return 1; } +int TallGrass2::getSpawnResourcesAuxValue(int data) +{ + return data & ~UPPER_BIT; +} + bool TallGrass2::isSilkTouchable() { return true; @@ -248,42 +371,130 @@ shared_ptr TallGrass2::getSilkTouchItemInstance(int data) void TallGrass2::playerDestroy(Level* level, shared_ptr player, int x, int y, int z, int data) { - if (!level->isClientSide - && player->getSelectedItem() != nullptr - && player->getSelectedItem()->id == Item::shears->id) - { - player->awardStat( - GenericStats::blocksMined(id), - GenericStats::param_blocksMined(id, data, 1)); + int resolvedVariant; + bool isUpper = (data & UPPER_BIT) != 0; + int resolvedX = x; + int resolvedY = y; + int resolvedZ = z; + int resolvedData = data; - if ((data & UPPER_BIT) == 0) - { - int variant = data & ~UPPER_BIT; - popResource(level, x, y, z, std::make_shared(this, 1, variant)); - } - } - else - { + if (isUpper) + { + int lowerTileId = level->getTile(x, y - 1, z); + auto cacheKey = std::make_tuple(level, x, y, z); + auto cacheIt = s_tallGrass2DestroyCache.find(cacheKey); + if (lowerTileId == id) + { + resolvedVariant = level->getData(x, y - 1, z) & ~UPPER_BIT; + resolvedData = level->getData(x, y - 1, z) & ~UPPER_BIT; + resolvedY = y - 1; + if (cacheIt != s_tallGrass2DestroyCache.end()) + s_tallGrass2DestroyCache.erase(cacheIt); + } + else if (cacheIt != s_tallGrass2DestroyCache.end()) + { + resolvedVariant = cacheIt->second; + resolvedData = cacheIt->second; + resolvedY = y - 1; + s_tallGrass2DestroyCache.erase(cacheIt); + } + else + { + resolvedVariant = data & ~UPPER_BIT; + resolvedData = data & ~UPPER_BIT; + } + } + else + { + resolvedVariant = data & ~UPPER_BIT; + } - Tile::playerDestroy(level, player, x, y, z, data); - } + if (resolvedVariant < 0 || resolvedVariant >= VARIANT_COUNT) resolvedVariant = 0; + + if (isUpper && resolvedVariant != SUNFLOWER) + { + return; + } + + if (resolvedVariant != TALL_GRASS && resolvedVariant != LARGE_FERN) + { + if (!level->isClientSide && !player->abilities.instabuild) + { + player->awardStat( + GenericStats::blocksMined(id), + GenericStats::param_blocksMined(id, resolvedData, 1)); + popResource(level, resolvedX, resolvedY, resolvedZ, std::make_shared(this, 1, resolvedVariant)); + } + return; + } + + if (!level->isClientSide + && player->getSelectedItem() != nullptr + && player->getSelectedItem()->id == Item::shears->id) + { + player->awardStat( + GenericStats::blocksMined(id), + GenericStats::param_blocksMined(id, resolvedData, 1)); + + if ((resolvedData & UPPER_BIT) == 0) + { + popResource(level, resolvedX, resolvedY, resolvedZ, std::make_shared(this, 1, resolvedVariant)); + } + } + else + { + player->awardStat( + GenericStats::blocksMined(id), + GenericStats::param_blocksMined(id, resolvedData, 1)); + player->awardStat(GenericStats::totalBlocksMined(), GenericStats::param_noArgs()); + player->causeFoodExhaustion(FoodConstants::EXHAUSTION_MINE); + + if (id == Tile::log_Id || id == Tile::log2_Id) + player->awardStat(GenericStats::mineWood(), GenericStats::param_noArgs()); + + if (isSilkTouchable() && EnchantmentHelper::hasSilkTouch(player)) + { + shared_ptr item = getSilkTouchItemInstance(resolvedData); + if (item != nullptr) + { + popResource(level, resolvedX, resolvedY, resolvedZ, item); + } + } + else + { + int playerBonusLevel = EnchantmentHelper::getDiggingLootBonus(player); + spawnResources(level, resolvedX, resolvedY, resolvedZ, resolvedData, playerBonusLevel); + } + } } void TallGrass2::playerWillDestroy(Level* level, int x, int y, int z, int data, shared_ptr player) { - if (player->abilities.instabuild) - { - if ((data & UPPER_BIT) != 0) - { - if (level->getTile(x, y - 1, z) == id) - level->removeTile(x, y - 1, z); - } - else - { - if (level->getTile(x, y + 1, z) == id) - level->removeTile(x, y + 1, z); - } - } + auto cacheKey = std::make_tuple(level, x, y, z); + s_tallGrass2DestroyCache.erase(cacheKey); + + if ((data & UPPER_BIT) != 0) + { + if (level->getTile(x, y - 1, z) == id) + { + int lowerData = level->getData(x, y - 1, z) & ~UPPER_BIT; + s_tallGrass2DestroyCache[cacheKey] = lowerData; + } + } + + if (player->abilities.instabuild) + { + if ((data & UPPER_BIT) != 0) + { + if (level->getTile(x, y - 1, z) == id) + level->removeTile(x, y - 1, z); + } + else + { + if (level->getTile(x, y + 1, z) == id) + level->removeTile(x, y + 1, z); + } + } } int TallGrass2::cloneTileData(Level* level, int x, int y, int z) diff --git a/Minecraft.World/TallGrass2.h b/Minecraft.World/TallGrass2.h index 1be2f485..7c890de3 100644 --- a/Minecraft.World/TallGrass2.h +++ b/Minecraft.World/TallGrass2.h @@ -18,15 +18,24 @@ public: private: Icon* iconBottom[VARIANT_COUNT]; Icon* iconTop[VARIANT_COUNT]; + Icon* iconHeadFront[VARIANT_COUNT]; + Icon* iconHeadBack[VARIANT_COUNT]; protected: TallGrass2(int id); public: virtual void updateDefaultShape() override; + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource* level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual Icon* getTexture(int face, int data) override; virtual Icon* getTexture(LevelSource* level, int x, int y, int z, int face) override; virtual void registerIcons(IconRegister* iconRegister) override; + Icon* getSunflowerHeadFrontIcon() const { return iconHeadFront[SUNFLOWER]; } + Icon* getSunflowerHeadBackIcon() const { return iconHeadBack[SUNFLOWER]; } virtual int getRenderShape() override; virtual bool blocksLight() override; virtual bool isSolidRender(bool isServerLevel = false) override; @@ -46,6 +55,7 @@ public: virtual int getResource(int data, Random* random, int playerBonusLevel) override; virtual int getResourceCountForLootBonus(int bonusLevel, Random* random) override; + virtual int getSpawnResourcesAuxValue(int data) override; virtual void playerDestroy(Level* level, shared_ptr player, int x, int y, int z, int data) override; virtual void playerWillDestroy(Level* level, int x, int y, int z, int data, shared_ptr player) override; diff --git a/Minecraft.World/TheEndBiomeDecorator.cpp b/Minecraft.World/TheEndBiomeDecorator.cpp index 2b80bcfc..f744f700 100644 --- a/Minecraft.World/TheEndBiomeDecorator.cpp +++ b/Minecraft.World/TheEndBiomeDecorator.cpp @@ -33,8 +33,8 @@ TheEndBiomeDecorator::SPIKE TheEndBiomeDecorator::SpikeValA[8]= TheEndBiomeDecorator::TheEndBiomeDecorator(Biome *biome) : BiomeDecorator(biome) { - spikeFeature = new SpikeFeature(Tile::endStone_Id); - endPodiumFeature = new EndPodiumFeature(Tile::endStone_Id); + spikeFeature = new SpikeFeature(Tile::end_stone_Id); + endPodiumFeature = new EndPodiumFeature(Tile::end_stone_Id); } void TheEndBiomeDecorator::decorate() diff --git a/Minecraft.World/TheEndLevelRandomLevelSource.cpp b/Minecraft.World/TheEndLevelRandomLevelSource.cpp index 3b42f8ca..aa10d5fd 100644 --- a/Minecraft.World/TheEndLevelRandomLevelSource.cpp +++ b/Minecraft.World/TheEndLevelRandomLevelSource.cpp @@ -86,7 +86,7 @@ void TheEndLevelRandomLevelSource::prepareHeights(int xOffs, int zOffs, byteArra int tileId = 0; if (val > 0) { - tileId = Tile::endStone_Id; + tileId = Tile::end_stone_Id; } else { } @@ -119,8 +119,8 @@ void TheEndLevelRandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray int runDepth = 1; int run = -1; - byte top = (byte) Tile::endStone_Id; - byte material = (byte) Tile::endStone_Id; + byte top = (byte) Tile::end_stone_Id; + byte material = (byte) Tile::end_stone_Id; for (int y = Level::genDepthMinusOne; y >= 0; y--) { @@ -139,7 +139,7 @@ void TheEndLevelRandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray if (runDepth <= 0) { top = 0; - material = static_cast(Tile::endStone_Id); + material = static_cast(Tile::end_stone_Id); } run = runDepth; @@ -320,10 +320,10 @@ void TheEndLevelRandomLevelSource::calcWaterDepths(ChunkSource *parent, int xt, if (level->getHeightmap(xp - 1, zp) > 0 || level->getHeightmap(xp + 1, zp) > 0 || level->getHeightmap(xp, zp - 1) > 0 || level->getHeightmap(xp, zp + 1) > 0) { bool hadWater = false; - if (hadWater || (level->getTile(xp - 1, y, zp) == Tile::calmWater_Id && level->getData(xp - 1, y, zp) < 7)) hadWater = true; - if (hadWater || (level->getTile(xp + 1, y, zp) == Tile::calmWater_Id && level->getData(xp + 1, y, zp) < 7)) hadWater = true; - if (hadWater || (level->getTile(xp, y, zp - 1) == Tile::calmWater_Id && level->getData(xp, y, zp - 1) < 7)) hadWater = true; - if (hadWater || (level->getTile(xp, y, zp + 1) == Tile::calmWater_Id && level->getData(xp, y, zp + 1) < 7)) hadWater = true; + if (hadWater || (level->getTile(xp - 1, y, zp) == Tile::water_Id && level->getData(xp - 1, y, zp) < 7)) hadWater = true; + if (hadWater || (level->getTile(xp + 1, y, zp) == Tile::water_Id && level->getData(xp + 1, y, zp) < 7)) hadWater = true; + if (hadWater || (level->getTile(xp, y, zp - 1) == Tile::water_Id && level->getData(xp, y, zp - 1) < 7)) hadWater = true; + if (hadWater || (level->getTile(xp, y, zp + 1) == Tile::water_Id && level->getData(xp, y, zp + 1) < 7)) hadWater = true; if (hadWater) { for (int x2 = -5; x2 <= 5; x2++) @@ -335,7 +335,7 @@ void TheEndLevelRandomLevelSource::calcWaterDepths(ChunkSource *parent, int xt, if (d <= 5) { d = 6 - d; - if (level->getTile(xp + x2, y, zp + z2) == Tile::calmWater_Id) + if (level->getTile(xp + x2, y, zp + z2) == Tile::water_Id) { int od = level->getData(xp + x2, y, zp + z2); if (od < 7 && od < d) @@ -348,10 +348,10 @@ void TheEndLevelRandomLevelSource::calcWaterDepths(ChunkSource *parent, int xt, } if (hadWater) { - level->setTileAndData(xp, y, zp, Tile::calmWater_Id, 7, Tile::UPDATE_CLIENTS); + level->setTileAndData(xp, y, zp, Tile::water_Id, 7, Tile::UPDATE_CLIENTS); for (int y2 = 0; y2 < y; y2++) { - level->setTileAndData(xp, y2, zp, Tile::calmWater_Id, 8, Tile::UPDATE_CLIENTS); + level->setTileAndData(xp, y2, zp, Tile::water_Id, 8, Tile::UPDATE_CLIENTS); } } } diff --git a/Minecraft.World/TheEndPortalFrameTile.cpp b/Minecraft.World/TheEndPortalFrameTile.cpp index 80e78f49..96aafca2 100644 --- a/Minecraft.World/TheEndPortalFrameTile.cpp +++ b/Minecraft.World/TheEndPortalFrameTile.cpp @@ -13,6 +13,32 @@ TheEndPortalFrameTile::TheEndPortalFrameTile(int id) : Tile(id, Material::glass, iconEye = nullptr; } +void TheEndPortalFrameTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TheEndPortalFrameTile::defaultBlockState() +{ + return 0; +} + +int TheEndPortalFrameTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0x7) : 0; +} + +Tile::BlockState TheEndPortalFrameTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0x7); +} + +Tile::BlockState TheEndPortalFrameTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0x7); +} + Icon *TheEndPortalFrameTile::getTexture(int face, int data) { if (face == Facing::UP) diff --git a/Minecraft.World/TheEndPortalFrameTile.h b/Minecraft.World/TheEndPortalFrameTile.h index d3119d00..b092d459 100644 --- a/Minecraft.World/TheEndPortalFrameTile.h +++ b/Minecraft.World/TheEndPortalFrameTile.h @@ -13,6 +13,11 @@ private: public: TheEndPortalFrameTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; virtual Icon *getTexture(int face, int data); void registerIcons(IconRegister *iconRegister); Icon *getEye(); diff --git a/Minecraft.World/ThinFenceTile.cpp b/Minecraft.World/ThinFenceTile.cpp index 65638ef6..e2da300b 100644 --- a/Minecraft.World/ThinFenceTile.cpp +++ b/Minecraft.World/ThinFenceTile.cpp @@ -5,6 +5,7 @@ ThinFenceTile::ThinFenceTile(int id, const wstring &tex, const wstring &edgeTex, Material *material, bool dropsResources) : Tile(id, material,isSolidRender()) { + setLightBlock(0); iconSide = nullptr; edgeTexture = edgeTex; this->dropsResources = dropsResources; diff --git a/Minecraft.World/Throwable.cpp b/Minecraft.World/Throwable.cpp index 08e40aa6..4d754f28 100644 --- a/Minecraft.World/Throwable.cpp +++ b/Minecraft.World/Throwable.cpp @@ -206,7 +206,7 @@ void Throwable::tick() if (res != nullptr) { - if ( (res->type == HitResult::TILE) && (level->getTile(res->x, res->y, res->z) == Tile::portalTile_Id) ) + if ( (res->type == HitResult::TILE) && (level->getTile(res->x, res->y, res->z) == Tile::portal_Id) ) { handleInsidePortal(); } diff --git a/Minecraft.World/Tile.cpp b/Minecraft.World/Tile.cpp index 28bdd939..f7840344 100644 --- a/Minecraft.World/Tile.cpp +++ b/Minecraft.World/Tile.cpp @@ -34,6 +34,7 @@ Tile::SoundType *Tile::SOUND_WOOD = nullptr; Tile::SoundType *Tile::SOUND_GRAVEL = nullptr; Tile::SoundType *Tile::SOUND_GRASS = nullptr; Tile::SoundType *Tile::SOUND_STONE = nullptr; +Tile::SoundType *Tile::SOUND_SLIME = nullptr; Tile::SoundType *Tile::SOUND_METAL = nullptr; Tile::SoundType *Tile::SOUND_GLASS = nullptr; Tile::SoundType *Tile::SOUND_CLOTH = nullptr; @@ -68,6 +69,7 @@ Tile *Tile::sand = nullptr; Tile *Tile::gravel = nullptr; Tile *Tile::goldOre = nullptr; Tile *Tile::ironOre = nullptr; +Tile *Tile::slimeBlock = nullptr; Tile *Tile::coalOre = nullptr; Tile *Tile::treeTrunk = nullptr; LeafTile *Tile::leaves = nullptr; @@ -82,14 +84,14 @@ Tile *Tile::noteblock = nullptr; Tile *Tile::bed = nullptr; Tile *Tile::goldenRail = nullptr; Tile *Tile::detectorRail = nullptr; -PistonBaseTile *Tile::pistonStickyBase = nullptr; +PistonBaseTile *Tile::sticky_piston = nullptr; Tile *Tile::web = nullptr; TallGrass *Tile::tallgrass = nullptr; DeadBushTile *Tile::deadBush = nullptr; PistonBaseTile *Tile::pistonBase = nullptr; -PistonExtensionTile *Tile::pistonExtension = nullptr; -Tile *Tile::wool = nullptr; PistonMovingPiece *Tile::pistonMovingPiece = nullptr; +Tile *Tile::wool = nullptr; +PistonExtensionTile *Tile::pistonExtension = nullptr; Bush *Tile::flower = nullptr; Bush *Tile::rose = nullptr; Bush *Tile::mushroom_brown = nullptr; @@ -117,17 +119,17 @@ Tile *Tile::farmland = nullptr; Tile *Tile::furnace = nullptr; Tile *Tile::furnace_lit = nullptr; Tile *Tile::sign = nullptr; -Tile *Tile::door_wood = nullptr; +Tile *Tile::wooden_door = nullptr; Tile *Tile::ladder = nullptr; Tile *Tile::rail = nullptr; Tile *Tile::stairs_stone = nullptr; Tile *Tile::wallSign = nullptr; Tile *Tile::lever = nullptr; Tile *Tile::pressurePlate_stone = nullptr; -Tile *Tile::door_iron = nullptr; +Tile *Tile::iron_door = nullptr; Tile *Tile::pressurePlate_wood = nullptr; Tile *Tile::redStoneOre = nullptr; -Tile *Tile::redStoneOre_lit = nullptr; +Tile *Tile::lit_redstone_ore = nullptr; Tile *Tile::redstoneTorch_off = nullptr; Tile *Tile::redstoneTorch_on = nullptr; Tile *Tile::button = nullptr; @@ -146,36 +148,36 @@ Tile *Tile::glowstone = nullptr; PortalTile *Tile::portalTile = nullptr; Tile *Tile::litPumpkin = nullptr; Tile *Tile::cake = nullptr; -RepeaterTile *Tile::diode_off = nullptr; -RepeaterTile *Tile::diode_on = nullptr; +RepeaterTile *Tile::unpowered_repeater = nullptr; +RepeaterTile *Tile::powered_repeater = nullptr; Tile *Tile::stained_glass = nullptr; Tile *Tile::trapdoor = nullptr; -Tile *Tile::monsterStoneEgg = nullptr; +Tile *Tile::monster_egg = nullptr; Tile *Tile::stoneBrick = nullptr; -Tile *Tile::hugeMushroom_brown = nullptr; -Tile *Tile::hugeMushroom_red = nullptr; -Tile *Tile::ironFence = nullptr; -Tile *Tile::thinGlass = nullptr; +Tile *Tile::brown_mushroom_block = nullptr; +Tile *Tile::red_mushroom_block = nullptr; +Tile *Tile::iron_bars = nullptr; +Tile *Tile::glass_pane = nullptr; Tile *Tile::melon = nullptr; -Tile *Tile::pumpkinStem = nullptr; -Tile *Tile::melonStem = nullptr; +Tile *Tile::pumpkin_stem = nullptr; +Tile *Tile::melon_stem = nullptr; Tile *Tile::vine = nullptr; Tile *Tile::fenceGate = nullptr; Tile *Tile::stairs_bricks = nullptr; -Tile *Tile::stairs_stoneBrickSmooth = nullptr; +Tile *Tile::stone_brick_stairsSmooth = nullptr; MycelTile *Tile::mycel = nullptr; Tile *Tile::waterLily = nullptr; Tile *Tile::netherBrick = nullptr; Tile *Tile::netherFence = nullptr; -Tile *Tile::stairs_netherBricks = nullptr; +Tile *Tile::nether_brick_stairs = nullptr; Tile *Tile::netherStalk = nullptr; Tile *Tile::enchantTable = nullptr; Tile *Tile::brewingStand = nullptr; CauldronTile *Tile::cauldron = nullptr; -Tile *Tile::endPortalTile = nullptr; -Tile *Tile::endPortalFrameTile = nullptr; +Tile *Tile::end_portal = nullptr; +Tile *Tile::end_portal_frame = nullptr; Tile *Tile::endStone = nullptr; Tile *Tile::dragonEgg = nullptr; Tile *Tile::redstoneLight = nullptr; @@ -203,13 +205,13 @@ Tile *Tile::cocoa = nullptr; Tile *Tile::skull = nullptr; Tile *Tile::cobbleWall = nullptr; -Tile *Tile::flowerPot = nullptr; +Tile *Tile::flower_pot = nullptr; Tile *Tile::carrots = nullptr; Tile *Tile::potatoes = nullptr; Tile *Tile::anvil = nullptr; Tile *Tile::chest_trap = nullptr; -Tile *Tile::weightedPlate_light = nullptr; -Tile *Tile::weightedPlate_heavy = nullptr; +Tile *Tile::light_weighted_pressure_plate = nullptr; +Tile *Tile::heavy_weighted_pressure_plate = nullptr; ComparatorTile *Tile::comparator_off = nullptr; ComparatorTile *Tile::comparator_on = nullptr; @@ -222,7 +224,7 @@ Tile *Tile::quartzBlock = nullptr; Tile *Tile::stairs_quartz = nullptr; Tile *Tile::activatorRail = nullptr; Tile *Tile::dropper = nullptr; -Tile *Tile::clayHardened_colored = nullptr; +Tile *Tile::stained_hardened_clay = nullptr; Tile *Tile::stained_glass_pane = nullptr; Tile *Tile::hayBlock = nullptr; @@ -235,11 +237,11 @@ Tile* Tile::woodStairsAcacia = nullptr; Tile* Tile::woodStairsDark = nullptr; Tile* Tile::iron_trapdoor = nullptr; -Tile* Tile::door_spruce = nullptr; -Tile* Tile::door_birch = nullptr; -Tile* Tile::door_jungle = nullptr; -Tile* Tile::door_acacia = nullptr; -Tile* Tile::door_dark = nullptr; +Tile* Tile::spruce_door = nullptr; +Tile* Tile::birch_door = nullptr; +Tile* Tile::jungle_door = nullptr; +Tile* Tile::acacia_door = nullptr; +Tile* Tile::dark_oak_door = nullptr; Tile* Tile::spruceFence = nullptr; Tile* Tile::birchFence = nullptr; @@ -253,7 +255,7 @@ Tile* Tile::jungleGate = nullptr; Tile* Tile::acaciaGate = nullptr; Tile* Tile::darkGate = nullptr; -Tile* Tile::invertedDaylightDetector = nullptr; +Tile* Tile::daylight_detector_inverted = nullptr; Tile* Tile::red_sandstone = nullptr; Tile* Tile::stairs_red_sandstone = nullptr; HalfSlabTile* Tile::stoneSlab2 = nullptr; @@ -262,11 +264,11 @@ Tile* Tile::seaLantern = nullptr; Tile* Tile::prismarine = nullptr; -Tile* Tile::tree2Trunk = nullptr; +Tile* Tile::log2 = nullptr; Tile* Tile::packedIce = nullptr; Tile* Tile::barrier = nullptr; -TallGrass2* Tile::tallgrass2 = nullptr; +TallGrass2* Tile::double_plant = nullptr; DWORD Tile::tlsIdxShape = TlsAlloc(); @@ -287,13 +289,58 @@ void Tile::ReleaseThreadStorage() ThreadStorage *tls = static_cast(TlsGetValue(Tile::tlsIdxShape)); delete tls; } -class TallGrass2TileItem : public ColoredTileItem + +Tile::BlockStateDefinition::BlockStateDefinition(Tile *ownerTile) +{ + owner = ownerTile; +} + +void Tile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int Tile::defaultBlockState() +{ + return m_defaultBlockState; +} + +Tile::BlockStateDefinition *Tile::getBlockStateDefinition() +{ + return m_blockStateDefinition; +} + +int Tile::convertBlockStateToLegacyData(BlockState *state) +{ + (void)state; + return 0; +} + +int Tile::getBlockState() +{ + return m_defaultBlockState; +} + +Tile::BlockState Tile::getBlockState(LevelSource *level, int x, int y, int z) +{ + (void)level; (void)x; (void)y; (void)z; + return BlockState(defaultBlockState()); +} + +class double_plantTileItem : public ColoredTileItem { public: - TallGrass2TileItem(int id) : ColoredTileItem(id, true) {} + double_plantTileItem(int id) : ColoredTileItem(id, true) {} virtual Icon* getIcon(int auxValue) override { + if (auxValue == TallGrass2::SUNFLOWER) + { + TallGrass2* tile = static_cast(Tile::tiles[getTileId()]); + if (tile != nullptr) + return tile->getSunflowerHeadBackIcon(); + } return Tile::tiles[getTileId()]->getTexture(Facing::UP, auxValue); } @@ -313,6 +360,7 @@ void Tile::staticCtor() Tile::SOUND_GRAVEL = new Tile::SoundType(eMaterialSoundType_GRAVEL, 1, 1); Tile::SOUND_GRASS = new Tile::SoundType(eMaterialSoundType_GRASS, 1, 1); Tile::SOUND_STONE = new Tile::SoundType(eMaterialSoundType_STONE, 1, 1); + Tile::SOUND_SLIME = new Tile::SoundType(eMaterialSoundType_STONE, 1, 1, eSoundType_MOB_SLIME_BIG, eSoundType_MOB_SLIME_BIG); Tile::SOUND_METAL = new Tile::SoundType(eMaterialSoundType_STONE, 1, 1.5f); Tile::SOUND_GLASS = new Tile::SoundType(eMaterialSoundType_STONE, 1, 1, eSoundType_RANDOM_GLASS,eSoundType_STEP_STONE); Tile::SOUND_CLOTH = new Tile::SoundType(eMaterialSoundType_CLOTH, 1, 1); @@ -357,7 +405,7 @@ void Tile::staticCtor() Tile::bed = (new BedTile(26)) ->setDestroyTime(0.2f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"bed")->setDescriptionId(IDS_TILE_BED)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_BED); Tile::goldenRail = (new PoweredRailTile(27)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_rail, Item::eMaterial_gold)->setDestroyTime(0.7f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"rail_golden")->setDescriptionId(IDS_TILE_GOLDEN_RAIL)->sendTileData()->setUseDescriptionId(IDS_DESC_POWEREDRAIL)->disableMipmap(); Tile::detectorRail = (new DetectorRailTile(28)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_rail, Item::eMaterial_detector)->setDestroyTime(0.7f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"rail_detector")->setDescriptionId(IDS_TILE_DETECTOR_RAIL)->sendTileData()->setUseDescriptionId(IDS_DESC_DETECTORRAIL)->disableMipmap(); - Tile::pistonStickyBase = static_cast((new PistonBaseTile(29, true))->setBaseItemTypeAndMaterial(Item::eBaseItemType_piston, Item::eMaterial_stickypiston)->setIconName(L"pistonStickyBase")->setDescriptionId(IDS_TILE_PISTON_STICK_BASE)->setUseDescriptionId(IDS_DESC_STICKY_PISTON)->sendTileData()); + Tile::sticky_piston = static_cast((new PistonBaseTile(29, true))->setBaseItemTypeAndMaterial(Item::eBaseItemType_piston, Item::eMaterial_stickypiston)->setIconName(L"sticky_piston")->setDescriptionId(IDS_TILE_PISTON_STICK_BASE)->setUseDescriptionId(IDS_DESC_STICKY_PISTON)->sendTileData()); Tile::web = (new WebTile(30)) ->setLightBlock(1)->setDestroyTime(4.0f)->setIconName(L"web")->setDescriptionId(IDS_TILE_WEB)->setUseDescriptionId(IDS_DESC_WEB); Tile::tallgrass = static_cast((new TallGrass(31))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"tallgrass")->setDescriptionId(IDS_TILE_TALL_GRASS)->setUseDescriptionId(IDS_DESC_TALL_GRASS)->disableMipmap()); @@ -373,8 +421,8 @@ void Tile::staticCtor() Tile::goldBlock = (new MetalTile(41)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_block, Item::eMaterial_gold)->setDestroyTime(3.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_METAL)->setIconName(L"gold_block")->setDescriptionId(IDS_TILE_BLOCK_GOLD)->setUseDescriptionId(IDS_DESC_BLOCK_GOLD); Tile::ironBlock = (new MetalTile(42)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_block, Item::eMaterial_iron)->setDestroyTime(5.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_METAL)->setIconName(L"iron_block")->setDescriptionId(IDS_TILE_BLOCK_IRON)->setUseDescriptionId(IDS_DESC_BLOCK_IRON); - Tile::stoneSlab = static_cast((new FullStoneSlabTile(Tile::stoneSlab_Id))->setBaseItemTypeAndMaterial(Item::eBaseItemType_slab, Item::eMaterial_stone)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"stoneSlab")->setDescriptionId(IDS_TILE_STONESLAB)->setUseDescriptionId(IDS_DESC_SLAB)); - Tile::stoneSlabHalf = static_cast((new HalfStoneSlabTile(Tile::stoneSlabHalf_Id))->setBaseItemTypeAndMaterial(Item::eBaseItemType_halfslab, Item::eMaterial_stone)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"stoneSlab")->setDescriptionId(IDS_TILE_STONESLAB)->setUseDescriptionId(IDS_DESC_HALFSLAB)); + Tile::stoneSlab = static_cast((new FullStoneSlabTile(Tile::double_stone_slab_Id))->setBaseItemTypeAndMaterial(Item::eBaseItemType_slab, Item::eMaterial_stone)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"stoneSlab")->setDescriptionId(IDS_TILE_STONESLAB)->setUseDescriptionId(IDS_DESC_SLAB)); + Tile::stoneSlabHalf = static_cast((new HalfStoneSlabTile(Tile::stone_slab_Id))->setBaseItemTypeAndMaterial(Item::eBaseItemType_halfslab, Item::eMaterial_stone)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"stoneSlab")->setDescriptionId(IDS_TILE_STONESLAB)->setUseDescriptionId(IDS_DESC_HALFSLAB)); Tile::redBrick = (new Tile(45, Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_brick)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"brick")->setDescriptionId(IDS_TILE_BRICK)->setUseDescriptionId(IDS_DESC_BRICK); Tile::tnt = (new TntTile(46)) ->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"tnt")->setDescriptionId(IDS_TILE_TNT)->setUseDescriptionId(IDS_DESC_TNT); Tile::bookshelf = (new BookshelfTile(47)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_paper, Item::eMaterial_bookshelf)->setDestroyTime(1.5f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"bookshelf")->setDescriptionId(IDS_TILE_BOOKSHELF)->setUseDescriptionId(IDS_DESC_BOOKSHELF); @@ -396,22 +444,22 @@ void Tile::staticCtor() Tile::furnace = (new FurnaceTile(61, false)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_device, Item::eMaterial_stone)->setDestroyTime(3.5f)->setSoundType(Tile::SOUND_STONE)->setIconName(L"furnace")->setDescriptionId(IDS_TILE_FURNACE)->sendTileData()->setUseDescriptionId(IDS_DESC_FURNACE); Tile::furnace_lit = (new FurnaceTile(62, true)) ->setDestroyTime(3.5f)->setSoundType(Tile::SOUND_STONE)->setLightEmission(14 / 16.0f)->setIconName(L"furnace")->setDescriptionId(IDS_TILE_FURNACE)->sendTileData()->setUseDescriptionId(IDS_DESC_FURNACE); Tile::sign = (new SignTile(63, eTYPE_SIGNTILEENTITY, true)) ->setDestroyTime(1.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"sign")->setDescriptionId(IDS_TILE_SIGN)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_SIGN); - Tile::door_wood = (new DoorTile(64, Material::wood, L"doorWood"))->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"door_wood")->setDescriptionId(IDS_TILE_DOOR_WOOD)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_WOOD); + Tile::wooden_door = (new DoorTile(64, Material::wood, L"doorWood"))->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"wooden_door")->setDescriptionId(IDS_TILE_DOOR_WOOD)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_WOOD); Tile::ladder = (new LadderTile(65)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stick, Item::eMaterial_wood)->setDestroyTime(0.4f)->setSoundType(Tile::SOUND_LADDER)->setIconName(L"ladder")->setDescriptionId(IDS_TILE_LADDER)->sendTileData()->setUseDescriptionId(IDS_DESC_LADDER)->disableMipmap(); Tile::rail = (new RailTile(66)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_rail, Item::eMaterial_iron)->setDestroyTime(0.7f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"rail_normal")->setDescriptionId(IDS_TILE_RAIL)->sendTileData()->setUseDescriptionId(IDS_DESC_RAIL)->disableMipmap(); Tile::stairs_stone =(new StairTile(67, Tile::cobblestone,0)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_stone) ->setIconName(L"stairsStone")->setDescriptionId(IDS_TILE_STAIRS_STONE) ->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); Tile::wallSign = (new SignTile(68, eTYPE_SIGNTILEENTITY, false)) ->setDestroyTime(1.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"sign")->setDescriptionId(IDS_TILE_SIGN)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_SIGN); Tile::lever = (new LeverTile(69)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_lever, Item::eMaterial_wood)->setDestroyTime(0.5f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"lever")->setDescriptionId(IDS_TILE_LEVER)->sendTileData()->setUseDescriptionId(IDS_DESC_LEVER); Tile::pressurePlate_stone = (Tile *)(new PressurePlateTile(70, L"stone", Material::stone, PressurePlateTile::mobs)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, Item::eMaterial_stone)->setDestroyTime(0.5f)->setSoundType(Tile::SOUND_STONE)->setDescriptionId(IDS_TILE_PRESSURE_PLATE)->sendTileData()->setUseDescriptionId(IDS_DESC_PRESSUREPLATE); - Tile::door_spruce = (new DoorTile(193, Material::wood, L"doorSpruce"))->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"door_spruce")->setDescriptionId(IDS_TILE_DOOR_SPRUCE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_WOOD); - Tile::door_birch = (new DoorTile(194, Material::wood, L"doorBirch"))->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"door_birch")->setDescriptionId(IDS_TILE_DOOR_SPRUCE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_WOOD); - Tile::door_jungle = (new DoorTile(195, Material::wood, L"doorJungle"))->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"door_jungle")->setDescriptionId(IDS_TILE_DOOR_SPRUCE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_WOOD); - Tile::door_acacia = (new DoorTile(196, Material::wood, L"doorAcacia"))->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"door_acacia")->setDescriptionId(IDS_TILE_DOOR_SPRUCE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_WOOD); - Tile::door_dark = (new DoorTile(197, Material::wood, L"doorDark"))->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"door_dark")->setDescriptionId(IDS_TILE_DOOR_SPRUCE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_WOOD); - Tile::door_iron = (new DoorTile(71, Material::metal, L"doorIron"))->setDestroyTime(5.0f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"door_iron")->setDescriptionId(IDS_TILE_DOOR_IRON)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_IRON); + Tile::spruce_door = (new DoorTile(193, Material::wood, L"doorSpruce"))->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"spruce_door")->setDescriptionId(IDS_TILE_DOOR_SPRUCE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_WOOD); + Tile::birch_door = (new DoorTile(194, Material::wood, L"doorBirch"))->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"birch_door")->setDescriptionId(IDS_TILE_DOOR_SPRUCE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_WOOD); + Tile::jungle_door = (new DoorTile(195, Material::wood, L"doorJungle"))->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"jungle_door")->setDescriptionId(IDS_TILE_DOOR_SPRUCE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_WOOD); + Tile::acacia_door = (new DoorTile(196, Material::wood, L"doorAcacia"))->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"acacia_door")->setDescriptionId(IDS_TILE_DOOR_SPRUCE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_WOOD); + Tile::dark_oak_door = (new DoorTile(197, Material::wood, L"doorDark"))->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"dark_oak_door")->setDescriptionId(IDS_TILE_DOOR_SPRUCE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_WOOD); + Tile::iron_door = (new DoorTile(71, Material::metal, L"doorIron"))->setDestroyTime(5.0f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"iron_door")->setDescriptionId(IDS_TILE_DOOR_IRON)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_IRON); Tile::pressurePlate_wood = (new PressurePlateTile(72, L"planks_oak", Material::wood, PressurePlateTile::everything)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, Item::eMaterial_wood)->setDestroyTime(0.5f)->setSoundType(Tile::SOUND_WOOD)->setDescriptionId(IDS_TILE_PRESSURE_PLATE)->sendTileData()->setUseDescriptionId(IDS_DESC_PRESSUREPLATE); Tile::redStoneOre = (new RedStoneOreTile(73,false)) ->setDestroyTime(3.0f)->setExplodeable(5)->setSoundType(Tile::SOUND_STONE)->setIconName(L"redstone_ore")->setDescriptionId(IDS_TILE_ORE_REDSTONE)->sendTileData()->setUseDescriptionId(IDS_DESC_ORE_REDSTONE); - Tile::redStoneOre_lit = (new RedStoneOreTile(74, true)) ->setLightEmission(10 / 16.0f)->setDestroyTime(3.0f)->setExplodeable(5)->setSoundType(Tile::SOUND_STONE)->setIconName(L"redstone_ore")->setDescriptionId(IDS_TILE_ORE_REDSTONE)->sendTileData()->setUseDescriptionId(IDS_DESC_ORE_REDSTONE); + Tile::lit_redstone_ore = (new RedStoneOreTile(74, true)) ->setLightEmission(10 / 16.0f)->setDestroyTime(3.0f)->setExplodeable(5)->setSoundType(Tile::SOUND_STONE)->setIconName(L"redstone_ore")->setDescriptionId(IDS_TILE_ORE_REDSTONE)->sendTileData()->setUseDescriptionId(IDS_DESC_ORE_REDSTONE); Tile::redstoneTorch_off = (new NotGateTile(75, false)) ->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"redstone_torch_off")->setDescriptionId(IDS_TILE_NOT_GATE)->sendTileData()->setUseDescriptionId(IDS_DESC_REDSTONETORCH)->disableMipmap(); Tile::redstoneTorch_on = (new NotGateTile(76, true)) ->setDestroyTime(0.0f)->setLightEmission(8 / 16.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"redstone_torch_on")->setDescriptionId(IDS_TILE_NOT_GATE)->sendTileData()->setUseDescriptionId(IDS_DESC_REDSTONETORCH)->disableMipmap(); Tile::button = (new StoneButtonTile(77)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_button, Item::eMaterial_stone)->setDestroyTime(0.5f)->setSoundType(Tile::SOUND_STONE)->setIconName(L"button")->setDescriptionId(IDS_TILE_BUTTON)->sendTileData()->setUseDescriptionId(IDS_DESC_BUTTON); @@ -432,49 +480,49 @@ void Tile::staticCtor() Tile::litPumpkin = (new PumpkinTile(91, true)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_torch, Item::eMaterial_pumpkin)->setDestroyTime(1.0f)->setSoundType(Tile::SOUND_WOOD)->setLightEmission(1.0f)->setIconName(L"pumpkin")->setDescriptionId(IDS_TILE_LIT_PUMPKIN)->sendTileData()->setUseDescriptionId(IDS_DESC_JACKOLANTERN); Tile::cake = (new CakeTile(92)) ->setDestroyTime(0.5f)->setSoundType(Tile::SOUND_CLOTH)->setIconName(L"cake")->setDescriptionId(IDS_TILE_CAKE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_CAKE); - Tile::diode_off = static_cast((new RepeaterTile(93, false))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"repeater_off")->setDescriptionId(IDS_ITEM_DIODE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_REDSTONEREPEATER)->disableMipmap()); - Tile::diode_on = static_cast((new RepeaterTile(94, true))->setDestroyTime(0.0f)->setLightEmission(10 / 16.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"repeater_on")->setDescriptionId(IDS_ITEM_DIODE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_REDSTONEREPEATER)->disableMipmap()); + Tile::unpowered_repeater = static_cast((new RepeaterTile(93, false))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"repeater_off")->setDescriptionId(IDS_ITEM_DIODE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_REDSTONEREPEATER)->disableMipmap()); + Tile::powered_repeater = static_cast((new RepeaterTile(94, true))->setDestroyTime(0.0f)->setLightEmission(10 / 16.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"repeater_on")->setDescriptionId(IDS_ITEM_DIODE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_REDSTONEREPEATER)->disableMipmap()); Tile::stained_glass = (new StainedGlassBlock(95, Material::glass))->setBaseItemTypeAndMaterial(Item::eBaseItemType_glass, Item::eMaterial_glass)->setDestroyTime(0.3f)->setSoundType(SOUND_GLASS)->setIconName(L"glass")->setDescriptionId(IDS_TILE_STAINED_GLASS)->setUseDescriptionId(IDS_DESC_STAINED_GLASS); Tile::trapdoor = (new TrapDoorTile(96, Material::wood)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_door, Item::eMaterial_trap)->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"trapdoor")->setDescriptionId(IDS_TILE_TRAPDOOR)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_TRAPDOOR); - Tile::monsterStoneEgg = (new StoneMonsterTile(97)) ->setDestroyTime(0.75f)->setIconName(L"monsterStoneEgg")->setDescriptionId(IDS_TILE_STONE_SILVERFISH)->setUseDescriptionId(IDS_DESC_STONE_SILVERFISH); + Tile::monster_egg = (new StoneMonsterTile(97)) ->setDestroyTime(0.75f)->setIconName(L"monster_egg")->setDescriptionId(IDS_TILE_STONE_SILVERFISH)->setUseDescriptionId(IDS_DESC_STONE_SILVERFISH); Tile::stoneBrick = (new SmoothStoneBrickTile(98)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_stoneSmooth)->setDestroyTime(1.5f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setIconName(L"stonebrick")->setDescriptionId(IDS_TILE_STONE_BRICK_SMOOTH)->setUseDescriptionId(IDS_DESC_STONE_BRICK_SMOOTH); - Tile::hugeMushroom_brown = (new HugeMushroomTile(99, Material::wood, HugeMushroomTile::MUSHROOM_TYPE_BROWN)) ->setDestroyTime(0.2f)->setSoundType(SOUND_WOOD)->setIconName(L"mushroom_block")->setDescriptionId(IDS_TILE_HUGE_MUSHROOM_1)->setUseDescriptionId(IDS_DESC_MUSHROOM)->sendTileData(); - Tile::hugeMushroom_red = (new HugeMushroomTile(100, Material::wood, HugeMushroomTile::MUSHROOM_TYPE_RED)) ->setDestroyTime(0.2f)->setSoundType(SOUND_WOOD)->setIconName(L"mushroom_block")->setDescriptionId(IDS_TILE_HUGE_MUSHROOM_2)->setUseDescriptionId(IDS_DESC_MUSHROOM)->sendTileData(); + Tile::brown_mushroom_block = (new HugeMushroomTile(99, Material::wood, HugeMushroomTile::MUSHROOM_TYPE_BROWN)) ->setDestroyTime(0.2f)->setSoundType(SOUND_WOOD)->setIconName(L"mushroom_block")->setDescriptionId(IDS_TILE_HUGE_MUSHROOM_1)->setUseDescriptionId(IDS_DESC_MUSHROOM)->sendTileData(); + Tile::red_mushroom_block = (new HugeMushroomTile(100, Material::wood, HugeMushroomTile::MUSHROOM_TYPE_RED)) ->setDestroyTime(0.2f)->setSoundType(SOUND_WOOD)->setIconName(L"mushroom_block")->setDescriptionId(IDS_TILE_HUGE_MUSHROOM_2)->setUseDescriptionId(IDS_DESC_MUSHROOM)->sendTileData(); - Tile::ironFence = (new ThinFenceTile(101, L"iron_bars", L"iron_bars", Material::metal, true)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fence, Item::eMaterial_iron)->setDestroyTime(5.0f)->setExplodeable(10)->setSoundType(SOUND_METAL)->setDescriptionId(IDS_TILE_IRON_FENCE)->setUseDescriptionId(IDS_DESC_IRON_FENCE); - Tile::thinGlass = (new ThinFenceTile(102, L"glass", L"glass_pane_top", Material::glass, false)) + Tile::iron_bars = (new ThinFenceTile(101, L"iron_bars", L"iron_bars", Material::metal, true)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fence, Item::eMaterial_iron)->setDestroyTime(5.0f)->setExplodeable(10)->setSoundType(SOUND_METAL)->setDescriptionId(IDS_TILE_IRON_FENCE)->setUseDescriptionId(IDS_DESC_IRON_FENCE); + Tile::glass_pane = (new ThinFenceTile(102, L"glass", L"glass_pane_top", Material::glass, false)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_glass, Item::eMaterial_glass) ->setDestroyTime(0.3f) ->setSoundType(SOUND_GLASS) ->setDescriptionId(IDS_TILE_THIN_GLASS) ->setUseDescriptionId(IDS_DESC_THIN_GLASS); Tile::melon = (new MelonTile(103)) ->setDestroyTime(1.0f)->setSoundType(SOUND_WOOD)->setIconName(L"melon")->setDescriptionId(IDS_TILE_MELON)->setUseDescriptionId(IDS_DESC_MELON_BLOCK); - Tile::pumpkinStem = (new StemTile(104, Tile::pumpkin)) ->setDestroyTime(0.0f)->setSoundType(SOUND_WOOD)->setIconName(L"pumpkin_stem")->setDescriptionId(IDS_TILE_PUMPKIN_STEM)->sendTileData(); - Tile::melonStem = (new StemTile(105, Tile::melon)) ->setDestroyTime(0.0f)->setSoundType(SOUND_WOOD)->setIconName(L"melon_stem")->setDescriptionId(IDS_TILE_MELON_STEM)->sendTileData(); + Tile::pumpkin_stem = (new StemTile(104, Tile::pumpkin)) ->setDestroyTime(0.0f)->setSoundType(SOUND_WOOD)->setIconName(L"pumpkin_stem")->setDescriptionId(IDS_TILE_PUMPKIN_STEM)->sendTileData(); + Tile::melon_stem = (new StemTile(105, Tile::melon)) ->setDestroyTime(0.0f)->setSoundType(SOUND_WOOD)->setIconName(L"melon_stem")->setDescriptionId(IDS_TILE_MELON_STEM)->sendTileData(); Tile::vine = (new VineTile(106))->setDestroyTime(0.2f) ->setSoundType(SOUND_GRASS)->setIconName(L"vine")->setDescriptionId(IDS_TILE_VINE)->setUseDescriptionId(IDS_DESC_VINE)->sendTileData(); Tile::fenceGate = (new FenceGateTile(107))->setBaseItemTypeAndMaterial(Item::eBaseItemType_fenceGate, Item::eMaterial_wood)->setDestroyTime(2.0f)->setExplodeable(5)->setSoundType(SOUND_WOOD)->setIconName(L"planks_oak")->setDescriptionId(IDS_TILE_FENCE_GATE)->sendTileData()->setUseDescriptionId(IDS_DESC_FENCE_GATE); Tile::stairs_bricks = (new StairTile(108, Tile::redBrick,0)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_brick) ->setIconName(L"stairsBrick")->setDescriptionId(IDS_TILE_STAIRS_BRICKS) ->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); - Tile::stairs_stoneBrickSmooth = (new StairTile(109, Tile::stoneBrick,0)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_stoneSmooth)->setIconName(L"stairsStoneBrickSmooth")->setDescriptionId(IDS_TILE_STAIRS_STONE_BRICKS_SMOOTH) ->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); + Tile::stone_brick_stairsSmooth = (new StairTile(109, Tile::stoneBrick,0)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_stoneSmooth)->setIconName(L"stairsStoneBrickSmooth")->setDescriptionId(IDS_TILE_STAIRS_STONE_BRICKS_SMOOTH) ->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); Tile::mycel = static_cast((new MycelTile(110))->setDestroyTime(0.6f)->setSoundType(SOUND_GRASS)->setIconName(L"mycelium")->setDescriptionId(IDS_TILE_MYCEL)->setUseDescriptionId(IDS_DESC_MYCEL)); Tile::waterLily = (new WaterlilyTile(111)) ->setDestroyTime(0.0f)->setSoundType(SOUND_GRASS)->setIconName(L"waterlily")->setDescriptionId(IDS_TILE_WATERLILY)->setUseDescriptionId(IDS_DESC_WATERLILY); Tile::netherBrick = (new Tile(112, Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_netherbrick)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setIconName(L"nether_brick")->setDescriptionId(IDS_TILE_NETHERBRICK)->setUseDescriptionId(IDS_DESC_NETHERBRICK); Tile::netherFence = (new FenceTile(113, L"nether_brick", Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fence, Item::eMaterial_netherbrick)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setDescriptionId(IDS_TILE_NETHERFENCE)->setUseDescriptionId(IDS_DESC_NETHERFENCE); - Tile::stairs_netherBricks = (new StairTile(114, Tile::netherBrick,0)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_netherbrick)->setIconName(L"stairsNetherBrick")->setDescriptionId(IDS_TILE_STAIRS_NETHERBRICK) ->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); + Tile::nether_brick_stairs = (new StairTile(114, Tile::netherBrick,0)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_netherbrick)->setIconName(L"stairsNetherBrick")->setDescriptionId(IDS_TILE_STAIRS_NETHERBRICK) ->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); Tile::netherStalk = (new NetherWartTile(115)) ->setIconName(L"nether_wart")->setDescriptionId(IDS_TILE_NETHERSTALK)->sendTileData()->setUseDescriptionId(IDS_DESC_NETHERSTALK); Tile::enchantTable = (new EnchantmentTableTile(116)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_device, Item::eMaterial_magic)->setDestroyTime(5.0f)->setExplodeable(2000)->setIconName(L"enchanting_table")->setDescriptionId(IDS_TILE_ENCHANTMENTTABLE)->setUseDescriptionId(IDS_DESC_ENCHANTMENTTABLE); Tile::brewingStand = (new BrewingStandTile(117)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_device, Item::eMaterial_blaze)->setDestroyTime(0.5f)->setLightEmission(2 / 16.0f)->setIconName(L"brewing_stand")->setDescriptionId(IDS_TILE_BREWINGSTAND)->sendTileData()->setUseDescriptionId(IDS_DESC_BREWING_STAND); Tile::cauldron = static_cast((new CauldronTile(118))->setDestroyTime(2.0f)->setIconName(L"cauldron")->setDescriptionId(IDS_TILE_CAULDRON)->sendTileData()->setUseDescriptionId(IDS_DESC_CAULDRON)); - Tile::endPortalTile = (new TheEndPortal(119, Material::portal)) ->setDestroyTime(INDESTRUCTIBLE_DESTROY_TIME)->setExplodeable(6000000)->setDescriptionId(IDS_TILE_END_PORTAL)->setUseDescriptionId(IDS_DESC_END_PORTAL); - Tile::endPortalFrameTile = (new TheEndPortalFrameTile(120)) ->setSoundType(SOUND_GLASS)->setLightEmission(2 / 16.0f)->setDestroyTime(INDESTRUCTIBLE_DESTROY_TIME)->setIconName(L"endframe")->setDescriptionId(IDS_TILE_ENDPORTALFRAME)->sendTileData()->setExplodeable(6000000)->setUseDescriptionId(IDS_DESC_ENDPORTALFRAME); + Tile::end_portal = (new TheEndPortal(119, Material::portal)) ->setDestroyTime(INDESTRUCTIBLE_DESTROY_TIME)->setExplodeable(6000000)->setDescriptionId(IDS_TILE_END_PORTAL)->setUseDescriptionId(IDS_DESC_END_PORTAL); + Tile::end_portal_frame = (new TheEndPortalFrameTile(120)) ->setSoundType(SOUND_GLASS)->setLightEmission(2 / 16.0f)->setDestroyTime(INDESTRUCTIBLE_DESTROY_TIME)->setIconName(L"endframe")->setDescriptionId(IDS_TILE_ENDPORTALFRAME)->sendTileData()->setExplodeable(6000000)->setUseDescriptionId(IDS_DESC_ENDPORTALFRAME); Tile::endStone = (new Tile(121, Material::stone)) ->setDestroyTime(3.0f)->setExplodeable(15)->setSoundType(SOUND_STONE)->setIconName(L"end_stone")->setDescriptionId(IDS_TILE_WHITESTONE)->setUseDescriptionId(IDS_DESC_WHITESTONE); Tile::dragonEgg = (new EggTile(122)) ->setDestroyTime(3.0f)->setExplodeable(15)->setSoundType(SOUND_STONE)->setLightEmission(2.0f / 16.0f)->setIconName(L"dragon_egg")->setDescriptionId(IDS_TILE_DRAGONEGG)->setUseDescriptionId(IDS_DESC_DRAGONEGG); Tile::redstoneLight = (new RedlightTile(123, false)) ->setDestroyTime(0.3f)->setSoundType(SOUND_GLASS)->setIconName(L"redstone_lamp_off")->setDescriptionId(IDS_TILE_REDSTONE_LIGHT)->setUseDescriptionId(IDS_DESC_REDSTONE_LIGHT); Tile::redstoneLight_lit = (new RedlightTile(124, true)) ->setDestroyTime(0.3f)->setSoundType(SOUND_GLASS)->setIconName(L"redstone_lamp_on")->setDescriptionId(IDS_TILE_REDSTONE_LIGHT)->setUseDescriptionId(IDS_DESC_REDSTONE_LIGHT); - Tile::woodSlab = static_cast((new FullWoodSlabTile(Tile::woodSlab_Id))->setBaseItemTypeAndMaterial(Item::eBaseItemType_slab, Item::eMaterial_wood)->setDestroyTime(2.0f)->setExplodeable(5)->setSoundType(SOUND_WOOD)->setIconName(L"woodSlab")->setDescriptionId(IDS_DESC_WOODSLAB)->setUseDescriptionId(IDS_DESC_WOODSLAB)); - Tile::woodSlabHalf = static_cast((new HalfWoodSlabTile(Tile::woodSlabHalf_Id))->setBaseItemTypeAndMaterial(Item::eBaseItemType_halfslab, Item::eMaterial_wood)->setDestroyTime(2.0f)->setExplodeable(5)->setSoundType(SOUND_WOOD)->setIconName(L"woodSlab")->setDescriptionId(IDS_DESC_WOODSLAB)->setUseDescriptionId(IDS_DESC_WOODSLAB)); + Tile::woodSlab = static_cast((new FullWoodSlabTile(Tile::double_wooden_slab_Id))->setBaseItemTypeAndMaterial(Item::eBaseItemType_slab, Item::eMaterial_wood)->setDestroyTime(2.0f)->setExplodeable(5)->setSoundType(SOUND_WOOD)->setIconName(L"woodSlab")->setDescriptionId(IDS_DESC_WOODSLAB)->setUseDescriptionId(IDS_DESC_WOODSLAB)); + Tile::woodSlabHalf = static_cast((new HalfWoodSlabTile(Tile::wooden_slab_Id))->setBaseItemTypeAndMaterial(Item::eBaseItemType_halfslab, Item::eMaterial_wood)->setDestroyTime(2.0f)->setExplodeable(5)->setSoundType(SOUND_WOOD)->setIconName(L"woodSlab")->setDescriptionId(IDS_DESC_WOODSLAB)->setUseDescriptionId(IDS_DESC_WOODSLAB)); Tile::cocoa = (new CocoaTile(127)) ->setDestroyTime(0.2f)->setExplodeable(5)->setSoundType(SOUND_WOOD)->setIconName(L"cocoa")->sendTileData()->setDescriptionId(IDS_TILE_COCOA)->setUseDescriptionId(IDS_DESC_COCOA); Tile::stairs_sandstone = (new StairTile(128, Tile::sandStone,0)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_sand) ->setIconName(L"stairsSandstone")->setDescriptionId(IDS_TILE_STAIRS_SANDSTONE) ->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); @@ -491,7 +539,7 @@ void Tile::staticCtor() Tile::commandBlock = (new CommandBlock(137)) ->setIndestructible()->setExplodeable(6000000)->setIconName(L"command_block")->setDescriptionId(IDS_TILE_COMMAND_BLOCK)->setUseDescriptionId(IDS_DESC_COMMAND_BLOCK); Tile::beacon = static_cast((new BeaconTile(138))->setLightEmission(1.0f)->setIconName(L"beacon")->setDescriptionId(IDS_TILE_BEACON)->setUseDescriptionId(IDS_DESC_BEACON)); Tile::cobbleWall = (new WallTile(139, Tile::stoneBrick)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fence, Item::eMaterial_stone)->setIconName(L"cobbleWall")->setDescriptionId(IDS_TILE_COBBLESTONE_WALL)->setUseDescriptionId(IDS_DESC_COBBLESTONE_WALL); - Tile::flowerPot = (new FlowerPotTile(140)) ->setDestroyTime(0.0f)->setSoundType(SOUND_NORMAL)->setIconName(L"flower_pot")->setDescriptionId(IDS_TILE_FLOWERPOT)->setUseDescriptionId(IDS_DESC_FLOWERPOT); + Tile::flower_pot = (new FlowerPotTile(140)) ->setDestroyTime(0.0f)->setSoundType(SOUND_NORMAL)->setIconName(L"flower_pot")->setDescriptionId(IDS_TILE_FLOWERPOT)->setUseDescriptionId(IDS_DESC_FLOWERPOT); Tile::carrots = (new CarrotTile(141)) ->setIconName(L"carrots")->setDescriptionId(IDS_TILE_CARROTS)->setUseDescriptionId(IDS_DESC_CARROTS)->disableMipmap(); Tile::potatoes = (new PotatoTile(142)) ->setIconName(L"potatoes")->setDescriptionId(IDS_TILE_POTATOES)->setUseDescriptionId(IDS_DESC_POTATO)->disableMipmap(); @@ -499,8 +547,8 @@ void Tile::staticCtor() Tile::skull = (new SkullTile(144)) ->setDestroyTime(1.0f)->setSoundType(SOUND_STONE)->setIconName(L"skull")->setDescriptionId(IDS_TILE_SKULL)->setUseDescriptionId(IDS_DESC_SKULL); Tile::anvil = (new AnvilTile(145)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_device, Item::eMaterial_iron)->setDestroyTime(5.0f)->setSoundType(SOUND_ANVIL)->setExplodeable(2000)->setIconName(L"anvil")->sendTileData()->setDescriptionId(IDS_TILE_ANVIL)->setUseDescriptionId(IDS_DESC_ANVIL); Tile::chest_trap = (new ChestTile(146, ChestTile::TYPE_TRAP)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_chest, Item::eMaterial_trap)->setDestroyTime(2.5f)->setSoundType(SOUND_WOOD)->setDescriptionId(IDS_TILE_CHEST_TRAP)->setUseDescriptionId(IDS_DESC_CHEST_TRAP); - Tile::weightedPlate_light = (new WeightedPressurePlateTile(147, L"gold_block", Material::metal, Redstone::SIGNAL_MAX)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, Item::eMaterial_gold)->setDestroyTime(0.5f)->setSoundType(SOUND_WOOD)->setDescriptionId(IDS_TILE_WEIGHTED_PLATE_LIGHT)->setUseDescriptionId(IDS_DESC_WEIGHTED_PLATE_LIGHT); - Tile::weightedPlate_heavy = (new WeightedPressurePlateTile(148, L"iron_block", Material::metal, Redstone::SIGNAL_MAX * 10))->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, Item::eMaterial_iron)->setDestroyTime(0.5f)->setSoundType(SOUND_WOOD)->setDescriptionId(IDS_TILE_WEIGHTED_PLATE_HEAVY)->setUseDescriptionId(IDS_DESC_WEIGHTED_PLATE_HEAVY); + Tile::light_weighted_pressure_plate = (new WeightedPressurePlateTile(147, L"gold_block", Material::metal, Redstone::SIGNAL_MAX)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, Item::eMaterial_gold)->setDestroyTime(0.5f)->setSoundType(SOUND_WOOD)->setDescriptionId(IDS_TILE_WEIGHTED_PLATE_LIGHT)->setUseDescriptionId(IDS_DESC_WEIGHTED_PLATE_LIGHT); + Tile::heavy_weighted_pressure_plate = (new WeightedPressurePlateTile(148, L"iron_block", Material::metal, Redstone::SIGNAL_MAX * 10))->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, Item::eMaterial_iron)->setDestroyTime(0.5f)->setSoundType(SOUND_WOOD)->setDescriptionId(IDS_TILE_WEIGHTED_PLATE_HEAVY)->setUseDescriptionId(IDS_DESC_WEIGHTED_PLATE_HEAVY); Tile::comparator_off = static_cast((new ComparatorTile(149, false))->setDestroyTime(0.0f)->setSoundType(SOUND_WOOD)->setIconName(L"comparator_off")->setDescriptionId(IDS_TILE_COMPARATOR)->setUseDescriptionId(IDS_DESC_COMPARATOR)); Tile::comparator_on = static_cast((new ComparatorTile(150, true))->setDestroyTime(0.0f)->setLightEmission(10 / 16.0f)->setSoundType(SOUND_WOOD)->setIconName(L"comparator_on")->setDescriptionId(IDS_TILE_COMPARATOR)->setUseDescriptionId(IDS_DESC_COMPARATOR)); @@ -512,12 +560,13 @@ void Tile::staticCtor() Tile::stairs_quartz = (new StairTile(156, Tile::quartzBlock, QuartzBlockTile::TYPE_DEFAULT)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_quartz)->setIconName(L"stairsQuartz")->setDescriptionId(IDS_TILE_STAIRS_QUARTZ)->setUseDescriptionId(IDS_DESC_STAIRS); Tile::activatorRail = (new PoweredRailTile(157)) ->setDestroyTime(0.7f)->setSoundType(SOUND_METAL)->setIconName(L"rail_activator")->setDescriptionId(IDS_TILE_ACTIVATOR_RAIL)->setUseDescriptionId(IDS_DESC_ACTIVATOR_RAIL); Tile::dropper = (new DropperTile(158)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_redstoneContainer, Item::eMaterial_undefined)->setDestroyTime(3.5f)->setSoundType(SOUND_STONE)->setIconName(L"dropper")->setDescriptionId(IDS_TILE_DROPPER)->setUseDescriptionId(IDS_DESC_DROPPER); - Tile::clayHardened_colored = (new ColoredTile(159, Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_clay, Item::eMaterial_clay)->setDestroyTime(1.25f)->setExplodeable(7)->setSoundType(SOUND_STONE)->setIconName(L"hardened_clay_stained")->setDescriptionId(IDS_TILE_STAINED_CLAY)->setUseDescriptionId(IDS_DESC_STAINED_CLAY); + Tile::stained_hardened_clay = (new ColoredTile(159, Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_clay, Item::eMaterial_clay)->setDestroyTime(1.25f)->setExplodeable(7)->setSoundType(SOUND_STONE)->setIconName(L"hardened_clay_stained")->setDescriptionId(IDS_TILE_STAINED_CLAY)->setUseDescriptionId(IDS_DESC_STAINED_CLAY); Tile::stained_glass_pane = (new StainedGlassPaneBlock(160)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_glass, Item::eMaterial_glass)->setDestroyTime(0.3f)->setSoundType(SOUND_GLASS)->setIconName(L"glass")->setDescriptionId(IDS_TILE_STAINED_GLASS_PANE)->setUseDescriptionId(IDS_DESC_STAINED_GLASS_PANE); // - Tile::tree2Trunk = (new TreeTile2(162))->setDestroyTime(2.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"log")->setDescriptionId(IDS_TILE_LOG)->sendTileData()->setUseDescriptionId(IDS_DESC_LOG); + Tile::log2 = (new TreeTile2(162))->setDestroyTime(2.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"log")->setDescriptionId(IDS_TILE_LOG)->sendTileData()->setUseDescriptionId(IDS_DESC_LOG); Tile::woodStairsAcacia = (new StairTile(163, Tile::wood, TreeTile::ACACIA_TRUNK))->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_acaciawood)->setIconName(L"stairsWoodAcacia")->setDescriptionId(IDS_TILE_STAIRS_ACACIAWOOD)->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); Tile::woodStairsDark = (new StairTile(164, Tile::wood, TreeTile::DARK_TRUNK))->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_darkwood)->setIconName(L"stairsWoodDark")->setDescriptionId(IDS_TILE_STAIRS_DARKWOOD)->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); + Tile::slimeBlock = (new SlimeTile(165))->setSoundType(SOUND_SLIME)->setIconName(L"slime")->setDescriptionId(IDS_TILE_SLIME_BLOCK)->setUseDescriptionId(IDS_DESC_SLIME_BLOCK)->disableMipmap(); Tile::barrier = (new BarrierTile(166, Material::stone, false)) ->setIndestructible()->setExplodeable(6000000)->setSoundType(Tile::SOUND_STONE)->setIconName(L"barrier")->setDescriptionId(IDS_TILE_BARRIER)->setNotCollectStatistics()->setUseDescriptionId(IDS_DESC_BARRIER); Tile::iron_trapdoor = (new TrapDoorTile(167, Material::metal))->setBaseItemTypeAndMaterial(Item::eBaseItemType_door, Item::eMaterial_trap)->setDestroyTime(5.0f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"iron_trapdoor")->setDescriptionId(IDS_TILE_IRON_TRAPDOOR)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_TRAPDOOR); @@ -529,9 +578,9 @@ void Tile::staticCtor() // Tile::packedIce = (new PackedIceTile(174))->setDestroyTime(0.5f)->setSoundType(SOUND_GLASS)->setIconName(L"packed_ice")->setDescriptionId(IDS_TILE_PACKED_ICE)->setUseDescriptionId(IDS_DESC_PACKED_ICE); - Tile::invertedDaylightDetector = static_cast((new DaylightDetectorTile(178, true))->setDestroyTime(0.2f)->setSoundType(SOUND_WOOD)->setIconName(L"daylight_detector")->setDescriptionId(IDS_TILE_DAYLIGHT_DETECTOR)->setUseDescriptionId(IDS_DESC_DAYLIGHT_DETECTOR)); + Tile::daylight_detector_inverted = static_cast((new DaylightDetectorTile(178, true))->setDestroyTime(0.2f)->setSoundType(SOUND_WOOD)->setIconName(L"daylight_detector")->setDescriptionId(IDS_TILE_DAYLIGHT_DETECTOR)->setUseDescriptionId(IDS_DESC_DAYLIGHT_DETECTOR)); Tile::red_sandstone = (new RedSandStoneTile(red_sandstone_Id))->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_sand)->setSoundType(Tile::SOUND_STONE)->setDestroyTime(0.8f)->sendTileData()->setIconName(L"red_sandstone")->setDescriptionId(IDS_TILE_RED_SANDSTONE)->setUseDescriptionId(IDS_DESC_RED_SANDSTONE)->sendTileData(); - Tile::stairs_red_sandstone = (new StairTile(stairs_red_sandstone_Id, Tile::red_sandstone, 0))->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_sand)->setIconName(L"stairsRedSandstone")->setDescriptionId(IDS_TILE_STAIRS_RED_SANDSTONE)->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); + Tile::stairs_red_sandstone = (new StairTile(red_sandstone_stairs_Id, Tile::red_sandstone, 0))->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_sand)->setIconName(L"stairsRedSandstone")->setDescriptionId(IDS_TILE_STAIRS_RED_SANDSTONE)->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); Tile::stoneSlab2 = static_cast((new FullStoneSlabTile2(double_stone_slab2_Id))->setBaseItemTypeAndMaterial(Item::eBaseItemType_slab, Item::eMaterial_stone)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->sendTileData()->setIconName(L"red_sandstone")->setDescriptionId(IDS_TILE_RED_SANDSTONE)->setUseDescriptionId(IDS_DESC_SLAB)); Tile::stoneSlab2Half = static_cast((new HalfStoneSlabTile2(stone_slab2_Id))->setBaseItemTypeAndMaterial(Item::eBaseItemType_halfslab, Item::eMaterial_stone)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->sendTileData()->setIconName(L"red_sandstone")->setDescriptionId(IDS_TILE_RED_SANDSTONE)->setUseDescriptionId(IDS_DESC_HALFSLAB)); @@ -551,25 +600,25 @@ void Tile::staticCtor() Tile::seaLantern = (new SeaLanternTile(169, Material::glass))->setBaseItemTypeAndMaterial(Item::eBaseItemType_torch, Item::eMaterial_glowstone)->setDestroyTime(0.3f)->setSoundType(Tile::SOUND_GLASS)->setLightEmission(1.0f)->setIconName(L"glowstone")->setDescriptionId(IDS_TILE_SEA_LANTERN)->setUseDescriptionId(IDS_DESC_SEA_LANTERN); Tile::prismarine = (new PrismarineTile(168))->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_stone)->setDestroyTime(1.5f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setIconName(L"prismarine")->setDescriptionId(IDS_TILE_PRISMARINE)->setUseDescriptionId(IDS_DESC_PRISMARINE); - Tile::tallgrass2 = static_cast((new TallGrass2(175))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"tallgrass2_tall_grass_upper")->setDescriptionId(IDS_DESC_DOUBLE_TALL_GRASS)->setUseDescriptionId(IDS_DESC_TALL_GRASS)->disableMipmap()->sendTileData(0xFF)); + Tile::double_plant = static_cast((new TallGrass2(175))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"tallgrass2_tall_grass_upper")->setDescriptionId(IDS_DESC_DOUBLE_TALL_GRASS)->setUseDescriptionId(IDS_DESC_TALL_GRASS)->disableMipmap()->sendTileData(0xFF)); // Special cases for certain items since they can have different icons Item::items[wool_Id] = ( new WoolTileItem(Tile::wool_Id- 256) )->setIconName(L"cloth")->setDescriptionId(IDS_TILE_CLOTH)->setUseDescriptionId(IDS_DESC_WOOL); - Item::items[clayHardened_colored_Id]= ( new WoolTileItem(Tile::clayHardened_colored_Id - 256))->setIconName(L"clayHardenedStained")->setDescriptionId(IDS_TILE_STAINED_CLAY)->setUseDescriptionId(IDS_DESC_STAINED_CLAY); + Item::items[stained_hardened_clay_Id]= ( new WoolTileItem(Tile::stained_hardened_clay_Id - 256))->setIconName(L"clayHardenedStained")->setDescriptionId(IDS_TILE_STAINED_CLAY)->setUseDescriptionId(IDS_DESC_STAINED_CLAY); Item::items[stained_glass_Id] = ( new WoolTileItem(Tile::stained_glass_Id - 256))->setIconName(L"stainedGlass")->setDescriptionId(IDS_TILE_STAINED_GLASS)->setUseDescriptionId(IDS_DESC_STAINED_GLASS); Item::items[stained_glass_pane_Id] = ( new WoolTileItem(Tile::stained_glass_pane_Id - 256))->setIconName(L"stainedGlassPane")->setDescriptionId(IDS_TILE_STAINED_GLASS_PANE)->setUseDescriptionId(IDS_DESC_STAINED_GLASS_PANE); - Item::items[woolCarpet_Id] = ( new WoolTileItem(Tile::woolCarpet_Id - 256))->setIconName(L"woolCarpet")->setDescriptionId(IDS_TILE_CARPET)->setUseDescriptionId(IDS_DESC_CARPET); - Item::items[treeTrunk_Id] = (new MultiTextureTileItem(Tile::treeTrunk_Id - 256, treeTrunk, (int*)TreeTile::TREE_NAMES, 6))->setIconName(L"log")->setDescriptionId(IDS_TILE_LOG)->setUseDescriptionId(IDS_DESC_LOG); - Item::items[wood_Id] = (new MultiTextureTileItem(Tile::wood_Id - 256, Tile::wood, (int*)WoodTile::WOOD_NAMES, 6, IDS_TILE_PLANKS))->setIconName(L"wood")->setDescriptionId(IDS_TILE_OAKWOOD_PLANKS)->setUseDescriptionId(IDS_DESC_LOG); // <- TODO - Item::items[monsterStoneEgg_Id] = ( new MultiTextureTileItem(Tile::monsterStoneEgg_Id - 256, monsterStoneEgg, (int *)StoneMonsterTile::STONE_MONSTER_NAMES, 3))->setIconName(L"monsterStoneEgg")->setDescriptionId(IDS_TILE_STONE_SILVERFISH)->setUseDescriptionId(IDS_DESC_STONE_SILVERFISH); // 4J - Brought forward from post-1.2 to fix stacking problem + Item::items[carpet_Id] = ( new WoolTileItem(Tile::carpet_Id - 256))->setIconName(L"woolCarpet")->setDescriptionId(IDS_TILE_CARPET)->setUseDescriptionId(IDS_DESC_CARPET); + Item::items[log_Id] = (new MultiTextureTileItem(Tile::log_Id - 256, treeTrunk, (int*)TreeTile::TREE_NAMES, 6))->setIconName(L"log")->setDescriptionId(IDS_TILE_LOG)->setUseDescriptionId(IDS_DESC_LOG); + Item::items[planks_Id] = (new MultiTextureTileItem(Tile::planks_Id - 256, Tile::wood, (int*)WoodTile::WOOD_NAMES, 6, IDS_TILE_PLANKS))->setIconName(L"wood")->setDescriptionId(IDS_TILE_OAKWOOD_PLANKS)->setUseDescriptionId(IDS_DESC_LOG); // <- TODO + Item::items[monster_egg_Id] = ( new MultiTextureTileItem(Tile::monster_egg_Id - 256, monster_egg, (int *)StoneMonsterTile::STONE_MONSTER_NAMES, 3))->setIconName(L"monster_egg")->setDescriptionId(IDS_TILE_STONE_SILVERFISH)->setUseDescriptionId(IDS_DESC_STONE_SILVERFISH); // 4J - Brought forward from post-1.2 to fix stacking problem Item::items[stone_Id] = ( new MultiTextureTileItem(Tile::stone_Id - 256,Tile::stone,(int*)StoneTile::STONE_NAMES, StoneTile::STONE_NAMES_LENGTH))->setIconName(L"stone")->setDescriptionId(IDS_TILE_STONE); - Item::items[stoneBrick_Id] = ( new MultiTextureTileItem(Tile::stoneBrick_Id - 256, stoneBrick,(int *)SmoothStoneBrickTile::SMOOTH_STONE_BRICK_NAMES, 4))->setIconName(L"stonebricksmooth")->setDescriptionId(IDS_TILE_STONE_BRICK_SMOOTH); - Item::items[sandStone_Id] = ( new MultiTextureTileItem(sandStone_Id - 256, sandStone, SandStoneTile::SANDSTONE_NAMES, SandStoneTile::SANDSTONE_BLOCK_NAMES) )->setIconName(L"sandStone")->setDescriptionId(IDS_TILE_SANDSTONE)->setUseDescriptionId(IDS_DESC_SANDSTONE); - Item::items[quartzBlock_Id] = ( new MultiTextureTileItem(quartzBlock_Id - 256, quartzBlock, QuartzBlockTile::BLOCK_NAMES, QuartzBlockTile::QUARTZ_BLOCK_NAMES) )->setIconName(L"quartzBlock")->setDescriptionId(IDS_TILE_QUARTZ_BLOCK)->setUseDescriptionId(IDS_DESC_QUARTZ_BLOCK); - Item::items[stoneSlabHalf_Id] = ( new StoneSlabTileItem(Tile::stoneSlabHalf_Id - 256, Tile::stoneSlabHalf, Tile::stoneSlab, false) )->setIconName(L"stoneSlab")->setDescriptionId(IDS_TILE_STONESLAB)->setUseDescriptionId(IDS_DESC_HALFSLAB); - Item::items[stoneSlab_Id] = ( new StoneSlabTileItem(Tile::stoneSlab_Id - 256, Tile::stoneSlabHalf, Tile::stoneSlab, true))->setIconName(L"stoneSlab")->setDescriptionId(IDS_DESC_STONESLAB)->setUseDescriptionId(IDS_DESC_SLAB); - Item::items[woodSlabHalf_Id] = ( new StoneSlabTileItem(Tile::woodSlabHalf_Id - 256, Tile::woodSlabHalf, Tile::woodSlab, false))->setIconName(L"woodSlab")->setDescriptionId(IDS_DESC_WOODSLAB)->setUseDescriptionId(IDS_DESC_WOODSLAB); - Item::items[woodSlab_Id] = ( new StoneSlabTileItem(Tile::woodSlab_Id - 256, Tile::woodSlabHalf, Tile::woodSlab, true))->setIconName(L"woodSlab")->setDescriptionId(IDS_DESC_WOODSLAB)->setUseDescriptionId(IDS_DESC_WOODSLAB); + Item::items[stonebrick_Id] = ( new MultiTextureTileItem(Tile::stonebrick_Id - 256, stoneBrick,(int *)SmoothStoneBrickTile::SMOOTH_STONE_BRICK_NAMES, 4))->setIconName(L"stonebricksmooth")->setDescriptionId(IDS_TILE_STONE_BRICK_SMOOTH); + Item::items[sandstone_Id] = ( new MultiTextureTileItem(sandstone_Id - 256, sandStone, SandStoneTile::SANDSTONE_NAMES, SandStoneTile::SANDSTONE_BLOCK_NAMES) )->setIconName(L"sandStone")->setDescriptionId(IDS_TILE_SANDSTONE)->setUseDescriptionId(IDS_DESC_SANDSTONE); + Item::items[quartz_block_Id] = ( new MultiTextureTileItem(quartz_block_Id - 256, quartzBlock, QuartzBlockTile::BLOCK_NAMES, QuartzBlockTile::QUARTZ_BLOCK_NAMES) )->setIconName(L"quartzBlock")->setDescriptionId(IDS_TILE_QUARTZ_BLOCK)->setUseDescriptionId(IDS_DESC_QUARTZ_BLOCK); + Item::items[stone_slab_Id] = ( new StoneSlabTileItem(Tile::stone_slab_Id - 256, Tile::stoneSlabHalf, Tile::stoneSlab, false) )->setIconName(L"stoneSlab")->setDescriptionId(IDS_TILE_STONESLAB)->setUseDescriptionId(IDS_DESC_HALFSLAB); + Item::items[double_stone_slab_Id] = ( new StoneSlabTileItem(Tile::double_stone_slab_Id - 256, Tile::stoneSlabHalf, Tile::stoneSlab, true))->setIconName(L"stoneSlab")->setDescriptionId(IDS_DESC_STONESLAB)->setUseDescriptionId(IDS_DESC_SLAB); + Item::items[wooden_slab_Id] = ( new StoneSlabTileItem(Tile::wooden_slab_Id - 256, Tile::woodSlabHalf, Tile::woodSlab, false))->setIconName(L"woodSlab")->setDescriptionId(IDS_DESC_WOODSLAB)->setUseDescriptionId(IDS_DESC_WOODSLAB); + Item::items[double_wooden_slab_Id] = ( new StoneSlabTileItem(Tile::double_wooden_slab_Id - 256, Tile::woodSlabHalf, Tile::woodSlab, true))->setIconName(L"woodSlab")->setDescriptionId(IDS_DESC_WOODSLAB)->setUseDescriptionId(IDS_DESC_WOODSLAB); Item::items[sapling_Id] = (new MultiTextureTileItem(Tile::sapling_Id - 256, Tile::sapling, Sapling::SAPLING_NAMES, Sapling::SAPLING_NAMES_SIZE))->setIconName(L"sapling")->setDescriptionId(IDS_TILE_SAPLING)->setUseDescriptionId(IDS_DESC_SAPLING);; //Item::items[sapling2_Id] = ( new MultiTextureTileItem(Tile::sapling2_Id - 256, Tile::sapling2, Sapling2::SAPLING_NAMES, 2) )->setIconName(L"sapling2")->setDescriptionId(IDS_TILE_SAPLING)->setUseDescriptionId(IDS_DESC_SAPLING); Item::items[leaves_Id] = ( new LeafTileItem(Tile::leaves_Id - 256) )->setIconName(L"leaves")->setDescriptionId(IDS_TILE_LEAVES)->setUseDescriptionId(IDS_DESC_LEAVES); @@ -578,23 +627,23 @@ void Tile::staticCtor() int idsData[3] = {IDS_TILE_SHRUB, IDS_TILE_TALL_GRASS, IDS_TILE_FERN}; intArray ids = intArray(idsData, 3); Item::items[tallgrass_Id] = static_cast((new ColoredTileItem(Tile::tallgrass_Id - 256, true))->setDescriptionId(IDS_TILE_TALL_GRASS))->setDescriptionPostfixes(ids); - Item::items[topSnow_Id] = ( new SnowItem(topSnow_Id - 256, topSnow) ); - Item::items[waterLily_Id] = ( new WaterLilyTileItem(Tile::waterLily_Id - 256)); - Item::items[pistonBase_Id] = ( new PistonTileItem(Tile::pistonBase_Id - 256) )->setDescriptionId(IDS_TILE_PISTON_BASE)->setUseDescriptionId(IDS_DESC_PISTON); - Item::items[pistonStickyBase_Id] = ( new PistonTileItem(Tile::pistonStickyBase_Id - 256) )->setDescriptionId(IDS_TILE_PISTON_STICK_BASE)->setUseDescriptionId(IDS_DESC_STICKY_PISTON); - Item::items[cobbleWall_Id] = ( new MultiTextureTileItem(cobbleWall_Id - 256, cobbleWall, (int *)WallTile::COBBLE_NAMES, 2) )->setDescriptionId(IDS_TILE_COBBLESTONE_WALL)->setUseDescriptionId(IDS_DESC_COBBLESTONE_WALL); + Item::items[snow_layer_Id] = ( new SnowItem(snow_layer_Id - 256, topSnow) ); + Item::items[waterlily_Id] = ( new WaterLilyTileItem(Tile::waterlily_Id - 256)); + Item::items[piston_Id] = ( new PistonTileItem(Tile::piston_Id - 256) )->setDescriptionId(IDS_TILE_PISTON_BASE)->setUseDescriptionId(IDS_DESC_PISTON); + Item::items[sticky_piston_Id] = ( new PistonTileItem(Tile::sticky_piston_Id - 256) )->setDescriptionId(IDS_TILE_PISTON_STICK_BASE)->setUseDescriptionId(IDS_DESC_STICKY_PISTON); + Item::items[cobblestone_wall_Id] = ( new MultiTextureTileItem(cobblestone_wall_Id - 256, cobbleWall, (int *)WallTile::COBBLE_NAMES, 2) )->setDescriptionId(IDS_TILE_COBBLESTONE_WALL)->setUseDescriptionId(IDS_DESC_COBBLESTONE_WALL); Item::items[anvil_Id] = ( new AnvilTileItem(anvil) )->setDescriptionId(IDS_TILE_ANVIL)->setUseDescriptionId(IDS_DESC_ANVIL); Item::items[dirt_Id] = (new MultiTextureTileItem(Tile::dirt_Id - 256, dirt, (int*)DirtTile::DIRT_NAMES, 3))->setIconName(L"dirt")->setDescriptionId(IDS_TILE_DIRT)->setUseDescriptionId(IDS_DESC_DIRT); - Item::items[rose_Id] = (new MultiTextureTileItem(Tile::rose_Id - 256, rose, (int*)Rose::FLOWER_NAMES, Rose::FLOWER_NAMES_LENGTH))->setIconName(L"flower_rose")->setDescriptionId(IDS_TILE_ROSE)->setUseDescriptionId(IDS_DESC_FLOWER); + Item::items[red_flower_Id] = (new MultiTextureTileItem(Tile::red_flower_Id - 256, rose, (int*)Rose::FLOWER_NAMES, Rose::FLOWER_NAMES_LENGTH))->setIconName(L"flower_rose")->setDescriptionId(IDS_TILE_ROSE)->setUseDescriptionId(IDS_DESC_FLOWER); Item::items[sand_Id] = (new MultiTextureTileItem(Tile::sand_Id - 256, sand, (int*)SandTile::SAND_NAMES, SandTile::SAND_NAMES_LENGTH))->setIconName(L"sand")->setDescriptionId(IDS_TILE_SAND)->setUseDescriptionId(IDS_DESC_SAND); Item::items[red_sandstone_Id] = (new MultiTextureTileItem(Tile::red_sandstone_Id - 256, red_sandstone, (int*)RedSandStoneTile::SANDSTONE_NAMES, RedSandStoneTile::SANDSTONE_BLOCK_NAMES))->setIconName(L"red_sandstone")->setDescriptionId(IDS_TILE_RED_SANDSTONE)->setUseDescriptionId(IDS_DESC_SANDSTONE); Item::items[stone_slab2_Id] = (new StoneSlabTileItem(Tile::stone_slab2_Id - 256, Tile::stoneSlab2Half, Tile::stoneSlab2, false))->setIconName(L"red_sandstone")->setDescriptionId(IDS_TILE_RED_SANDSTONE)->setUseDescriptionId(IDS_DESC_HALFSLAB); Item::items[double_stone_slab2_Id] = (new StoneSlabTileItem(Tile::double_stone_slab2_Id - 256, Tile::stoneSlab2Half, Tile::stoneSlab2, true))->setIconName(L"red_sandstone")->setDescriptionId(IDS_TILE_RED_SANDSTONE)->setUseDescriptionId(IDS_DESC_SLAB); - Item::items[tree2Trunk_Id] = (new MultiTextureTileItem(Tile::tree2Trunk_Id - 256, tree2Trunk, (int*)TreeTile2::TREE_NAMES, TreeTile2::TREE_NAMES_LENGTH))->setIconName(L"log")->setDescriptionId(IDS_TILE_LOG)->setUseDescriptionId(IDS_DESC_LOG); + Item::items[log2_Id] = (new MultiTextureTileItem(Tile::log2_Id - 256, log2, (int*)TreeTile2::TREE_NAMES, TreeTile2::TREE_NAMES_LENGTH))->setIconName(L"log")->setDescriptionId(IDS_TILE_LOG)->setUseDescriptionId(IDS_DESC_LOG); Item::items[sponge_Id] = (new MultiTextureTileItem(Tile::sponge_Id - 256, sponge, (int*)Sponge::SPONGE_NAMES, Sponge::SPONGE_NAMES_LENGTH))->setIconName(L"sponge")->setDescriptionId(IDS_TILE_SPONGE)->setUseDescriptionId(IDS_DESC_SPONGE); - int tallgrass2IdsData[TallGrass2::VARIANT_COUNT] = { + int double_plantIdsData[TallGrass2::VARIANT_COUNT] = { IDS_TILE_SUNFLOWER, // 0 - Sunflower, not implemented yet IDS_TILE_LILAC, // 1 - Lilac IDS_TILE_DOUBLE_TALL_GRASS, // 2 - Tall Grass @@ -602,8 +651,8 @@ void Tile::staticCtor() IDS_TILE_ROSE_BUSH, // 4 - Rose Bush IDS_TILE_PEONY, // 5 - Peony }; - intArray tallgrass2Ids = intArray(tallgrass2IdsData, 6); - Item::items[tallgrass2_Id] = static_cast((new TallGrass2TileItem(Tile::tallgrass2_Id - 256))->setDescriptionId(IDS_TILE_DOUBLE_TALL_GRASS)->setUseDescriptionId(IDS_DESC_TALL_GRASS))->setDescriptionPostfixes(tallgrass2Ids); + intArray double_plantIds = intArray(double_plantIdsData, 6); + Item::items[double_plant_Id] = static_cast((new double_plantTileItem(Tile::double_plant_Id - 256))->setDescriptionId(IDS_TILE_DOUBLE_TALL_GRASS)->setUseDescriptionId(IDS_DESC_TALL_GRASS))->setDescriptionPostfixes(double_plantIds); for (int i = 0; i < 256; i++) { @@ -659,6 +708,9 @@ void Tile::_init(int id, Material *material, bool isSolidRender) _isTicking = false; _isEntityTile = false; + m_blockStateDefinition = nullptr; + m_defaultBlockState = 0; + /* 4J - TODO if (Tile.tiles[id] != null) { @@ -1188,7 +1240,9 @@ bool Tile::mayPlace(Level *level, int x, int y, int z, int face) bool Tile::mayPlace(Level *level, int x, int y, int z) { int t = level->getTile(x, y, z); - return t == 0 || Tile::tiles[t]->material->isReplaceable(); + Tile *tile = Tile::tiles[t]; + if (tile == nullptr && t != 0) return false; + return t == 0 || tile->material->isReplaceable(); } // 4J-PB - Adding a TestUse for tooltip display @@ -1364,8 +1418,8 @@ void Tile::playerDestroy(Level *level, shared_ptr player, int x, int y, player->awardStat(GenericStats::totalBlocksMined(), GenericStats::param_noArgs()); // 4J : WESTY : Added for other award. player->causeFoodExhaustion(FoodConstants::EXHAUSTION_MINE); - if( id == Tile::treeTrunk_Id ) - if( id == Tile::treeTrunk_Id || id == Tile::tree2Trunk_Id ) + if( id == Tile::log_Id ) + if( id == Tile::log_Id || id == Tile::log2_Id ) player->awardStat(GenericStats::mineWood(), GenericStats::param_noArgs()); @@ -1560,6 +1614,12 @@ void Tile::registerIcons(IconRegister *iconRegister) icon = iconRegister->registerIcon(getIconName()); } +void Tile::updateEntityAfterFallOn(Level *level, shared_ptr entity) +{ + if (!entity) return; + entity->fallDistance = 0.0f; +} + wstring Tile::getTileItemIconName() { return L""; @@ -1699,82 +1759,81 @@ const int Tile::stone_Id; const int Tile::grass_Id; const int Tile::dirt_Id; // 4 -const int Tile::wood_Id; +const int Tile::planks_Id; const int Tile::sapling_Id; const int Tile::sapling2_Id; -const int Tile::unbreakable_Id; +const int Tile::bedrock_Id; +const int Tile::flowing_water_Id; const int Tile::water_Id; -const int Tile::calmWater_Id; +const int Tile::flowing_lava_Id; const int Tile::lava_Id; -const int Tile::calmLava_Id; const int Tile::sand_Id; const int Tile::gravel_Id; -const int Tile::goldOre_Id; -const int Tile::ironOre_Id; -const int Tile::coalOre_Id; -const int Tile::treeTrunk_Id; +const int Tile::gold_ore_Id; +const int Tile::iron_ore_Id; +const int Tile::coal_ore_Id; +const int Tile::log_Id; const int Tile::leaves_Id; const int Tile::leaves2_Id; const int Tile::sponge_Id; const int Tile::glass_Id; -const int Tile::lapisOre_Id; -const int Tile::lapisBlock_Id; +const int Tile::lapis_ore_Id; +const int Tile::lapis_block_Id; const int Tile::dispenser_Id; -const int Tile::sandStone_Id; +const int Tile::sandstone_Id; // 25 const int Tile::bed_Id; -const int Tile::goldenRail_Id; -const int Tile::detectorRail_Id; -const int Tile::pistonStickyBase_Id; +const int Tile::golden_rail_Id; +const int Tile::detector_rail_Id; +const int Tile::sticky_piston_Id; const int Tile::web_Id; const int Tile::tallgrass_Id; -const int Tile::deadBush_Id; -const int Tile::pistonBase_Id; -const int Tile::pistonExtensionPiece_Id; +const int Tile::deadbush_Id; +const int Tile::piston_Id; const int Tile::wool_Id; -const int Tile::pistonMovingPiece_Id; -const int Tile::flower_Id; -const int Tile::rose_Id; +const int Tile::piston_extension_Id; +const int Tile::yellow_flower_Id; +const int Tile::red_flower_Id; const int Tile::mushroom_brown_Id; const int Tile::mushroom_red_Id; -const int Tile::goldBlock_Id; -const int Tile::ironBlock_Id; -const int Tile::stoneSlab_Id; -const int Tile::stoneSlabHalf_Id; -const int Tile::redBrick_Id; +const int Tile::gold_block_Id; +const int Tile::iron_block_Id; +const int Tile::double_stone_slab_Id; +const int Tile::stone_slab_Id; +const int Tile::brick_block_Id; const int Tile::tnt_Id; const int Tile::bookshelf_Id; -const int Tile::mossyCobblestone_Id; +const int Tile::mossy_cobblestone_Id; const int Tile::obsidian_Id; const int Tile::torch_Id; const int Tile::fire_Id; -const int Tile::mobSpawner_Id; -const int Tile::stairs_wood_Id; +const int Tile::mob_spawner_Id; +const int Tile::oak_stairs_Id; const int Tile::chest_Id; -const int Tile::redStoneDust_Id; -const int Tile::diamondOre_Id; -const int Tile::diamondBlock_Id; -const int Tile::workBench_Id; +const int Tile::redstone_wire_Id; +const int Tile::diamond_ore_Id; +const int Tile::diamond_block_Id; +const int Tile::crafting_table_Id; const int Tile::wheat_Id; const int Tile::farmland_Id; const int Tile::furnace_Id; -const int Tile::furnace_lit_Id; -const int Tile::sign_Id; -const int Tile::door_wood_Id; +const int Tile::lit_furnace_Id; +const int Tile::standing_sign_Id; +const int Tile::wooden_door_Id; const int Tile::ladder_Id; const int Tile::rail_Id; -const int Tile::stairs_stone_Id; -const int Tile::wallSign_Id; +const int Tile::stone_stairs_Id; +const int Tile::wall_standing_sign_Id; const int Tile::lever_Id; -const int Tile::pressurePlate_stone_Id; -const int Tile::door_iron_Id; -const int Tile::pressurePlate_wood_Id; -const int Tile::redStoneOre_Id; -const int Tile::redStoneOre_lit_Id; -const int Tile::redstoneTorch_off_Id; -const int Tile::redstoneTorch_on_Id; -const int Tile::button_stone_Id; -const int Tile::topSnow_Id; +const int Tile::stone_pressure_plate_Id; +const int Tile::iron_door_Id; +const int Tile::wooden_pressure_plate_Id; +const int Tile::redstone_ore_Id; +const int Tile::lit_redstone_ore_Id; +const int Tile::unlit_redstone_torch_Id; +const int Tile::redstone_torch_Id; +const int Tile::stone_button_Id; +const int Tile::snow_layer_Id; const int Tile::ice_Id; const int Tile::snow_Id; const int Tile::cactus_Id; @@ -1783,67 +1842,68 @@ const int Tile::reeds_Id; const int Tile::jukebox_Id; const int Tile::fence_Id; const int Tile::pumpkin_Id; -const int Tile::netherRack_Id; -const int Tile::soulsand_Id; +const int Tile::netherrack_Id; +const int Tile::soul_sand_Id; const int Tile::glowstone_Id; -const int Tile::portalTile_Id; -const int Tile::litPumpkin_Id; +const int Tile::portal_Id; +const int Tile::lit_pumpkin_Id; const int Tile::cake_Id; -const int Tile::diode_off_Id; -const int Tile::diode_on_Id; +const int Tile::unpowered_repeater_Id; +const int Tile::powered_repeater_Id; const int Tile::stained_glass_Id; const int Tile::trapdoor_Id; -const int Tile::monsterStoneEgg_Id; -const int Tile::stoneBrick_Id; -const int Tile::hugeMushroom_brown_Id; -const int Tile::hugeMushroom_red_Id; -const int Tile::ironFence_Id; -const int Tile::thinGlass_Id; -const int Tile::melon_Id; -const int Tile::pumpkinStem_Id; -const int Tile::melonStem_Id; +const int Tile::monster_egg_Id; +const int Tile::stonebrick_Id; +const int Tile::brown_mushroom_block_Id; +const int Tile::red_mushroom_block_Id; +const int Tile::iron_bars_Id; +const int Tile::glass_pane_Id; +const int Tile::melon_block_Id; +const int Tile::pumpkin_stem_Id; +const int Tile::melon_stem_Id; const int Tile::vine_Id; -const int Tile::fenceGate_Id; -const int Tile::stairs_bricks_Id; -const int Tile::stairs_stoneBrick_Id; -const int Tile::mycel_Id; -const int Tile::waterLily_Id; -const int Tile::netherBrick_Id; -const int Tile::netherFence_Id; -const int Tile::stairs_netherBricks_Id; -const int Tile::netherStalk_Id; -const int Tile::enchantTable_Id; -const int Tile::brewingStand_Id; +const int Tile::fence_gate_Id; +const int Tile::brick_stairs_Id; +const int Tile::stone_brick_stairs_Id; +const int Tile::mycelium_Id; +const int Tile::waterlily_Id; +const int Tile::nether_brick_Id; +const int Tile::nether_brick_fence_Id; +const int Tile::nether_brick_stairs_Id; +const int Tile::nether_wart_Id; +const int Tile::enchanting_table_Id; +const int Tile::brewing_stand_Id; const int Tile::cauldron_Id; -const int Tile::endPortalTile_Id; -const int Tile::endPortalFrameTile_Id; -const int Tile::endStone_Id; -const int Tile::dragonEgg_Id; -const int Tile::redstoneLight_Id; -const int Tile::redstoneLight_lit_Id; -const int Tile::woodSlab_Id; -const int Tile::woodSlabHalf_Id; +const int Tile::end_portal_Id; +const int Tile::endPortalFrame_Id; +const int Tile::end_stone_Id; +const int Tile::dragon_egg_Id; +const int Tile::redstone_lamp_Id; +const int Tile::lit_redstone_lamp_Id; +const int Tile::double_wooden_slab_Id; +const int Tile::wooden_slab_Id; const int Tile::cocoa_Id; -const int Tile::stairs_sandstone_Id; -const int Tile::stairs_sprucewood_Id; -const int Tile::stairs_birchwood_Id; -const int Tile::stairs_junglewood_Id; -const int Tile::emeraldOre_Id; -const int Tile::enderChest_Id; -const int Tile::tripWireSource_Id; -const int Tile::tripWire_Id; -const int Tile::emeraldBlock_Id; -const int Tile::cobbleWall_Id; -const int Tile::flowerPot_Id; +const int Tile::sandstone_stairs_Id; +const int Tile::spruce_stairs_Id; +const int Tile::birch_stairs_Id; +const int Tile::jungle_stairs_Id; +const int Tile::emerald_ore_Id; +const int Tile::ender_chest_Id; +const int Tile::tripwire_hook_Id; +const int Tile::tripwire_Id; +const int Tile::emerald_block_Id; +const int Tile::cobblestone_wall_Id; +const int Tile::flower_pot_Id; const int Tile::carrots_Id; const int Tile::potatoes_Id; const int Tile::anvil_Id; -const int Tile::button_wood_Id; +const int Tile::wooden_button_Id; const int Tile::skull_Id; -const int Tile::netherQuartz_Id; -const int Tile::quartzBlock_Id; -const int Tile::stairs_quartz_Id; -const int Tile::woolCarpet_Id; -const int Tile::stairs_acaciawood_Id; -const int Tile::stairs_darkwood_Id; +const int Tile::quartz_ore_Id; +const int Tile::quartz_block_Id; +const int Tile::quartz_stairs_Id; +const int Tile::carpet_Id; +const int Tile::acacia_stairs_Id; +const int Tile::dark_oak_stairs_Id; +const int Tile::slime_Id; #endif diff --git a/Minecraft.World/Tile.h b/Minecraft.World/Tile.h index 8afc8d21..595815dc 100644 --- a/Minecraft.World/Tile.h +++ b/Minecraft.World/Tile.h @@ -65,6 +65,30 @@ protected: }; static DWORD tlsIdxShape; public: + class BlockState { + public: + int value; + BlockState(int v = 0) : value(v) {} + }; + + class BlockStateDefinition { + public: + Tile *owner; + BlockStateDefinition(Tile *ownerTile); + }; + + // create blockstate definition + virtual void createBlockStateDefinition(); + // return default tile blockstate + virtual int defaultBlockState(); + // return blockstate definition + virtual BlockStateDefinition *getBlockStateDefinition(); + // convert blockstate to legacy bitmask + virtual int convertBlockStateToLegacyData(BlockState *state); + // defaultblockstate part 2 + virtual int getBlockState(); + // return blockstate for tile at world position + virtual BlockState getBlockState(LevelSource *level, int x, int y, int z); // Each new thread that needs to use Vec3 pools will need to call one of the following 2 functions, to either create its own // local storage, or share the default storage already allocated by the main thread static void CreateNewThreadStorage(); @@ -125,6 +149,7 @@ public: static SoundType *SOUND_GRAVEL; static SoundType *SOUND_GRASS; static SoundType *SOUND_STONE; + static SoundType *SOUND_SLIME; static SoundType *SOUND_METAL; static SoundType *SOUND_GLASS; static SoundType *SOUND_CLOTH; @@ -175,8 +200,9 @@ public: static const int SHAPE_HOPPER = 38; static const int SHAPE_QUARTZ = 39; static const int SHAPE_THIN_PANE = 40; + static const int SHAPE_SLIME = 41; - static const int SHAPE_COUNT = 41; + static const int SHAPE_COUNT = 42; static Tile **tiles; @@ -194,90 +220,90 @@ public: static const int grass_Id = 2; static const int dirt_Id = 3; static const int cobblestone_Id = 4; - static const int wood_Id = 5; + static const int planks_Id = 5; static const int sapling_Id = 6; //static const int sapling2_Id = 199;//should go inside sapling. - static const int unbreakable_Id = 7; - static const int water_Id = 8; - static const int calmWater_Id = 9; - static const int lava_Id = 10; + static const int bedrock_Id = 7; + static const int flowing_water_Id = 8; + static const int water_Id = 9; + static const int flowing_lava_Id = 10; - static const int calmLava_Id = 11; + static const int lava_Id = 11; static const int sand_Id = 12; static const int gravel_Id = 13; - static const int goldOre_Id = 14; - static const int ironOre_Id = 15; - static const int coalOre_Id = 16; - static const int treeTrunk_Id = 17; + static const int gold_ore_Id = 14; + static const int iron_ore_Id = 15; + static const int coal_ore_Id = 16; + static const int log_Id = 17; static const int leaves_Id = 18; static const int leaves2_Id = 161; static const int sponge_Id = 19; static const int glass_Id = 20; - static const int lapisOre_Id = 21; - static const int lapisBlock_Id = 22; + static const int lapis_ore_Id = 21; + static const int lapis_block_Id = 22; static const int dispenser_Id = 23; - static const int sandStone_Id = 24; + static const int sandstone_Id = 24; static const int noteblock_Id = 25; static const int bed_Id = 26; - static const int goldenRail_Id = 27; - static const int detectorRail_Id = 28; - static const int pistonStickyBase_Id = 29; + static const int golden_rail_Id = 27; + static const int detector_rail_Id = 28; + static const int sticky_piston_Id = 29; static const int web_Id = 30; static const int tallgrass_Id = 31; - static const int deadBush_Id = 32; - static const int pistonBase_Id = 33; - static const int pistonExtensionPiece_Id = 34; + static const int deadbush_Id = 32; + static const int piston_Id = 33; + static const int piston_head_Id = 34; static const int wool_Id = 35; - static const int pistonMovingPiece_Id = 36; - static const int flower_Id = 37; - static const int rose_Id = 38; + static const int piston_extension_Id = 36; + static const int yellow_flower_Id = 37; + static const int red_flower_Id = 38; static const int mushroom_brown_Id = 39; static const int mushroom_red_Id = 40; - static const int goldBlock_Id = 41; - static const int ironBlock_Id = 42; - static const int stoneSlab_Id = 43; - static const int stoneSlabHalf_Id = 44; - static const int redBrick_Id = 45; + static const int gold_block_Id = 41; + static const int iron_block_Id = 42; + static const int double_stone_slab_Id = 43; + static const int stone_slab_Id = 44; + static const int brick_block_Id = 45; static const int tnt_Id = 46; static const int bookshelf_Id = 47; - static const int mossyCobblestone_Id = 48; + static const int mossy_cobblestone_Id = 48; static const int obsidian_Id = 49; static const int torch_Id = 50; static const int fire_Id = 51; - static const int mobSpawner_Id = 52; - static const int stairs_wood_Id = 53; + static const int mob_spawner_Id = 52; + static const int oak_stairs_Id = 53; static const int chest_Id = 54; - static const int redStoneDust_Id = 55; - static const int diamondOre_Id = 56; - static const int diamondBlock_Id = 57; - static const int workBench_Id = 58; + static const int redstone_wire_Id = 55; + static const int diamond_ore_Id = 56; + static const int diamond_block_Id = 57; + static const int crafting_table_Id = 58; static const int wheat_Id = 59; static const int farmland_Id = 60; static const int furnace_Id = 61; - static const int furnace_lit_Id = 62; - static const int sign_Id = 63; - static const int door_wood_Id = 64; + static const int lit_furnace_Id = 62; + static const int standing_sign_Id = 63; + static const int wooden_door_Id = 64; static const int ladder_Id = 65; static const int rail_Id = 66; - static const int stairs_stone_Id = 67; - static const int wallSign_Id = 68; + static const int stone_stairs_Id = 67; + static const int wall_standing_sign_Id = 68; static const int lever_Id = 69; - static const int pressurePlate_stone_Id = 70; + static const int stone_pressure_plate_Id = 70; - static const int door_iron_Id = 71; - static const int pressurePlate_wood_Id = 72; - static const int redStoneOre_Id = 73; - static const int redStoneOre_lit_Id = 74; - static const int redstoneTorch_off_Id = 75; - static const int redstoneTorch_on_Id = 76; - static const int button_stone_Id = 77; - static const int topSnow_Id = 78; + static const int iron_door_Id = 71; + static const int wooden_pressure_plate_Id = 72; + static const int redstone_ore_Id = 73; + static const int lit_redstone_ore_Id = 74; + static const int unlit_redstone_torch_Id = 75; + static const int redstone_torch_Id = 76; + static const int stone_button_Id = 77; + static const int snow_layer_Id = 78; static const int ice_Id = 79; static const int snow_Id = 80; @@ -287,120 +313,120 @@ public: static const int jukebox_Id = 84; static const int fence_Id = 85; static const int pumpkin_Id = 86; - static const int netherRack_Id = 87; - static const int soulsand_Id = 88; + static const int netherrack_Id = 87; + static const int soul_sand_Id = 88; static const int glowstone_Id = 89; - static const int portalTile_Id = 90; + static const int portal_Id = 90; - static const int litPumpkin_Id = 91; + static const int lit_pumpkin_Id = 91; static const int cake_Id = 92; - static const int diode_off_Id = 93; - static const int diode_on_Id = 94; + static const int unpowered_repeater_Id = 93; + static const int powered_repeater_Id = 94; static const int stained_glass_Id = 95; static const int trapdoor_Id = 96; - static const int monsterStoneEgg_Id = 97; - static const int stoneBrick_Id = 98; - static const int hugeMushroom_brown_Id = 99; - static const int hugeMushroom_red_Id = 100; + static const int monster_egg_Id = 97; + static const int stonebrick_Id = 98; + static const int brown_mushroom_block_Id = 99; + static const int red_mushroom_block_Id = 100; - static const int ironFence_Id = 101; - static const int thinGlass_Id = 102; - static const int melon_Id = 103; - static const int pumpkinStem_Id = 104; - static const int melonStem_Id = 105; + static const int iron_bars_Id = 101; + static const int glass_pane_Id = 102; + static const int melon_block_Id = 103; + static const int pumpkin_stem_Id = 104; + static const int melon_stem_Id = 105; static const int vine_Id = 106; - static const int fenceGate_Id = 107; - static const int stairs_bricks_Id = 108; - static const int stairs_stoneBrick_Id = 109; - static const int mycel_Id = 110; + static const int fence_gate_Id = 107; + static const int brick_stairs_Id = 108; + static const int stone_brick_stairs_Id = 109; + static const int mycelium_Id = 110; - static const int waterLily_Id = 111; - static const int netherBrick_Id = 112; - static const int netherFence_Id = 113; - static const int stairs_netherBricks_Id = 114; - static const int netherStalk_Id = 115; - static const int enchantTable_Id = 116; - static const int brewingStand_Id = 117; + static const int waterlily_Id = 111; + static const int nether_brick_Id = 112; + static const int nether_brick_fence_Id = 113; + static const int nether_brick_stairs_Id = 114; + static const int nether_wart_Id = 115; + static const int enchanting_table_Id = 116; + static const int brewing_stand_Id = 117; static const int cauldron_Id = 118; - static const int endPortalTile_Id = 119; - static const int endPortalFrameTile_Id = 120; + static const int end_portal_Id = 119; + static const int end_portal_frame_Id = 120; - static const int endStone_Id = 121; - static const int dragonEgg_Id = 122; - static const int redstoneLight_Id = 123; - static const int redstoneLight_lit_Id = 124; - static const int woodSlab_Id = 125; - static const int woodSlabHalf_Id = 126; + static const int end_stone_Id = 121; + static const int dragon_egg_Id = 122; + static const int redstone_lamp_Id = 123; + static const int lit_redstone_lamp_Id = 124; + static const int double_wooden_slab_Id = 125; + static const int wooden_slab_Id = 126; static const int cocoa_Id = 127; - static const int stairs_sandstone_Id = 128; - static const int emeraldOre_Id = 129; - static const int enderChest_Id = 130; + static const int sandstone_stairs_Id = 128; + static const int emerald_ore_Id = 129; + static const int ender_chest_Id = 130; - static const int tripWireSource_Id = 131; - static const int tripWire_Id = 132; - static const int emeraldBlock_Id = 133; - static const int stairs_sprucewood_Id = 134; - static const int stairs_birchwood_Id = 135; - static const int stairs_junglewood_Id = 136; - static const int commandBlock_Id = 137; + static const int tripwire_hook_Id = 131; + static const int tripwire_Id = 132; + static const int emerald_block_Id = 133; + static const int spruce_stairs_Id = 134; + static const int birch_stairs_Id = 135; + static const int jungle_stairs_Id = 136; + static const int command_block_Id = 137; static const int beacon_Id = 138; - static const int cobbleWall_Id = 139; - static const int flowerPot_Id = 140; + static const int cobblestone_wall_Id = 139; + static const int flower_pot_Id = 140; static const int carrots_Id = 141; static const int potatoes_Id = 142; - static const int button_wood_Id = 143; + static const int wooden_button_Id = 143; static const int skull_Id = 144; static const int anvil_Id = 145; static const int chest_trap_Id = 146; - static const int weightedPlate_light_Id = 147; - static const int weightedPlate_heavy_Id = 148; - static const int comparator_off_Id = 149; - static const int comparator_on_Id = 150; + static const int light_weighted_pressure_plate_Id = 147; + static const int heavy_weighted_pressure_plate_Id = 148; + static const int unpowered_comparator_Id = 149; + static const int powered_comparator_Id = 150; - static const int daylightDetector_Id = 151; - static const int redstoneBlock_Id = 152; - static const int netherQuartz_Id = 153; + static const int daylight_detector_Id = 151; + static const int redstone_block_Id = 152; + static const int quartz_ore_Id = 153; static const int hopper_Id = 154; - static const int quartzBlock_Id = 155; - static const int stairs_quartz_Id = 156; - static const int activatorRail_Id = 157; + static const int quartz_block_Id = 155; + static const int quartz_stairs_Id = 156; + static const int activator_rail_Id = 157; static const int dropper_Id = 158; - static const int clayHardened_colored_Id = 159; + static const int stained_hardened_clay_Id = 159; static const int stained_glass_pane_Id = 160; - static const int tree2Trunk_Id = 162; + static const int log2_Id = 162; - static const int stairs_acaciawood_Id = 163; - static const int stairs_darkwood_Id = 164; - //165 slimeblock + static const int acacia_stairs_Id = 163; + static const int dark_oak_stairs_Id = 164; + static const int slime_Id = 165; static const int barrier_Id = 166; static const int iron_trapdoor_Id = 167; static const int prismarine_Id = 168; - static const int seaLantern_Id = 169; - static const int hayBlock_Id = 170; - static const int woolCarpet_Id = 171; - static const int clayHardened_Id = 172; - static const int coalBlock_Id = 173; - static const int packedIce_Id = 174; - static const int tallgrass2_Id = 175; + static const int sea_lantern_Id = 169; + static const int hay_block_Id = 170; + static const int carpet_Id = 171; + static const int hardened_clay_Id = 172; + static const int coal_block_Id = 173; + static const int packed_ice_Id = 174; + static const int double_plant_Id = 175; //176 standing_banner //177 wall_banner - static const int invertedDaylightDetector_Id = 178; + static const int daylight_detector_inverted_Id = 178; static const int red_sandstone_Id = 179; - static const int stairs_red_sandstone_Id = 180; + static const int red_sandstone_stairs_Id = 180; static const int double_stone_slab2_Id = 181; static const int stone_slab2_Id = 182; - static const int spruceGate_Id = 183; - static const int birchGate_Id = 184; - static const int jungleGate_Id = 185; - static const int darkGate_Id = 186; - static const int acaciaGate_Id = 187; - static const int spruceFence_Id = 188; - static const int birchFence_Id = 189; - static const int jungleFence_Id = 190; - static const int darkFence_Id = 191; - static const int acaciaFence_Id = 192; + static const int spruce_fence_gate_Id = 183; + static const int birch_fence_gate_Id = 184; + static const int jungle_fence_gate_Id = 185; + static const int dark_oak_fence_gate_Id = 186; + static const int acacia_fence_gate_Id = 187; + static const int spruce_fence_Id = 188; + static const int birch_fence_Id = 189; + static const int jungle_fence_Id = 190; + static const int dark_oak_fence_Id = 191; + static const int acacia_fence_Id = 192; static const int spruce_door_Id = 193; static const int birch_door_Id = 194; static const int jungle_door_Id = 195; @@ -458,7 +484,7 @@ public: static Tile *bed; static Tile *goldenRail; static Tile *detectorRail; - static PistonBaseTile *pistonStickyBase; + static PistonBaseTile *sticky_piston; static Tile *web; static TallGrass *tallgrass; static DeadBushTile *deadBush; @@ -493,17 +519,18 @@ public: static Tile *furnace; static Tile *furnace_lit; static Tile *sign; - static Tile *door_wood; + static Tile *wooden_door; static Tile *ladder; static Tile *rail; static Tile *stairs_stone; static Tile *wallSign; + static Tile *slimeBlock; static Tile *lever; static Tile *pressurePlate_stone; - static Tile *door_iron; + static Tile *iron_door; static Tile *pressurePlate_wood; static Tile *redStoneOre; - static Tile *redStoneOre_lit; + static Tile *lit_redstone_ore; static Tile *redstoneTorch_off; static Tile *redstoneTorch_on; static Tile *button; @@ -522,36 +549,36 @@ public: static PortalTile *portalTile; static Tile *litPumpkin; static Tile *cake; - static RepeaterTile *diode_off; - static RepeaterTile *diode_on; + static RepeaterTile *unpowered_repeater; + static RepeaterTile *powered_repeater; static Tile *stained_glass; static Tile *trapdoor; - static Tile *monsterStoneEgg; + static Tile *monster_egg; static Tile *stoneBrick; - static Tile *hugeMushroom_brown; - static Tile *hugeMushroom_red; - static Tile *ironFence; - static Tile *thinGlass; + static Tile *brown_mushroom_block; + static Tile *red_mushroom_block; + static Tile *iron_bars; + static Tile *glass_pane; static Tile *melon; - static Tile *pumpkinStem; - static Tile *melonStem; + static Tile *pumpkin_stem; + static Tile *melon_stem; static Tile *vine; static Tile *fenceGate; static Tile *stairs_bricks; - static Tile *stairs_stoneBrickSmooth; + static Tile *stone_brick_stairsSmooth; static MycelTile *mycel; static Tile *waterLily; static Tile *netherBrick; static Tile *netherFence; - static Tile *stairs_netherBricks; + static Tile *nether_brick_stairs; static Tile *netherStalk; static Tile *enchantTable; static Tile *brewingStand; static CauldronTile *cauldron; - static Tile *endPortalTile; - static Tile *endPortalFrameTile; + static Tile *end_portal; + static Tile *end_portal_frame; static Tile *endStone; static Tile *dragonEgg; static Tile *redstoneLight; @@ -580,13 +607,13 @@ public: static Tile *skull; static Tile *cobbleWall; - static Tile *flowerPot; + static Tile *flower_pot; static Tile *carrots; static Tile *potatoes; static Tile *anvil; static Tile *chest_trap; - static Tile *weightedPlate_light; - static Tile *weightedPlate_heavy; + static Tile *light_weighted_pressure_plate; + static Tile *heavy_weighted_pressure_plate; static ComparatorTile *comparator_off; static ComparatorTile *comparator_on; @@ -599,7 +626,7 @@ public: static Tile *stairs_quartz; static Tile *activatorRail; static Tile *dropper; - static Tile *clayHardened_colored; + static Tile *stained_hardened_clay; static Tile *stained_glass_pane; static Tile *hayBlock; @@ -610,11 +637,11 @@ public: static Tile *barrier; static Tile *iron_trapdoor; - static Tile* door_spruce; - static Tile* door_birch; - static Tile* door_jungle; - static Tile* door_acacia; - static Tile* door_dark; + static Tile* spruce_door; + static Tile* birch_door; + static Tile* jungle_door; + static Tile* acacia_door; + static Tile* dark_oak_door; static Tile* spruceFence; static Tile* birchFence; @@ -628,17 +655,17 @@ public: static Tile* acaciaGate; static Tile* darkGate; - static Tile* invertedDaylightDetector; + static Tile* daylight_detector_inverted; static Tile* red_sandstone; static Tile* stairs_red_sandstone; static HalfSlabTile* stoneSlab2; static HalfSlabTile* stoneSlab2Half; - static Tile* tree2Trunk; + static Tile* log2; static Tile* packedIce; static Tile* seaLantern; static Tile* prismarine; - static TallGrass2* tallgrass2; + static TallGrass2* double_plant; static void staticCtor(); @@ -654,6 +681,9 @@ protected: int m_iMaterial; int m_iBaseItemType; + BlockStateDefinition *m_blockStateDefinition; + int m_defaultBlockState; + // 4J Stu - Removed this in favour of a TLS version //double xx0, yy0, zz0, xx1, yy1, zz1; @@ -820,6 +850,7 @@ protected: public: virtual void registerIcons(IconRegister *iconRegister); + virtual void updateEntityAfterFallOn(Level *level, shared_ptr entity); virtual wstring getTileItemIconName(); // AP - added this function so we can generate the faceFlags for a block in a single fast function diff --git a/Minecraft.World/TileItem.cpp b/Minecraft.World/TileItem.cpp index 4e2e5081..3e73c56e 100644 --- a/Minecraft.World/TileItem.cpp +++ b/Minecraft.World/TileItem.cpp @@ -50,11 +50,11 @@ bool TileItem::useOn(shared_ptr instance, shared_ptr playe { // 4J-PB - Adding a test only version to allow tooltips to be displayed int currentTile = level->getTile(x, y, z); - if (currentTile == Tile::topSnow_Id && (level->getData(x, y, z) & TopSnowTile::HEIGHT_MASK) < 1) + if (currentTile == Tile::snow_layer_Id && (level->getData(x, y, z) & TopSnowTile::HEIGHT_MASK) < 1) { face = Facing::UP; } - else if (currentTile == Tile::vine_Id || currentTile == Tile::tallgrass_Id || currentTile == Tile::deadBush_Id) + else if (currentTile == Tile::vine_Id || currentTile == Tile::tallgrass_Id || currentTile == Tile::deadbush_Id) { } else @@ -87,12 +87,12 @@ bool TileItem::useOn(shared_ptr instance, shared_ptr playe { // 4J-JEV: Snow/Iron Golems do not have owners apparently. int newTileId = level->getTile(x,y,z); - if ( (tileId == Tile::pumpkin_Id || tileId == Tile::litPumpkin_Id) && newTileId == 0 ) + if ( (tileId == Tile::pumpkin_Id || tileId == Tile::lit_pumpkin_Id) && newTileId == 0 ) { eINSTANCEOF golemType; switch (undertile) { - case Tile::ironBlock_Id: golemType = eTYPE_VILLAGERGOLEM; break; + case Tile::iron_block_Id: golemType = eTYPE_VILLAGERGOLEM; break; case Tile::snow_Id: golemType = eTYPE_SNOWMAN; break; default: golemType = eTYPE_NOTSET; break; } @@ -165,11 +165,11 @@ bool TileItem::useOn(shared_ptr instance, shared_ptr playe bool TileItem::mayPlace(Level *level, int x, int y, int z, int face, shared_ptr player, shared_ptr item) { int currentTile = level->getTile(x, y, z); - if (currentTile == Tile::topSnow_Id) + if (currentTile == Tile::snow_layer_Id) { face = Facing::UP; } - else if (currentTile != Tile::vine_Id && currentTile != Tile::tallgrass_Id && currentTile != Tile::deadBush_Id) + else if (currentTile != Tile::vine_Id && currentTile != Tile::tallgrass_Id && currentTile != Tile::deadbush_Id) { if (face == 0) y--; if (face == 1) y++; diff --git a/Minecraft.World/TilePlanterItem.cpp b/Minecraft.World/TilePlanterItem.cpp index 3a8f0dea..2806a018 100644 --- a/Minecraft.World/TilePlanterItem.cpp +++ b/Minecraft.World/TilePlanterItem.cpp @@ -19,11 +19,11 @@ bool TilePlanterItem::useOn(shared_ptr instance, shared_ptrgetTile(x, y, z); - if (currentTile == Tile::topSnow_Id && (level->getData(x, y, z) & TopSnowTile::HEIGHT_MASK) < 1) + if (currentTile == Tile::snow_layer_Id && (level->getData(x, y, z) & TopSnowTile::HEIGHT_MASK) < 1) { face = Facing::UP; } - else if (currentTile == Tile::vine_Id || currentTile == Tile::tallgrass_Id || currentTile == Tile::deadBush_Id) + else if (currentTile == Tile::vine_Id || currentTile == Tile::tallgrass_Id || currentTile == Tile::deadbush_Id) { } else diff --git a/Minecraft.World/TimeCommand.cpp b/Minecraft.World/TimeCommand.cpp index af9a4eba..326654e7 100644 --- a/Minecraft.World/TimeCommand.cpp +++ b/Minecraft.World/TimeCommand.cpp @@ -20,12 +20,17 @@ void TimeCommand::execute(shared_ptr source, byteArray commandDat ByteArrayInputStream bais(commandData); DataInputStream dis(&bais); - bool night = dis.readBoolean(); - - bais.reset(); - int amount = 0; - if(night) amount = 12500; + if (commandData.length >= sizeof(int)) + { + amount = dis.readInt(); + } + else + { + bool night = dis.readBoolean(); + amount = night ? 12500 : 0; + } + doSetTime(source, amount); //logAdminAction(source, "commands.time.set", amount); logAdminAction(source, ChatPacket::e_ChatCustom, L"commands.time.set"); diff --git a/Minecraft.World/TntTile.cpp b/Minecraft.World/TntTile.cpp index eff9efae..440b92d5 100644 --- a/Minecraft.World/TntTile.cpp +++ b/Minecraft.World/TntTile.cpp @@ -16,6 +16,32 @@ TntTile::TntTile(int id) : Tile(id, Material::explosive) iconBottom = nullptr; } +void TntTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TntTile::defaultBlockState() +{ + return 0; +} + +int TntTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & EXPLODE_BIT) : 0; +} + +Tile::BlockState TntTile::getBlockState(int data) +{ + return Tile::BlockState(data & EXPLODE_BIT); +} + +Tile::BlockState TntTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & EXPLODE_BIT); +} + Icon *TntTile::getTexture(int face, int data) { if (face == Facing::DOWN) return iconBottom; @@ -87,7 +113,7 @@ void TntTile::destroy(Level *level, int x, int y, int z, int data, shared_ptr
  • player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly/*=false*/) // 4J added soundOnly param { if (soundOnly) return false; - if (player->getSelectedItem() != nullptr && player->getSelectedItem()->id == Item::flintAndSteel_Id) + if (player->getSelectedItem() != nullptr && player->getSelectedItem()->id == Item::flint_and_steel_Id) { destroy(level, x, y, z, EXPLODE_BIT, player); level->removeTile(x, y, z); diff --git a/Minecraft.World/TntTile.h b/Minecraft.World/TntTile.h index ac73e64b..22883e12 100644 --- a/Minecraft.World/TntTile.h +++ b/Minecraft.World/TntTile.h @@ -11,6 +11,11 @@ private: public: static const int EXPLODE_BIT = 1; TntTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual Icon *getTexture(int face, int data); virtual void onPlace(Level *level, int x, int y, int z); diff --git a/Minecraft.World/ToolRecipies.cpp b/Minecraft.World/ToolRecipies.cpp index 82b02df1..5a5019d7 100644 --- a/Minecraft.World/ToolRecipies.cpp +++ b/Minecraft.World/ToolRecipies.cpp @@ -31,33 +31,33 @@ void ToolRecipies::_init() ADD_OBJECT(map[0],Tile::wood); ADD_OBJECT(map[0],Tile::cobblestone); - ADD_OBJECT(map[0],Item::ironIngot); + ADD_OBJECT(map[0],Item::iron_ingot); ADD_OBJECT(map[0],Item::diamond); - ADD_OBJECT(map[0],Item::goldIngot); + ADD_OBJECT(map[0],Item::gold_ingot); - ADD_OBJECT(map[1],Item::pickAxe_wood); - ADD_OBJECT(map[1],Item::pickAxe_stone); - ADD_OBJECT(map[1],Item::pickAxe_iron); - ADD_OBJECT(map[1],Item::pickAxe_diamond); - ADD_OBJECT(map[1],Item::pickAxe_gold); + ADD_OBJECT(map[1],Item::wooden_pickaxe); + ADD_OBJECT(map[1],Item::stone_pickaxe); + ADD_OBJECT(map[1],Item::iron_pickaxe); + ADD_OBJECT(map[1],Item::diamond_pickaxe); + ADD_OBJECT(map[1],Item::golden_pickaxe); - ADD_OBJECT(map[2],Item::shovel_wood); - ADD_OBJECT(map[2],Item::shovel_stone); - ADD_OBJECT(map[2],Item::shovel_iron); - ADD_OBJECT(map[2],Item::shovel_diamond); - ADD_OBJECT(map[2],Item::shovel_gold); + ADD_OBJECT(map[2],Item::wooden_shovel); + ADD_OBJECT(map[2],Item::stone_shovel); + ADD_OBJECT(map[2],Item::iron_shovel); + ADD_OBJECT(map[2],Item::diamond_shovel); + ADD_OBJECT(map[2],Item::golden_shovel); - ADD_OBJECT(map[3],Item::hatchet_wood); - ADD_OBJECT(map[3],Item::hatchet_stone); - ADD_OBJECT(map[3],Item::hatchet_iron); - ADD_OBJECT(map[3],Item::hatchet_diamond); - ADD_OBJECT(map[3],Item::hatchet_gold); + ADD_OBJECT(map[3],Item::wooden_axe); + ADD_OBJECT(map[3],Item::stone_axe); + ADD_OBJECT(map[3],Item::iron_axe); + ADD_OBJECT(map[3],Item::diamond_axe); + ADD_OBJECT(map[3],Item::golden_axe); - ADD_OBJECT(map[4],Item::hoe_wood); - ADD_OBJECT(map[4],Item::hoe_stone); - ADD_OBJECT(map[4],Item::hoe_iron); - ADD_OBJECT(map[4],Item::hoe_diamond); - ADD_OBJECT(map[4],Item::hoe_gold); + ADD_OBJECT(map[4],Item::wooden_hoe); + ADD_OBJECT(map[4],Item::stone_hoe); + ADD_OBJECT(map[4],Item::iron_hoe); + ADD_OBJECT(map[4],Item::diamond_hoe); + ADD_OBJECT(map[4],Item::golden_hoe); } void ToolRecipies::addRecipes(Recipes *r) @@ -107,7 +107,7 @@ void ToolRecipies::addRecipes(Recipes *r) L"sscig", L" #", // L"# ", // - L'#', Item::ironIngot, + L'#', Item::iron_ingot, L'T' ); } \ No newline at end of file diff --git a/Minecraft.World/TopSnowTile.cpp b/Minecraft.World/TopSnowTile.cpp index 7719f838..da91f91b 100644 --- a/Minecraft.World/TopSnowTile.cpp +++ b/Minecraft.World/TopSnowTile.cpp @@ -13,11 +13,38 @@ const int TopSnowTile::HEIGHT_MASK = 7; // max 8 steps TopSnowTile::TopSnowTile(int id) : Tile(id, Material::topSnow,isSolidRender()) { + m_defaultBlockState = 1; setShape(0, 0, 0, 1, 2 / 16.0f, 1); setTicking(true); updateShape(0); } +void TopSnowTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TopSnowTile::defaultBlockState() +{ + return 1; +} + +int TopSnowTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state && state->value > 0 ? ((state->value - 1) & HEIGHT_MASK) : 0; +} + +Tile::BlockState TopSnowTile::getBlockState(int data) +{ + return Tile::BlockState((data & HEIGHT_MASK) + 1); +} + +Tile::BlockState TopSnowTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState((level->getData(x, y, z) & HEIGHT_MASK) + 1); +} + void TopSnowTile::registerIcons(IconRegister *iconRegister) { icon = iconRegister->registerIcon(L"snow"); @@ -98,7 +125,7 @@ bool TopSnowTile::checkCanSurvive(Level *level, int x, int y, int z) void TopSnowTile::playerDestroy(Level *level, shared_ptr player, int x, int y, int z, int data) { - int type = Item::snowBall->id; + int type = Item::snowball->id; int height = data & HEIGHT_MASK; popResource(level, x, y, z, std::make_shared(type, height + 1, 0)); level->removeTile(x, y, z); @@ -106,7 +133,7 @@ void TopSnowTile::playerDestroy(Level *level, shared_ptr player, int x, int TopSnowTile::getResource(int data, Random *random, int playerBonusLevel) { - return Item::snowBall->id; + return Item::snowball->id; } int TopSnowTile::getResourceCount(Random *random) @@ -128,7 +155,7 @@ bool TopSnowTile::shouldRenderFace(LevelSource *level, int x, int y, int z, int if (face == 1) return true; // 4J - don't render faces if neighbouring tiles are also TopSnowTile with at least the same height as this one // Otherwise we get horrible artifacts from the non-manifold geometry created. Fixes bug #8506 - if ( ( level->getTile(x,y,z) == Tile::topSnow_Id ) && ( face >= 2 ) ) + if ( ( level->getTile(x,y,z) == Tile::snow_layer_Id ) && ( face >= 2 ) ) { int h0 = level->getData(x,y,z) & HEIGHT_MASK; int xx = x; diff --git a/Minecraft.World/TopSnowTile.h b/Minecraft.World/TopSnowTile.h index 059f0f42..e3628eb1 100644 --- a/Minecraft.World/TopSnowTile.h +++ b/Minecraft.World/TopSnowTile.h @@ -14,6 +14,13 @@ public: protected: TopSnowTile(int id); +public: + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(int data); + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + public: void registerIcons(IconRegister *iconRegister); AABB *getAABB(Level *level, int x, int y, int z); diff --git a/Minecraft.World/TorchTile.cpp b/Minecraft.World/TorchTile.cpp index ce600a9b..80af95c9 100644 --- a/Minecraft.World/TorchTile.cpp +++ b/Minecraft.World/TorchTile.cpp @@ -6,6 +6,7 @@ TorchTile::TorchTile(int id) : Tile(id, Material::decoration,isSolidRender()) { + setLightBlock(0); this->setTicking(true); } @@ -77,7 +78,7 @@ bool TorchTile::isConnection(Level *level, int x, int y, int z) int tile = level->getTile(x, y, z); Tile *below = (tile >= 0 && tile < Tile::TILE_NUM_COUNT) ? Tile::tiles[tile] : nullptr; if (below != nullptr && below->getRenderShape() == Tile::SHAPE_FENCE - || tile == Tile::glass_Id || tile == Tile::cobbleWall_Id) + || tile == Tile::glass_Id || tile == Tile::cobblestone_wall_Id) { return true; } diff --git a/Minecraft.World/TransparentTile.cpp b/Minecraft.World/TransparentTile.cpp index 129b16b2..db6d5445 100644 --- a/Minecraft.World/TransparentTile.cpp +++ b/Minecraft.World/TransparentTile.cpp @@ -5,6 +5,7 @@ TransparentTile::TransparentTile(int id, Material *material, bool allowSame, bool isSolidRender) : Tile(id, material,isSolidRender) { this->allowSame = allowSame; + setLightBlock(1); } bool TransparentTile::isSolidRender(bool isServerLevel) diff --git a/Minecraft.World/TrapDoorTile.cpp b/Minecraft.World/TrapDoorTile.cpp index 6ea64172..97ea849a 100644 --- a/Minecraft.World/TrapDoorTile.cpp +++ b/Minecraft.World/TrapDoorTile.cpp @@ -10,9 +10,36 @@ TrapDoorTile::TrapDoorTile(int id, Material *material) : Tile(id, material,isSol { float r = 0.5f; float h = 1.0f; + setLightBlock(0); setShape(0.5f - r, 0, 0.5f - r, 0.5f + r, h, 0.5f + r); } +void TrapDoorTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TrapDoorTile::defaultBlockState() +{ + return 0; +} + +int TrapDoorTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState TrapDoorTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState TrapDoorTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + bool TrapDoorTile::blocksLight() { return false; diff --git a/Minecraft.World/TrapDoorTile.h b/Minecraft.World/TrapDoorTile.h index 19cec150..9629c50a 100644 --- a/Minecraft.World/TrapDoorTile.h +++ b/Minecraft.World/TrapDoorTile.h @@ -25,6 +25,11 @@ protected: public: bool blocksLight(); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); public: bool isSolidRender(bool isServerLevel = false); diff --git a/Minecraft.World/TreeFeature.cpp b/Minecraft.World/TreeFeature.cpp index 2bfec147..07312d73 100644 --- a/Minecraft.World/TreeFeature.cpp +++ b/Minecraft.World/TreeFeature.cpp @@ -44,7 +44,7 @@ bool TreeFeature::place(Level *level, Random *random, int x, int y, int z) if (yy >= 0 && yy < Level::maxBuildHeight) { int tt = level->getTile(xx, yy, zz); - if (tt != 0 && tt != Tile::leaves_Id && tt != Tile::grass_Id && tt != Tile::dirt_Id && tt != Tile::treeTrunk_Id) free = false; + if (tt != 0 && tt != Tile::leaves_Id && tt != Tile::grass_Id && tt != Tile::dirt_Id && tt != Tile::log_Id) free = false; } else { @@ -88,7 +88,7 @@ bool TreeFeature::place(Level *level, Random *random, int x, int y, int z) int t = level->getTile(x, y + hh, z); if (t == 0 || t == Tile::leaves_Id) { - placeBlock(level, x, y + hh, z, Tile::treeTrunk_Id, trunkType); + placeBlock(level, x, y + hh, z, Tile::log_Id, trunkType); if (addJungleFeatures && hh > 0) { if (random->nextInt(3) > 0 && level->isEmptyTile(x - 1, y + hh, z)) diff --git a/Minecraft.World/TreeTile.cpp b/Minecraft.World/TreeTile.cpp index 6cf8da8b..a1ed0ce8 100644 --- a/Minecraft.World/TreeTile.cpp +++ b/Minecraft.World/TreeTile.cpp @@ -21,6 +21,32 @@ TreeTile::TreeTile(int id) : RotatedPillarTile(id, Material::wood) { } +void TreeTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TreeTile::defaultBlockState() +{ + return 0; +} + +int TreeTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & (MASK_TYPE | MASK_FACING)) : 0; +} + +Tile::BlockState TreeTile::getBlockState(int data) +{ + return Tile::BlockState(data & (MASK_TYPE | MASK_FACING)); +} + +Tile::BlockState TreeTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & (MASK_TYPE | MASK_FACING)); +} + int TreeTile::getResourceCount(Random *random) { return 1; @@ -28,7 +54,7 @@ int TreeTile::getResourceCount(Random *random) int TreeTile::getResource(int data, Random *random, int playerBonusLevel) { - return Tile::treeTrunk_Id; + return Tile::log_Id; } void TreeTile::onRemove(Level *level, int x, int y, int z, int id, int data) diff --git a/Minecraft.World/TreeTile.h b/Minecraft.World/TreeTile.h index f227e80a..fdcfcc13 100644 --- a/Minecraft.World/TreeTile.h +++ b/Minecraft.World/TreeTile.h @@ -42,6 +42,11 @@ protected: public: virtual int getResourceCount(Random *random); virtual int getResource(int data, Random *random, int playerBonusLevel); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void onRemove(Level *level, int x, int y, int z, int id, int data); virtual unsigned int getDescriptionId(int iData = -1); diff --git a/Minecraft.World/TreeTile2.cpp b/Minecraft.World/TreeTile2.cpp index 405c2add..e22fadd0 100644 --- a/Minecraft.World/TreeTile2.cpp +++ b/Minecraft.World/TreeTile2.cpp @@ -17,6 +17,32 @@ TreeTile2::TreeTile2(int id) : RotatedPillarTile(id, Material::wood) { } +void TreeTile2::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TreeTile2::defaultBlockState() +{ + return 0; +} + +int TreeTile2::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & (MASK_TYPE | MASK_FACING)) : 0; +} + +Tile::BlockState TreeTile2::getBlockState(int data) +{ + return Tile::BlockState(data & (MASK_TYPE | MASK_FACING)); +} + +Tile::BlockState TreeTile2::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & (MASK_TYPE | MASK_FACING)); +} + int TreeTile2::getResourceCount(Random* random) { return 1; @@ -24,7 +50,7 @@ int TreeTile2::getResourceCount(Random* random) int TreeTile2::getResource(int data, Random* random, int playerBonusLevel) { - return Tile::tree2Trunk_Id; + return Tile::log2_Id; } void TreeTile2::onRemove(Level* level, int x, int y, int z, int id, int data) diff --git a/Minecraft.World/TreeTile2.h b/Minecraft.World/TreeTile2.h index 412341ac..168620d4 100644 --- a/Minecraft.World/TreeTile2.h +++ b/Minecraft.World/TreeTile2.h @@ -38,6 +38,11 @@ protected: public: virtual int getResourceCount(Random* random); virtual int getResource(int data, Random* random, int playerBonusLevel); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void onRemove(Level* level, int x, int y, int z, int id, int data); protected: diff --git a/Minecraft.World/TripWireSourceTile.cpp b/Minecraft.World/TripWireSourceTile.cpp index fcd7564d..1d4ca4a6 100644 --- a/Minecraft.World/TripWireSourceTile.cpp +++ b/Minecraft.World/TripWireSourceTile.cpp @@ -10,6 +10,32 @@ TripWireSourceTile::TripWireSourceTile(int id) : Tile(id, Material::decoration, this->setTicking(true); } +void TripWireSourceTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TripWireSourceTile::defaultBlockState() +{ + return 0; +} + +int TripWireSourceTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState TripWireSourceTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState TripWireSourceTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + AABB *TripWireSourceTile::getAABB(Level *level, int x, int y, int z) { return nullptr; @@ -115,7 +141,7 @@ void TripWireSourceTile::calculateState(Level *level, int x, int y, int z, int i int dir = data & MASK_DIR; bool wasAttached = (data & MASK_ATTACHED) == MASK_ATTACHED; bool wasPowered = (data & MASK_POWERED) == MASK_POWERED; - bool attached = id == Tile::tripWireSource_Id; // id is only != TripwireSource_id when 'onRemove' + bool attached = id == Tile::tripwire_hook_Id; // id is only != tripwire_hook_Id when 'onRemove' bool powered = false; bool suspended = !level->isTopSolidBlocking(x, y - 1, z); int stepX = Direction::STEP_X[dir]; @@ -130,7 +156,7 @@ void TripWireSourceTile::calculateState(Level *level, int x, int y, int z, int i int zz = z + stepZ * i; int tile = level->getTile(xx, y, zz); - if (tile == Tile::tripWireSource_Id) + if (tile == Tile::tripwire_hook_Id) { int otherData = level->getData(xx, y, zz); @@ -141,7 +167,7 @@ void TripWireSourceTile::calculateState(Level *level, int x, int y, int z, int i break; } - else if (tile == Tile::tripWire_Id || i == wireSource) // wireSource is the wiretile that caused an 'updateSource' + else if (tile == Tile::tripwire_Id || i == wireSource) // wireSource is the wiretile that caused an 'updateSource' { int wireData = i == wireSource ? wireSourceData : level->getData(xx, y, zz); bool wireArmed = (wireData & TripWireTile::MASK_DISARMED) != TripWireTile::MASK_DISARMED; diff --git a/Minecraft.World/TripWireSourceTile.h b/Minecraft.World/TripWireSourceTile.h index 83adb9ab..fcb26e14 100644 --- a/Minecraft.World/TripWireSourceTile.h +++ b/Minecraft.World/TripWireSourceTile.h @@ -14,6 +14,11 @@ public: static const int WIRE_DIST_MAX = 2 + 40; // 2 hooks + x string TripWireSourceTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); AABB *getAABB(Level *level, int x, int y, int z); bool blocksLight(); diff --git a/Minecraft.World/TripWireTile.cpp b/Minecraft.World/TripWireTile.cpp index ee302af2..40b6ee58 100644 --- a/Minecraft.World/TripWireTile.cpp +++ b/Minecraft.World/TripWireTile.cpp @@ -11,6 +11,39 @@ TripWireTile::TripWireTile(int id) : Tile(id, Material::decoration, isSolidRende this->setTicking(true); } +void TripWireTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int TripWireTile::defaultBlockState() +{ + return 0; +} + +int TripWireTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState TripWireTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState TripWireTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + int data = level->getData(x, y, z); + int state = 0; + if (shouldConnectTo(level, x, y, z, data, Direction::NORTH)) state |= 0x1; + if (shouldConnectTo(level, x, y, z, data, Direction::SOUTH)) state |= 0x2; + if (shouldConnectTo(level, x, y, z, data, Direction::EAST)) state |= 0x4; + if (shouldConnectTo(level, x, y, z, data, Direction::WEST)) state |= 0x8; + if ((data & MASK_POWERED) == MASK_POWERED) state |= BLOCKSTATE_POWERED_BIT; + return Tile::BlockState(state); +} + int TripWireTile::getTickDelay(Level *level) { // 4J: Increased (x2); quick update caused problems with shared @@ -122,7 +155,7 @@ void TripWireTile::updateSource(Level *level, int x, int y, int z, int data) int zz = z + Direction::STEP_Z[dir] * i; int tile = level->getTile(xx, y, zz); - if (tile == Tile::tripWireSource_Id) + if (tile == Tile::tripwire_hook_Id) { int sourceDir = level->getData(xx, y, zz) & TripWireSourceTile::MASK_DIR; @@ -133,7 +166,7 @@ void TripWireTile::updateSource(Level *level, int x, int y, int z, int data) break; } - else if (tile != Tile::tripWire_Id) + else if (tile != Tile::tripwire_Id) { break; } @@ -209,7 +242,7 @@ bool TripWireTile::shouldConnectTo(LevelSource *level, int x, int y, int z, int int t = level->getTile(tx, ty, tz); bool suspended = (data & MASK_SUSPENDED) == MASK_SUSPENDED; - if (t == Tile::tripWireSource_Id) + if (t == Tile::tripwire_hook_Id) { int otherData = level->getData(tx, ty, tz); int facing = otherData & TripWireSourceTile::MASK_DIR; @@ -217,7 +250,7 @@ bool TripWireTile::shouldConnectTo(LevelSource *level, int x, int y, int z, int return facing == Direction::DIRECTION_OPPOSITE[dir]; } - if (t == Tile::tripWire_Id) + if (t == Tile::tripwire_Id) { int otherData = level->getData(tx, ty, tz); bool otherSuspended = (otherData & MASK_SUSPENDED) == MASK_SUSPENDED; diff --git a/Minecraft.World/TripWireTile.h b/Minecraft.World/TripWireTile.h index 7880e664..04ebb925 100644 --- a/Minecraft.World/TripWireTile.h +++ b/Minecraft.World/TripWireTile.h @@ -10,8 +10,14 @@ public: static const int MASK_SUSPENDED = 0x2; static const int MASK_ATTACHED = 0x4; static const int MASK_DISARMED = 0x8; + static const int BLOCKSTATE_POWERED_BIT = 0x10; TripWireTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); int getTickDelay(Level *level); AABB *getAABB(Level *level, int x, int y, int z); diff --git a/Minecraft.World/Village.cpp b/Minecraft.World/Village.cpp index b7c82fa4..f12576d3 100644 --- a/Minecraft.World/Village.cpp +++ b/Minecraft.World/Village.cpp @@ -346,7 +346,7 @@ bool Village::isDoor(int x, int y, int z) { int tileId = level->getTile(x, y, z); if (tileId <= 0) return false; - return tileId == Tile::door_wood_Id; + return tileId == Tile::wooden_door_Id; } void Village::calcInfo() diff --git a/Minecraft.World/VillagePieces.cpp b/Minecraft.World/VillagePieces.cpp index 7ab2c66b..9067506c 100644 --- a/Minecraft.World/VillagePieces.cpp +++ b/Minecraft.World/VillagePieces.cpp @@ -412,29 +412,29 @@ int VillagePieces::VillagePiece::biomeBlock(int tile, int data) { if (isDesertVillage) { - if (tile == Tile::treeTrunk_Id) + if (tile == Tile::log_Id) { - return Tile::sandStone_Id; + return Tile::sandstone_Id; } else if (tile == Tile::cobblestone_Id) { - return Tile::sandStone_Id; + return Tile::sandstone_Id; } - else if (tile == Tile::wood_Id) + else if (tile == Tile::planks_Id) { - return Tile::sandStone_Id; + return Tile::sandstone_Id; } - else if (tile == Tile::stairs_wood_Id) + else if (tile == Tile::oak_stairs_Id) { - return Tile::stairs_sandstone_Id; + return Tile::sandstone_stairs_Id; } - else if (tile == Tile::stairs_stone_Id) + else if (tile == Tile::stone_stairs_Id) { - return Tile::stairs_sandstone_Id; + return Tile::sandstone_stairs_Id; } else if (tile == Tile::gravel_Id) { - return Tile::sandStone_Id; + return Tile::sandstone_Id; } } return tile; @@ -444,7 +444,7 @@ int VillagePieces::VillagePiece::biomeData(int tile, int data) { if (isDesertVillage) { - if (tile == Tile::treeTrunk_Id) + if (tile == Tile::log_Id) { return 0; } @@ -452,7 +452,7 @@ int VillagePieces::VillagePiece::biomeData(int tile, int data) { return SandStoneTile::TYPE_DEFAULT; } - else if (tile == Tile::wood_Id) + else if (tile == Tile::planks_Id) { return SandStoneTile::TYPE_SMOOTHSIDE; } @@ -530,7 +530,7 @@ bool VillagePieces::Well::postProcess(Level *level, Random *random, BoundingBox boundingBox->move(0, heightPosition - boundingBox->y1 + 3, 0); } - generateBox(level, chunkBB, 1, 0, 1, 4, height - 3, 4, Tile::cobblestone_Id, Tile::water_Id, false); + generateBox(level, chunkBB, 1, 0, 1, 4, height - 3, 4, Tile::cobblestone_Id, Tile::flowing_water_Id, false); placeBlock(level, 0, 0, 2, height - 3, 2, chunkBB); placeBlock(level, 0, 0, 3, height - 3, 2, chunkBB); placeBlock(level, 0, 0, 2, height - 3, 3, chunkBB); @@ -779,8 +779,8 @@ bool VillagePieces::SimpleHouse::postProcess(Level *level, Random *random, Bound // floor generateBox(level, chunkBB, 0, 0, 0, 4, 0, 4, Tile::cobblestone_Id, Tile::cobblestone_Id, false); // roof - generateBox(level, chunkBB, 0, 4, 0, 4, 4, 4, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - generateBox(level, chunkBB, 1, 4, 1, 3, 4, 3, Tile::wood_Id, Tile::wood_Id, false); + generateBox(level, chunkBB, 0, 4, 0, 4, 4, 4, Tile::log_Id, Tile::log_Id, false); + generateBox(level, chunkBB, 1, 4, 1, 3, 4, 3, Tile::planks_Id, Tile::planks_Id, false); // window walls placeBlock(level, Tile::cobblestone_Id, 0, 0, 1, 0, chunkBB); @@ -795,24 +795,24 @@ bool VillagePieces::SimpleHouse::postProcess(Level *level, Random *random, Bound placeBlock(level, Tile::cobblestone_Id, 0, 4, 1, 4, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 4, 2, 4, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 4, 3, 4, chunkBB); - generateBox(level, chunkBB, 0, 1, 1, 0, 3, 3, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 4, 1, 1, 4, 3, 3, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 1, 1, 4, 3, 3, 4, Tile::wood_Id, Tile::wood_Id, false); - placeBlock(level, Tile::thinGlass_Id, 0, 0, 2, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 2, 2, 4, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 4, 2, 2, chunkBB); + generateBox(level, chunkBB, 0, 1, 1, 0, 3, 3, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 4, 1, 1, 4, 3, 3, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 1, 1, 4, 3, 3, 4, Tile::planks_Id, Tile::planks_Id, false); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 2, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 2, 2, 4, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 4, 2, 2, chunkBB); // door wall - placeBlock(level, Tile::wood_Id, 0, 1, 1, 0, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 1, 2, 0, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 1, 3, 0, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 2, 3, 0, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 3, 3, 0, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 3, 2, 0, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 3, 1, 0, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 1, 1, 0, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 1, 2, 0, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 1, 3, 0, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 2, 3, 0, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 3, 3, 0, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 3, 2, 0, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 3, 1, 0, chunkBB); if (getBlock(level, 2, 0, -1, chunkBB) == 0 && getBlock(level, 2, -1, -1, chunkBB) != 0) { - placeBlock(level, Tile::stairs_stone_Id, getOrientationData(Tile::stairs_stone_Id, 3), 2, 0, -1, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, getOrientationData(Tile::stone_stairs_Id, 3), 2, 0, -1, chunkBB); } // fill room with air @@ -942,28 +942,28 @@ bool VillagePieces::SmallTemple::postProcess(Level *level, Random *random, Bound placeBlock(level, Tile::cobblestone_Id, 0, 2, 1, 7, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 3, 1, 6, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 3, 1, 7, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, getOrientationData(Tile::stairs_stone_Id, 3), 1, 1, 5, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, getOrientationData(Tile::stairs_stone_Id, 3), 2, 1, 6, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, getOrientationData(Tile::stairs_stone_Id, 3), 3, 1, 5, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, getOrientationData(Tile::stairs_stone_Id, 1), 1, 2, 7, chunkBB); - placeBlock(level, Tile::stairs_stone_Id, getOrientationData(Tile::stairs_stone_Id, 0), 3, 2, 7, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, getOrientationData(Tile::stone_stairs_Id, 3), 1, 1, 5, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, getOrientationData(Tile::stone_stairs_Id, 3), 2, 1, 6, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, getOrientationData(Tile::stone_stairs_Id, 3), 3, 1, 5, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, getOrientationData(Tile::stone_stairs_Id, 1), 1, 2, 7, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, getOrientationData(Tile::stone_stairs_Id, 0), 3, 2, 7, chunkBB); // windows - placeBlock(level, Tile::thinGlass_Id, 0, 0, 2, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 0, 3, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 4, 2, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 4, 3, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 0, 6, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 0, 7, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 4, 6, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 4, 7, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 2, 6, 0, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 2, 7, 0, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 2, 6, 4, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 2, 7, 4, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 0, 3, 6, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 4, 3, 6, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 2, 3, 8, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 2, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 3, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 4, 2, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 4, 3, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 6, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 7, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 4, 6, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 4, 7, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 2, 6, 0, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 2, 7, 0, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 2, 6, 4, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 2, 7, 4, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 3, 6, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 4, 3, 6, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 2, 3, 8, chunkBB); // torches placeBlock(level, Tile::torch_Id, 0, 2, 4, 7, chunkBB); @@ -981,10 +981,10 @@ bool VillagePieces::SmallTemple::postProcess(Level *level, Random *random, Bound // entrance placeBlock(level, 0, 0, 2, 1, 0, chunkBB); placeBlock(level, 0, 0, 2, 2, 0, chunkBB); - createDoor(level, chunkBB, random, 2, 1, 0, getOrientationData(Tile::door_wood_Id, 1)); + createDoor(level, chunkBB, random, 2, 1, 0, getOrientationData(Tile::wooden_door_Id, 1)); if (getBlock(level, 2, 0, -1, chunkBB) == 0 && getBlock(level, 2, -1, -1, chunkBB) != 0) { - placeBlock(level, Tile::stairs_stone_Id, getOrientationData(Tile::stairs_stone_Id, 3), 2, 0, -1, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, getOrientationData(Tile::stone_stairs_Id, 3), 2, 0, -1, chunkBB); } @@ -1054,12 +1054,12 @@ bool VillagePieces::BookHouse::postProcess(Level *level, Random *random, Boundin generateBox(level, chunkBB, 0, 5, 0, 8, 5, 5, Tile::cobblestone_Id, Tile::cobblestone_Id, false); generateBox(level, chunkBB, 0, 6, 1, 8, 6, 4, Tile::cobblestone_Id, Tile::cobblestone_Id, false); generateBox(level, chunkBB, 0, 7, 2, 8, 7, 3, Tile::cobblestone_Id, Tile::cobblestone_Id, false); - int southStairs = getOrientationData(Tile::stairs_wood_Id, 3); - int northStairs = getOrientationData(Tile::stairs_wood_Id, 2); + int southStairs = getOrientationData(Tile::oak_stairs_Id, 3); + int northStairs = getOrientationData(Tile::oak_stairs_Id, 2); for (int d = -1; d <= 2; d++) { for (int w = 0; w <= 8; w++) { - placeBlock(level, Tile::stairs_wood_Id, southStairs, w, 6 + d, d, chunkBB); - placeBlock(level, Tile::stairs_wood_Id, northStairs, w, 6 + d, 5 - d, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, southStairs, w, 6 + d, d, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, northStairs, w, 6 + d, 5 - d, chunkBB); } } @@ -1074,59 +1074,59 @@ bool VillagePieces::BookHouse::postProcess(Level *level, Random *random, Boundin generateBox(level, chunkBB, 8, 2, 0, 8, 4, 0, Tile::cobblestone_Id, Tile::cobblestone_Id, false); // wooden walls - generateBox(level, chunkBB, 0, 2, 1, 0, 4, 4, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 1, 2, 5, 7, 4, 5, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 8, 2, 1, 8, 4, 4, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 1, 2, 0, 7, 4, 0, Tile::wood_Id, Tile::wood_Id, false); + generateBox(level, chunkBB, 0, 2, 1, 0, 4, 4, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 1, 2, 5, 7, 4, 5, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 8, 2, 1, 8, 4, 4, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 1, 2, 0, 7, 4, 0, Tile::planks_Id, Tile::planks_Id, false); // windows - placeBlock(level, Tile::thinGlass_Id, 0, 4, 2, 0, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 5, 2, 0, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 6, 2, 0, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 4, 3, 0, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 5, 3, 0, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 6, 3, 0, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 0, 2, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 0, 2, 3, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 0, 3, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 0, 3, 3, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 8, 2, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 8, 2, 3, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 8, 3, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 8, 3, 3, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 2, 2, 5, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 3, 2, 5, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 5, 2, 5, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 6, 2, 5, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 4, 2, 0, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 5, 2, 0, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 6, 2, 0, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 4, 3, 0, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 5, 3, 0, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 6, 3, 0, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 2, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 2, 3, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 3, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 3, 3, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 8, 2, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 8, 2, 3, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 8, 3, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 8, 3, 3, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 2, 2, 5, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 3, 2, 5, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 5, 2, 5, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 6, 2, 5, chunkBB); // roof inside and bookshelf - generateBox(level, chunkBB, 1, 4, 1, 7, 4, 1, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 1, 4, 4, 7, 4, 4, Tile::wood_Id, Tile::wood_Id, false); + generateBox(level, chunkBB, 1, 4, 1, 7, 4, 1, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 1, 4, 4, 7, 4, 4, Tile::planks_Id, Tile::planks_Id, false); generateBox(level, chunkBB, 1, 3, 4, 7, 3, 4, Tile::bookshelf_Id, Tile::bookshelf_Id, false); // couch - placeBlock(level, Tile::wood_Id, 0, 7, 1, 4, chunkBB); - placeBlock(level, Tile::stairs_wood_Id, getOrientationData(Tile::stairs_wood_Id, 0), 7, 1, 3, chunkBB); - int orientationData = getOrientationData(Tile::stairs_wood_Id, 3); - placeBlock(level, Tile::stairs_wood_Id, orientationData, 6, 1, 4, chunkBB); - placeBlock(level, Tile::stairs_wood_Id, orientationData, 5, 1, 4, chunkBB); - placeBlock(level, Tile::stairs_wood_Id, orientationData, 4, 1, 4, chunkBB); - placeBlock(level, Tile::stairs_wood_Id, orientationData, 3, 1, 4, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 7, 1, 4, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, getOrientationData(Tile::oak_stairs_Id, 0), 7, 1, 3, chunkBB); + int orientationData = getOrientationData(Tile::oak_stairs_Id, 3); + placeBlock(level, Tile::oak_stairs_Id, orientationData, 6, 1, 4, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, orientationData, 5, 1, 4, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, orientationData, 4, 1, 4, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, orientationData, 3, 1, 4, chunkBB); // tables placeBlock(level, Tile::fence_Id, 0, 6, 1, 3, chunkBB); - placeBlock(level, Tile::pressurePlate_wood_Id, 0, 6, 2, 3, chunkBB); + placeBlock(level, Tile::wooden_pressure_plate_Id, 0, 6, 2, 3, chunkBB); placeBlock(level, Tile::fence_Id, 0, 4, 1, 3, chunkBB); - placeBlock(level, Tile::pressurePlate_wood_Id, 0, 4, 2, 3, chunkBB); - placeBlock(level, Tile::workBench_Id, 0, 7, 1, 1, chunkBB); + placeBlock(level, Tile::wooden_pressure_plate_Id, 0, 4, 2, 3, chunkBB); + placeBlock(level, Tile::crafting_table_Id, 0, 7, 1, 1, chunkBB); // entrance placeBlock(level, 0, 0, 1, 1, 0, chunkBB); placeBlock(level, 0, 0, 1, 2, 0, chunkBB); - createDoor(level, chunkBB, random, 1, 1, 0, getOrientationData(Tile::door_wood_Id, 1)); + createDoor(level, chunkBB, random, 1, 1, 0, getOrientationData(Tile::wooden_door_Id, 1)); if (getBlock(level, 1, 0, -1, chunkBB) == 0 && getBlock(level, 1, -1, -1, chunkBB) != 0) { - placeBlock(level, Tile::stairs_stone_Id, getOrientationData(Tile::stairs_stone_Id, 3), 1, 0, -1, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, getOrientationData(Tile::stone_stairs_Id, 3), 1, 0, -1, chunkBB); } for (int z = 0; z < depth; z++) @@ -1209,50 +1209,50 @@ bool VillagePieces::SmallHut::postProcess(Level *level, Random *random, Bounding generateBox(level, chunkBB, 1, 0, 1, 2, 0, 3, Tile::dirt_Id, Tile::dirt_Id, false); // roof if (lowCeiling) { - generateBox(level, chunkBB, 1, 4, 1, 2, 4, 3, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); + generateBox(level, chunkBB, 1, 4, 1, 2, 4, 3, Tile::log_Id, Tile::log_Id, false); } else { - generateBox(level, chunkBB, 1, 5, 1, 2, 5, 3, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); + generateBox(level, chunkBB, 1, 5, 1, 2, 5, 3, Tile::log_Id, Tile::log_Id, false); } - placeBlock(level, Tile::treeTrunk_Id, 0, 1, 4, 0, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 2, 4, 0, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 1, 4, 4, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 2, 4, 4, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 0, 4, 1, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 0, 4, 2, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 0, 4, 3, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 3, 4, 1, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 3, 4, 2, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 3, 4, 3, chunkBB); + placeBlock(level, Tile::log_Id, 0, 1, 4, 0, chunkBB); + placeBlock(level, Tile::log_Id, 0, 2, 4, 0, chunkBB); + placeBlock(level, Tile::log_Id, 0, 1, 4, 4, chunkBB); + placeBlock(level, Tile::log_Id, 0, 2, 4, 4, chunkBB); + placeBlock(level, Tile::log_Id, 0, 0, 4, 1, chunkBB); + placeBlock(level, Tile::log_Id, 0, 0, 4, 2, chunkBB); + placeBlock(level, Tile::log_Id, 0, 0, 4, 3, chunkBB); + placeBlock(level, Tile::log_Id, 0, 3, 4, 1, chunkBB); + placeBlock(level, Tile::log_Id, 0, 3, 4, 2, chunkBB); + placeBlock(level, Tile::log_Id, 0, 3, 4, 3, chunkBB); // corners - generateBox(level, chunkBB, 0, 1, 0, 0, 3, 0, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - generateBox(level, chunkBB, 3, 1, 0, 3, 3, 0, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - generateBox(level, chunkBB, 0, 1, 4, 0, 3, 4, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - generateBox(level, chunkBB, 3, 1, 4, 3, 3, 4, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); + generateBox(level, chunkBB, 0, 1, 0, 0, 3, 0, Tile::log_Id, Tile::log_Id, false); + generateBox(level, chunkBB, 3, 1, 0, 3, 3, 0, Tile::log_Id, Tile::log_Id, false); + generateBox(level, chunkBB, 0, 1, 4, 0, 3, 4, Tile::log_Id, Tile::log_Id, false); + generateBox(level, chunkBB, 3, 1, 4, 3, 3, 4, Tile::log_Id, Tile::log_Id, false); // wooden walls - generateBox(level, chunkBB, 0, 1, 1, 0, 3, 3, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 3, 1, 1, 3, 3, 3, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 1, 1, 0, 2, 3, 0, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 1, 1, 4, 2, 3, 4, Tile::wood_Id, Tile::wood_Id, false); + generateBox(level, chunkBB, 0, 1, 1, 0, 3, 3, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 3, 1, 1, 3, 3, 3, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 1, 1, 0, 2, 3, 0, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 1, 1, 4, 2, 3, 4, Tile::planks_Id, Tile::planks_Id, false); // windows - placeBlock(level, Tile::thinGlass_Id, 0, 0, 2, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 3, 2, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 2, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 3, 2, 2, chunkBB); // table if (tablePlacement > 0) { placeBlock(level, Tile::fence_Id, 0, tablePlacement, 1, 3, chunkBB); - placeBlock(level, Tile::pressurePlate_wood_Id, 0, tablePlacement, 2, 3, chunkBB); + placeBlock(level, Tile::wooden_pressure_plate_Id, 0, tablePlacement, 2, 3, chunkBB); } // entrance placeBlock(level, 0, 0, 1, 1, 0, chunkBB); placeBlock(level, 0, 0, 1, 2, 0, chunkBB); - createDoor(level, chunkBB, random, 1, 1, 0, getOrientationData(Tile::door_wood_Id, 1)); + createDoor(level, chunkBB, random, 1, 1, 0, getOrientationData(Tile::wooden_door_Id, 1)); if (getBlock(level, 1, 0, -1, chunkBB) == 0 && getBlock(level, 1, -1, -1, chunkBB) != 0) { - placeBlock(level, Tile::stairs_stone_Id, getOrientationData(Tile::stairs_stone_Id, 3), 1, 0, -1, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, getOrientationData(Tile::stone_stairs_Id, 3), 1, 0, -1, chunkBB); } for (int z = 0; z < depth; z++) @@ -1320,75 +1320,75 @@ bool VillagePieces::PigHouse::postProcess(Level *level, Random *random, Bounding generateBox(level, chunkBB, 3, 1, 10, 7, 1, 10, Tile::fence_Id, Tile::fence_Id, false); // floor - generateBox(level, chunkBB, 1, 0, 1, 7, 0, 4, Tile::wood_Id, Tile::wood_Id, false); + generateBox(level, chunkBB, 1, 0, 1, 7, 0, 4, Tile::planks_Id, Tile::planks_Id, false); generateBox(level, chunkBB, 0, 0, 0, 0, 3, 5, Tile::cobblestone_Id, Tile::cobblestone_Id, false); generateBox(level, chunkBB, 8, 0, 0, 8, 3, 5, Tile::cobblestone_Id, Tile::cobblestone_Id, false); generateBox(level, chunkBB, 1, 0, 0, 7, 1, 0, Tile::cobblestone_Id, Tile::cobblestone_Id, false); generateBox(level, chunkBB, 1, 0, 5, 7, 1, 5, Tile::cobblestone_Id, Tile::cobblestone_Id, false); // roof - generateBox(level, chunkBB, 1, 2, 0, 7, 3, 0, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 1, 2, 5, 7, 3, 5, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 0, 4, 1, 8, 4, 1, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 0, 4, 4, 8, 4, 4, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 0, 5, 2, 8, 5, 3, Tile::wood_Id, Tile::wood_Id, false); - placeBlock(level, Tile::wood_Id, 0, 0, 4, 2, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 0, 4, 3, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 8, 4, 2, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 8, 4, 3, chunkBB); + generateBox(level, chunkBB, 1, 2, 0, 7, 3, 0, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 1, 2, 5, 7, 3, 5, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 0, 4, 1, 8, 4, 1, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 0, 4, 4, 8, 4, 4, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 0, 5, 2, 8, 5, 3, Tile::planks_Id, Tile::planks_Id, false); + placeBlock(level, Tile::planks_Id, 0, 0, 4, 2, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 0, 4, 3, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 8, 4, 2, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 8, 4, 3, chunkBB); - int southStairs = getOrientationData(Tile::stairs_wood_Id, 3); - int northStairs = getOrientationData(Tile::stairs_wood_Id, 2); + int southStairs = getOrientationData(Tile::oak_stairs_Id, 3); + int northStairs = getOrientationData(Tile::oak_stairs_Id, 2); for (int d = -1; d <= 2; d++) { for (int w = 0; w <= 8; w++) { - placeBlock(level, Tile::stairs_wood_Id, southStairs, w, 4 + d, d, chunkBB); - placeBlock(level, Tile::stairs_wood_Id, northStairs, w, 4 + d, 5 - d, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, southStairs, w, 4 + d, d, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, northStairs, w, 4 + d, 5 - d, chunkBB); } } // windows etc - placeBlock(level, Tile::treeTrunk_Id, 0, 0, 2, 1, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 0, 2, 4, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 8, 2, 1, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 8, 2, 4, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 0, 2, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 0, 2, 3, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 8, 2, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 8, 2, 3, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 2, 2, 5, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 3, 2, 5, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 5, 2, 0, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 6, 2, 5, chunkBB); + placeBlock(level, Tile::log_Id, 0, 0, 2, 1, chunkBB); + placeBlock(level, Tile::log_Id, 0, 0, 2, 4, chunkBB); + placeBlock(level, Tile::log_Id, 0, 8, 2, 1, chunkBB); + placeBlock(level, Tile::log_Id, 0, 8, 2, 4, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 2, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 2, 3, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 8, 2, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 8, 2, 3, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 2, 2, 5, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 3, 2, 5, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 5, 2, 0, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 6, 2, 5, chunkBB); // table placeBlock(level, Tile::fence_Id, 0, 2, 1, 3, chunkBB); - placeBlock(level, Tile::pressurePlate_wood_Id, 0, 2, 2, 3, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 1, 1, 4, chunkBB); - placeBlock(level, Tile::stairs_wood_Id, getOrientationData(Tile::stairs_wood_Id, 3), 2, 1, 4, chunkBB); - placeBlock(level, Tile::stairs_wood_Id, getOrientationData(Tile::stairs_wood_Id, 1), 1, 1, 3, chunkBB); + placeBlock(level, Tile::wooden_pressure_plate_Id, 0, 2, 2, 3, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 1, 1, 4, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, getOrientationData(Tile::oak_stairs_Id, 3), 2, 1, 4, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, getOrientationData(Tile::oak_stairs_Id, 1), 1, 1, 3, chunkBB); // butcher table - generateBox(level, chunkBB, 5, 0, 1, 7, 0, 3, Tile::stoneSlab_Id, Tile::stoneSlab_Id, false); - placeBlock(level, Tile::stoneSlab_Id, 0, 6, 1, 1, chunkBB); - placeBlock(level, Tile::stoneSlab_Id, 0, 6, 1, 2, chunkBB); + generateBox(level, chunkBB, 5, 0, 1, 7, 0, 3, Tile::double_stone_slab_Id, Tile::double_stone_slab_Id, false); + placeBlock(level, Tile::double_stone_slab_Id, 0, 6, 1, 1, chunkBB); + placeBlock(level, Tile::double_stone_slab_Id, 0, 6, 1, 2, chunkBB); // entrance placeBlock(level, 0, 0, 2, 1, 0, chunkBB); placeBlock(level, 0, 0, 2, 2, 0, chunkBB); placeBlock(level, Tile::torch_Id, 0, 2, 3, 1, chunkBB); - createDoor(level, chunkBB, random, 2, 1, 0, getOrientationData(Tile::door_wood_Id, 1)); + createDoor(level, chunkBB, random, 2, 1, 0, getOrientationData(Tile::wooden_door_Id, 1)); if (getBlock(level, 2, 0, -1, chunkBB) == 0 && getBlock(level, 2, -1, -1, chunkBB) != 0) { - placeBlock(level, Tile::stairs_stone_Id, getOrientationData(Tile::stairs_stone_Id, 3), 2, 0, -1, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, getOrientationData(Tile::stone_stairs_Id, 3), 2, 0, -1, chunkBB); } // pig entrance placeBlock(level, 0, 0, 6, 1, 5, chunkBB); placeBlock(level, 0, 0, 6, 2, 5, chunkBB); placeBlock(level, Tile::torch_Id, 0, 6, 3, 4, chunkBB); - createDoor(level, chunkBB, random, 6, 1, 5, getOrientationData(Tile::door_wood_Id, 1)); + createDoor(level, chunkBB, random, 6, 1, 5, getOrientationData(Tile::wooden_door_Id, 1)); for (int z = 0; z < 5; z++) { @@ -1457,8 +1457,8 @@ bool VillagePieces::TwoRoomHouse::postProcess(Level *level, Random *random, Boun generateBox(level, chunkBB, 2, 1, 6, 8, 4, 10, 0, 0, false); // floor - generateBox(level, chunkBB, 2, 0, 5, 8, 0, 10, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 1, 0, 1, 7, 0, 4, Tile::wood_Id, Tile::wood_Id, false); + generateBox(level, chunkBB, 2, 0, 5, 8, 0, 10, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 1, 0, 1, 7, 0, 4, Tile::planks_Id, Tile::planks_Id, false); generateBox(level, chunkBB, 0, 0, 0, 0, 3, 5, Tile::cobblestone_Id, Tile::cobblestone_Id, false); generateBox(level, chunkBB, 8, 0, 0, 8, 3, 10, Tile::cobblestone_Id, Tile::cobblestone_Id, false); generateBox(level, chunkBB, 1, 0, 0, 7, 2, 0, Tile::cobblestone_Id, Tile::cobblestone_Id, false); @@ -1467,94 +1467,94 @@ bool VillagePieces::TwoRoomHouse::postProcess(Level *level, Random *random, Boun generateBox(level, chunkBB, 3, 0, 10, 7, 3, 10, Tile::cobblestone_Id, Tile::cobblestone_Id, false); // room 1 roof - generateBox(level, chunkBB, 1, 2, 0, 7, 3, 0, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 1, 2, 5, 2, 3, 5, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 0, 4, 1, 8, 4, 1, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 0, 4, 4, 3, 4, 4, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 0, 5, 2, 8, 5, 3, Tile::wood_Id, Tile::wood_Id, false); - placeBlock(level, Tile::wood_Id, 0, 0, 4, 2, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 0, 4, 3, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 8, 4, 2, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 8, 4, 3, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 8, 4, 4, chunkBB); + generateBox(level, chunkBB, 1, 2, 0, 7, 3, 0, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 1, 2, 5, 2, 3, 5, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 0, 4, 1, 8, 4, 1, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 0, 4, 4, 3, 4, 4, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 0, 5, 2, 8, 5, 3, Tile::planks_Id, Tile::planks_Id, false); + placeBlock(level, Tile::planks_Id, 0, 0, 4, 2, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 0, 4, 3, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 8, 4, 2, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 8, 4, 3, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 8, 4, 4, chunkBB); - int southStairs = getOrientationData(Tile::stairs_wood_Id, 3); - int northStairs = getOrientationData(Tile::stairs_wood_Id, 2); + int southStairs = getOrientationData(Tile::oak_stairs_Id, 3); + int northStairs = getOrientationData(Tile::oak_stairs_Id, 2); for (int d = -1; d <= 2; d++) { for (int w = 0; w <= 8; w++) { - placeBlock(level, Tile::stairs_wood_Id, southStairs, w, 4 + d, d, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, southStairs, w, 4 + d, d, chunkBB); if ((d > -1 || w <= 1) && (d > 0 || w <= 3) && (d > 1 || w <= 4 || w >= 6)) { - placeBlock(level, Tile::stairs_wood_Id, northStairs, w, 4 + d, 5 - d, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, northStairs, w, 4 + d, 5 - d, chunkBB); } } } // room 2 roof - generateBox(level, chunkBB, 3, 4, 5, 3, 4, 10, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 7, 4, 2, 7, 4, 10, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 4, 5, 4, 4, 5, 10, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 6, 5, 4, 6, 5, 10, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 5, 6, 3, 5, 6, 10, Tile::wood_Id, Tile::wood_Id, false); - int westStairs = getOrientationData(Tile::stairs_wood_Id, 0); + generateBox(level, chunkBB, 3, 4, 5, 3, 4, 10, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 7, 4, 2, 7, 4, 10, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 4, 5, 4, 4, 5, 10, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 6, 5, 4, 6, 5, 10, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 5, 6, 3, 5, 6, 10, Tile::planks_Id, Tile::planks_Id, false); + int westStairs = getOrientationData(Tile::oak_stairs_Id, 0); for (int w = 4; w >= 1; w--) { - placeBlock(level, Tile::wood_Id, 0, w, 2 + w, 7 - w, chunkBB); + placeBlock(level, Tile::planks_Id, 0, w, 2 + w, 7 - w, chunkBB); for (int d = 8 - w; d <= 10; d++) { - placeBlock(level, Tile::stairs_wood_Id, westStairs, w, 2 + w, d, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, westStairs, w, 2 + w, d, chunkBB); } } - int eastStairs = getOrientationData(Tile::stairs_wood_Id, 1); - placeBlock(level, Tile::wood_Id, 0, 6, 6, 3, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 7, 5, 4, chunkBB); - placeBlock(level, Tile::stairs_wood_Id, eastStairs, 6, 6, 4, chunkBB); + int eastStairs = getOrientationData(Tile::oak_stairs_Id, 1); + placeBlock(level, Tile::planks_Id, 0, 6, 6, 3, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 7, 5, 4, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, eastStairs, 6, 6, 4, chunkBB); for (int w = 6; w <= 8; w++) { for (int d = 5; d <= 10; d++) { - placeBlock(level, Tile::stairs_wood_Id, eastStairs, w, 12 - w, d, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, eastStairs, w, 12 - w, d, chunkBB); } } // windows etc - placeBlock(level, Tile::treeTrunk_Id, 0, 0, 2, 1, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 0, 2, 4, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 0, 2, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 0, 2, 3, chunkBB); + placeBlock(level, Tile::log_Id, 0, 0, 2, 1, chunkBB); + placeBlock(level, Tile::log_Id, 0, 0, 2, 4, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 2, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 2, 3, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 4, 2, 0, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 5, 2, 0, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 6, 2, 0, chunkBB); + placeBlock(level, Tile::log_Id, 0, 4, 2, 0, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 5, 2, 0, chunkBB); + placeBlock(level, Tile::log_Id, 0, 6, 2, 0, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 8, 2, 1, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 8, 2, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 8, 2, 3, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 8, 2, 4, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 8, 2, 5, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 8, 2, 6, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 8, 2, 7, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 8, 2, 8, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 8, 2, 9, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 2, 2, 6, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 2, 2, 7, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 2, 2, 8, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 2, 2, 9, chunkBB); + placeBlock(level, Tile::log_Id, 0, 8, 2, 1, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 8, 2, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 8, 2, 3, chunkBB); + placeBlock(level, Tile::log_Id, 0, 8, 2, 4, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 8, 2, 5, chunkBB); + placeBlock(level, Tile::log_Id, 0, 8, 2, 6, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 8, 2, 7, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 8, 2, 8, chunkBB); + placeBlock(level, Tile::log_Id, 0, 8, 2, 9, chunkBB); + placeBlock(level, Tile::log_Id, 0, 2, 2, 6, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 2, 2, 7, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 2, 2, 8, chunkBB); + placeBlock(level, Tile::log_Id, 0, 2, 2, 9, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 4, 4, 10, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 5, 4, 10, chunkBB); - placeBlock(level, Tile::treeTrunk_Id, 0, 6, 4, 10, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 5, 5, 10, chunkBB); + placeBlock(level, Tile::log_Id, 0, 4, 4, 10, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 5, 4, 10, chunkBB); + placeBlock(level, Tile::log_Id, 0, 6, 4, 10, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 5, 5, 10, chunkBB); // entrance placeBlock(level, 0, 0, 2, 1, 0, chunkBB); placeBlock(level, 0, 0, 2, 2, 0, chunkBB); placeBlock(level, Tile::torch_Id, 0, 2, 3, 1, chunkBB); - createDoor(level, chunkBB, random, 2, 1, 0, getOrientationData(Tile::door_wood_Id, 1)); + createDoor(level, chunkBB, random, 2, 1, 0, getOrientationData(Tile::wooden_door_Id, 1)); generateBox(level, chunkBB, 1, 0, -1, 3, 2, -1, 0, 0, false); if (getBlock(level, 2, 0, -1, chunkBB) == 0 && getBlock(level, 2, -1, -1, chunkBB) != 0) { - placeBlock(level, Tile::stairs_stone_Id, getOrientationData(Tile::stairs_stone_Id, 3), 2, 0, -1, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, getOrientationData(Tile::stone_stairs_Id, 3), 2, 0, -1, chunkBB); } for (int z = 0; z < 5; z++) @@ -1584,23 +1584,23 @@ void VillagePieces::Smithy::staticCtor() { treasureItems = WeighedTreasureArray(17); treasureItems[0] = new WeighedTreasure(Item::diamond_Id, 0, 1, 3, 3); - treasureItems[1] = new WeighedTreasure(Item::ironIngot_Id, 0, 1, 5, 10); - treasureItems[2] = new WeighedTreasure(Item::goldIngot_Id, 0, 1, 3, 5); + treasureItems[1] = new WeighedTreasure(Item::iron_ingot_Id, 0, 1, 5, 10); + treasureItems[2] = new WeighedTreasure(Item::gold_ingot_Id, 0, 1, 3, 5); treasureItems[3] = new WeighedTreasure(Item::bread_Id, 0, 1, 3, 15); treasureItems[4] = new WeighedTreasure(Item::apple_Id, 0, 1, 3, 15); - treasureItems[5] = new WeighedTreasure(Item::pickAxe_iron_Id, 0, 1, 1, 5); - treasureItems[6] = new WeighedTreasure(Item::sword_iron_Id, 0, 1, 1, 5); - treasureItems[7] = new WeighedTreasure(Item::chestplate_iron_Id, 0, 1, 1, 5); - treasureItems[8] = new WeighedTreasure(Item::helmet_iron_Id, 0, 1, 1, 5); - treasureItems[9] = new WeighedTreasure(Item::leggings_iron_Id, 0, 1, 1, 5); - treasureItems[10] = new WeighedTreasure(Item::boots_iron_Id, 0, 1, 1, 5); + treasureItems[5] = new WeighedTreasure(Item::iron_pickaxe_Id, 0, 1, 1, 5); + treasureItems[6] = new WeighedTreasure(Item::iron_sword_Id, 0, 1, 1, 5); + treasureItems[7] = new WeighedTreasure(Item::iron_chestplate_Id, 0, 1, 1, 5); + treasureItems[8] = new WeighedTreasure(Item::iron_helmet_Id, 0, 1, 1, 5); + treasureItems[9] = new WeighedTreasure(Item::iron_leggings_Id, 0, 1, 1, 5); + treasureItems[10] = new WeighedTreasure(Item::iron_boots_Id, 0, 1, 1, 5); treasureItems[11] = new WeighedTreasure(Tile::obsidian_Id, 0, 3, 7, 5); treasureItems[12] = new WeighedTreasure(Tile::sapling_Id, 0, 3, 7, 5); // very rare for villages ... treasureItems[13] = new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 3); - treasureItems[14] = new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 1); - treasureItems[15] = new WeighedTreasure(Item::horseArmorGold_Id, 0, 1, 1, 1); - treasureItems[16] = new WeighedTreasure(Item::horseArmorDiamond_Id, 0, 1, 1, 1); + treasureItems[14] = new WeighedTreasure(Item::iron_horse_armor_Id, 0, 1, 1, 1); + treasureItems[15] = new WeighedTreasure(Item::golden_horse_armor_Id, 0, 1, 1, 1); + treasureItems[16] = new WeighedTreasure(Item::diamond_horse_armor_Id, 0, 1, 1, 1); // ... } @@ -1662,19 +1662,19 @@ bool VillagePieces::Smithy::postProcess(Level *level, Random *random, BoundingBo // roof generateBox(level, chunkBB, 0, 4, 0, 9, 4, 6, Tile::cobblestone_Id, Tile::cobblestone_Id, false); - generateBox(level, chunkBB, 0, 5, 0, 9, 5, 6, Tile::stoneSlabHalf_Id, Tile::stoneSlabHalf_Id, false); + generateBox(level, chunkBB, 0, 5, 0, 9, 5, 6, Tile::stone_slab_Id, Tile::stone_slab_Id, false); generateBox(level, chunkBB, 1, 5, 1, 8, 5, 5, 0, 0, false); // room walls - generateBox(level, chunkBB, 1, 1, 0, 2, 3, 0, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 0, 1, 0, 0, 4, 0, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - generateBox(level, chunkBB, 3, 1, 0, 3, 4, 0, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - generateBox(level, chunkBB, 0, 1, 6, 0, 4, 6, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - placeBlock(level, Tile::wood_Id, 0, 3, 3, 1, chunkBB); - generateBox(level, chunkBB, 3, 1, 2, 3, 3, 2, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 4, 1, 3, 5, 3, 3, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 0, 1, 1, 0, 3, 5, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 1, 1, 6, 5, 3, 6, Tile::wood_Id, Tile::wood_Id, false); + generateBox(level, chunkBB, 1, 1, 0, 2, 3, 0, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 0, 1, 0, 0, 4, 0, Tile::log_Id, Tile::log_Id, false); + generateBox(level, chunkBB, 3, 1, 0, 3, 4, 0, Tile::log_Id, Tile::log_Id, false); + generateBox(level, chunkBB, 0, 1, 6, 0, 4, 6, Tile::log_Id, Tile::log_Id, false); + placeBlock(level, Tile::planks_Id, 0, 3, 3, 1, chunkBB); + generateBox(level, chunkBB, 3, 1, 2, 3, 3, 2, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 4, 1, 3, 5, 3, 3, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 0, 1, 1, 0, 3, 5, Tile::planks_Id, Tile::planks_Id, false); + generateBox(level, chunkBB, 1, 1, 6, 5, 3, 6, Tile::planks_Id, Tile::planks_Id, false); // pillars generateBox(level, chunkBB, 5, 1, 0, 5, 3, 0, Tile::fence_Id, Tile::fence_Id, false); @@ -1682,28 +1682,28 @@ bool VillagePieces::Smithy::postProcess(Level *level, Random *random, BoundingBo // furnace generateBox(level, chunkBB, 6, 1, 4, 9, 4, 6, Tile::cobblestone_Id, Tile::cobblestone_Id, false); - placeBlock(level, Tile::lava_Id, 0, 7, 1, 5, chunkBB); - placeBlock(level, Tile::lava_Id, 0, 8, 1, 5, chunkBB); - placeBlock(level, Tile::ironFence_Id, 0, 9, 2, 5, chunkBB); - placeBlock(level, Tile::ironFence_Id, 0, 9, 2, 4, chunkBB); + placeBlock(level, Tile::flowing_lava_Id, 0, 7, 1, 5, chunkBB); + placeBlock(level, Tile::flowing_lava_Id, 0, 8, 1, 5, chunkBB); + placeBlock(level, Tile::iron_bars_Id, 0, 9, 2, 5, chunkBB); + placeBlock(level, Tile::iron_bars_Id, 0, 9, 2, 4, chunkBB); generateBox(level, chunkBB, 7, 2, 4, 8, 2, 5, 0, 0, false); placeBlock(level, Tile::cobblestone_Id, 0, 6, 1, 3, chunkBB); placeBlock(level, Tile::furnace_Id, 0, 6, 2, 3, chunkBB); placeBlock(level, Tile::furnace_Id, 0, 6, 3, 3, chunkBB); - placeBlock(level, Tile::stoneSlab_Id, 0, 8, 1, 1, chunkBB); + placeBlock(level, Tile::double_stone_slab_Id, 0, 8, 1, 1, chunkBB); // windows etc - placeBlock(level, Tile::thinGlass_Id, 0, 0, 2, 2, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 0, 2, 4, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 2, 2, 6, chunkBB); - placeBlock(level, Tile::thinGlass_Id, 0, 4, 2, 6, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 2, 2, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 0, 2, 4, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 2, 2, 6, chunkBB); + placeBlock(level, Tile::glass_pane_Id, 0, 4, 2, 6, chunkBB); // table placeBlock(level, Tile::fence_Id, 0, 2, 1, 4, chunkBB); - placeBlock(level, Tile::pressurePlate_wood_Id, 0, 2, 2, 4, chunkBB); - placeBlock(level, Tile::wood_Id, 0, 1, 1, 5, chunkBB); - placeBlock(level, Tile::stairs_wood_Id, getOrientationData(Tile::stairs_wood_Id, 3), 2, 1, 5, chunkBB); - placeBlock(level, Tile::stairs_wood_Id, getOrientationData(Tile::stairs_wood_Id, 1), 1, 1, 4, chunkBB); + placeBlock(level, Tile::wooden_pressure_plate_Id, 0, 2, 2, 4, chunkBB); + placeBlock(level, Tile::planks_Id, 0, 1, 1, 5, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, getOrientationData(Tile::oak_stairs_Id, 3), 2, 1, 5, chunkBB); + placeBlock(level, Tile::oak_stairs_Id, getOrientationData(Tile::oak_stairs_Id, 1), 1, 1, 4, chunkBB); if (!hasPlacedChest) { @@ -1721,7 +1721,7 @@ bool VillagePieces::Smithy::postProcess(Level *level, Random *random, BoundingBo { if (getBlock(level, x, 0, -1, chunkBB) == 0 && getBlock(level, x, -1, -1, chunkBB) != 0 ) { - placeBlock(level, Tile::stairs_stone_Id, getOrientationData(Tile::stairs_stone_Id, 3), x, 0, -1, chunkBB); + placeBlock(level, Tile::stone_stairs_Id, getOrientationData(Tile::stone_stairs_Id, 3), x, 0, -1, chunkBB); } } @@ -1820,12 +1820,12 @@ bool VillagePieces::Farmland::postProcess(Level *level, Random *random, Bounding generateBox(level, chunkBB, 1, 0, 1, 2, 0, 7, Tile::farmland_Id, Tile::farmland_Id, false); generateBox(level, chunkBB, 4, 0, 1, 5, 0, 7, Tile::farmland_Id, Tile::farmland_Id, false); // walkpaths - generateBox(level, chunkBB, 0, 0, 0, 0, 0, 8, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - generateBox(level, chunkBB, 6, 0, 0, 6, 0, 8, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - generateBox(level, chunkBB, 1, 0, 0, 5, 0, 0, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - generateBox(level, chunkBB, 1, 0, 8, 5, 0, 8, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); + generateBox(level, chunkBB, 0, 0, 0, 0, 0, 8, Tile::log_Id, Tile::log_Id, false); + generateBox(level, chunkBB, 6, 0, 0, 6, 0, 8, Tile::log_Id, Tile::log_Id, false); + generateBox(level, chunkBB, 1, 0, 0, 5, 0, 0, Tile::log_Id, Tile::log_Id, false); + generateBox(level, chunkBB, 1, 0, 8, 5, 0, 8, Tile::log_Id, Tile::log_Id, false); // water - generateBox(level, chunkBB, 3, 0, 1, 3, 0, 7, Tile::water_Id, Tile::water_Id, false); + generateBox(level, chunkBB, 3, 0, 1, 3, 0, 7, Tile::flowing_water_Id, Tile::flowing_water_Id, false); // crops for (int d = 1; d <= 7; d++) { @@ -1934,14 +1934,14 @@ bool VillagePieces::DoubleFarmland::postProcess(Level *level, Random *random, Bo generateBox(level, chunkBB, 7, 0, 1, 8, 0, 7, Tile::farmland_Id, Tile::farmland_Id, false); generateBox(level, chunkBB, 10, 0, 1, 11, 0, 7, Tile::farmland_Id, Tile::farmland_Id, false); // walkpaths - generateBox(level, chunkBB, 0, 0, 0, 0, 0, 8, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - generateBox(level, chunkBB, 6, 0, 0, 6, 0, 8, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - generateBox(level, chunkBB, 12, 0, 0, 12, 0, 8, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - generateBox(level, chunkBB, 1, 0, 0, 11, 0, 0, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); - generateBox(level, chunkBB, 1, 0, 8, 11, 0, 8, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); + generateBox(level, chunkBB, 0, 0, 0, 0, 0, 8, Tile::log_Id, Tile::log_Id, false); + generateBox(level, chunkBB, 6, 0, 0, 6, 0, 8, Tile::log_Id, Tile::log_Id, false); + generateBox(level, chunkBB, 12, 0, 0, 12, 0, 8, Tile::log_Id, Tile::log_Id, false); + generateBox(level, chunkBB, 1, 0, 0, 11, 0, 0, Tile::log_Id, Tile::log_Id, false); + generateBox(level, chunkBB, 1, 0, 8, 11, 0, 8, Tile::log_Id, Tile::log_Id, false); // water - generateBox(level, chunkBB, 3, 0, 1, 3, 0, 7, Tile::water_Id, Tile::water_Id, false); - generateBox(level, chunkBB, 9, 0, 1, 9, 0, 7, Tile::water_Id, Tile::water_Id, false); + generateBox(level, chunkBB, 3, 0, 1, 3, 0, 7, Tile::flowing_water_Id, Tile::flowing_water_Id, false); + generateBox(level, chunkBB, 9, 0, 1, 9, 0, 7, Tile::flowing_water_Id, Tile::flowing_water_Id, false); // crops for (int d = 1; d <= 7; d++) { diff --git a/Minecraft.World/Villager.cpp b/Minecraft.World/Villager.cpp index a181df84..90ade912 100644 --- a/Minecraft.World/Villager.cpp +++ b/Minecraft.World/Villager.cpp @@ -154,7 +154,7 @@ bool Villager::mobInteract(shared_ptr player) { // [EB]: Truly dislike this code but I don't see another easy way shared_ptr item = player->inventory->getSelected(); - bool holdingSpawnEgg = item != nullptr && item->id == Item::spawnEgg_Id; + bool holdingSpawnEgg = item != nullptr && item->id == Item::spawn_egg_Id; if (!player->isSneaking() && !holdingSpawnEgg && isAlive() && !isTrading() && !isBaby()) { @@ -408,15 +408,15 @@ void Villager::addOffers(int addCount) case PROFESSION_FARMER: addItemForTradeIn(newOffers, Item::wheat_Id, random, getRecipeChance(.9f)); addItemForTradeIn(newOffers, Tile::wool_Id, random, getRecipeChance(.5f)); - addItemForTradeIn(newOffers, Item::chicken_raw_Id, random, getRecipeChance(.5f)); - addItemForTradeIn(newOffers, Item::fish_cooked_Id, random, getRecipeChance(.4f)); + addItemForTradeIn(newOffers, Item::chicken_Id, random, getRecipeChance(.5f)); + addItemForTradeIn(newOffers, Item::cooked_fish_Id, random, getRecipeChance(.4f)); addItemForPurchase(newOffers, Item::bread_Id, random, getRecipeChance(.9f)); - addItemForPurchase(newOffers, Item::melon_Id, random, getRecipeChance(.3f)); + addItemForPurchase(newOffers, Item::melon_block_Id, random, getRecipeChance(.3f)); addItemForPurchase(newOffers, Item::apple_Id, random, getRecipeChance(.3f)); addItemForPurchase(newOffers, Item::cookie_Id, random, getRecipeChance(.3f)); addItemForPurchase(newOffers, Item::shears_Id, random, getRecipeChance(.3f)); - addItemForPurchase(newOffers, Item::flintAndSteel_Id, random, getRecipeChance(.3f)); - addItemForPurchase(newOffers, Item::chicken_cooked_Id, random, getRecipeChance(.3f)); + addItemForPurchase(newOffers, Item::flint_and_steel_Id, random, getRecipeChance(.3f)); + addItemForPurchase(newOffers, Item::cooked_chicken_Id, random, getRecipeChance(.3f)); addItemForPurchase(newOffers, Item::arrow_Id, random, getRecipeChance(.5f)); if (random->nextFloat() < getRecipeChance(.5f)) { @@ -425,74 +425,74 @@ void Villager::addOffers(int addCount) break; case PROFESSION_BUTCHER: addItemForTradeIn(newOffers, Item::coal_Id, random, getRecipeChance(.7f)); - addItemForTradeIn(newOffers, Item::porkChop_raw_Id, random, getRecipeChance(.5f)); - addItemForTradeIn(newOffers, Item::beef_raw_Id, random, getRecipeChance(.5f)); + addItemForTradeIn(newOffers, Item::porkchop_Id, random, getRecipeChance(.5f)); + addItemForTradeIn(newOffers, Item::beef_Id, random, getRecipeChance(.5f)); addItemForPurchase(newOffers, Item::saddle_Id, random, getRecipeChance(.1f)); - addItemForPurchase(newOffers, Item::chestplate_leather_Id, random, getRecipeChance(.3f)); - addItemForPurchase(newOffers, Item::boots_leather_Id, random, getRecipeChance(.3f)); - addItemForPurchase(newOffers, Item::helmet_leather_Id, random, getRecipeChance(.3f)); - addItemForPurchase(newOffers, Item::leggings_leather_Id, random, getRecipeChance(.3f)); - addItemForPurchase(newOffers, Item::porkChop_cooked_Id, random, getRecipeChance(.3f)); - addItemForPurchase(newOffers, Item::beef_cooked_Id, random, getRecipeChance(.3f)); + addItemForPurchase(newOffers, Item::leather_chestplate_Id, random, getRecipeChance(.3f)); + addItemForPurchase(newOffers, Item::leather_boots_Id, random, getRecipeChance(.3f)); + addItemForPurchase(newOffers, Item::leather_helmet_Id, random, getRecipeChance(.3f)); + addItemForPurchase(newOffers, Item::leather_leggings_Id, random, getRecipeChance(.3f)); + addItemForPurchase(newOffers, Item::cooked_porkchop_Id, random, getRecipeChance(.3f)); + addItemForPurchase(newOffers, Item::cooked_beef_Id, random, getRecipeChance(.3f)); break; case PROFESSION_SMITH: addItemForTradeIn(newOffers, Item::coal_Id, random, getRecipeChance(.7f)); - addItemForTradeIn(newOffers, Item::ironIngot_Id, random, getRecipeChance(.5f)); - addItemForTradeIn(newOffers, Item::goldIngot_Id, random, getRecipeChance(.5f)); + addItemForTradeIn(newOffers, Item::iron_ingot_Id, random, getRecipeChance(.5f)); + addItemForTradeIn(newOffers, Item::gold_ingot_Id, random, getRecipeChance(.5f)); addItemForTradeIn(newOffers, Item::diamond_Id, random, getRecipeChance(.5f)); - addItemForPurchase(newOffers, Item::sword_iron_Id, random, getRecipeChance(.5f)); - addItemForPurchase(newOffers, Item::sword_diamond_Id, random, getRecipeChance(.5f)); - addItemForPurchase(newOffers, Item::hatchet_iron_Id, random, getRecipeChance(.3f)); - addItemForPurchase(newOffers, Item::hatchet_diamond_Id, random, getRecipeChance(.3f)); - addItemForPurchase(newOffers, Item::pickAxe_iron_Id, random, getRecipeChance(.5f)); - addItemForPurchase(newOffers, Item::pickAxe_diamond_Id, random, getRecipeChance(.5f)); - addItemForPurchase(newOffers, Item::shovel_iron_Id, random, getRecipeChance(.2f)); - addItemForPurchase(newOffers, Item::shovel_diamond_Id, random, getRecipeChance(.2f)); - addItemForPurchase(newOffers, Item::hoe_iron_Id, random, getRecipeChance(.2f)); - addItemForPurchase(newOffers, Item::hoe_diamond_Id, random, getRecipeChance(.2f)); - addItemForPurchase(newOffers, Item::boots_iron_Id, random, getRecipeChance(.2f)); - addItemForPurchase(newOffers, Item::boots_diamond_Id, random, getRecipeChance(.2f)); - addItemForPurchase(newOffers, Item::helmet_iron_Id, random, getRecipeChance(.2f)); - addItemForPurchase(newOffers, Item::helmet_diamond_Id, random, getRecipeChance(.2f)); - addItemForPurchase(newOffers, Item::chestplate_iron_Id, random, getRecipeChance(.2f)); - addItemForPurchase(newOffers, Item::chestplate_diamond_Id, random, getRecipeChance(.2f)); - addItemForPurchase(newOffers, Item::leggings_iron_Id, random, getRecipeChance(.2f)); - addItemForPurchase(newOffers, Item::leggings_diamond_Id, random, getRecipeChance(.2f)); - addItemForPurchase(newOffers, Item::boots_chain_Id, random, getRecipeChance(.1f)); - addItemForPurchase(newOffers, Item::helmet_chain_Id, random, getRecipeChance(.1f)); - addItemForPurchase(newOffers, Item::chestplate_chain_Id, random, getRecipeChance(.1f)); - addItemForPurchase(newOffers, Item::leggings_chain_Id, random, getRecipeChance(.1f)); + addItemForPurchase(newOffers, Item::iron_sword_Id, random, getRecipeChance(.5f)); + addItemForPurchase(newOffers, Item::diamond_sword_Id, random, getRecipeChance(.5f)); + addItemForPurchase(newOffers, Item::iron_axe_Id, random, getRecipeChance(.3f)); + addItemForPurchase(newOffers, Item::diamond_axe_Id, random, getRecipeChance(.3f)); + addItemForPurchase(newOffers, Item::iron_pickaxe_Id, random, getRecipeChance(.5f)); + addItemForPurchase(newOffers, Item::diamond_pickaxe_Id, random, getRecipeChance(.5f)); + addItemForPurchase(newOffers, Item::iron_shovel_Id, random, getRecipeChance(.2f)); + addItemForPurchase(newOffers, Item::diamond_shovel_Id, random, getRecipeChance(.2f)); + addItemForPurchase(newOffers, Item::iron_hoe_Id, random, getRecipeChance(.2f)); + addItemForPurchase(newOffers, Item::diamond_hoe_Id, random, getRecipeChance(.2f)); + addItemForPurchase(newOffers, Item::iron_boots_Id, random, getRecipeChance(.2f)); + addItemForPurchase(newOffers, Item::diamond_boots_Id, random, getRecipeChance(.2f)); + addItemForPurchase(newOffers, Item::iron_helmet_Id, random, getRecipeChance(.2f)); + addItemForPurchase(newOffers, Item::diamond_helmet_Id, random, getRecipeChance(.2f)); + addItemForPurchase(newOffers, Item::iron_chestplate_Id, random, getRecipeChance(.2f)); + addItemForPurchase(newOffers, Item::diamond_chestplate_Id, random, getRecipeChance(.2f)); + addItemForPurchase(newOffers, Item::iron_leggings_Id, random, getRecipeChance(.2f)); + addItemForPurchase(newOffers, Item::diamond_leggings_Id, random, getRecipeChance(.2f)); + addItemForPurchase(newOffers, Item::chainmail_boots_Id, random, getRecipeChance(.1f)); + addItemForPurchase(newOffers, Item::chainmail_helmet_Id, random, getRecipeChance(.1f)); + addItemForPurchase(newOffers, Item::chainmail_chestplate_Id, random, getRecipeChance(.1f)); + addItemForPurchase(newOffers, Item::chainmail_leggings_Id, random, getRecipeChance(.1f)); break; case PROFESSION_LIBRARIAN: addItemForTradeIn(newOffers, Item::paper_Id, random, getRecipeChance(.8f)); addItemForTradeIn(newOffers, Item::book_Id, random, getRecipeChance(.8f)); - //addItemForTradeIn(newOffers, Item::writtenBook_Id, random, getRecipeChance(0.3f)); + //addItemForTradeIn(newOffers, Item::written_book_Id, random, getRecipeChance(0.3f)); addItemForPurchase(newOffers, Tile::bookshelf_Id, random, getRecipeChance(.8f)); addItemForPurchase(newOffers, Tile::glass_Id, random, getRecipeChance(.2f)); addItemForPurchase(newOffers, Item::compass_Id, random, getRecipeChance(.2f)); addItemForPurchase(newOffers, Item::clock_Id, random, getRecipeChance(.2f)); - addItemForPurchase(newOffers, Item::nameTag_Id, random, getRecipeChance(.2f)); + addItemForPurchase(newOffers, Item::name_tag_Id, random, getRecipeChance(.2f)); if (random->nextFloat() < getRecipeChance(0.07f)) { Enchantment *enchantment = Enchantment::validEnchantments[random->nextInt(Enchantment::validEnchantments.size())]; int level = Mth::nextInt(random, enchantment->getMinLevel(), enchantment->getMaxLevel()); - shared_ptr book = Item::enchantedBook->createForEnchantment(new EnchantmentInstance(enchantment, level)); + shared_ptr book = Item::enchanted_book->createForEnchantment(new EnchantmentInstance(enchantment, level)); int cost = 2 + random->nextInt(5 + (level * 10)) + 3 * level; newOffers->push_back(new MerchantRecipe(std::make_shared(Item::book), std::make_shared(Item::emerald, cost), book)); } break; case PROFESSION_PRIEST: - addItemForPurchase(newOffers, Item::eyeOfEnder_Id, random, getRecipeChance(.3f)); - addItemForPurchase(newOffers, Item::expBottle_Id, random, getRecipeChance(.2f)); - addItemForPurchase(newOffers, Item::redStone_Id, random, getRecipeChance(.4f)); + addItemForPurchase(newOffers, Item::eye_of_ender_Id, random, getRecipeChance(.3f)); + addItemForPurchase(newOffers, Item::experience_bottle_Id, random, getRecipeChance(.2f)); + addItemForPurchase(newOffers, Item::redstone_Id, random, getRecipeChance(.4f)); addItemForPurchase(newOffers, Tile::glowstone_Id, random, getRecipeChance(.3f)); { int enchantItems[] = { - Item::sword_iron_Id, Item::sword_diamond_Id, Item::chestplate_iron_Id, Item::chestplate_diamond_Id, Item::hatchet_iron_Id, Item::hatchet_diamond_Id, Item::pickAxe_iron_Id, - Item::pickAxe_diamond_Id + Item::iron_sword_Id, Item::diamond_sword_Id, Item::iron_chestplate_Id, Item::diamond_chestplate_Id, Item::iron_axe_Id, Item::diamond_axe_Id, Item::iron_pickaxe_Id, + Item::diamond_pickaxe_Id }; for (unsigned int i = 0; i < 8; ++i) { @@ -510,7 +510,7 @@ void Villager::addOffers(int addCount) if (newOffers->empty()) { - addItemForTradeIn(newOffers, Item::goldIngot_Id, random, 1.0f); + addItemForTradeIn(newOffers, Item::gold_ingot_Id, random, 1.0f); } // shuffle the list to make it more interesting @@ -539,69 +539,69 @@ void Villager::overrideOffers(MerchantRecipeList *recipeList) void Villager::staticCtor() { MIN_MAX_VALUES[Item::coal_Id] = pair(16, 24); - MIN_MAX_VALUES[Item::ironIngot_Id] = pair(8, 10); - MIN_MAX_VALUES[Item::goldIngot_Id] = pair(8, 10); + MIN_MAX_VALUES[Item::iron_ingot_Id] = pair(8, 10); + MIN_MAX_VALUES[Item::gold_ingot_Id] = pair(8, 10); MIN_MAX_VALUES[Item::diamond_Id] = pair(4, 6); MIN_MAX_VALUES[Item::paper_Id] = pair(24, 36); MIN_MAX_VALUES[Item::book_Id] = pair(11, 13); - //MIN_MAX_VALUES.insert(Item::writtenBook_Id, pair(1, 1)); - MIN_MAX_VALUES[Item::enderPearl_Id] = pair(3, 4); - MIN_MAX_VALUES[Item::eyeOfEnder_Id] = pair(2, 3); - MIN_MAX_VALUES[Item::porkChop_raw_Id] = pair(14, 18); - MIN_MAX_VALUES[Item::beef_raw_Id] = pair(14, 18); - MIN_MAX_VALUES[Item::chicken_raw_Id] = pair(14, 18); - MIN_MAX_VALUES[Item::fish_cooked_Id] = pair(9, 13); - MIN_MAX_VALUES[Item::seeds_wheat_Id] = pair(34, 48); - MIN_MAX_VALUES[Item::seeds_melon_Id] = pair(30, 38); - MIN_MAX_VALUES[Item::seeds_pumpkin_Id] = pair(30, 38); + //MIN_MAX_VALUES.insert(Item::written_book_Id, pair(1, 1)); + MIN_MAX_VALUES[Item::ender_pearl_Id] = pair(3, 4); + MIN_MAX_VALUES[Item::eye_of_ender_Id] = pair(2, 3); + MIN_MAX_VALUES[Item::porkchop_Id] = pair(14, 18); + MIN_MAX_VALUES[Item::beef_Id] = pair(14, 18); + MIN_MAX_VALUES[Item::chicken_Id] = pair(14, 18); + MIN_MAX_VALUES[Item::cooked_fish_Id] = pair(9, 13); + MIN_MAX_VALUES[Item::wheat_seeds_Id] = pair(34, 48); + MIN_MAX_VALUES[Item::melon_seeds_Id] = pair(30, 38); + MIN_MAX_VALUES[Item::pumpkin_seeds_Id] = pair(30, 38); MIN_MAX_VALUES[Item::wheat_Id] = pair(18, 22); MIN_MAX_VALUES[Tile::wool_Id] = pair(14, 22); MIN_MAX_VALUES[Item::rotten_flesh_Id] = pair(36, 64); - MIN_MAX_PRICES[Item::flintAndSteel_Id] = pair(3, 4); + MIN_MAX_PRICES[Item::flint_and_steel_Id] = pair(3, 4); MIN_MAX_PRICES[Item::shears_Id] = pair(3, 4); - MIN_MAX_PRICES[Item::sword_iron_Id] = pair(7, 11); - MIN_MAX_PRICES[Item::sword_diamond_Id] = pair(12, 14); - MIN_MAX_PRICES[Item::hatchet_iron_Id] = pair(6, 8); - MIN_MAX_PRICES[Item::hatchet_diamond_Id] = pair(9, 12); - MIN_MAX_PRICES[Item::pickAxe_iron_Id] = pair(7, 9); - MIN_MAX_PRICES[Item::pickAxe_diamond_Id] = pair(10, 12); - MIN_MAX_PRICES[Item::shovel_iron_Id] = pair(4, 6); - MIN_MAX_PRICES[Item::shovel_diamond_Id] = pair(7, 8); - MIN_MAX_PRICES[Item::hoe_iron_Id] = pair(4, 6); - MIN_MAX_PRICES[Item::hoe_diamond_Id] = pair(7, 8); - MIN_MAX_PRICES[Item::boots_iron_Id] = pair(4, 6); - MIN_MAX_PRICES[Item::boots_diamond_Id] = pair(7, 8); - MIN_MAX_PRICES[Item::helmet_iron_Id] = pair(4, 6); - MIN_MAX_PRICES[Item::helmet_diamond_Id] = pair(7, 8); - MIN_MAX_PRICES[Item::chestplate_iron_Id] = pair(10, 14); - MIN_MAX_PRICES[Item::chestplate_diamond_Id] = pair(16, 19); - MIN_MAX_PRICES[Item::leggings_iron_Id] = pair(8, 10); - MIN_MAX_PRICES[Item::leggings_diamond_Id] = pair(11, 14); - MIN_MAX_PRICES[Item::boots_chain_Id] = pair(5, 7); - MIN_MAX_PRICES[Item::helmet_chain_Id] = pair(5, 7); - MIN_MAX_PRICES[Item::chestplate_chain_Id] = pair(11, 15); - MIN_MAX_PRICES[Item::leggings_chain_Id] = pair(9, 11); + MIN_MAX_PRICES[Item::iron_sword_Id] = pair(7, 11); + MIN_MAX_PRICES[Item::diamond_sword_Id] = pair(12, 14); + MIN_MAX_PRICES[Item::iron_axe_Id] = pair(6, 8); + MIN_MAX_PRICES[Item::diamond_axe_Id] = pair(9, 12); + MIN_MAX_PRICES[Item::iron_pickaxe_Id] = pair(7, 9); + MIN_MAX_PRICES[Item::diamond_pickaxe_Id] = pair(10, 12); + MIN_MAX_PRICES[Item::iron_shovel_Id] = pair(4, 6); + MIN_MAX_PRICES[Item::diamond_shovel_Id] = pair(7, 8); + MIN_MAX_PRICES[Item::iron_hoe_Id] = pair(4, 6); + MIN_MAX_PRICES[Item::diamond_hoe_Id] = pair(7, 8); + MIN_MAX_PRICES[Item::iron_boots_Id] = pair(4, 6); + MIN_MAX_PRICES[Item::diamond_boots_Id] = pair(7, 8); + MIN_MAX_PRICES[Item::iron_helmet_Id] = pair(4, 6); + MIN_MAX_PRICES[Item::diamond_helmet_Id] = pair(7, 8); + MIN_MAX_PRICES[Item::iron_chestplate_Id] = pair(10, 14); + MIN_MAX_PRICES[Item::diamond_chestplate_Id] = pair(16, 19); + MIN_MAX_PRICES[Item::iron_leggings_Id] = pair(8, 10); + MIN_MAX_PRICES[Item::diamond_leggings_Id] = pair(11, 14); + MIN_MAX_PRICES[Item::chainmail_boots_Id] = pair(5, 7); + MIN_MAX_PRICES[Item::chainmail_helmet_Id] = pair(5, 7); + MIN_MAX_PRICES[Item::chainmail_chestplate_Id] = pair(11, 15); + MIN_MAX_PRICES[Item::chainmail_leggings_Id] = pair(9, 11); MIN_MAX_PRICES[Item::bread_Id] = pair(-4, -2); - MIN_MAX_PRICES[Item::melon_Id] = pair(-8, -4); + MIN_MAX_PRICES[Item::melon_block_Id] = pair(-8, -4); MIN_MAX_PRICES[Item::apple_Id] = pair(-8, -4); MIN_MAX_PRICES[Item::cookie_Id] = pair(-10, -7); MIN_MAX_PRICES[Tile::glass_Id] = pair(-5, -3); MIN_MAX_PRICES[Tile::bookshelf_Id] = pair(3, 4); - MIN_MAX_PRICES[Item::chestplate_leather_Id] = pair(4, 5); - MIN_MAX_PRICES[Item::boots_leather_Id] = pair(2, 4); - MIN_MAX_PRICES[Item::helmet_leather_Id] = pair(2, 4); - MIN_MAX_PRICES[Item::leggings_leather_Id] = pair(2, 4); + MIN_MAX_PRICES[Item::leather_chestplate_Id] = pair(4, 5); + MIN_MAX_PRICES[Item::leather_boots_Id] = pair(2, 4); + MIN_MAX_PRICES[Item::leather_helmet_Id] = pair(2, 4); + MIN_MAX_PRICES[Item::leather_leggings_Id] = pair(2, 4); MIN_MAX_PRICES[Item::saddle_Id] = pair(6, 8); - MIN_MAX_PRICES[Item::expBottle_Id] = pair(-4, -1); - MIN_MAX_PRICES[Item::redStone_Id] = pair(-4, -1); + MIN_MAX_PRICES[Item::experience_bottle_Id] = pair(-4, -1); + MIN_MAX_PRICES[Item::redstone_Id] = pair(-4, -1); MIN_MAX_PRICES[Item::compass_Id] = pair(10, 12); MIN_MAX_PRICES[Item::clock_Id] = pair(10, 12); MIN_MAX_PRICES[Tile::glowstone_Id] = pair(-3, -1); - MIN_MAX_PRICES[Item::porkChop_cooked_Id] = pair(-7, -5); - MIN_MAX_PRICES[Item::beef_cooked_Id] = pair(-7, -5); - MIN_MAX_PRICES[Item::chicken_cooked_Id] = pair(-8, -6); - MIN_MAX_PRICES[Item::eyeOfEnder_Id] = pair(7, 11); + MIN_MAX_PRICES[Item::cooked_porkchop_Id] = pair(-7, -5); + MIN_MAX_PRICES[Item::cooked_beef_Id] = pair(-7, -5); + MIN_MAX_PRICES[Item::cooked_chicken_Id] = pair(-8, -6); + MIN_MAX_PRICES[Item::eye_of_ender_Id] = pair(7, 11); MIN_MAX_PRICES[Item::arrow_Id] = pair(-12, -8); } diff --git a/Minecraft.World/VillagerGolem.cpp b/Minecraft.World/VillagerGolem.cpp index 04028056..e07237fa 100644 --- a/Minecraft.World/VillagerGolem.cpp +++ b/Minecraft.World/VillagerGolem.cpp @@ -210,12 +210,12 @@ void VillagerGolem::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) int roses = random->nextInt(3); for (int i = 0; i < roses; i++) { - spawnAtLocation(Tile::rose_Id, 1); + spawnAtLocation(Tile::red_flower_Id, 1); } int iron = 3 + random->nextInt(3); for (int i = 0; i < iron; i++) { - spawnAtLocation(Item::ironIngot_Id, 1); + spawnAtLocation(Item::iron_ingot_Id, 1); } } diff --git a/Minecraft.World/Villages.cpp b/Minecraft.World/Villages.cpp index 432a8b6b..49c70c99 100644 --- a/Minecraft.World/Villages.cpp +++ b/Minecraft.World/Villages.cpp @@ -173,7 +173,7 @@ shared_ptr Villages::getDoorInfo(int x, int y, int z) void Villages::createDoorInfo(int x, int y, int z) { - int dir = static_cast(Tile::door_wood)->getDir(level, x, y, z); + int dir = static_cast(Tile::wooden_door)->getDir(level, x, y, z); if (dir == 0 || dir == 2) { int canSeeX = 0; @@ -208,7 +208,7 @@ bool Villages::hasQuery(int x, int y, int z) bool Villages::isDoor(int x, int y, int z) { int tileId = level->getTile(x, y, z); - return tileId == Tile::door_wood_Id; + return tileId == Tile::wooden_door_Id; } void Villages::load(CompoundTag *tag) diff --git a/Minecraft.World/VineTile.cpp b/Minecraft.World/VineTile.cpp index 8f16a921..7110cc16 100644 --- a/Minecraft.World/VineTile.cpp +++ b/Minecraft.World/VineTile.cpp @@ -13,6 +13,32 @@ VineTile::VineTile(int id) : Tile(id, Material::replaceable_plant, isSolidRender setTicking(true); } +void VineTile::createBlockStateDefinition() +{ + if (!m_blockStateDefinition) + m_blockStateDefinition = new BlockStateDefinition(this); +} + +int VineTile::defaultBlockState() +{ + return 0; +} + +int VineTile::convertBlockStateToLegacyData(BlockState *state) +{ + return state ? (state->value & 0xF) : 0; +} + +Tile::BlockState VineTile::getBlockState(int data) +{ + return Tile::BlockState(data & 0xF); +} + +Tile::BlockState VineTile::getBlockState(LevelSource *level, int x, int y, int z) +{ + return Tile::BlockState(level->getData(x, y, z) & 0xF); +} + void VineTile::updateDefaultShape() { setShape(0, 0, 0, 1, 1, 1); diff --git a/Minecraft.World/VineTile.h b/Minecraft.World/VineTile.h index bdea2cdc..38f089c1 100644 --- a/Minecraft.World/VineTile.h +++ b/Minecraft.World/VineTile.h @@ -14,6 +14,11 @@ public: public: VineTile(int id); + virtual void createBlockStateDefinition() override; + virtual int defaultBlockState() override; + virtual int convertBlockStateToLegacyData(BlockState *state) override; + virtual Tile::BlockState getBlockState(LevelSource *level, int x, int y, int z) override; + virtual Tile::BlockState getBlockState(int data); virtual void updateDefaultShape(); virtual int getRenderShape(); virtual bool isSolidRender(bool isServerLevel = false); diff --git a/Minecraft.World/WallTile.cpp b/Minecraft.World/WallTile.cpp index b7d3f038..9b9ff947 100644 --- a/Minecraft.World/WallTile.cpp +++ b/Minecraft.World/WallTile.cpp @@ -17,6 +17,7 @@ const unsigned int WallTile::COBBLE_NAMES[2] = { IDS_TILE_COBBLESTONE_WALL, WallTile::WallTile(int id, Tile *baseTile) : Tile(id, baseTile->material, isSolidRender()) { + setLightBlock(0); setDestroyTime(baseTile->destroySpeed); setExplodeable(baseTile->explosionResistance / 3); setSoundType(baseTile->soundType); @@ -154,7 +155,7 @@ AABB *WallTile::getAABB(Level *level, int x, int y, int z) bool WallTile::connectsTo(LevelSource *level, int x, int y, int z) { int tile = level->getTile(x, y, z); - if (tile == id || tile == Tile::fenceGate_Id) + if (tile == id || tile == Tile::fence_gate_Id) { return true; } diff --git a/Minecraft.World/WaterLilyTile.cpp b/Minecraft.World/WaterLilyTile.cpp index 73d1e057..1ed239c7 100644 --- a/Minecraft.World/WaterLilyTile.cpp +++ b/Minecraft.World/WaterLilyTile.cpp @@ -61,7 +61,7 @@ int WaterlilyTile::getColor(LevelSource *level, int x, int y, int z, int data) / bool WaterlilyTile::mayPlaceOn(int tile) { - return tile == Tile::calmWater_Id; + return tile == Tile::water_Id; } bool WaterlilyTile::canSurvive(Level *level, int x, int y, int z) diff --git a/Minecraft.World/WaterlilyFeature.cpp b/Minecraft.World/WaterlilyFeature.cpp index eccfcaf6..4e2f3d3d 100644 --- a/Minecraft.World/WaterlilyFeature.cpp +++ b/Minecraft.World/WaterlilyFeature.cpp @@ -14,7 +14,7 @@ bool WaterlilyFeature::place(Level *level, Random *random, int x, int y, int z) { if (Tile::waterLily->mayPlace(level, x2, y2, z2)) { - level->setTileAndData(x2, y2, z2, Tile::waterLily_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x2, y2, z2, Tile::waterlily_Id, 0, Tile::UPDATE_CLIENTS); } } } diff --git a/Minecraft.World/WeaponRecipies.cpp b/Minecraft.World/WeaponRecipies.cpp index 1dbe6bda..8fef0295 100644 --- a/Minecraft.World/WeaponRecipies.cpp +++ b/Minecraft.World/WeaponRecipies.cpp @@ -20,15 +20,15 @@ void WeaponRecipies::_init() ADD_OBJECT(map[0],Tile::wood); ADD_OBJECT(map[0],Tile::cobblestone); - ADD_OBJECT(map[0],Item::ironIngot); + ADD_OBJECT(map[0],Item::iron_ingot); ADD_OBJECT(map[0],Item::diamond); - ADD_OBJECT(map[0],Item::goldIngot); + ADD_OBJECT(map[0],Item::gold_ingot); - ADD_OBJECT(map[1],Item::sword_wood); - ADD_OBJECT(map[1],Item::sword_stone); - ADD_OBJECT(map[1],Item::sword_iron); - ADD_OBJECT(map[1],Item::sword_diamond); - ADD_OBJECT(map[1],Item::sword_gold); + ADD_OBJECT(map[1],Item::wooden_sword); + ADD_OBJECT(map[1],Item::stone_sword); + ADD_OBJECT(map[1],Item::iron_sword); + ADD_OBJECT(map[1],Item::diamond_sword); + ADD_OBJECT(map[1],Item::golden_sword); } void WeaponRecipies::addRecipes(Recipes *r) diff --git a/Minecraft.World/WebTile.cpp b/Minecraft.World/WebTile.cpp index 43609e56..98f490c3 100644 --- a/Minecraft.World/WebTile.cpp +++ b/Minecraft.World/WebTile.cpp @@ -5,6 +5,7 @@ WebTile::WebTile(int id) : Tile(id, Material::web) { + setLightBlock(0); } diff --git a/Minecraft.World/Witch.cpp b/Minecraft.World/Witch.cpp index 375c8388..344be228 100644 --- a/Minecraft.World/Witch.cpp +++ b/Minecraft.World/Witch.cpp @@ -16,7 +16,7 @@ AttributeModifier *Witch::SPEED_MODIFIER_DRINKING = (new AttributeModifier(eModifierId_MOB_WITCH_DRINKSPEED, -0.25f, AttributeModifier::OPERATION_ADDITION))->setSerialize(false); const int Witch::DEATH_LOOT[Witch::DEATH_LOOT_COUNT] = { - Item::yellowDust_Id, Item::sugar_Id, Item::redStone_Id, Item::spiderEye_Id, Item::glassBottle_Id, Item::gunpowder_Id, Item::stick_Id, Item::stick_Id, + Item::glowstone_dust_Id, Item::sugar_Id, Item::redstone_Id, Item::spider_eye_Id, Item::glass_bottle_Id, Item::gunpowder_Id, Item::stick_Id, Item::stick_Id, }; Witch::Witch(Level *level) : Monster(level) diff --git a/Minecraft.World/WitherBoss.cpp b/Minecraft.World/WitherBoss.cpp index af406a93..f9b49223 100644 --- a/Minecraft.World/WitherBoss.cpp +++ b/Minecraft.World/WitherBoss.cpp @@ -337,7 +337,7 @@ void WitherBoss::newServerAiStep() int ty = feet + yStep; int tz = oz + zStep; int tile = level->getTile(tx, ty, tz); - if (tile > 0 && tile != Tile::unbreakable_Id && tile != Tile::endPortalTile_Id && tile != Tile::endPortalFrameTile_Id) + if (tile > 0 && tile != Tile::bedrock_Id && tile != Tile::end_portal_Id && tile != Tile::end_portal_frame_Id) { destroyed = level->destroyTile(tx, ty, tz, true) || destroyed; } @@ -495,7 +495,7 @@ bool WitherBoss::hurt(DamageSource *source, float dmg) void WitherBoss::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) { - spawnAtLocation(Item::netherStar_Id, 1); + spawnAtLocation(Item::nether_star_Id, 1); } void WitherBoss::checkDespawn() diff --git a/Minecraft.World/WitherSkull.cpp b/Minecraft.World/WitherSkull.cpp index ccde41d4..79a8d24d 100644 --- a/Minecraft.World/WitherSkull.cpp +++ b/Minecraft.World/WitherSkull.cpp @@ -43,7 +43,7 @@ float WitherSkull::getTileExplosionResistance(Explosion *explosion, Level *level { float result = Fireball::getTileExplosionResistance(explosion, level, x, y, z, tile); - if (isDangerous() && tile != Tile::unbreakable && tile != Tile::endPortalTile && tile != Tile::endPortalFrameTile) + if (isDangerous() && tile != Tile::unbreakable && tile != Tile::end_portal && tile != Tile::end_portal_frame) { result = min(0.8f, result); } diff --git a/Minecraft.World/Wolf.cpp b/Minecraft.World/Wolf.cpp index 38047cf2..306bdf35 100644 --- a/Minecraft.World/Wolf.cpp +++ b/Minecraft.World/Wolf.cpp @@ -365,7 +365,7 @@ bool Wolf::mobInteract(shared_ptr player) return true; } } - else if (item->id == Item::dye_powder_Id) + else if (item->id == Item::dye_Id) { int color = ColoredTile::getTileDataForItemAuxValue(item->getAuxValue()); if (color != getCollarColor()) diff --git a/Minecraft.World/WoodSlabTile.cpp b/Minecraft.World/WoodSlabTile.cpp index 434e2b1f..2d44982d 100644 --- a/Minecraft.World/WoodSlabTile.cpp +++ b/Minecraft.World/WoodSlabTile.cpp @@ -29,7 +29,7 @@ Icon *WoodSlabTile::getTexture(int face, int data) int WoodSlabTile::getResource(int data, Random *random, int playerBonusLevel) { - return Tile::woodSlabHalf_Id; + return Tile::wooden_slab_Id; } shared_ptr WoodSlabTile::getSilkTouchItemInstance(int data) diff --git a/Minecraft.World/WoolCarpetTile.cpp b/Minecraft.World/WoolCarpetTile.cpp index 370b4010..16ee9c70 100644 --- a/Minecraft.World/WoolCarpetTile.cpp +++ b/Minecraft.World/WoolCarpetTile.cpp @@ -6,6 +6,7 @@ WoolCarpetTile::WoolCarpetTile(int id) : Tile(id, Material::clothDecoration, isSolidRender() ) { + setLightBlock(0); setShape(0, 0, 0, 1, 1 / 16.0f, 1); setTicking(true); updateShape(0); diff --git a/Minecraft.World/WoolTileItem.cpp b/Minecraft.World/WoolTileItem.cpp index e1ff8be6..4e7bbb52 100644 --- a/Minecraft.World/WoolTileItem.cpp +++ b/Minecraft.World/WoolTileItem.cpp @@ -143,9 +143,9 @@ unsigned int WoolTileItem::getDescriptionId(shared_ptr instance) return GLASS_COLOR_DESCS[ColoredTile::getTileDataForItemAuxValue(instance->getAuxValue())]; case Tile::stained_glass_pane_Id: return GLASS_PANE_COLOR_DESCS[ColoredTile::getTileDataForItemAuxValue(instance->getAuxValue())]; - case Tile::clayHardened_colored_Id: + case Tile::stained_hardened_clay_Id: return CLAY_COLOR_DESCS[ColoredTile::getTileDataForItemAuxValue(instance->getAuxValue())]; - case Tile::woolCarpet_Id: + case Tile::carpet_Id: return CARPET_COLOR_DESCS[ColoredTile::getTileDataForItemAuxValue(instance->getAuxValue())]; case Tile::wool_Id: default: diff --git a/Minecraft.World/Zombie.cpp b/Minecraft.World/Zombie.cpp index 8032a1fe..87e4e173 100644 --- a/Minecraft.World/Zombie.cpp +++ b/Minecraft.World/Zombie.cpp @@ -275,10 +275,10 @@ void Zombie::dropRareDeathLoot(int rareLootLevel) switch (random->nextInt(3)) { case 0: - spawnAtLocation(Item::ironIngot_Id, 1); + spawnAtLocation(Item::iron_ingot_Id, 1); break; case 1: - spawnAtLocation(Item::carrots_Id, 1); + spawnAtLocation(Item::carrot_Id, 1); break; case 2: spawnAtLocation(Item::potato_Id, 1); @@ -295,11 +295,11 @@ void Zombie::populateDefaultEquipmentSlots() int rand = random->nextInt(3); if (rand == 0) { - setEquippedSlot(SLOT_WEAPON, std::make_shared(Item::sword_iron)); + setEquippedSlot(SLOT_WEAPON, std::make_shared(Item::iron_sword)); } else { - setEquippedSlot(SLOT_WEAPON, std::make_shared(Item::shovel_iron)); + setEquippedSlot(SLOT_WEAPON, std::make_shared(Item::iron_shovel)); } } } @@ -430,7 +430,7 @@ bool Zombie::mobInteract(shared_ptr player) { shared_ptr item = player->getSelectedItem(); - if (item != nullptr && item->getItem() == Item::apple_gold && item->getAuxValue() == 0 && isVillager() && hasEffect(MobEffect::weakness)) + if (item != nullptr && item->getItem() == Item::golden_apple && item->getAuxValue() == 0 && isVillager() && hasEffect(MobEffect::weakness)) { if (!player->abilities.instabuild) item->count--; if (item->count <= 0) @@ -515,7 +515,7 @@ int Zombie::getConversionProgress() { int tile = level->getTile(xx, yy, zz); - if (tile == Tile::ironFence_Id || tile == Tile::bed_Id) + if (tile == Tile::iron_bars_Id || tile == Tile::bed_Id) { if (random->nextFloat() < 0.3f) amount++; specialBlocksCount++; diff --git a/Minecraft.World/ZoomLayer.cpp b/Minecraft.World/ZoomLayer.cpp index 88f3e0b3..ce68c2f4 100644 --- a/Minecraft.World/ZoomLayer.cpp +++ b/Minecraft.World/ZoomLayer.cpp @@ -11,8 +11,8 @@ intArray ZoomLayer::getArea(int xo, int yo, int w, int h) { int px = xo >> 1; int py = yo >> 1; - int pw = (w >> 1) + 3; - int ph = (h >> 1) + 3; + int pw = (w >> 1) + 2; + int ph = (h >> 1) + 2; intArray p = parent->getArea(px, py, pw, ph); intArray tmp = IntCache::allocate((pw * 2) * (ph * 2)); diff --git a/Minecraft.World/cmake/sources/Common.cmake b/Minecraft.World/cmake/sources/Common.cmake index 6b45f3b6..a54e2c99 100644 --- a/Minecraft.World/cmake/sources/Common.cmake +++ b/Minecraft.World/cmake/sources/Common.cmake @@ -840,6 +840,8 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_ENTITY_ITEM "${CMAKE_CURRENT_SOURCE_DIR}/ItemEntity.h" "${CMAKE_CURRENT_SOURCE_DIR}/Minecart.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Minecart.h" + "${CMAKE_CURRENT_SOURCE_DIR}/MinecartSoundInstance.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/MinecartSoundInstance.h" "${CMAKE_CURRENT_SOURCE_DIR}/MinecartChest.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MinecartChest.h" "${CMAKE_CURRENT_SOURCE_DIR}/MinecartContainer.cpp" @@ -1365,6 +1367,8 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_BIOME "${CMAKE_CURRENT_SOURCE_DIR}/RainforestBiome.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/RainforestBiome.h" "${CMAKE_CURRENT_SOURCE_DIR}/RiverBiome.h" + "${CMAKE_CURRENT_SOURCE_DIR}/StoneBeachBiome.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/StoneBeachBiome.h" "${CMAKE_CURRENT_SOURCE_DIR}/SwampBiome.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/SwampBiome.h" "${CMAKE_CURRENT_SOURCE_DIR}/TaigaBiome.cpp" @@ -1955,6 +1959,8 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_TILE "${CMAKE_CURRENT_SOURCE_DIR}/SignTile.h" "${CMAKE_CURRENT_SOURCE_DIR}/SkullTile.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/SkullTile.h" + "${CMAKE_CURRENT_SOURCE_DIR}/SlimeTile.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/SlimeTile.h" "${CMAKE_CURRENT_SOURCE_DIR}/SmoothStoneBrickTile.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/SmoothStoneBrickTile.h" "${CMAKE_CURRENT_SOURCE_DIR}/SnowTile.cpp" diff --git a/Minecraft.World/net.minecraft.world.level.biome.h b/Minecraft.World/net.minecraft.world.level.biome.h index b7e0bc60..64dbaea2 100644 --- a/Minecraft.World/net.minecraft.world.level.biome.h +++ b/Minecraft.World/net.minecraft.world.level.biome.h @@ -34,4 +34,5 @@ //TU31 #include "SavannaBiome.h" -#include "MesaBiome.h" \ No newline at end of file +#include "MesaBiome.h" +#include "StoneBeachBiome.h" \ No newline at end of file diff --git a/Minecraft.World/net.minecraft.world.level.tile.h b/Minecraft.World/net.minecraft.world.level.tile.h index 93843135..f819e761 100644 --- a/Minecraft.World/net.minecraft.world.level.tile.h +++ b/Minecraft.World/net.minecraft.world.level.tile.h @@ -97,6 +97,7 @@ #include "SignTile.h" #include "SkullTile.h" +#include "SlimeTile.h" #include "SmoothStoneBrickTile.h" #include "SnowTile.h" #include "SoulSandTile.h" diff --git a/tools/msscmp_extract.py b/tools/msscmp_extract.py new file mode 100644 index 00000000..025b5841 --- /dev/null +++ b/tools/msscmp_extract.py @@ -0,0 +1,286 @@ +#!/usr/bin/env python3 + +import os +import sys +import struct +import subprocess +from collections import defaultdict + +# helper functions +def read_c_string(data, offset): + end = data.find(b'\x00', offset) + + if end == -1: + return "" + + return data[offset:end].decode( + "utf-8", + errors="ignore" + ) + + +def convert_to_flac(infile, outfile): + + # skip if already exists + if os.path.exists(outfile): + return + + try: + subprocess.run( + [ + "ffmpeg", + "-y", + "-i", infile, + "-c:a", "flac", + outfile + ], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + check=True + ) + + print(f"[FLAC] {outfile}") + + except Exception: + print(f"[FAIL] ffmpeg failed on {infile}") + +def main(): + + if len(sys.argv) < 2: + print("usage: python3 file_extract.py Minecraft.msscmp") + return + + infile = sys.argv[1] + + with open(infile, "rb") as f: + data = f.read() + + # validation + if data[:4] != b'BANK': + print("Not a BANK file") + return + + filesize = len(data) + + # header recognition + file_table_offset = struct.unpack( + ">I", + data[0x18:0x1C] + )[0] + + entry_count = struct.unpack( + ">I", + data[0x34:0x38] + )[0] + + print(f"[+] table @ {hex(file_table_offset)}") + print(f"[+] entries: {entry_count}") + + if file_table_offset >= filesize: + print("Bad table offset") + return + + # binka and flac output folder(s) + binka_root = "extracted_binka" + flac_root = "extracted_flac" + + os.makedirs(binka_root, exist_ok=True) + os.makedirs(flac_root, exist_ok=True) + + folder_counts = defaultdict(int) + entries_cache = [] + + for i in range(entry_count): + + entry_off = file_table_offset + (i * 8) + + if entry_off + 8 > filesize: + break + + try: + + folder_off = struct.unpack( + ">I", + data[entry_off:entry_off+4] + )[0] + + info_off = struct.unpack( + ">I", + data[entry_off+4:entry_off+8] + )[0] + + if folder_off >= filesize: + continue + + if info_off >= filesize: + continue + + # yoink audio name from parent dir + folder = read_c_string( + data, + folder_off + ) + + filename_rel = struct.unpack( + ">I", + data[info_off+4:info_off+8] + )[0] + + filename_off = info_off + filename_rel + + if filename_off >= filesize: + continue + + filename = read_c_string( + data, + filename_off + ) + + data_off = struct.unpack( + "I", + data[info_off+20:info_off+24] + )[0] + + size = struct.unpack( + ">I", + data[info_off+24:info_off+28] + )[0] + + if size <= 0: + continue + + if data_off + size > filesize: + continue + + clean_folder = folder.replace( + "\\", + "/" + ).strip("/") + + clean_name = filename.replace( + "*", + "" + ).strip() + + if not clean_name.endswith(".binka"): + clean_name += ".binka" + + folder_counts[clean_folder] += 1 + + entries_cache.append( + ( + clean_folder, + clean_name, + data_off, + size, + sample_rate + ) + ) + + except Exception: + continue + + # extract + convert to flac + extracted = 0 + + for ( + clean_folder, + clean_name, + data_off, + size, + sample_rate + ) in entries_cache: + + try: + + binka_folder = os.path.join( + binka_root, + clean_folder + ) + + os.makedirs( + binka_folder, + exist_ok=True + ) + + binka_path = os.path.join( + binka_folder, + clean_name + ) + + with open(binka_path, "wb") as out: + out.write( + data[data_off:data_off+size] + ) + + # folders with one sound get deleted + if folder_counts[clean_folder] == 1: + + folder_parts = clean_folder.split("/") + + parent_folder = os.path.join( + flac_root, + *folder_parts[:-1] + ) + + os.makedirs( + parent_folder, + exist_ok=True + ) + + flac_filename = ( + folder_parts[-1] + ".flac" + ) + + flac_path = os.path.join( + parent_folder, + flac_filename + ) + + else: + + flac_folder = os.path.join( + flac_root, + clean_folder + ) + + os.makedirs( + flac_folder, + exist_ok=True + ) + + flac_filename = ( + os.path.splitext(clean_name)[0] + + ".flac" + ) + + flac_path = os.path.join( + flac_folder, + flac_filename + ) + + convert_to_flac( + binka_path, + flac_path + ) + + print( + f"[+] {clean_name} " + f"({size} bytes @ {sample_rate}hz)" + ) + + extracted += 1 + + except Exception: + continue + + print(f"\nDone. Extracted {extracted} files.") + + +if __name__ == "__main__": + main() diff --git a/tools/pck_extract.py b/tools/pck_extract.py new file mode 100644 index 00000000..3dc90391 --- /dev/null +++ b/tools/pck_extract.py @@ -0,0 +1,232 @@ +#!/usr/bin/env python3 + +import struct +import argparse +import zipfile +import os +import sys + +# default endian mode +ENDIAN = ">" + +def detect_endianness(f): + """ + Detect whether the PCK uses big-endian or little-endian. + """ + + global ENDIAN + + pos = f.tell() + + raw = f.read(4) + + if len(raw) != 4: + raise EOFError("File too small") + + be = struct.unpack(">I", raw)[0] + le = struct.unpack("' else 'Little'} Endian") + + +def read_u32(f): + data = f.read(4) + + if len(data) != 4: + raise EOFError("Unexpected EOF while reading uint32") + + return struct.unpack(f"{ENDIAN}I", data)[0] + + +def read_utf16_string(f): + """ + PCK strings are: + uint32 length + UTF-16 bytes + uint32 padding + """ + + length = read_u32(f) + + if length > 100000: + raise ValueError(f"Unreasonable string length: {length}") + + raw = f.read(length * 2) + + if len(raw) != length * 2: + raise EOFError("Unexpected EOF while reading string") + + encoding = "utf-16-be" if ENDIAN == ">" else "utf-16-le" + + text = raw.decode(encoding, errors="replace") + + # skip padding + padding = f.read(4) + + if len(padding) != 4: + raise EOFError("Unexpected EOF while reading string padding") + + return text + + +def extract_pck_to_zip(input_file, output_zip): + + with open(input_file, "rb") as f: + + # detect endianness before reading anything + detect_endianness(f) + + # ----- HEADER ----- + + pck_type = read_u32(f) + param_count = read_u32(f) + + print(f"PCK Type: {pck_type}") + print(f"Parameter Count: {param_count}") + + # ----- PARAMETER LOOKUP TABLE ----- + + lookup = [None] * param_count + + for _ in range(param_count): + + idx = read_u32(f) + key = read_utf16_string(f) + + if idx >= param_count: + raise ValueError(f"Invalid parameter index: {idx}") + + lookup[idx] = key + + # Optional XMLVERSION field + + if "XMLVERSION" in lookup: + xml_version = read_u32(f) + print(f"XML Version: {xml_version}") + + # ----- ASSET TABLE ----- + + asset_count = read_u32(f) + + print(f"Asset Count: {asset_count}") + + assets = [] + + for i in range(asset_count): + + size = read_u32(f) + asset_type = read_u32(f) + name = read_utf16_string(f) + + name = name.replace("\\", "/") + + print(f"[{i+1}/{asset_count}] {name} ({size} bytes)") + + assets.append({ + "name": name, + "size": size, + "type": asset_type, + }) + + # ----- ASSET DATA ----- + + for asset in assets: + + asset_param_count = read_u32(f) + + params = {} + + for _ in range(asset_param_count): + + key_index = read_u32(f) + value = read_utf16_string(f) + + if key_index < len(lookup): + key = lookup[key_index] + params[key] = value + + asset["params"] = params + + data = f.read(asset["size"]) + + if len(data) != asset["size"]: + raise EOFError( + f"Unexpected EOF while reading asset data: {asset['name']}" + ) + + asset["data"] = data + + # ----- WRITE ZIP ----- + + print(f"\nWriting ZIP: {output_zip}") + + with zipfile.ZipFile( + output_zip, + "w", + compression=zipfile.ZIP_DEFLATED + ) as zf: + + for asset in assets: + + zip_name = asset["name"].lstrip("/") + + if not zip_name: + continue + + print(f"Adding: {zip_name}") + + zf.writestr(zip_name, asset["data"]) + + print("\nDone!") + + +def main(): + + parser = argparse.ArgumentParser( + description="Convert Minecraft Legacy Console .pck files to .zip" + ) + + parser.add_argument( + "input", + help="Input .pck file" + ) + + parser.add_argument( + "-o", + "--output", + help="Output zip filename" + ) + + args = parser.parse_args() + + input_path = args.input + + if not os.path.isfile(input_path): + print(f"Input file not found: {input_path}") + sys.exit(1) + + output_path = args.output + + if not output_path: + output_path = os.path.splitext(input_path)[0] + ".zip" + + try: + extract_pck_to_zip(input_path, output_path) + + except Exception as e: + print(f"\nERROR: {e}") + sys.exit(1) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/tools/pck_pack.py b/tools/pck_pack.py new file mode 100644 index 00000000..589c9f66 --- /dev/null +++ b/tools/pck_pack.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python3 + +import struct +import argparse +import os +import sys + +# default endian +ENDIAN = ">" + +# defaults +DEFAULT_PCK_TYPE = 3 +DEFAULT_XML_VERSION = 4 +DEFAULT_ASSET_TYPE = 0 + + +def write_u32(f, value): + f.write(struct.pack(f"{ENDIAN}I", value)) + + +def write_utf16_string(f, text): + """ + PCK strings: + uint32 length + UTF-16 bytes + uint32 padding + """ + + encoding = "utf-16-be" if ENDIAN == ">" else "utf-16-le" + + encoded = text.encode(encoding) + + write_u32(f, len(text)) + f.write(encoded) + + # padding + write_u32(f, 0) + + +def collect_folder_assets(folder_path): + + assets = [] + + for root, _, files in os.walk(folder_path): + + for file in files: + + full_path = os.path.join(root, file) + + rel_path = os.path.relpath(full_path, folder_path) + + # PCKs usually use backslashes + rel_path = rel_path.replace("/", "\\") + rel_path = rel_path.replace("\\\\", "\\") + + with open(full_path, "rb") as f: + data = f.read() + + assets.append({ + "name": rel_path, + "size": len(data), + "type": DEFAULT_ASSET_TYPE, + "params": {}, + "data": data, + }) + + return assets + + +def pack_folder_to_pck(input_folder, output_pck): + + assets = collect_folder_assets(input_folder) + + if not assets: + raise ValueError("No files found in folder") + + # parameter lookup table + lookup = [ + "PATH", + "TYPE", + "XMLVERSION", + ] + + print(f"Assets: {len(assets)}") + + with open(output_pck, "wb") as f: + + # ----- HEADER ----- + + write_u32(f, DEFAULT_PCK_TYPE) + + write_u32(f, len(lookup)) + + # ----- PARAMETER LOOKUP TABLE ----- + + for idx, key in enumerate(lookup): + + write_u32(f, idx) + + write_utf16_string(f, key) + + # optional XMLVERSION + if "XMLVERSION" in lookup: + write_u32(f, DEFAULT_XML_VERSION) + + # ----- ASSET TABLE ----- + + write_u32(f, len(assets)) + + for asset in assets: + + write_u32(f, asset["size"]) + write_u32(f, asset["type"]) + + write_utf16_string(f, asset["name"]) + + print(f"Indexing: {asset['name']} ({asset['size']} bytes)") + + # ----- ASSET DATA ----- + + for asset in assets: + + params = asset["params"] + + write_u32(f, len(params)) + + for key, value in params.items(): + + key_index = lookup.index(key) + + write_u32(f, key_index) + + write_utf16_string(f, value) + + f.write(asset["data"]) + + print(f"Writing: {asset['name']}") + + print(f"\nDone! Wrote: {output_pck}") + + +def main(): + + global ENDIAN + + parser = argparse.ArgumentParser( + description="Pack a folder into a Minecraft Legacy Console .pck" + ) + + parser.add_argument( + "input", + help="Input folder" + ) + + parser.add_argument( + "-o", + "--output", + help="Output .pck filename" + ) + + parser.add_argument( + "--little", + action="store_true", + help="Write little-endian PCK" + ) + + args = parser.parse_args() + + input_path = args.input + + if not os.path.isdir(input_path): + print(f"Input folder not found: {input_path}") + sys.exit(1) + + if args.little: + ENDIAN = "<" + + output_path = args.output + + if not output_path: + output_path = os.path.basename( + os.path.normpath(input_path) + ) + ".pck" + + try: + pack_folder_to_pck(input_path, output_path) + + except Exception as e: + print(f"\nERROR: {e}") + sys.exit(1) + + +if __name__ == "__main__": + main()