#include "../../Minecraft.World/Platform/stdafx.h" #include "../Tutorial/Tutorial.h" #include "../../Minecraft.Client/Player/MultiPlayerLocalPlayer.h" #include "../../Minecraft.World/Util/StringHelpers.h" #include "../../Minecraft.World/Blocks/Tile.h" #include "../../Minecraft.World/Items/Item.h" #include "XUI_Ctrl_CraftIngredientSlot.h" #include "XUI_XZP_Icons.h" //---------------------------------------------------------------------------------- // Performs initialization tasks - retrieves controls. //---------------------------------------------------------------------------------- HRESULT CScene_TutorialPopup::OnInit(XUIMessageInit* pInitData, BOOL& bHandled) { HRESULT hr = S_OK; tutorial = (Tutorial*)pInitData->pvInitData; m_iPad = tutorial->getPad(); MapChildControls(); // splitscreen? // if we are in splitscreen, then we need to figure out if we want to move // this scene if (app.GetLocalPlayerCount() > 1) { app.AdjustSplitscreenScene(m_hObj, &m_OriginalPosition, m_iPad); } m_textFontSize = _fromString(m_fontSizeControl.GetText()); m_fontSizeControl.SetShow(false); m_interactScene = NULL; m_lastSceneMovedLeft = false; m_bAllowFade = false; SetShow(false); XuiSetTimer(m_hObj, TUTORIAL_POPUP_MOVE_SCENE_TIMER_ID, TUTORIAL_POPUP_MOVE_SCENE_TIME); return hr; } HRESULT CScene_TutorialPopup::OnDestroy() { return S_OK; } HRESULT CScene_TutorialPopup::OnTimer(XUIMessageTimer* pData, BOOL& rfHandled) { if (pData->nId == TUTORIAL_POPUP_FADE_TIMER_ID) { XuiKillTimer(m_hObj, TUTORIAL_POPUP_FADE_TIMER_ID); SetShow(false); XuiSetTimer(m_hObj, TUTORIAL_POPUP_MOVE_SCENE_TIMER_ID, TUTORIAL_POPUP_MOVE_SCENE_TIME); } else if (pData->nId == TUTORIAL_POPUP_MOVE_SCENE_TIMER_ID) { UpdateInteractScenePosition(IsShown() == TRUE); XuiKillTimer(m_hObj, TUTORIAL_POPUP_MOVE_SCENE_TIMER_ID); } return S_OK; } void CScene_TutorialPopup::UpdateInteractScenePosition(bool visible) { if (m_interactScene == NULL) return; // 4J-PB - check this players screen section to see if we should allow the // animation bool bAllowAnim = false; HXUICLASS sceneClass = XuiGetObjectClass(m_interactScene->m_hObj); HXUICLASS inventoryClass = XuiFindClass(L"CXuiSceneInventory"); HXUICLASS furnaceClass = XuiFindClass(L"CXuiSceneFurnace"); HXUICLASS craftingClass = XuiFindClass(L"CXuiSceneCraftingPanel"); HXUICLASS trapClass = XuiFindClass(L"CXuiSceneTrap"); HXUICLASS containerClass = XuiFindClass(L"CXuiSceneContainer"); HXUICLASS creativeInventoryClass = XuiFindClass(L"CXuiSceneInventoryCreative"); HXUICLASS enchantingClass = XuiFindClass(L"CXuiSceneEnchant"); HXUICLASS brewingClass = XuiFindClass(L"CXuiSceneBrewingStand"); HXUICLASS anvilClass = XuiFindClass(L"CXuiSceneAnvil"); HXUICLASS tradingClass = XuiFindClass(L"CXuiSceneTrading"); bool isCraftingScene = XuiClassDerivesFrom(sceneClass, craftingClass) != FALSE; bool isCreativeScene = XuiClassDerivesFrom(sceneClass, creativeInventoryClass) != FALSE; switch (Minecraft::GetInstance()->localplayers[m_iPad]->m_iScreenSection) { case C4JRender::VIEWPORT_TYPE_FULLSCREEN: case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: bAllowAnim = true; break; default: // anim allowed for everything except the crafting 2x2 and 3x3, and // the creative menu if (!isCraftingScene && !isCreativeScene) { bAllowAnim = true; } break; } if (bAllowAnim) { XUITimeline* timeline; XUINamedFrame* startFrame; XUINamedFrame* endFrame; bool movingLeft = false; // Also returns TRUE if they are the same (which is what we want) if (XuiClassDerivesFrom(sceneClass, inventoryClass) || XuiClassDerivesFrom(sceneClass, furnaceClass) || XuiClassDerivesFrom(sceneClass, trapClass) || XuiClassDerivesFrom(sceneClass, containerClass) || XuiClassDerivesFrom(sceneClass, enchantingClass) || XuiClassDerivesFrom(sceneClass, brewingClass) || XuiClassDerivesFrom(sceneClass, anvilClass) || XuiClassDerivesFrom(sceneClass, tradingClass) || isCreativeScene || isCraftingScene) { XuiElementGetTimeline(m_interactScene->m_hObj, &timeline); if (visible) { startFrame = timeline->FindNamedFrame(L"MoveLeft"); endFrame = timeline->FindNamedFrame(L"EndMoveLeft"); movingLeft = true; } else { startFrame = timeline->FindNamedFrame(L"MoveRight"); endFrame = timeline->FindNamedFrame(L"EndMoveRight"); } if ((m_lastInteractSceneMoved != m_interactScene && movingLeft) || (m_lastInteractSceneMoved == m_interactScene && m_lastSceneMovedLeft != movingLeft)) { timeline->Play(startFrame->m_dwFrame, startFrame->m_dwFrame, endFrame->m_dwFrame, FALSE, FALSE); m_lastInteractSceneMoved = m_interactScene; m_lastSceneMovedLeft = movingLeft; } } } } HRESULT CScene_TutorialPopup::_SetDescription(CXuiScene* interactScene, LPCWSTR desc, LPCWSTR title, bool allowFade, bool isReminder) { HRESULT hr = S_OK; m_interactScene = interactScene; if (interactScene != m_lastInteractSceneMoved) m_lastInteractSceneMoved = NULL; if (desc == NULL) { SetShow(false); XuiSetTimer(m_hObj, TUTORIAL_POPUP_MOVE_SCENE_TIMER_ID, TUTORIAL_POPUP_MOVE_SCENE_TIME); XuiKillTimer(m_hObj, TUTORIAL_POPUP_FADE_TIMER_ID); } else { SetShow(true); XuiSetTimer(m_hObj, TUTORIAL_POPUP_MOVE_SCENE_TIMER_ID, TUTORIAL_POPUP_MOVE_SCENE_TIME); if (allowFade) { // Initialise a timer to fade us out again XuiSetTimer(m_hObj, TUTORIAL_POPUP_FADE_TIMER_ID, tutorial->GetTutorialDisplayMessageTime()); } else { XuiKillTimer(m_hObj, TUTORIAL_POPUP_FADE_TIMER_ID); } m_bAllowFade = allowFade; if (isReminder) { std::wstring text(app.GetString(IDS_TUTORIAL_REMINDER)); text.append(desc); // set the text colour wchar_t formatting[40]; swprintf(formatting, 40, L"", app.GetHTMLColour(eHTMLColor_White), m_textFontSize); text = formatting + text; hr = m_description.SetText(text.c_str()); } else { std::wstring text(desc); // set the text colour wchar_t formatting[40]; swprintf(formatting, 40, L"", app.GetHTMLColour(eHTMLColor_White), m_textFontSize); text = formatting + text; hr = m_description.SetText(text.c_str()); } D3DXVECTOR3 titlePos; hr = XuiElementGetPosition(m_title, &titlePos); bool titleShowAtStart = m_title.IsShown() != FALSE; if (title != NULL && title[0] != 0) { m_title.SetText(title); m_title.SetShow(TRUE); } else { m_title.SetText(L""); m_title.SetShow(FALSE); } bool titleShowAtEnd = m_title.IsShown() != FALSE; if (titleShowAtStart != titleShowAtEnd) { float fHeight, fWidth, fTitleHeight, fDescHeight, fDescWidth; m_title.GetBounds(&fWidth, &fTitleHeight); GetBounds(&fWidth, &fHeight); // 4J Stu - For some reason when we resize the scene it resets the // size of the HTML control We don't want that to happen, so get // it's size before and set it back after m_description.GetBounds(&fDescWidth, &fDescHeight); if (titleShowAtEnd) { titlePos.y += fTitleHeight; SetBounds(fWidth, fHeight + fTitleHeight); } else { SetBounds(fWidth, fHeight - fTitleHeight); } XuiElementSetPosition(m_description, &titlePos); m_description.SetBounds(fDescWidth, fDescHeight); } // Check if we need to resize the box XUIContentDims contentDims; m_description.GetContentDims(&contentDims); int heightDiff = contentDims.nContentHeight - contentDims.nPageHeight; float fHeight, fWidth; GetBounds(&fWidth, &fHeight); SetBounds(fWidth, fHeight + heightDiff); m_description.GetBounds(&fWidth, &fHeight); m_description.SetBounds(fWidth, (float)(contentDims.nPageHeight + heightDiff)); } return hr; } HRESULT CScene_TutorialPopup::SetDescription(int iPad, TutorialPopupInfo* info) { HRESULT hr = S_OK; #ifdef _XBOX HXUIOBJ hObj = app.GetCurrentTutorialScene(iPad); HXUICLASS thisClass = XuiFindClass(L"CScene_TutorialPopup"); HXUICLASS objClass = XuiGetObjectClass(hObj); // Also returns TRUE if they are the same (which is what we want) if (XuiClassDerivesFrom(objClass, thisClass)) { CScene_TutorialPopup* pThis; hr = XuiObjectFromHandle(hObj, (void**)&pThis); if (FAILED(hr)) return hr; std::wstring parsed = pThis->_SetIcon(info->icon, info->iAuxVal, info->isFoil, info->desc); parsed = pThis->_SetImage(parsed); parsed = CScene_TutorialPopup::ParseDescription(iPad, parsed); if (parsed.empty()) { hr = pThis->_SetDescription(info->interactScene, NULL, NULL, info->allowFade, info->isReminder); } else { hr = pThis->_SetDescription(info->interactScene, parsed.c_str(), info->title, info->allowFade, info->isReminder); } } #endif return hr; } std::wstring CScene_TutorialPopup::_SetIcon(int icon, int iAuxVal, bool isFoil, LPCWSTR desc) { std::wstring temp(desc); bool iconShowAtStart = m_pCraftingPic->IsShown() != FALSE; if (icon != TUTORIAL_NO_ICON) { bool itemIsFoil = false; itemIsFoil = (std::shared_ptr(new ItemInstance(icon, 1, iAuxVal))) ->isFoil(); if (!itemIsFoil) itemIsFoil = isFoil; m_pCraftingPic->SetIcon(m_iPad, icon, iAuxVal, 1, 10, 31, false, itemIsFoil); } else { std::wstring openTag(L"{*ICON*}"); std::wstring closeTag(L"{*/ICON*}"); int iconTagStartPos = (int)temp.find(openTag); int iconStartPos = iconTagStartPos + (int)openTag.length(); if (iconTagStartPos > 0 && iconStartPos < (int)temp.length()) { int iconEndPos = (int)temp.find(closeTag, iconStartPos); if (iconEndPos > iconStartPos && iconEndPos < (int)temp.length()) { std::wstring id = temp.substr(iconStartPos, iconEndPos - iconStartPos); std::vector idAndAux = stringSplit(id, L':'); int iconId = _fromString(idAndAux[0]); if (idAndAux.size() > 1) { iAuxVal = _fromString(idAndAux[1]); } else { iAuxVal = 0; } bool itemIsFoil = false; itemIsFoil = (std::shared_ptr( new ItemInstance(iconId, 1, iAuxVal))) ->isFoil(); if (!itemIsFoil) itemIsFoil = isFoil; m_pCraftingPic->SetIcon(m_iPad, iconId, iAuxVal, 1, 10, 31, false, itemIsFoil); temp.replace(iconTagStartPos, iconEndPos - iconTagStartPos + closeTag.length(), L""); } } // remove any icon text else if (temp.find(L"{*CraftingTableIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, Tile::workBench->id, 0, 1, 10, 31, false); } else if (temp.find(L"{*SticksIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, Item::stick->id, 0, 1, 10, 31, false); } else if (temp.find(L"{*PlanksIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, Tile::wood->id, 0, 1, 10, 31, false); } else if (temp.find(L"{*WoodenShovelIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, Item::shovel_wood->id, 0, 1, 10, 31, false); } else if (temp.find(L"{*WoodenHatchetIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, Item::hatchet_wood->id, 0, 1, 10, 31, false); } else if (temp.find(L"{*WoodenPickaxeIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, Item::pickAxe_wood->id, 0, 1, 10, 31, false); } else if (temp.find(L"{*FurnaceIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, Tile::furnace_Id, 0, 1, 10, 31, false); } else if (temp.find(L"{*WoodenDoorIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, Item::door_wood->id, 0, 1, 10, 31, false); } else if (temp.find(L"{*TorchIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, Tile::torch_Id, 0, 1, 10, 31, false); } else if (temp.find(L"{*BoatIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, Item::boat_Id, 0, 1, 10, 31, false); } else if (temp.find(L"{*FishingRodIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, Item::fishingRod_Id, 0, 1, 10, 31, false); } else if (temp.find(L"{*FishIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, Item::fish_raw_Id, 0, 1, 10, 31, false); } else if (temp.find(L"{*MinecartIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, Item::minecart_Id, 0, 1, 10, 31, false); } else if (temp.find(L"{*RailIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, Tile::rail_Id, 0, 1, 10, 31, false); } else if (temp.find(L"{*PoweredRailIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, Tile::goldenRail_Id, 0, 1, 10, 31, false); } else if (temp.find(L"{*StructuresIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, XZP_ICON_STRUCTURES, 0, 1, 10, 31, false); } else if (temp.find(L"{*ToolsIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, XZP_ICON_TOOLS, 0, 1, 10, 31, false); } else if (temp.find(L"{*StoneIcon*}") != std::wstring::npos) { m_pCraftingPic->SetIcon(m_iPad, Tile::rock_Id, 0, 1, 10, 31, false); } else { // hide the icon slot m_pCraftingPic->SetIcon(m_iPad, 0, 0, 0, 0, 0, false, false, FALSE); } } bool iconShowAtEnd = m_pCraftingPic->IsShown() != FALSE; if (iconShowAtStart != iconShowAtEnd) { float fHeight, fWidth, fIconHeight, fDescHeight, fDescWidth; m_pCraftingPic->GetBounds(&fWidth, &fIconHeight); GetBounds(&fWidth, &fHeight); // 4J Stu - For some reason when we resize the scene it resets the size // of the HTML control We don't want that to happen, so get it's size // before and set it back after m_description.GetBounds(&fDescWidth, &fDescHeight); if (iconShowAtEnd) { SetBounds(fWidth, fHeight + fIconHeight); } else { SetBounds(fWidth, fHeight - fIconHeight); } m_description.SetBounds(fDescWidth, fDescHeight); } return temp; } std::wstring CScene_TutorialPopup::_SetImage(std::wstring& desc) { bool imageShowAtStart = m_image.IsShown() != FALSE; std::wstring openTag(L"{*IMAGE*}"); std::wstring closeTag(L"{*/IMAGE*}"); int imageTagStartPos = (int)desc.find(openTag); int imageStartPos = imageTagStartPos + (int)openTag.length(); if (imageTagStartPos > 0 && imageStartPos < (int)desc.length()) { int imageEndPos = (int)desc.find(closeTag, imageStartPos); if (imageEndPos > imageStartPos && imageEndPos < (int)desc.length()) { std::wstring id = desc.substr(imageStartPos, imageEndPos - imageStartPos); m_image.SetImagePath(id.c_str()); m_image.SetShow(TRUE); desc.replace(imageTagStartPos, imageEndPos - imageTagStartPos + closeTag.length(), L""); } } else { // hide the icon slot m_image.SetShow(FALSE); } bool imageShowAtEnd = m_image.IsShown() != FALSE; if (imageShowAtStart != imageShowAtEnd) { float fHeight, fWidth, fIconHeight, fDescHeight, fDescWidth; m_image.GetBounds(&fWidth, &fIconHeight); GetBounds(&fWidth, &fHeight); // 4J Stu - For some reason when we resize the scene it resets the size // of the HTML control We don't want that to happen, so get it's size // before and set it back after m_description.GetBounds(&fDescWidth, &fDescHeight); if (imageShowAtEnd) { SetBounds(fWidth, fHeight + fIconHeight); } else { SetBounds(fWidth, fHeight - fIconHeight); } m_description.SetBounds(fDescWidth, fDescHeight); } return desc; } std::wstring CScene_TutorialPopup::ParseDescription(int iPad, std::wstring& text) { text = replaceAll(text, L"{*CraftingTableIcon*}", L""); text = replaceAll(text, L"{*SticksIcon*}", L""); text = replaceAll(text, L"{*PlanksIcon*}", L""); text = replaceAll(text, L"{*WoodenShovelIcon*}", L""); text = replaceAll(text, L"{*WoodenHatchetIcon*}", L""); text = replaceAll(text, L"{*WoodenPickaxeIcon*}", L""); text = replaceAll(text, L"{*FurnaceIcon*}", L""); text = replaceAll(text, L"{*WoodenDoorIcon*}", L""); text = replaceAll(text, L"{*TorchIcon*}", L""); text = replaceAll(text, L"{*MinecartIcon*}", L""); text = replaceAll(text, L"{*BoatIcon*}", L""); text = replaceAll(text, L"{*FishingRodIcon*}", L""); text = replaceAll(text, L"{*FishIcon*}", L""); text = replaceAll(text, L"{*RailIcon*}", L""); text = replaceAll(text, L"{*PoweredRailIcon*}", L""); text = replaceAll(text, L"{*StructuresIcon*}", L""); text = replaceAll(text, L"{*ToolsIcon*}", L""); text = replaceAll(text, L"{*StoneIcon*}", L""); if (app.GetLocalPlayerCount() > 1) { // TODO TU-1 - This should really be a string as well rather than // hardcoded here text = replaceAll( text, L"{*EXIT_PICTURE*}", L"
"); // TODO TU-1 - This should also be separate strings, or move these // things out of a localisable file so we can add/change them at will text = replaceAll(text, L"height=\"30\" width=\"30\"", L"height=\"20\" width=\"20\""); } else { text = replaceAll(text, L"{*EXIT_PICTURE*}", app.GetString(IDS_TUTORIAL_HTML_EXIT_PICTURE)); } /* #define MINECRAFT_ACTION_RENDER_DEBUG ACTION_INGAME_13 #define MINECRAFT_ACTION_PAUSEMENU ACTION_INGAME_15 #define MINECRAFT_ACTION_SNEAK_TOGGLE ACTION_INGAME_17 */ return app.FormatHTMLString(iPad, text); } HRESULT CScene_TutorialPopup::_SetVisible(bool show) { HRESULT hr = this->SetShow(show); if (show && m_bAllowFade) { // Initialise a timer to fade us out again XuiSetTimer(m_hObj, TUTORIAL_POPUP_FADE_TIMER_ID, tutorial->GetTutorialDisplayMessageTime()); } return hr; } bool CScene_TutorialPopup::_IsSceneVisible() { bool isVisible = this->IsShown() == TRUE ? true : false; return isVisible; } HRESULT CScene_TutorialPopup::SetSceneVisible(int iPad, bool show) { HRESULT hr = S_OK; HXUIOBJ hObj = app.GetCurrentTutorialScene(iPad); HXUICLASS thisClass = XuiFindClass(L"CScene_TutorialPopup"); HXUICLASS objClass = XuiGetObjectClass(hObj); // Also returns TRUE if they are the same (which is what we want) if (XuiClassDerivesFrom(objClass, thisClass)) { CScene_TutorialPopup* pThis; hr = XuiObjectFromHandle(hObj, (void**)&pThis); if (FAILED(hr)) return hr; hr = pThis->_SetVisible(show); } return hr; } HRESULT CScene_TutorialPopup::OnCustomMessage_Splitscreenplayer( bool bJoining, BOOL& bHandled) { bHandled = true; return app.AdjustSplitscreenScene_PlayerChanged(m_hObj, &m_OriginalPosition, m_iPad, bJoining); } bool CScene_TutorialPopup::IsSceneVisible(int iPad) { bool isVisible = false; HRESULT hr; HXUIOBJ hObj = app.GetCurrentTutorialScene(iPad); HXUICLASS thisClass = XuiFindClass(L"CScene_TutorialPopup"); HXUICLASS objClass = XuiGetObjectClass(hObj); // Also returns TRUE if they are the same (which is what we want) if (XuiClassDerivesFrom(objClass, thisClass)) { CScene_TutorialPopup* pThis; hr = XuiObjectFromHandle(hObj, (void**)&pThis); if (FAILED(hr)) return false; isVisible = pThis->_IsSceneVisible(); } return isVisible; }