This code was not tested and breaks in Release builds, reverting to restore
functionality of the nightly. All in-game menus do not work and generating
a world crashes.
This reverts commit a9be52c41a.
464 lines
12 KiB
C++
464 lines
12 KiB
C++
#include "stdafx.h"
|
|
#include "XUI_HUD.h"
|
|
#include "..\..\Minecraft.h"
|
|
#include "..\..\Gui.h"
|
|
#include "..\..\MultiplayerLocalPlayer.h"
|
|
#include "..\..\..\Minecraft.World\net.minecraft.world.inventory.h"
|
|
#include "..\..\..\Minecraft.World\Random.h"
|
|
#include "..\..\..\Minecraft.World\net.minecraft.world.effect.h"
|
|
#include "..\..\..\Minecraft.World\net.minecraft.world.level.material.h"
|
|
|
|
HRESULT CXuiSceneHud::OnInit( XUIMessageInit* pInitData, BOOL& bHandled )
|
|
{
|
|
m_iPad = *(int *)pInitData->pvInitData;
|
|
|
|
MapChildControls();
|
|
|
|
XuiElementGetPosition(m_hObj,&m_OriginalPosition);
|
|
|
|
m_tickCount = 0;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CXuiSceneHud::OnCustomMessage_Splitscreenplayer(bool bJoining, BOOL& bHandled)
|
|
{
|
|
bHandled=true;
|
|
|
|
app.ReloadHudScene(m_iPad, bJoining);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CXuiSceneHud::OnCustomMessage_TickScene()
|
|
{
|
|
Minecraft *pMinecraft = Minecraft::GetInstance();
|
|
if(pMinecraft->localplayers[m_iPad] == NULL || pMinecraft->localgameModes[m_iPad] == NULL) return S_OK;
|
|
|
|
++m_tickCount;
|
|
|
|
int iGuiScale;
|
|
|
|
if(pMinecraft->localplayers[m_iPad]->m_iScreenSection == C4JRender::VIEWPORT_TYPE_FULLSCREEN)
|
|
{
|
|
iGuiScale=app.GetGameSettings(m_iPad,eGameSetting_UISize);
|
|
}
|
|
else
|
|
{
|
|
iGuiScale=app.GetGameSettings(m_iPad,eGameSetting_UISizeSplitscreen);
|
|
}
|
|
|
|
int startFrame = 0;
|
|
switch(iGuiScale)
|
|
{
|
|
case 0:
|
|
XuiElementFindNamedFrame(m_hObj, L"ScaleSmall", &startFrame);
|
|
break;
|
|
case 1:
|
|
XuiElementFindNamedFrame(m_hObj, L"Normal", &startFrame);
|
|
break;
|
|
case 2:
|
|
XuiElementFindNamedFrame(m_hObj, L"ScaleLarge", &startFrame);
|
|
break;
|
|
}
|
|
if(startFrame >= 0) XuiElementPlayTimeline( m_hObj, startFrame, startFrame, startFrame, FALSE, TRUE);
|
|
|
|
// Move the whole hud group if we are not in fullscreen
|
|
if(pMinecraft->localplayers[m_iPad]->m_iScreenSection != C4JRender::VIEWPORT_TYPE_FULLSCREEN)
|
|
{
|
|
int iTooltipsYOffset = 0;
|
|
// if tooltips are off, set the y offset to zero
|
|
if(app.GetGameSettings(m_iPad,eGameSetting_Tooltips)==0)
|
|
{
|
|
switch(iGuiScale)
|
|
{
|
|
case 0:
|
|
iTooltipsYOffset=28;//screenHeight/10;
|
|
break;
|
|
case 2:
|
|
iTooltipsYOffset=28;//screenHeight/10;
|
|
break;
|
|
case 1:
|
|
default:
|
|
iTooltipsYOffset=28;//screenHeight/10;
|
|
break;
|
|
}
|
|
}
|
|
|
|
float fHeight, fWidth;
|
|
GetBounds(&fWidth, &fHeight);
|
|
|
|
int iSafezoneYHalf = 0;
|
|
switch(pMinecraft->localplayers[m_iPad]->m_iScreenSection)
|
|
{
|
|
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
|
break;
|
|
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
|
iSafezoneYHalf = -fHeight/10;// 5% (need to treat the whole screen is 2x this screen)
|
|
break;
|
|
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
|
|
iSafezoneYHalf = (fHeight/2)-(fHeight/10);// 5% (need to treat the whole screen is 2x this screen)
|
|
break;
|
|
case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT:
|
|
iSafezoneYHalf = (fHeight/2)-(fHeight/10);// 5% (need to treat the whole screen is 2x this screen)
|
|
break;
|
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
|
|
break;
|
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
|
|
break;
|
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
|
|
iSafezoneYHalf = -fHeight/10; // 5% (the whole screen is 2x this screen)
|
|
break;
|
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
|
|
iSafezoneYHalf = -fHeight/10; // 5% (the whole screen is 2x this screen)
|
|
break;
|
|
};
|
|
|
|
D3DXVECTOR3 pos;
|
|
m_hudGroup.GetPosition(&pos);
|
|
pos.y = iTooltipsYOffset + iSafezoneYHalf;
|
|
m_hudGroup.SetPosition(&pos);
|
|
}
|
|
|
|
// Update inventory
|
|
float opacity = 1.0f;
|
|
GetOpacity(&opacity);
|
|
int selected = pMinecraft->localplayers[m_iPad]->inventory->selected;
|
|
for(unsigned int j = 0; j < 9; ++j)
|
|
{
|
|
m_hotbarIcon[j]->SetSlot(m_hotbarIcon[j]->m_hObj,pMinecraft->localplayers[m_iPad]->inventoryMenu->getSlot(InventoryMenu::USE_ROW_SLOT_START + j));
|
|
m_hotbarIcon[j]->SetUserIndex(m_hotbarIcon[j]->m_hObj, m_iPad );
|
|
|
|
if(j == selected)
|
|
{
|
|
m_hotbarIcon[j]->SetEnable(FALSE); //Makes the selected overlay display
|
|
}
|
|
else
|
|
{
|
|
m_hotbarIcon[j]->SetEnable(TRUE); //Hides the selected overlay display
|
|
}
|
|
|
|
m_hotbarIcon[j]->SetAlpha( m_hotbarIcon[j]->m_hObj, opacity );
|
|
}
|
|
|
|
// Update xp progress
|
|
if (pMinecraft->localgameModes[m_iPad]->canHurtPlayer())
|
|
{
|
|
int xpNeededForNextLevel = pMinecraft->localplayers[m_iPad]->getXpNeededForNextLevel();
|
|
int progress = (int)(pMinecraft->localplayers[m_iPad]->experienceProgress *xpNeededForNextLevel);
|
|
|
|
m_ExperienceProgress.SetShow(TRUE);
|
|
m_ExperienceProgress.SetRange(0,xpNeededForNextLevel);
|
|
m_ExperienceProgress.SetValue(progress);
|
|
}
|
|
else
|
|
{
|
|
m_ExperienceProgress.SetShow(FALSE);
|
|
}
|
|
|
|
// Update xp level
|
|
if (pMinecraft->localgameModes[m_iPad]->hasExperience() && pMinecraft->localplayers[m_iPad]->experienceLevel > 0)
|
|
{
|
|
m_xpLevel.SetShow(TRUE);
|
|
|
|
wchar_t formatted[10];
|
|
swprintf(formatted, 10, L"%d",pMinecraft->localplayers[m_iPad]->experienceLevel);
|
|
|
|
m_xpLevel.SetText(formatted);
|
|
}
|
|
else
|
|
{
|
|
m_xpLevel.SetShow(FALSE);
|
|
}
|
|
|
|
if (pMinecraft->localgameModes[m_iPad]->canHurtPlayer())
|
|
{
|
|
m_random.setSeed(m_tickCount * 312871);
|
|
|
|
// Update health
|
|
int heartOffsetIndex = -1;
|
|
if (pMinecraft->localplayers[m_iPad]->hasEffect(MobEffect::regeneration))
|
|
{
|
|
heartOffsetIndex = m_tickCount % 25;
|
|
}
|
|
|
|
bool blink = pMinecraft->localplayers[m_iPad]->invulnerableTime / 3 % 2 == 1;
|
|
if (pMinecraft->localplayers[m_iPad]->invulnerableTime < 10) blink = false;
|
|
int iHealth = pMinecraft->localplayers[m_iPad]->getHealth();
|
|
int iLastHealth = pMinecraft->localplayers[m_iPad]->lastHealth;
|
|
bool bHasPoison = pMinecraft->localplayers[m_iPad]->hasEffect(MobEffect::poison);
|
|
for (int icon = 0; icon < Player::MAX_HEALTH / 2; icon++)
|
|
{
|
|
if(blink)
|
|
{
|
|
if (icon * 2 + 1 < iLastHealth || icon * 2 + 1 < iHealth)
|
|
{
|
|
// Full
|
|
if(bHasPoison)
|
|
{
|
|
m_healthIcon[icon].PlayVisualRange(L"FullPoisonFlash",NULL,L"FullPoisonFlash");
|
|
}
|
|
else
|
|
{
|
|
m_healthIcon[icon].PlayVisualRange(L"FullFlash",NULL,L"FullFlash");
|
|
}
|
|
}
|
|
else if (icon * 2 + 1 == iLastHealth || icon * 2 + 1 == iHealth)
|
|
{
|
|
// Half
|
|
if(bHasPoison)
|
|
{
|
|
m_healthIcon[icon].PlayVisualRange(L"HalfPoisonFlash",NULL,L"HalfPoisonFlash");
|
|
}
|
|
else
|
|
{
|
|
m_healthIcon[icon].PlayVisualRange(L"HalfFlash",NULL,L"HalfFlash");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Empty
|
|
m_healthIcon[icon].PlayVisualRange(L"NormalFlash",NULL,L"NormalFlash");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (icon * 2 + 1 < iHealth)
|
|
{
|
|
// Full
|
|
if(bHasPoison)
|
|
{
|
|
m_healthIcon[icon].PlayVisualRange(L"FullPoison",NULL,L"FullPoison");
|
|
}
|
|
else
|
|
{
|
|
m_healthIcon[icon].PlayVisualRange(L"Full",NULL,L"Full");
|
|
}
|
|
}
|
|
else if (icon * 2 + 1 == iHealth)
|
|
{
|
|
// Half
|
|
if(bHasPoison)
|
|
{
|
|
m_healthIcon[icon].PlayVisualRange(L"HalfPoison",NULL,L"HalfPoison");
|
|
}
|
|
else
|
|
{
|
|
m_healthIcon[icon].PlayVisualRange(L"Half",NULL,L"Half");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Empty
|
|
m_healthIcon[icon].PlayVisualRange(L"Normal",NULL,L"Normal");
|
|
}
|
|
}
|
|
|
|
float yo = 0;
|
|
if (iHealth <= 4)
|
|
{
|
|
yo = (float)m_random.nextInt(2) * (iGuiScale+1);
|
|
}
|
|
if (icon == heartOffsetIndex)
|
|
{
|
|
yo = -2.0f * (iGuiScale+1);
|
|
}
|
|
|
|
D3DXVECTOR3 pos;
|
|
m_healthIcon[icon].GetPosition(&pos);
|
|
// TODO - 4J Stu - This should be scaled based on gui scale and overall size (ie full, split or 480)
|
|
pos.y = yo;
|
|
m_healthIcon[icon].SetPosition(&pos);
|
|
|
|
}
|
|
|
|
// Update food
|
|
bool foodBlink = false;
|
|
FoodData *foodData = pMinecraft->localplayers[m_iPad]->getFoodData();
|
|
int food = foodData->getFoodLevel();
|
|
int oldFood = foodData->getLastFoodLevel();
|
|
bool hasHungerEffect = pMinecraft->localplayers[m_iPad]->hasEffect(MobEffect::hunger);
|
|
int saturationLevel = pMinecraft->localplayers[m_iPad]->getFoodData()->getSaturationLevel();
|
|
for (int icon = 0; icon < 10; icon++)
|
|
{
|
|
if(foodBlink)
|
|
{
|
|
if (icon * 2 + 1 < oldFood || icon * 2 + 1 < food)
|
|
{
|
|
// Full
|
|
if(hasHungerEffect)
|
|
{
|
|
m_foodIcon[icon].PlayVisualRange(L"FullPoisonFlash",NULL,L"FullPoisonFlash");
|
|
}
|
|
else
|
|
{
|
|
m_foodIcon[icon].PlayVisualRange(L"FullFlash",NULL,L"FullFlash");
|
|
}
|
|
}
|
|
else if (icon * 2 + 1 == oldFood || icon * 2 + 1 == food)
|
|
{
|
|
// Half
|
|
if(hasHungerEffect)
|
|
{
|
|
m_foodIcon[icon].PlayVisualRange(L"HalfPoisonFlash",NULL,L"HalfPoisonFlash");
|
|
}
|
|
else
|
|
{
|
|
m_foodIcon[icon].PlayVisualRange(L"HalfFlash",NULL,L"HalfFlash");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Empty
|
|
m_foodIcon[icon].PlayVisualRange(L"NormalFlash",NULL,L"NormalFlash");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (icon * 2 + 1 < food)
|
|
{
|
|
// Full
|
|
if(hasHungerEffect)
|
|
{
|
|
m_foodIcon[icon].PlayVisualRange(L"FullPoison",NULL,L"FullPoison");
|
|
}
|
|
else
|
|
{
|
|
m_foodIcon[icon].PlayVisualRange(L"Full",NULL,L"Full");
|
|
}
|
|
}
|
|
else if (icon * 2 + 1 == food)
|
|
{
|
|
// Half
|
|
if(hasHungerEffect)
|
|
{
|
|
m_foodIcon[icon].PlayVisualRange(L"HalfPoison",NULL,L"HalfPoison");
|
|
}
|
|
else
|
|
{
|
|
m_foodIcon[icon].PlayVisualRange(L"Half",NULL,L"Half");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Empty
|
|
if(hasHungerEffect)
|
|
{
|
|
m_foodIcon[icon].PlayVisualRange(L"NormalPoison",NULL,L"NormalPoison");
|
|
}
|
|
else
|
|
{
|
|
m_foodIcon[icon].PlayVisualRange(L"Normal",NULL,L"Normal");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
float yo = 0;
|
|
if (saturationLevel <= 0)
|
|
{
|
|
if ((m_tickCount % (food * 3 + 1)) == 0)
|
|
{
|
|
yo = (float)(m_random.nextInt(3) - 1) * (iGuiScale+1);
|
|
}
|
|
}
|
|
|
|
D3DXVECTOR3 pos;
|
|
m_foodIcon[icon].GetPosition(&pos);
|
|
// TODO - 4J Stu - This should be scaled based on gui scale and overall size (ie full, split or 480)
|
|
pos.y = yo;
|
|
m_foodIcon[icon].SetPosition(&pos);
|
|
}
|
|
|
|
// Update armour
|
|
int armor = pMinecraft->localplayers[m_iPad]->getArmorValue();
|
|
if(armor > 0)
|
|
{
|
|
m_armourGroup.SetShow(TRUE);
|
|
for (int icon = 0; icon < 10; icon++)
|
|
{
|
|
if (icon * 2 + 1 < armor) m_armourIcon[icon].PlayVisualRange(L"Full",NULL,L"Full");
|
|
else if (icon * 2 + 1 == armor) m_armourIcon[icon].PlayVisualRange(L"Half",NULL,L"Half");
|
|
else if (icon * 2 + 1 > armor) m_armourIcon[icon].PlayVisualRange(L"Normal",NULL,L"Normal");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_armourGroup.SetShow(FALSE);
|
|
}
|
|
|
|
// Update air
|
|
if (pMinecraft->localplayers[m_iPad]->isUnderLiquid(Material::water))
|
|
{
|
|
m_airGroup.SetShow(TRUE);
|
|
int count = (int) ceil((pMinecraft->localplayers[m_iPad]->getAirSupply() - 2) * 10.0f / Player::TOTAL_AIR_SUPPLY);
|
|
int extra = (int) ceil((pMinecraft->localplayers[m_iPad]->getAirSupply()) * 10.0f / Player::TOTAL_AIR_SUPPLY) - count;
|
|
for (int icon = 0; icon < 10; icon++)
|
|
{
|
|
// Air bubbles
|
|
if (icon < count)
|
|
{
|
|
m_airIcon[icon].SetShow(TRUE);
|
|
m_airIcon[icon].PlayVisualRange(L"Bubble",NULL,L"Bubble");
|
|
}
|
|
else if(icon < count + extra)
|
|
{
|
|
m_airIcon[icon].SetShow(TRUE);
|
|
m_airIcon[icon].PlayVisualRange(L"Pop",NULL,L"Pop");
|
|
}
|
|
else m_airIcon[icon].SetShow(FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_airGroup.SetShow(FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_healthGroup.SetShow(FALSE);
|
|
m_foodGroup.SetShow(FALSE);
|
|
m_armourGroup.SetShow(FALSE);
|
|
m_airGroup.SetShow(FALSE);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CXuiSceneHud::OnCustomMessage_DLCInstalled()
|
|
{
|
|
// mounted DLC may have changed
|
|
bool bPauseMenuDisplayed=false;
|
|
bool bInGame=(Minecraft::GetInstance()->level!=NULL);
|
|
// ignore this if we have menus up - they'll deal with it
|
|
for(int i=0;i<XUSER_MAX_COUNT;i++)
|
|
{
|
|
if(app.IsPauseMenuDisplayed(i))
|
|
{
|
|
bPauseMenuDisplayed=true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(bInGame && !bPauseMenuDisplayed)
|
|
{
|
|
app.StartInstallDLCProcess(ProfileManager.GetPrimaryPad());
|
|
}
|
|
|
|
// this will send a CustomMessage_DLCMountingComplete when done
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT CXuiSceneHud::OnCustomMessage_DLCMountingComplete()
|
|
{
|
|
// A join from invite may have installed the trial pack during the game.
|
|
// Need to switch to the texture pack if it's not being used yet, and turn off background downloads
|
|
|
|
// what texture pack are we using?
|
|
// TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected();
|
|
// if(tPack->getDLCParentPackId()!=app.GetRequiredTexturePackID())
|
|
// {
|
|
// app.DebugPrintf("DLC install finished, and the game is using a texture pack that isn't the required one\n");
|
|
// }
|
|
return S_OK;
|
|
} |