aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/Common/XUI/XUI_HUD.cpp
diff options
context:
space:
mode:
authordaoge_cmd <3523206925@qq.com>2026-03-01 12:16:08 +0800
committerdaoge_cmd <3523206925@qq.com>2026-03-01 12:16:08 +0800
commitb691c43c44ff180d10e7d4a9afc83b98551ff586 (patch)
tree3e9849222cbc6ba49f2f1fc6e5fe7179632c7390 /Minecraft.Client/Common/XUI/XUI_HUD.cpp
parentdef8cb415354ac390b7e89052a50605285f1aca9 (diff)
Initial commit
Diffstat (limited to 'Minecraft.Client/Common/XUI/XUI_HUD.cpp')
-rw-r--r--Minecraft.Client/Common/XUI/XUI_HUD.cpp464
1 files changed, 464 insertions, 0 deletions
diff --git a/Minecraft.Client/Common/XUI/XUI_HUD.cpp b/Minecraft.Client/Common/XUI/XUI_HUD.cpp
new file mode 100644
index 00000000..286f06a7
--- /dev/null
+++ b/Minecraft.Client/Common/XUI/XUI_HUD.cpp
@@ -0,0 +1,464 @@
+#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;
+} \ No newline at end of file