6 Commits

Author SHA1 Message Date
Us3ful"-Dev
9d2eb5c9b0 Flame not working with oneshot arrow (#856)
set on fire before the entity takes damage (while still checking for invulnerability)
2026-03-09 03:18:31 +08:00
Marlian
8ad70cd2be Fix focus sound playing repeatedly on mouse hover (#890)
Only play eSFX_Focus when the focus control or child actually changes. Previously the sound fired on every focus event even when hovering over the same element, causing rapid sound spam over Texture Pack icons in the Create World menu.

Fixes a bug reported on Discord.

Co-authored-by: MCbabel <MCbabel@users.noreply.github.com>
2026-03-09 03:16:06 +08:00
Ayush Thoren
a14a4542c9 Fix stale held item appearing when switching worlds (#910)
Signed-off-by: Ayush Thoren <ayushthoren@gmail.com>
2026-03-09 03:12:49 +08:00
Ayush Thoren
2f443fe333 Fix F3 debug crash when throwing ender pearl long distance (#934)
Signed-off-by: Ayush Thoren <ayushthoren@gmail.com>
2026-03-09 03:10:47 +08:00
Adem Kurt
4cec4f4500 Allow closing some menus with inventory/crafting keys (#868) 2026-03-09 03:06:01 +08:00
Ayush Thoren
45704388b6 Fix second-person nametag pitch (#963)
Signed-off-by: Ayush Thoren <ayushthoren@gmail.com>
2026-03-09 02:39:37 +08:00
7 changed files with 74 additions and 25 deletions

View File

@@ -1331,11 +1331,17 @@ bool UIScene::hasRegisteredSubstitutionTexture(const wstring &textureName)
void UIScene::_handleFocusChange(F64 controlId, F64 childId)
{
m_iFocusControl = (int)controlId;
m_iFocusChild = (int)childId;
int newControl = (int)controlId;
int newChild = (int)childId;
handleFocusChange(controlId, childId);
ui.PlayUISFX(eSFX_Focus);
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)

View File

@@ -234,6 +234,7 @@ void EntityRenderDispatcher::prepare(Level *level, Textures *textures, Font *fon
if (pl->ThirdPersonView() == 2)
{
playerRotY += 180;
playerRotX = -playerRotX;
}
xPlayer = player->xOld + (player->x - player->xOld) * a;

View File

@@ -895,14 +895,14 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
int zBlockPos = Mth::floor(minecraft->player->z);
// Chunk player is in
int xChunkPos = minecraft->player->xChunk;
int yChunkPos = minecraft->player->yChunk;
int zChunkPos = minecraft->player->zChunk;
int xChunkPos = xBlockPos >> 4;
int yChunkPos = yBlockPos >> 4;
int zChunkPos = zBlockPos >> 4;
// Players offset within the chunk
int xChunkOffset = xBlockPos - xChunkPos * 16;
int yChunkOffset = yBlockPos - yChunkPos * 16;
int zChunkOffset = zBlockPos - zChunkPos * 16;
int xChunkOffset = xBlockPos & 15;
int yChunkOffset = yBlockPos & 15;
int zChunkOffset = zBlockPos & 15;
// Format the position like java with limited decumal places
WCHAR posString[44]; // Allows upto 7 digit positions (+-9_999_999)
@@ -951,18 +951,20 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
if (minecraft->level != NULL && minecraft->level->hasChunkAt(xBlockPos, fmod(yBlockPos, 256), zBlockPos))
{
LevelChunk *chunkAt = minecraft->level->getChunkAt(xBlockPos, zBlockPos);
if (chunkAt != NULL)
{
int skyLight = chunkAt->getBrightness(LightLayer::Sky, xChunkOffset, yChunkOffset, zChunkOffset);
int blockLight = chunkAt->getBrightness(LightLayer::Block, xChunkOffset, yChunkOffset, zChunkOffset);
int maxLight = fmax(skyLight, blockLight);
lines.push_back(L"Light: " + std::to_wstring(maxLight) + L" (" + std::to_wstring(skyLight) + L" sky, " + std::to_wstring(blockLight) + L" block)");
int skyLight = chunkAt->getBrightness(LightLayer::Sky, xChunkOffset, yChunkOffset, zChunkOffset);
int blockLight = chunkAt->getBrightness(LightLayer::Block, xChunkOffset, yChunkOffset, zChunkOffset);
int maxLight = fmax(skyLight, blockLight);
lines.push_back(L"Light: " + std::to_wstring(maxLight) + L" (" + std::to_wstring(skyLight) + L" sky, " + std::to_wstring(blockLight) + L" block)");
lines.push_back(L"CH S: " + std::to_wstring(chunkAt->getHeightmap(xChunkOffset, zChunkOffset)));
lines.push_back(L"CH S: " + std::to_wstring(chunkAt->getHeightmap(xChunkOffset, zChunkOffset)));
Biome *biome = chunkAt->getBiome(xChunkOffset, zChunkOffset, minecraft->level->getBiomeSource());
lines.push_back(L"Biome: " + biome->m_name + L" (" + std::to_wstring(biome->id) + L")");
Biome *biome = chunkAt->getBiome(xChunkOffset, zChunkOffset, minecraft->level->getBiomeSource());
lines.push_back(L"Biome: " + biome->m_name + L" (" + std::to_wstring(biome->id) + L")");
lines.push_back(L"Difficulty: " + std::to_wstring(minecraft->level->difficulty) + L" (Day " + std::to_wstring(minecraft->level->getGameTime() / Level::TICKS_PER_DAY) + L")");
lines.push_back(L"Difficulty: " + std::to_wstring(minecraft->level->difficulty) + L" (Day " + std::to_wstring(minecraft->level->getGameTime() / Level::TICKS_PER_DAY) + L")");
}
}

View File

@@ -930,6 +930,14 @@ void ItemInHandRenderer::tick()
}
void ItemInHandRenderer::reset()
{
selectedItem = nullptr;
lastSlot = -1;
height = 0.0f;
oHeight = 0.0f;
}
void ItemInHandRenderer::itemPlaced()
{
height = 0;

View File

@@ -41,6 +41,7 @@ private:
int lastSlot;
public:
void tick();
void reset();
void itemPlaced();
void itemUsed();
};

View File

@@ -1,5 +1,6 @@
#include "stdafx.h"
#include "Minecraft.h"
#include "Common/UI/UIScene.h"
#include "GameMode.h"
#include "Timer.h"
#include "ProgressRenderer.h"
@@ -9,6 +10,7 @@
#include "User.h"
#include "Textures.h"
#include "GameRenderer.h"
#include "ItemInHandRenderer.h"
#include "HumanoidModel.h"
#include "Options.h"
#include "TexturePackRepository.h"
@@ -216,6 +218,7 @@ Minecraft::Minecraft(Component *mouseComponent, Canvas *parent, MinecraftApplet
m_pendingLocalConnections[i] = NULL;
m_connectionFailed[i] = false;
localgameModes[i]=NULL;
localitemInHandRenderers[i] = NULL;
}
animateTickLevel = NULL; // 4J added
@@ -1479,9 +1482,22 @@ void Minecraft::run_middle()
if(g_KBMInput.IsMouseButtonPressed(KeyboardMouseInput::MOUSE_RIGHT))
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_USE;
bool isClosableByEitherKey = ui.IsSceneInStack(i, eUIScene_FurnaceMenu) ||
ui.IsSceneInStack(i, eUIScene_ContainerMenu) ||
ui.IsSceneInStack(i, eUIScene_DispenserMenu) ||
ui.IsSceneInStack(i, eUIScene_EnchantingMenu) ||
ui.IsSceneInStack(i, eUIScene_BrewingStandMenu) ||
ui.IsSceneInStack(i, eUIScene_TradingMenu) ||
ui.IsSceneInStack(i, eUIScene_AnvilMenu) ||
ui.IsSceneInStack(i, eUIScene_HopperMenu) ||
ui.IsSceneInStack(i, eUIScene_BeaconMenu) ||
ui.IsSceneInStack(i, eUIScene_InventoryMenu) ||
ui.IsSceneInStack(i, eUIScene_HorseMenu);
bool isEditing = ui.GetTopScene(i) && ui.GetTopScene(i)->isDirectEditBlocking();
if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_INVENTORY))
{
if(ui.IsSceneInStack(i, eUIScene_InventoryMenu))
if(isClosableByEitherKey && !isEditing)
{
ui.CloseUIScenes(i);
}
@@ -1496,7 +1512,7 @@ void Minecraft::run_middle()
if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_CRAFTING) || g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_CRAFTING_ALT))
{
if(ui.IsSceneInStack(i, eUIScene_Crafting2x2Menu) || ui.IsSceneInStack(i, eUIScene_Crafting3x3Menu) || ui.IsSceneInStack(i, eUIScene_CreativeMenu))
if((ui.IsSceneInStack(i, eUIScene_Crafting2x2Menu) || ui.IsSceneInStack(i, eUIScene_Crafting3x3Menu) || ui.IsSceneInStack(i, eUIScene_CreativeMenu) || isClosableByEitherKey) && !isEditing)
{
ui.CloseUIScenes(i);
}
@@ -4226,6 +4242,17 @@ void Minecraft::setLevel(MultiPlayerLevel *level, int message /*=-1*/, shared_pt
// 4J - stop update thread from processing this level, which blocks until it is safe to move on - will be re-enabled if we set the level to be non-NULL
gameRenderer->DisableUpdateThread();
if (level == NULL || player == NULL)
{
for (int i = 0; i < XUSER_MAX_COUNT; ++i)
{
if (localitemInHandRenderers[i] != NULL)
{
localitemInHandRenderers[i]->reset();
}
}
}
for(unsigned int i = 0; i < levels.length; ++i)
{
// 4J We only need to save out in multiplayer is we are setting the level to NULL

View File

@@ -303,16 +303,20 @@ void Arrow::tick()
damageSource = DamageSource::arrow(dynamic_pointer_cast<Arrow>(shared_from_this()), owner);
}
if(!res->entity->isInvulnerable())
{
if (isOnFire() && res->entity->GetType() != eTYPE_ENDERMAN)
{
res->entity->setOnFire(5);
}
}
if(res->entity->hurt(damageSource, dmg))
{
// Firx for #67839 - Customer Encountered: Bows enchanted with "Flame" still set things on fire if pvp/attack animals is turned off
// 4J Stu - We should not set the entity on fire unless we can cause some damage (this doesn't necessarily mean that the arrow hit lowered their health)
// set targets on fire first because we want cooked
// pork/chicken/steak
if (isOnFire() && res->entity->GetType() != eTYPE_ENDERMAN)
{
res->entity->setOnFire(5);
}
if (res->entity->instanceof(eTYPE_LIVINGENTITY))
{