mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-04-25 12:03:39 +00:00
427 lines
17 KiB
C++
427 lines
17 KiB
C++
#include "../../Minecraft.World/Platform/stdafx.h"
|
|
#include "XUI_HUD.h"
|
|
#include "../../Minecraft.Client/Minecraft.h"
|
|
#include "../../Minecraft.Client/UI/Gui.h"
|
|
#include "../../Minecraft.Client/Player/MultiPlayerLocalPlayer.h"
|
|
#include "../../Minecraft.World/Headers/net.minecraft.world.inventory.h"
|
|
#include "../../Minecraft.World/Util/Random.h"
|
|
#include "../../Minecraft.World/Headers/net.minecraft.world.effect.h"
|
|
#include "../../Minecraft.World/Headers/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;
|
|
} |