- Remove shadowcolor from font tags (Iggy doesn't support multiple)
- Enforce HTML text mode on chat labels and jukebox
- Move IDS translatable pattern matching into FormatChatMessage
- Add §r (reset) color code support
- Fix message truncation to count visible characters, skipping HTML tags
- Fix CJK truncation using raw index instead of visible char count
* f3 menu text scaling
* Reduce overscaling above 1080p
Restores original scaling for 1440p to try and keep the text size more
sane on high DPI monitors
---------
Co-authored-by: Loki Rautio <lokirautio@gmail.com>
Goal:
Allow players to type and display text in any language supported by
Unicode, including Chinese, Japanese, Korean, Thai, Arabic, Korean, Hindi, and more. This
covers all text surfaces: chat editor, chat messages, signs (in-world
and editor), world name/seed, server address/port fields, and all
Iggy Flash UI text fields.
Multi-language support:
Two complementary rendering systems were added to handle Unicode text
across the entire client:
1. Iggy UI (Flash-based text fields): A new UIUnicodeBitmapFont class
serves Java Minecraft's glyph page PNGs (glyph_00.png-glyph_FF.png)
through Iggy's bitmap font provider API. Registered as the global
fallback font with metrics matching the Mojangles bitmap font for
correct baseline alignment. When the primary bitmap font lacks a
glyph, it returns IGGY_GLYPH_INVALID and Iggy seamlessly falls back
to the unicode bitmap font.
2. Legacy C++ Font renderer (chat editor, in-world signs): Revived the
commented-out unicode glyph page system in Font.cpp. Characters not
in the bitmap font texture are rendered from glyph page PNGs loaded
on demand, with proper texture switching mid-string.
3. ChatScreen input: Removed the restrictive acceptableLetters filter
so all printable Unicode characters are accepted in chat.
Languages now supported for text input and rendering:
- Japanese (Hiragana, Katakana, Kanji)
- Chinese (Simplified and Traditional)
- Korean (Hangul)
- Thai
- Arabic
- Hindi (Devanagari)
- Russian (Cyrillic) - already worked via bitmap font
- Greek - already worked via bitmap font
- Polish, Czech, Turkish (Extended Latin) - already worked via bitmap font
- Armenian, Georgian, and other scripts covered by glyph pages
Security fixes:
- Fixed memset under-initialization of Font::charWidths (zeroed 460
bytes instead of 460*sizeof(int)=1840 bytes, leaving entries 115+
uninitialized) - pre-existing bug
- Added bounds checks to all UIUnicodeBitmapFont callbacks to reject
glyph IDs outside [0, 65535], preventing OOB array access
- Added bounds check in Font::width() section-sign fallback path to
prevent OOB read on charWidths[] with high codepoints
- Blocked Unicode bidirectional override characters (U+202A-202E,
U+2066-2069) in chat input to prevent message spoofing
Memory leak fix:
- Fixed SignTileEntity::load allocating wchar_t[256] with new[] on
every sign load without freeing. Replaced with stack allocation.
Debug logging:
- Added [SIGN] prefixed logging for sign save/update operations
- Added [CHAT] prefixed logging for chat send/receive operations
Files changed:
- UIUnicodeBitmapFont.h/.cpp (new) - Iggy bitmap font for glyph pages
- UIBitmapFont.cpp - Return IGGY_GLYPH_INVALID for unknown chars
- UIFontData.h/.cpp - Added hasGlyph() method
- UIController.h/.cpp - Load and register unicode bitmap fallback font
- UITTFFont.h/.cpp - Added registerAsDefaultFonts parameter
- Font.h/.cpp - Revived unicode glyph page rendering system
- ChatScreen.cpp - Accept all Unicode input, block bidi overrides
- Gui.cpp - Chat display debug logging
- ClientConnection.cpp - Sign update debug logging
- SignTileEntity.cpp - Sign save logging, memory leak fix
This commit adds new `NamedFrame` entries and `KeyFrame` animations in `skin_Minecraft.xui` for various hardcore game modes, improving the UI representation (likely will get rid of this since it's dead code). A new `isHardcore` variable in `XUI_HUD.cpp` allows for conditional health icon animations based on the game mode. Additionally, commented-out code in `Gui.cpp` has been removed to streamline rendering logic. Several new PNG images for health states in hardcore mode have also been added to enhance the user experience.
TL;DR: This commit is basically just prep for adding hardcore heathbar hearts while also fixing some breaking that occurred in Gui.cpp after a merge.
---
Minecraft.Client/ClientConnection.cpp
Purpose: Propagate hardcore flag through network level creation
- handleLogin() (2 sites): Changed MultiPlayerLevel constructor calls from hardcoded false for the
hardcore parameter to packet->m_isHardcore, so the client-side level correctly knows it's hardcore
when joining a server.
- handleRespawn(): Same change - when creating a new dimension level on respawn, uses
packet->m_isHardcore instead of querying minecraft->level->getLevelData()->isHardcore() (which could
be stale/wrong).
---
Minecraft.Client/Common/App_Defines.h
Purpose: Define bitmask for hardcore host option
- Added GAME_HOST_OPTION_BITMASK_HARDCORE (0x40000000) - a new bit in the host options bitfield to
store whether the game is hardcore.
---
Minecraft.Client/Common/App_enums.h
Purpose: Add hardcore enum value
- Added eGameHostOption_Hardcore to the eGameHostOption enum so code can get/set the hardcore flag
via SetGameHostOption/GetGameHostOption.
---
Minecraft.Client/Common/Consoles_App.cpp
Purpose: Implement hardcore get/set in host options bitfield
- SetGameHostOption(): Added case eGameHostOption_Hardcore - sets or clears the
GAME_HOST_OPTION_BITMASK_HARDCORE bit.
- GetGameHostOption(): Added case eGameHostOption_Hardcore - returns 1 if the hardcore bit is set, 0
otherwise.
---
Minecraft.Client/Common/Consoles_App.h
Purpose: Store save folder name for hardcore world deletion
- Added SetCurrentSaveFolderName() and GetCurrentSaveFolderName() public methods.
- Added wstring m_currentSaveFolderName private member - stores the save folder name so the hardcore
death handler can find and delete the world.
---
Minecraft.Client/Common/UI/IUIScene_PauseMenu.cpp
Purpose: Delete hardcore world's save data on exit
- Added Win64_DeleteSaveDirectory() - a recursive directory deletion helper (Windows64 only).
- In _ExitWorld(): Before the server is torn down, captures whether this is a hardcore death exit
(getDeleteWorldOnExit()). Tries 3 sources for the save folder name: app storage, StorageManager, and
MinecraftServer.
- After the server fully stops, if shouldDeleteHardcoreWorld is true, deletes the entire
Windows64\GameHDD\<savefolder> directory.
---
Minecraft.Client/Common/UI/UIScene_CreateWorldMenu.cpp
Purpose: Hardcore difficulty slider in Create World menu
- Added file-scope s_bHardcore flag to track when the slider is at position 4 (Hardcore).
- Constructor: Extended difficulty slider range from 0-3 to 0-4, resets s_bHardcore to false.
- handleSliderMove(): When slider value >= 4, sets s_bHardcore = true, stores actual difficulty as 3
(Hard), and displays "Hardcore" label. Otherwise behaves normally.
- CreateGame(): Clears the save folder name (new world), and sets eGameHostOption_Hardcore based on
s_bHardcore.
- Minor: Changed RequestErrorMessage to RequestAlertMessage for a content restriction dialog.
---
Minecraft.Client/Common/UI/UIScene_DeathMenu.cpp
Purpose: Hardcore death screen behavior (Iggy UI)
- Constructor: Checks if current level is hardcore. If so, shows IDS_HARDCORE_DEATH_MESSAGE on the
respawn button and hides it. Otherwise shows normal "Respawn" button.
- handlePress() - Respawn: Added safeguard - if hardcore, blocks respawn entirely.
- handlePress() - Exit Game: If hardcore and host, skips save dialog, disables save-on-exit, enables
delete-world-on-exit, and triggers immediate world exit.
---
Minecraft.Client/Common/UI/UIScene_LoadMenu.cpp
Purpose: Show "Difficulty: Hardcore" in Load World menu + persist hardcore through game launch
- Static array: Expanded m_iDifficultyTitleSettingA from 4 to 5 entries, added IDS_GAMEMODE_HARDCORE
at index 4.
- Constructor: Initializes m_bHardcore = false. In Windows64 block: sets up thumbnail name from save
details, and reads isHardcore from params->saveDetails. If hardcore, immediately initializes the
difficulty slider to show "Hardcore" locked at position 4.
- tick(): When host options are read (bHostOptionsRead block), also reads the hardcore flag and
re-initializes the slider if needed (for console path).
- handleSliderMove(): If m_bHardcore, locks the slider at position 4 (prevents changing difficulty).
- StartGameFromSave(): Stores the save folder name in app for later hardcore deletion. Sets
eGameHostOption_Hardcore from m_bHardcore.
---
Minecraft.Client/Common/UI/UIScene_LoadMenu.h
Purpose: Declare hardcore member
- Expanded m_iDifficultyTitleSettingA from [4] to [5].
- Added bool m_bHardcore private member.
---
Minecraft.Client/Common/UI/UIScene_LoadOrJoinMenu.cpp
Purpose: Read hardcore flag from level.dat when building the save list
- ReadLevelNameFromSaveFile(): Added optional bool *outHardcore parameter. Inside the NBT Data
compound tag parsing, if outHardcore is non-null, reads dataTag->getBoolean(L"hardcore").
- Save enumeration block (Windows64): Passes &saveHardcore to ReadLevelNameFromSaveFile and stores
the result in m_saveDetails[i].isHardcore.
---
Minecraft.Client/Common/UI/UIStructs.h
Purpose: Add isHardcore to save list details struct
- Added bool isHardcore field to _SaveListDetails struct.
- Initialized to false in the constructor.
---
Minecraft.Client/Common/XUI/XUI_Death.cpp
Purpose: Hardcore death screen behavior (XUI/Xbox UI)
- Mirror of the Iggy UIScene_DeathMenu.cpp changes but for the XUI rendering path.
- OnInit(): Checks isHardcore(), hides respawn button and shows death message if true.
- OnNotifyPressEx() - Exit Game: If hardcore and host, skips save, flags world for deletion, exits
immediately.
- OnNotifyPressEx() - Respawn: Safeguard to block respawn in hardcore.
---
Minecraft.Client/Gui.cpp
Purpose: Syntax fix
- Fixed lines.push_back(L"" → lines.push_back(L"") - missing closing quote/paren in debug terrain
feature display.
---
Minecraft.Client/MinecraftServer.cpp
Purpose: Server-side hardcore support
- Constructor: Initializes m_deleteWorldOnExit = false.
- loadLevel(): Captures the save folder name from StorageManager into m_saveFolderName for later use
in hardcore world deletion.
- isHardcore(): Changed from always returning false to returning
app.GetGameHostOption(eGameHostOption_Hardcore) > 0 - this is the key change that makes the server
actually report hardcore mode.
---
Minecraft.Client/MinecraftServer.h
Purpose: Declare hardcore-related members
- Added bool m_deleteWorldOnExit and wstring m_saveFolderName private members.
- Added setDeleteWorldOnExit(), getDeleteWorldOnExit(), and getSaveFolderName() public methods.
---
Minecraft.Client/PlayerConnection.h
Purpose: Thread-safety fix for kicked flag
- Changed m_bWasKicked from bool to std::atomic<bool> (initialized with {false}).
- Changed setWasKicked()/getWasKicked() to use .store()/.load() - fixes a race condition where the
kicked flag is set on one thread and read on another.
---
Minecraft.Client/PlayerList.cpp
Purpose: Hardcore multiplayer - ban, respawn as Adventure, thread-safe bans
- Constructor/Destructor: Added InitializeCriticalSection/DeleteCriticalSection for m_banCS.
- placeNewPlayer(): Passes isHardcore() flag to the LoginPacket constructor so clients joining know
it's hardcore.
- respawn(): After respawn in hardcore, forces the player into Adventure mode (spectate-like: can
look around but not interact). Sends GameEventPacket to sync client.
- respawn() and toggleDimension() (2 sites): Pass isHardcore() to RespawnPacket constructor.
- isXuidBanned(): Wrapped m_bannedXuids iteration with EnterCriticalSection/LeaveCriticalSection for
thread safety.
- banXuid() (new): Thread-safe method to add a player's XUID to the ban list - used when a player
dies in hardcore multiplayer.
---
Minecraft.Client/PlayerList.h
Purpose: Declare ban-related additions
- Added CRITICAL_SECTION m_banCS to protect m_bannedXuids.
- Added void banXuid(PlayerUID xuid) public method.
---
Minecraft.Client/SelectWorldScreen.cpp
Purpose: Show [Hardcore] badge in Java-style world list
- In renderItem(): If levelSummary->isHardcore(), appends [Hardcore] to the world name display.
---
Minecraft.Client/ServerPlayer.cpp
Purpose: Hardcore death behavior on server
- die(): If the level is hardcore, switches the dead player to Adventure mode (so they can't
interact if somehow respawned).
- Minor: Two comment lines changed // → /// (no functional change).
---
Minecraft.Client/Windows64Media/strings.h
Purpose: String IDs for hardcore UI text
- Added 8 new string IDs (2286-2293): IDS_GAMEMODE_HARDCORE, IDS_HARDCORE, IDS_HARDCORE_TOOLTIP,
IDS_HARDCORE_WARNING_TITLE, IDS_HARDCORE_WARNING_TEXT, IDS_HARDCORE_DEATH_MESSAGE,
IDS_LABEL_HARDCORE, IDS_GAMEOPTION_HARDCORE.
---
Minecraft.World/ConsoleSaveFileOriginal.cpp
Purpose: Capture save folder name after first save (for new worlds)
- SaveSaveDataCallback() (Windows64 only): After a successful save, if the app doesn't yet know the
save folder name, attempts to capture it via StorageManager or by scanning Windows64\GameHDD\ for
the newest folder. This handles the case where a newly-created hardcore world hasn't been saved yet
when the folder name is needed.
---
Minecraft.World/DisconnectPacket.h
Purpose: Hardcore disconnect reason
- Added eDisconnect_HardcoreDeath to the disconnect reason enum - used when kicking a player who
died in hardcore multiplayer.
---
Minecraft.World/LoginPacket.cpp & LoginPacket.h
Purpose: Serialize hardcore flag in login packet
- Added bool m_isHardcore member, initialized to false in both constructors.
- Server→Client constructor now accepts bool isHardcore = false parameter.
- read(): Reads m_isHardcore from the stream.
- write(): Writes m_isHardcore to the stream.
- getEstimatedSize(): Added sizeof(bool) for the new field.
---
Minecraft.World/RespawnPacket.cpp & RespawnPacket.h
Purpose: Serialize hardcore flag in respawn packet
- Added bool m_isHardcore member, initialized to false.
- Constructor now accepts bool isHardcore = false parameter.
- read()/write(): Serialize m_isHardcore via readBoolean()/writeBoolean().
- getEstimatedSize(): Changed from 13 to 14 bytes to account for the new boolean.
* Fix split-screen join failing when connecting to a remote host via UI
When a non-host client connected to a remote server through the in-game
UI (as opposed to the -ip/-port command line flags), the global variables
g_Win64MultiplayerIP and g_Win64MultiplayerPort were never updated from
their defaults ("127.0.0.1" and the default port). JoinSplitScreen()
relies on these globals to open a second TCP connection for the local
split-screen pad, so it would always attempt to connect to localhost,
failing immediately on any remote session.
Fix: update g_Win64MultiplayerIP and g_Win64MultiplayerPort inside
JoinGame() once the primary connection is established. This ensures
subsequent JoinSplitScreen() calls always reach the correct host
regardless of how the session was joined.
Additionally, guard PushFreeSmallId() against recycling smallIds in the
range [0, XUSER_MAX_COUNT), which are permanently reserved for the
host's local controller slots. Previously, if a host-side local pad
disconnected its smallId could re-enter the free pool and be handed
to an incoming remote client, causing that client's IQNetPlayer slot
to collide with a local pad slot on the non-host machine.
* Fix tutorial popup positioning in split-screen viewports
Replace the manual switch-case that computed viewport origin with the shared GetViewportRect/Fit16x9 helpers (from UISplitScreenHelpers.h). This ensures the tutorial popup is positioned and scaled consistently with the rest of the split-screen UI, fitting a 16:9 box inside each viewport and applying safezone offsets correctly.
Also adds missing default:break to safezone switch statements to silence compiler warnings.
Made-with: Cursor
* Prevent split-screen join when game window is not focused
Add g_KBMInput.IsWindowFocused() guard to the tryJoin condition so that gamepad input from background windows does not accidentally trigger a split-screen player join. This avoids phantom joins when the user is interacting with another application.
* Open debug overlay in fullscreen UI group during split-screen
Pass eUIGroup_Fullscreen to NavigateToScene when opening the debug overlay, so it spans the entire window instead of being confined to a single split-screen viewport. This makes the debug info readable regardless of the current split-screen layout.
* Fix non-host split-screen connections missing world updates
Previously, secondary (non-host) split-screen connections used isPrimaryConnection()
to gate nearly all world update packets, meaning the second local player would never
receive tile updates, entity movement, sounds, particles, explosions, etc.
The fix introduces per-connection tracking of which entities and chunks each
ClientConnection has loaded, and uses that information to decide whether a secondary
connection needs to process a given packet or if the primary connection already
handled it.
New members in ClientConnection:
- m_trackedEntityIds: set of entity IDs this connection has received AddEntity/AddMob/AddPlayer etc. for
- m_visibleChunks: set of chunk coordinates (packed into int64) this connection has marked visible
- Both sets are cleared on close(), respawn (dimension change), and destructor
New helpers:
- findPrimaryConnection(): walks the MultiPlayerLevel connection list to find the connection on the primary pad
- shouldProcessForEntity(id): secondary connection skips the packet only if the primary is already tracking that entity
- shouldProcessForPosition(x, z): secondary connection skips the packet only if the primary already has that chunk visible
- anyOtherConnectionHasChunk(x, z): used when a chunk becomes invisible to avoid hiding it from the level if another connection still needs it
- isTrackingEntity(id): public accessor used by shouldProcessForEntity on the primary connection
Packet handler changes:
- handleMoveEntity, handleMoveEntitySmall, handleSetEntityMotion, handleTakeItemEntity:
replaced isPrimaryConnection() with shouldProcessForEntity() so secondary
connections still process movement for entities they know about
- handleExplosion, handleLevelEvent:
replaced isPrimaryConnection() with shouldProcessForPosition() so block
destruction and level events fire for the correct connection based on chunks
- handleChunkTilesUpdate, handleBlockRegionUpdate, handleTileUpdate, handleSignUpdate,
handleTileEntityData, handleTileEvent, handleTileDestruction, handleComplexItemData,
handleSoundEvent, handleParticleEvent:
removed the isPrimaryConnection() guard entirely -- these are world-state updates
that all connections must process regardless of which pad is primary
- handleChunkVisibilityArea / handleChunkVisibility:
now populate m_visibleChunks; on visibility=false, setChunkVisible(false) is
only called on the level if no other connection still has that chunk loaded
- handleAddEntity, handleAddExperienceOrb, handleAddPainting, handleAddPlayer,
handleAddMob: now insert into m_trackedEntityIds on arrival
- handleRemoveEntity: now erases from m_trackedEntityIds on removal
- handleLevelEvent: removed a duplicate levelEvent() call that was always firing
regardless of the isPrimaryConnection() check above it (latent bug)
MultiPlayerLevel: added friend class ClientConnection to allow access to the
connections list without exposing it publicly.
* Fix fullscreen progress screen swallowing input before load completes
Two issues in UIScene_FullscreenProgress::handleInput:
1. The touchpad/button press that triggers movie skip or input forwarding
had no guard on m_threadCompleted, so pressing a button during the loading
phase would fire the skip/send logic before the background thread finished.
Added the m_threadCompleted check so that path is only reachable once
the load is actually done.
2. The `handled = true` assignment was missing from that branch, so input
events were not being consumed and could fall through to other handlers.
Added it unconditionally at the end of the block.
* Update player count decrement logic in PlatformNetworkManagerStub
Refactor the condition for decrementing the player count in CPlatformNetworkManagerStub::DoWork. The previous check was replaced with a while loop to ensure that the player count is only decremented when there are more than one player and the last player's custom data value is zero. This change improves the handling of player connections in the network manager.
* Refactor safe zone calculations in UI components for consistency
Updated the safe zone calculations across multiple UI components to ensure symmetry in split viewports. Removed unnecessary assignments and added comments for clarity. Modified the repositionHud function to include an additional parameter for better handling of HUD positioning in split-screen scenarios.
* Gui.cpp: fix F3 debug overlay in splitscreen + minor perf cleanup
The F3 debug screen was badly broken in splitscreen: it used the GUI
coordinate space which gets distorted by the splitscreen scaling, so
text appeared stretched, misaligned or completely off-screen depending
on the viewport layout.
Fixed by setting up a dedicated projection matrix using physical pixel
coordinates (g_rScreenWidth / g_rScreenHeight) each time the overlay is
drawn, completely decoupled from whatever transform the HUD is using.
The viewport dimensions are now computed per screen section so the ortho
projection matches the actual pixel area of each player's quadrant.
Version and branch strings are only shown for player 0 (iPad == 0) to
avoid repeating them across every splitscreen pane.
Also removed a few redundant calculations that were being done twice in
the same frame (atan for xRot, health halves, air supply scaled value).
These are minor and have negligible real-world impact; more substantial
per-frame caching work (safe zone calculations etc.) will follow in a
separate commit.
* Fix split-screen join failing when connecting to a remote host via UI
When a non-host client connected to a remote server through the in-game
UI (as opposed to the -ip/-port command line flags), the global variables
g_Win64MultiplayerIP and g_Win64MultiplayerPort were never updated from
their defaults ("127.0.0.1" and the default port). JoinSplitScreen()
relies on these globals to open a second TCP connection for the local
split-screen pad, so it would always attempt to connect to localhost,
failing immediately on any remote session.
Fix: update g_Win64MultiplayerIP and g_Win64MultiplayerPort inside
JoinGame() once the primary connection is established. This ensures
subsequent JoinSplitScreen() calls always reach the correct host
regardless of how the session was joined.
Additionally, guard PushFreeSmallId() against recycling smallIds in the
range [0, XUSER_MAX_COUNT), which are permanently reserved for the
host's local controller slots. Previously, if a host-side local pad
disconnected its smallId could re-enter the free pool and be handed
to an incoming remote client, causing that client's IQNetPlayer slot
to collide with a local pad slot on the non-host machine.
* Fix tutorial popup positioning in split-screen viewports
Replace the manual switch-case that computed viewport origin with the shared GetViewportRect/Fit16x9 helpers (from UISplitScreenHelpers.h). This ensures the tutorial popup is positioned and scaled consistently with the rest of the split-screen UI, fitting a 16:9 box inside each viewport and applying safezone offsets correctly.
Also adds missing default:break to safezone switch statements to silence compiler warnings.
Made-with: Cursor
* Prevent split-screen join when game window is not focused
Add g_KBMInput.IsWindowFocused() guard to the tryJoin condition so that gamepad input from background windows does not accidentally trigger a split-screen player join. This avoids phantom joins when the user is interacting with another application.
* Open debug overlay in fullscreen UI group during split-screen
Pass eUIGroup_Fullscreen to NavigateToScene when opening the debug overlay, so it spans the entire window instead of being confined to a single split-screen viewport. This makes the debug info readable regardless of the current split-screen layout.
* Fix non-host split-screen connections missing world updates
Previously, secondary (non-host) split-screen connections used isPrimaryConnection()
to gate nearly all world update packets, meaning the second local player would never
receive tile updates, entity movement, sounds, particles, explosions, etc.
The fix introduces per-connection tracking of which entities and chunks each
ClientConnection has loaded, and uses that information to decide whether a secondary
connection needs to process a given packet or if the primary connection already
handled it.
New members in ClientConnection:
- m_trackedEntityIds: set of entity IDs this connection has received AddEntity/AddMob/AddPlayer etc. for
- m_visibleChunks: set of chunk coordinates (packed into int64) this connection has marked visible
- Both sets are cleared on close(), respawn (dimension change), and destructor
New helpers:
- findPrimaryConnection(): walks the MultiPlayerLevel connection list to find the connection on the primary pad
- shouldProcessForEntity(id): secondary connection skips the packet only if the primary is already tracking that entity
- shouldProcessForPosition(x, z): secondary connection skips the packet only if the primary already has that chunk visible
- anyOtherConnectionHasChunk(x, z): used when a chunk becomes invisible to avoid hiding it from the level if another connection still needs it
- isTrackingEntity(id): public accessor used by shouldProcessForEntity on the primary connection
Packet handler changes:
- handleMoveEntity, handleMoveEntitySmall, handleSetEntityMotion, handleTakeItemEntity:
replaced isPrimaryConnection() with shouldProcessForEntity() so secondary
connections still process movement for entities they know about
- handleExplosion, handleLevelEvent:
replaced isPrimaryConnection() with shouldProcessForPosition() so block
destruction and level events fire for the correct connection based on chunks
- handleChunkTilesUpdate, handleBlockRegionUpdate, handleTileUpdate, handleSignUpdate,
handleTileEntityData, handleTileEvent, handleTileDestruction, handleComplexItemData,
handleSoundEvent, handleParticleEvent:
removed the isPrimaryConnection() guard entirely -- these are world-state updates
that all connections must process regardless of which pad is primary
- handleChunkVisibilityArea / handleChunkVisibility:
now populate m_visibleChunks; on visibility=false, setChunkVisible(false) is
only called on the level if no other connection still has that chunk loaded
- handleAddEntity, handleAddExperienceOrb, handleAddPainting, handleAddPlayer,
handleAddMob: now insert into m_trackedEntityIds on arrival
- handleRemoveEntity: now erases from m_trackedEntityIds on removal
- handleLevelEvent: removed a duplicate levelEvent() call that was always firing
regardless of the isPrimaryConnection() check above it (latent bug)
MultiPlayerLevel: added friend class ClientConnection to allow access to the
connections list without exposing it publicly.
* Fix fullscreen progress screen swallowing input before load completes
Two issues in UIScene_FullscreenProgress::handleInput:
1. The touchpad/button press that triggers movie skip or input forwarding
had no guard on m_threadCompleted, so pressing a button during the loading
phase would fire the skip/send logic before the background thread finished.
Added the m_threadCompleted check so that path is only reachable once
the load is actually done.
2. The `handled = true` assignment was missing from that branch, so input
events were not being consumed and could fall through to other handlers.
Added it unconditionally at the end of the block.
* Update player count decrement logic in PlatformNetworkManagerStub
Refactor the condition for decrementing the player count in CPlatformNetworkManagerStub::DoWork. The previous check was replaced with a while loop to ensure that the player count is only decremented when there are more than one player and the last player's custom data value is zero. This change improves the handling of player connections in the network manager.
* Refactor safe zone calculations in UI components for consistency
Updated the safe zone calculations across multiple UI components to ensure symmetry in split viewports. Removed unnecessary assignments and added comments for clarity. Modified the repositionHud function to include an additional parameter for better handling of HUD positioning in split-screen scenarios.
* Gui.cpp: fix F3 debug overlay in splitscreen + minor perf cleanup
The F3 debug screen was badly broken in splitscreen: it used the GUI
coordinate space which gets distorted by the splitscreen scaling, so
text appeared stretched, misaligned or completely off-screen depending
on the viewport layout.
Fixed by setting up a dedicated projection matrix using physical pixel
coordinates (g_rScreenWidth / g_rScreenHeight) each time the overlay is
drawn, completely decoupled from whatever transform the HUD is using.
The viewport dimensions are now computed per screen section so the ortho
projection matches the actual pixel area of each player's quadrant.
Version and branch strings are only shown for player 0 (iPad == 0) to
avoid repeating them across every splitscreen pane.
Also removed a few redundant calculations that were being done twice in
the same frame (atan for xRot, health halves, air supply scaled value).
These are minor and have negligible real-world impact; more substantial
per-frame caching work (safe zone calculations etc.) will follow in a
separate commit.
* Fixed boats falling and a TP glitch #266
* Replaced every C-style cast with C++ ones
* Replaced every C-style cast with C++ ones
* Fixed boats falling and a TP glitch #266
* Updated NULL to nullptr and fixing some type issues
* Modernized and fixed a few bugs
- Replaced most instances of `NULL` with `nullptr`.
- Replaced most `shared_ptr(new ...)` with `make_shared`.
- Removed the `nullptr` macro as it was interfering with the actual nullptr keyword in some instances.
* Fixing more conflicts
* Replace int loops with size_t and start work on overrides
* Add safety checks and fix a issue with vector going OOR
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.
* Fixed boats falling and a TP glitch #266
* Replaced every C-style cast with C++ ones
* Replaced every C-style cast with C++ ones
* Fixed boats falling and a TP glitch #266
* Updated NULL to nullptr and fixing some type issues
* Modernized and fixed a few bugs
- Replaced most instances of `NULL` with `nullptr`.
- Replaced most `shared_ptr(new ...)` with `make_shared`.
- Removed the `nullptr` macro as it was interfering with the actual nullptr keyword in some instances.
* Fixing more conflicts
* Replace int loops with size_t and start work on overrides
* Change F3 rendering and add git version information
* Change position, block, chunk and facing
* Limit position decimal places
* Move LCE unique to the bottom and add more java features
* Fix chunk information disappearing after y256
* Add chunk count information
* Move build number script to prebuild.ps1
* We dont need to specify vector and wstring are from std
* Restore build number to fix multiplayer
* Use short symbolic-ref
* Restore original BuildVer.h
---------
Co-authored-by: Loki <lokio.casebstv@gmail.com>
Co-authored-by: Loki Rautio <lokirautio@gmail.com>
Partially reverts changes in #682 that uses a better technique for rendering
the chat in favor of Iggy. We will need to go back once we update that
version for better visual parity with the Iggy chat rendering (position,
spacing, font size) but this works for now. Fixes#718