Merge branch 'main' into TU43

This commit is contained in:
Fireblade 2026-05-25 12:40:46 -04:00 committed by GitHub
commit fb46ed3005
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 204 additions and 220 deletions

View file

@ -1,9 +1,8 @@
name: Nightly Release
on:
push:
branches:
- experimental
- main
workflow_dispatch:
permissions:

2
BUMP
View file

@ -1 +1 @@
1.0.4b
1.0.6b

View file

@ -82,6 +82,8 @@ UIScene_JoinMenu::UIScene_JoinMenu(int iPad, void *_initData, UILayer *parentLay
IggyValueSetBooleanRS(&path, visibleName, nullptr, false);
}
}
updateServerDescription();
}
}
}
@ -129,46 +131,46 @@ void UIScene_JoinMenu::updateTooltips()
void UIScene_JoinMenu::tick()
{
if( !m_friendInfoRequestIssued )
if (!m_friendInfoRequestIssued)
{
ui.NavigateToScene(m_iPad, eUIScene_Timer);
g_NetworkManager.GetFullFriendSessionInfo(m_selectedSession, &friendSessionUpdated, this);
m_friendInfoRequestIssued = true;
}
if( m_friendInfoUpdatedOK )
if (m_friendInfoUpdatedOK)
{
m_friendInfoUpdatedOK = false;
m_buttonJoinGame.init(app.GetString(IDS_JOIN_GAME),eControl_JoinGame);
m_buttonJoinGame.init(app.GetString(IDS_JOIN_GAME), eControl_JoinGame);
m_buttonListPlayers.init(eControl_GamePlayers);
m_buttonListPlayers.setYPos( m_buttonListPlayers.getYPos() + 300 );
m_buttonListPlayers.setYPos(m_buttonListPlayers.getYPos() + 300);
#if defined(__PS3__) || defined(__ORBIS__) || defined __PSVITA__
for( int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++ )
for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++)
{
if( m_selectedSession->data.players[i] != nullptr )
if (m_selectedSession->data.players[i] != nullptr)
{
#ifndef _CONTENT_PACKAGE
if(app.DebugSettingsOn() && (app.GetGameSettingsDebugMask()&(1L<<eDebugSetting_DebugLeaderboards)))
#ifndef _CONTENT_PACKAGE
if (app.DebugSettingsOn() && (app.GetGameSettingsDebugMask() & (1L << eDebugSetting_DebugLeaderboards)))
{
m_buttonListPlayers.addItem(L"WWWWWWWWWWWWWWWW");
}
else
#endif
#endif
{
string playerName(m_selectedSession->data.players[i].getOnlineID());
#ifndef __PSVITA__
#ifndef __PSVITA__
// Append guest number (any players in an online game not signed into PSN are guests)
if( m_selectedSession->data.players[i].isSignedIntoPSN() == false )
if (m_selectedSession->data.players[i].isSignedIntoPSN() == false)
{
char suffix[5];
sprintf(suffix, " (%d)", m_selectedSession->data.players[i].getQuadrant() + 1);
playerName.append(suffix);
}
#endif
#endif
m_buttonListPlayers.addItem(playerName);
}
}
@ -179,9 +181,9 @@ void UIScene_JoinMenu::tick()
}
}
#elif defined(_DURANGO)
for( int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++ )
for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++)
{
if ( m_selectedSession->searchResult.m_playerNames[i].size() )
if (m_selectedSession->searchResult.m_playerNames[i].size())
{
m_buttonListPlayers.addItem(m_selectedSession->searchResult.m_playerNames[i]);
}
@ -214,74 +216,74 @@ void UIScene_JoinMenu::tick()
m_labelLabels[eLabel_FireOn].init(app.GetString(IDS_LABEL_FIRE_SPREADS));
unsigned int uiGameHostSettings = m_selectedSession->data.m_uiGameHostSettings;
switch(app.GetGameHostOption(uiGameHostSettings,eGameHostOption_Difficulty))
switch (app.GetGameHostOption(uiGameHostSettings, eGameHostOption_Difficulty))
{
case Difficulty::EASY:
m_labelValues[eLabel_Difficulty].init( app.GetString(IDS_DIFFICULTY_TITLE_EASY) );
m_labelValues[eLabel_Difficulty].init(app.GetString(IDS_DIFFICULTY_TITLE_EASY));
break;
case Difficulty::NORMAL:
m_labelValues[eLabel_Difficulty].init( app.GetString(IDS_DIFFICULTY_TITLE_NORMAL) );
m_labelValues[eLabel_Difficulty].init(app.GetString(IDS_DIFFICULTY_TITLE_NORMAL));
break;
case Difficulty::HARD:
m_labelValues[eLabel_Difficulty].init( app.GetString(IDS_DIFFICULTY_TITLE_HARD) );
m_labelValues[eLabel_Difficulty].init(app.GetString(IDS_DIFFICULTY_TITLE_HARD));
break;
case Difficulty::PEACEFUL:
default:
m_labelValues[eLabel_Difficulty].init( app.GetString(IDS_DIFFICULTY_TITLE_PEACEFUL) );
m_labelValues[eLabel_Difficulty].init(app.GetString(IDS_DIFFICULTY_TITLE_PEACEFUL));
break;
}
int option = app.GetGameHostOption(uiGameHostSettings,eGameHostOption_GameType);
if(option == GameType::CREATIVE->getId())
int option = app.GetGameHostOption(uiGameHostSettings, eGameHostOption_GameType);
if (option == GameType::CREATIVE->getId())
{
m_labelValues[eLabel_GameType].init( app.GetString(IDS_CREATIVE) );
m_labelValues[eLabel_GameType].init(app.GetString(IDS_CREATIVE));
}
else if(option == GameType::ADVENTURE->getId())
else if (option == GameType::ADVENTURE->getId())
{
m_labelValues[eLabel_GameType].init( app.GetString(IDS_ADVENTURE) );
m_labelValues[eLabel_GameType].init(app.GetString(IDS_ADVENTURE));
}
else
{
m_labelValues[eLabel_GameType].init( app.GetString(IDS_SURVIVAL) );
m_labelValues[eLabel_GameType].init(app.GetString(IDS_SURVIVAL));
}
if(app.GetGameHostOption(uiGameHostSettings,eGameHostOption_Gamertags)) m_labelValues[eLabel_GamertagsOn].init( app.GetString(IDS_ON) );
else m_labelValues[eLabel_GamertagsOn].init( app.GetString(IDS_OFF) );
if (app.GetGameHostOption(uiGameHostSettings, eGameHostOption_Gamertags)) m_labelValues[eLabel_GamertagsOn].init(app.GetString(IDS_ON));
else m_labelValues[eLabel_GamertagsOn].init(app.GetString(IDS_OFF));
if(app.GetGameHostOption(uiGameHostSettings,eGameHostOption_Structures)) m_labelValues[eLabel_Structures].init( app.GetString(IDS_ON) );
else m_labelValues[eLabel_Structures].init( app.GetString(IDS_OFF) );
if (app.GetGameHostOption(uiGameHostSettings, eGameHostOption_Structures)) m_labelValues[eLabel_Structures].init(app.GetString(IDS_ON));
else m_labelValues[eLabel_Structures].init(app.GetString(IDS_OFF));
if(app.GetGameHostOption(uiGameHostSettings,eGameHostOption_LevelType)) m_labelValues[eLabel_LevelType].init( app.GetString(IDS_LEVELTYPE_SUPERFLAT) );
else m_labelValues[eLabel_LevelType].init( app.GetString(IDS_LEVELTYPE_NORMAL) );
if (app.GetGameHostOption(uiGameHostSettings, eGameHostOption_LevelType)) m_labelValues[eLabel_LevelType].init(app.GetString(IDS_LEVELTYPE_SUPERFLAT));
else m_labelValues[eLabel_LevelType].init(app.GetString(IDS_LEVELTYPE_NORMAL));
if(app.GetGameHostOption(uiGameHostSettings,eGameHostOption_PvP))m_labelValues[eLabel_PVP].init( app.GetString(IDS_ON) );
else m_labelValues[eLabel_PVP].init( app.GetString(IDS_OFF) );
if (app.GetGameHostOption(uiGameHostSettings, eGameHostOption_PvP))m_labelValues[eLabel_PVP].init(app.GetString(IDS_ON));
else m_labelValues[eLabel_PVP].init(app.GetString(IDS_OFF));
if(app.GetGameHostOption(uiGameHostSettings,eGameHostOption_TrustPlayers)) m_labelValues[eLabel_Trust].init( app.GetString(IDS_ON) );
else m_labelValues[eLabel_Trust].init( app.GetString(IDS_OFF) );
if (app.GetGameHostOption(uiGameHostSettings, eGameHostOption_TrustPlayers)) m_labelValues[eLabel_Trust].init(app.GetString(IDS_ON));
else m_labelValues[eLabel_Trust].init(app.GetString(IDS_OFF));
if(app.GetGameHostOption(uiGameHostSettings,eGameHostOption_TNT)) m_labelValues[eLabel_TNTOn].init( app.GetString(IDS_ON) );
else m_labelValues[eLabel_TNTOn].init( app.GetString(IDS_OFF) );
if (app.GetGameHostOption(uiGameHostSettings, eGameHostOption_TNT)) m_labelValues[eLabel_TNTOn].init(app.GetString(IDS_ON));
else m_labelValues[eLabel_TNTOn].init(app.GetString(IDS_OFF));
if(app.GetGameHostOption(uiGameHostSettings,eGameHostOption_FireSpreads)) m_labelValues[eLabel_FireOn].init( app.GetString(IDS_ON) );
else m_labelValues[eLabel_FireOn].init( app.GetString(IDS_OFF) );
if (app.GetGameHostOption(uiGameHostSettings, eGameHostOption_FireSpreads)) m_labelValues[eLabel_FireOn].init(app.GetString(IDS_ON));
else m_labelValues[eLabel_FireOn].init(app.GetString(IDS_OFF));
m_bIgnoreInput = false;
// Alert the app the we want to be informed of ethernet connections
app.SetLiveLinkRequired( true );
app.SetLiveLinkRequired(true);
TelemetryManager->RecordMenuShown(m_iPad, eUIScene_JoinMenu, 0);
addTimer(UPDATE_PLAYERS_TIMER_ID,UPDATE_PLAYERS_TIMER_TIME);
addTimer(UPDATE_PLAYERS_TIMER_ID, UPDATE_PLAYERS_TIMER_TIME);
}
if( m_friendInfoUpdatedERROR )
if (m_friendInfoUpdatedERROR)
{
m_buttonJoinGame.init(app.GetString(IDS_JOIN_GAME),eControl_JoinGame);
m_buttonJoinGame.init(app.GetString(IDS_JOIN_GAME), eControl_JoinGame);
m_buttonListPlayers.init(eControl_GamePlayers);
m_buttonListPlayers.setYPos( m_buttonListPlayers.getYPos() + 300 );
m_buttonListPlayers.setYPos(m_buttonListPlayers.getYPos() + 300);
m_labelLabels[eLabel_Difficulty].init(app.GetString(IDS_LABEL_DIFFICULTY));
m_labelLabels[eLabel_GameType].init(app.GetString(IDS_LABEL_GAME_TYPE));
@ -294,14 +296,14 @@ void UIScene_JoinMenu::tick()
m_labelLabels[eLabel_FireOn].init(app.GetString(IDS_LABEL_FIRE_SPREADS));
m_labelValues[eLabel_Difficulty].init(app.GetString(IDS_DIFFICULTY_TITLE_PEACEFUL));
m_labelValues[eLabel_GameType].init( app.GetString(IDS_CREATIVE) );
m_labelValues[eLabel_GamertagsOn].init( app.GetString(IDS_OFF) );
m_labelValues[eLabel_Structures].init( app.GetString(IDS_OFF) );
m_labelValues[eLabel_LevelType].init( app.GetString(IDS_LEVELTYPE_NORMAL) );
m_labelValues[eLabel_PVP].init( app.GetString(IDS_OFF) );
m_labelValues[eLabel_Trust].init( app.GetString(IDS_OFF) );
m_labelValues[eLabel_TNTOn].init( app.GetString(IDS_OFF) );
m_labelValues[eLabel_FireOn].init( app.GetString(IDS_OFF) );
m_labelValues[eLabel_GameType].init(app.GetString(IDS_CREATIVE));
m_labelValues[eLabel_GamertagsOn].init(app.GetString(IDS_OFF));
m_labelValues[eLabel_Structures].init(app.GetString(IDS_OFF));
m_labelValues[eLabel_LevelType].init(app.GetString(IDS_LEVELTYPE_NORMAL));
m_labelValues[eLabel_PVP].init(app.GetString(IDS_OFF));
m_labelValues[eLabel_Trust].init(app.GetString(IDS_OFF));
m_labelValues[eLabel_TNTOn].init(app.GetString(IDS_OFF));
m_labelValues[eLabel_FireOn].init(app.GetString(IDS_OFF));
m_friendInfoUpdatedERROR = false;
@ -310,9 +312,9 @@ void UIScene_JoinMenu::tick()
UINT uiIDA[1];
uiIDA[0] = IDS_CONFIRM_OK;
#ifdef _XBOX_ONE
ui.RequestErrorMessage( IDS_CONNECTION_FAILED, IDS_DISCONNECTED_SERVER_QUIT, uiIDA,1,m_iPad,ErrorDialogReturned,this);
ui.RequestErrorMessage(IDS_CONNECTION_FAILED, IDS_DISCONNECTED_SERVER_QUIT, uiIDA, 1, m_iPad, ErrorDialogReturned, this);
#else
ui.RequestErrorMessage( IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA,1,m_iPad,ErrorDialogReturned,this);
ui.RequestErrorMessage(IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, m_iPad, ErrorDialogReturned, this);
#endif
}
@ -323,84 +325,7 @@ void UIScene_JoinMenu::tick()
{
IggyPlayerTickRS(s_movieServerDesc);
IggyValuePath *root = IggyPlayerRootPath(s_movieServerDesc);
if (root)
{
// scale the size before Iggy reads it
IggyValuePath textPath;
if (IggyValuePathMakeNameRef(&textPath, root, "HowToPlayText_0"))
{
IggyName nameX = IggyPlayerCreateFastName(s_movieServerDesc, (IggyUTF16 *)L"x", -1);
IggyName nameY = IggyPlayerCreateFastName(s_movieServerDesc, (IggyUTF16 *)L"y", -1);
IggyName nameW = IggyPlayerCreateFastName(s_movieServerDesc, (IggyUTF16 *)L"width", -1);
IggyName nameH = IggyPlayerCreateFastName(s_movieServerDesc, (IggyUTF16 *)L"height", -1);
if (m_loadedResolution == eSceneResolution_1080)
{
IggyValueSetF64RS(&textPath, nameX, nullptr, 333.0);// horizontal
IggyValueSetF64RS(&textPath, nameY, nullptr, 340.0);// vertical
IggyValueSetF64RS(&textPath, nameW, nullptr, 580.0);
IggyValueSetF64RS(&textPath, nameH, nullptr, 270.0);
}
else //720
{
IggyValueSetF64RS(&textPath, nameX, nullptr, 252.0);
IggyValueSetF64RS(&textPath, nameY, nullptr, 285.0);
IggyValueSetF64RS(&textPath, nameW, nullptr, 440.0);
IggyValueSetF64RS(&textPath, nameH, nullptr, 220.0);
}
}
// harcoded text for test it, later im gonna delete this and
// and convert it so that people can add their description when adding the server
if (!s_textInjected && s_funcLoadPage != 0)
{
IggyDataValue result;
IggyDataValue args[2];
args[0].type = IGGY_DATATYPE_number;
args[0].number = 0; // 0 is the what's new page on howtoplay don't change it
wstring testText = L"\nNothing yet...";
IggyStringUTF16 iggyStr;
wstring formattedText = app.FormatChatMessage(testText);
iggyStr.string = (IggyUTF16*)formattedText.c_str();
iggyStr.length = (unsigned int)formattedText.length();
args[1].type = IGGY_DATATYPE_string_UTF16;
args[1].string16 = iggyStr;
IggyResult res = IggyPlayerCallMethodRS(s_movieServerDesc, &result, root, s_funcLoadPage, 2, args);
if (res == IGGY_RESULT_SUCCESS)
{
s_textInjected = true;
}
}
// keeps the text fixed so it doesn't move from its place
IggyValuePath panelPath;
if (s_textInjected && IggyValuePathMakeNameRef(&panelPath, root, "DynamicHtmlText"))
{
IggyName nameX = IggyPlayerCreateFastName(s_movieServerDesc, (IggyUTF16 *)L"x", -1);
IggyName nameY = IggyPlayerCreateFastName(s_movieServerDesc, (IggyUTF16 *)L"y", -1);
IggyName nameW = IggyPlayerCreateFastName(s_movieServerDesc, (IggyUTF16 *)L"width", -1);
IggyName nameH = IggyPlayerCreateFastName(s_movieServerDesc, (IggyUTF16 *)L"height", -1);
if (m_loadedResolution == eSceneResolution_1080)
{
IggyValueSetF64RS(&panelPath, nameX, nullptr, 332.0);// horizontal
IggyValueSetF64RS(&panelPath, nameY, nullptr, 340.0);// vertical
IggyValueSetF64RS(&panelPath, nameW, nullptr, 580.0);
IggyValueSetF64RS(&panelPath, nameH, nullptr, 270.0);
}
else //720p
{
IggyValueSetF64RS(&panelPath, nameX, nullptr, 250.0);
IggyValueSetF64RS(&panelPath, nameY, nullptr, 290.0);
IggyValueSetF64RS(&panelPath, nameW, nullptr, 400.0);
IggyValueSetF64RS(&panelPath, nameH, nullptr, 230.0);
}
}
}
updateServerDescription();
}
}
#endif
@ -408,6 +333,88 @@ void UIScene_JoinMenu::tick()
UIScene::tick();
}
void UIScene_JoinMenu::updateServerDescription() {
IggyValuePath* root = IggyPlayerRootPath(s_movieServerDesc);
if (root)
{
// scale the size before Iggy reads it
IggyValuePath textPath;
if (IggyValuePathMakeNameRef(&textPath, root, "HowToPlayText_0"))
{
IggyName nameX = IggyPlayerCreateFastName(s_movieServerDesc, (IggyUTF16*)L"x", -1);
IggyName nameY = IggyPlayerCreateFastName(s_movieServerDesc, (IggyUTF16*)L"y", -1);
IggyName nameW = IggyPlayerCreateFastName(s_movieServerDesc, (IggyUTF16*)L"width", -1);
IggyName nameH = IggyPlayerCreateFastName(s_movieServerDesc, (IggyUTF16*)L"height", -1);
if (m_loadedResolution == eSceneResolution_1080)
{
IggyValueSetF64RS(&textPath, nameX, nullptr, 333.0);// horizontal
IggyValueSetF64RS(&textPath, nameY, nullptr, 340.0);// vertical
IggyValueSetF64RS(&textPath, nameW, nullptr, 580.0);
IggyValueSetF64RS(&textPath, nameH, nullptr, 270.0);
}
else //720
{
IggyValueSetF64RS(&textPath, nameX, nullptr, 252.0);
IggyValueSetF64RS(&textPath, nameY, nullptr, 285.0);
IggyValueSetF64RS(&textPath, nameW, nullptr, 440.0);
IggyValueSetF64RS(&textPath, nameH, nullptr, 220.0);
}
}
// harcoded text for test it, later im gonna delete this and
// and convert it so that people can add their description when adding the server
if (s_funcLoadPage != 0)
{
IggyDataValue result;
IggyDataValue args[2];
args[0].type = IGGY_DATATYPE_number;
args[0].number = 0; // 0 is the what's new page on howtoplay don't change it
wstring testText = L"\nNothing yet...";
IggyStringUTF16 iggyStr;
wstring formattedText = app.EscapeHTMLString(testText);
formattedText = app.FormatChatMessage(formattedText);
iggyStr.string = (IggyUTF16*)formattedText.c_str();
iggyStr.length = (unsigned int)formattedText.length();
args[1].type = IGGY_DATATYPE_string_UTF16;
args[1].string16 = iggyStr;
IggyResult res = IggyPlayerCallMethodRS(s_movieServerDesc, &result, root, s_funcLoadPage, 2, args);
if (res == IGGY_RESULT_SUCCESS)
{
s_textInjected = true;
}
}
// keeps the text fixed so it doesn't move from its place
IggyValuePath panelPath;
if (s_textInjected && IggyValuePathMakeNameRef(&panelPath, root, "DynamicHtmlText"))
{
IggyName nameX = IggyPlayerCreateFastName(s_movieServerDesc, (IggyUTF16*)L"x", -1);
IggyName nameY = IggyPlayerCreateFastName(s_movieServerDesc, (IggyUTF16*)L"y", -1);
IggyName nameW = IggyPlayerCreateFastName(s_movieServerDesc, (IggyUTF16*)L"width", -1);
IggyName nameH = IggyPlayerCreateFastName(s_movieServerDesc, (IggyUTF16*)L"height", -1);
if (m_loadedResolution == eSceneResolution_1080)
{
IggyValueSetF64RS(&panelPath, nameX, nullptr, 332.0);// horizontal
IggyValueSetF64RS(&panelPath, nameY, nullptr, 340.0);// vertical
IggyValueSetF64RS(&panelPath, nameW, nullptr, 580.0);
IggyValueSetF64RS(&panelPath, nameH, nullptr, 270.0);
}
else //720p
{
IggyValueSetF64RS(&panelPath, nameX, nullptr, 250.0);
IggyValueSetF64RS(&panelPath, nameY, nullptr, 290.0);
IggyValueSetF64RS(&panelPath, nameW, nullptr, 400.0);
IggyValueSetF64RS(&panelPath, nameH, nullptr, 230.0);
}
}
}
}
void UIScene_JoinMenu::friendSessionUpdated(bool success, void *pParam)
{
UIScene_JoinMenu *scene = static_cast<UIScene_JoinMenu *>(pParam);

View file

@ -93,6 +93,8 @@ protected:
// TODO: This should be pure virtual in this class
virtual wstring getMoviePath();
void updateServerDescription();
public:
public:
// INPUT

View file

@ -15,8 +15,8 @@ MultiPlayerChunkCache::MultiPlayerChunkCache(Level *level)
XZSIZE = level->dimension->getXZSize(); // 4J Added
XZOFFSET = XZSIZE/2; // 4J Added
m_XZSize = XZSIZE;
hasData = new bool[LEVEL_MIN_WIDTH * LEVEL_MIN_WIDTH];
memset(hasData, 0, sizeof(bool) * LEVEL_MIN_WIDTH * LEVEL_MIN_WIDTH);
hasData = new bool[XZSIZE * XZSIZE];
memset(hasData, 0, sizeof(bool) * XZSIZE * XZSIZE);
emptyChunk = new EmptyLevelChunk(level, byteArray(16 * 16 * Level::maxBuildHeight), 0, 0);
@ -93,8 +93,8 @@ MultiPlayerChunkCache::MultiPlayerChunkCache(Level *level)
this->level = level;
this->cache = new LevelChunk *[LEVEL_MIN_WIDTH * LEVEL_MIN_WIDTH];
memset(this->cache, 0, sizeof(LevelChunk*) * LEVEL_MIN_WIDTH * LEVEL_MIN_WIDTH);
this->cache = new LevelChunk *[XZSIZE * XZSIZE];
memset(this->cache, 0, sizeof(LevelChunk*) * XZSIZE * XZSIZE);
InitializeCriticalSectionAndSpinCount(&m_csLoadCreate,4000);
}
@ -129,11 +129,10 @@ bool MultiPlayerChunkCache::reallyHasChunk(int x, int z)
// Check we're in range of the stored level - if we aren't, then consider that we do have that chunk as we'll be able to use the water chunk there
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return true;
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return true;
int idx = wrapCoord(x, LEVEL_MIN_WIDTH) * LEVEL_MIN_WIDTH + wrapCoord(z, LEVEL_MIN_WIDTH);
int idx = ix * XZSIZE + iz;
LevelChunk *chunk = cache[idx];
if (chunk == nullptr || chunk->x != x || chunk->z != z)
if (chunk == nullptr)
{
return false;
}
@ -147,10 +146,10 @@ void MultiPlayerChunkCache::drop(const int x, const int z)
if ((ix < 0) || (ix >= XZSIZE)) return;
if ((iz < 0) || (iz >= XZSIZE)) return;
int idx = wrapCoord(x, LEVEL_MIN_WIDTH) * LEVEL_MIN_WIDTH + wrapCoord(z, LEVEL_MIN_WIDTH);
int idx = ix * XZSIZE + iz;
LevelChunk* chunk = cache[idx];
if (chunk != nullptr && !chunk->isEmpty() && chunk->x == x && chunk->z == z)
if (chunk != nullptr && !chunk->isEmpty())
{
// Drop entities in the chunks, especially for the case when a player is dead
// as they will not get the RemoveEntity packet if an entity is removed.
@ -170,12 +169,12 @@ LevelChunk *MultiPlayerChunkCache::create(int x, int z)
// Check we're in range of the stored level
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
int idx = wrapCoord(x, LEVEL_MIN_WIDTH) * LEVEL_MIN_WIDTH + wrapCoord(z, LEVEL_MIN_WIDTH);
int idx = ix * XZSIZE + iz;
LevelChunk *chunk = cache[idx];
LevelChunk *lastChunk = chunk;
if( chunk == nullptr || chunk->x != x || chunk->z != z )
if( chunk == nullptr )
{
EnterCriticalSection(&m_csLoadCreate);
@ -254,10 +253,10 @@ LevelChunk *MultiPlayerChunkCache::getChunk(int x, int z)
// Check we're in range of the stored level
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
int idx = wrapCoord(x, LEVEL_MIN_WIDTH) * LEVEL_MIN_WIDTH + wrapCoord(z, LEVEL_MIN_WIDTH);
int idx = ix * XZSIZE + iz;
LevelChunk *chunk = cache[idx];
if( chunk == nullptr || chunk->x != x || chunk->z != z )
if( chunk == nullptr )
{
return emptyChunk;
}
@ -316,6 +315,6 @@ void MultiPlayerChunkCache::dataReceived(int x, int z)
// Check we're in range of the stored level
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return;
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return;
int idx = wrapCoord(x, LEVEL_MIN_WIDTH) * LEVEL_MIN_WIDTH + wrapCoord(z, LEVEL_MIN_WIDTH);
int idx = ix * XZSIZE + iz;
hasData[idx] = true;
}

View file

@ -45,9 +45,4 @@ public:
virtual void dataReceived(int x, int z); // 4J added
virtual LevelChunk **getCache() { return cache; } // 4J added
static inline int wrapCoord(int v, int size) {
int r = v % size;
return (r < 0) ? r + size : r;
}
};

View file

@ -138,12 +138,21 @@ private:
// 4J - added for implementation of finite limit to number of item entities, tnt and falling block entities
public:
static const int MAX_HANGING_ENTITIES = 400;
static const int MAX_ITEM_ENTITIES = 200;
static const int MAX_ARROW_ENTITIES = 200;
static const int MAX_EXPERIENCEORB_ENTITIES = 50;
static const int MAX_PRIMED_TNT = 20;
static const int MAX_FALLING_TILE = 20;
static const int MAX_HANGING_ENTITIES = 800;
static const int MAX_ITEM_ENTITIES = 400;
static const int MAX_ARROW_ENTITIES = 400;
static const int MAX_EXPERIENCEORB_ENTITIES = 100;
static const int MAX_PRIMED_TNT = 40;
static const int MAX_FALLING_TILE = 40;
//static const int MAX_HANGING_ENTITIES = 400;
//static const int MAX_ITEM_ENTITIES = 200;
//static const int MAX_ARROW_ENTITIES = 200;
//static const int MAX_EXPERIENCEORB_ENTITIES = 50;
//static const int MAX_PRIMED_TNT = 20;
//static const int MAX_FALLING_TILE = 20;
int m_primedTntCount;
int m_fallingTileCount;

View file

@ -121,8 +121,14 @@ void GrassTile::tick(Level *level, int x, int y, int z, Random *random)
}
}
Material* above = level->getMaterial(x, y + 1, z);
if (level->isSolidBlockingTile(x, y + 1, z) || above->isLiquid()) level->setTileAndUpdate(x, y, z, Tile::dirt_Id);
// using isSolid() here is wrong because non full blocks like iron bars,
// fences, walls are also flagged as solid by their material
int aboveTileId = level->getTile(x, y + 1, z);
Material* above = level->getMaterial(x, y + 1, z);
if (above->isLiquid() || Tile::lightBlock[aboveTileId] > 2)
{
level->setTileAndUpdate(x, y, z, Tile::dirt_Id);
}
}
int GrassTile::getResource(int data, Random *random, int playerBonusLevel)

View file

@ -1335,7 +1335,7 @@ int Level::getBrightness(LightLayer::variety layer, int x, int y, int z)
if( ( ix < 0 ) || ( ix >= chunkSourceXZSize ) ) return 0;
if( ( iz < 0 ) || ( iz >= chunkSourceXZSize ) ) return 0;
int idx = MultiPlayerChunkCache::wrapCoord(ix, LEVEL_MIN_WIDTH) * LEVEL_MIN_WIDTH + MultiPlayerChunkCache::wrapCoord(iz, LEVEL_MIN_WIDTH);
int idx = ix * chunkSourceXZSize + iz;
LevelChunk *c = chunkSourceCache[idx];
if( c == nullptr) return (int)layer;
@ -1384,7 +1384,7 @@ void Level::getNeighbourBrightnesses(int *brightnesses, LightLayer::variety laye
return;
}
int idx = MultiPlayerChunkCache::wrapCoord(ix, LEVEL_MIN_WIDTH) * LEVEL_MIN_WIDTH + MultiPlayerChunkCache::wrapCoord(iz, LEVEL_MIN_WIDTH);
int idx = ix * chunkSourceXZSize + iz;
LevelChunk *c = chunkSourceCache[idx];
// 4J Stu - The java LightLayer was an enum class type with a member "surrounding" which is what we

View file

@ -63,18 +63,18 @@ void MobCategory::setMaxInstancesPerLevel(int max)
m_maxPerLevel = max;
}
int MobCategory::maxAnimalsWithBreeding() { return creature->getMaxInstancesPerLevel() + 20; }
int MobCategory::maxChickensWithBreeding() { return creature_chicken->getMaxInstancesPerLevel() + 8; }
int MobCategory::maxMushroomCowsWithBreeding() { return creature_mushroomcow->getMaxInstancesPerLevel() + 20; }
int MobCategory::maxWolvesWithBreeding() { return creature_wolf->getMaxInstancesPerLevel() + 8; }
int MobCategory::maxAnimalsWithBreeding() { return (creature->getMaxInstancesPerLevel() + 20)*2; }
int MobCategory::maxChickensWithBreeding() { return (creature_chicken->getMaxInstancesPerLevel() + 8)*2; }
int MobCategory::maxMushroomCowsWithBreeding() { return (creature_mushroomcow->getMaxInstancesPerLevel() + 20)*2; }
int MobCategory::maxWolvesWithBreeding() { return (creature_wolf->getMaxInstancesPerLevel() + 8)*2; }
int MobCategory::maxAnimalsWithSpawnEgg() { return maxAnimalsWithBreeding() + 20; }
int MobCategory::maxChickensWithSpawnEgg() { return maxChickensWithBreeding() + 10; }
int MobCategory::maxWolvesWithSpawnEgg() { return maxWolvesWithBreeding() + 10; }
int MobCategory::maxMonstersWithSpawnEgg() { return monster->getMaxInstancesPerLevel() + 20; }
int MobCategory::maxMushroomCowsWithSpawnEgg() { return maxMushroomCowsWithBreeding() + 8; }
int MobCategory::maxSquidsWithSpawnEgg() { return waterCreature->getMaxInstancesPerLevel() + 8; }
int MobCategory::maxAmbientWithSpawnEgg() { return ambient->getMaxInstancesPerLevel() + 8; }
int MobCategory::maxAnimalsWithSpawnEgg() { return (maxAnimalsWithBreeding() + 20)*2; }
int MobCategory::maxChickensWithSpawnEgg() { return (maxChickensWithBreeding() + 10)*2; }
int MobCategory::maxWolvesWithSpawnEgg() { return (maxWolvesWithBreeding() + 10)*2; }
int MobCategory::maxMonstersWithSpawnEgg() { return (monster->getMaxInstancesPerLevel() + 20)*2; }
int MobCategory::maxMushroomCowsWithSpawnEgg() { return (maxMushroomCowsWithBreeding() + 8)*2; }
int MobCategory::maxSquidsWithSpawnEgg() { return (waterCreature->getMaxInstancesPerLevel() + 8)*2; }
int MobCategory::maxAmbientWithSpawnEgg() { return (ambient->getMaxInstancesPerLevel() + 8)*2; }
Material *MobCategory::getSpawnPositionMaterial()
{

View file

@ -7,9 +7,9 @@ class MobCategory
{
public:
// 4J - putting constants for xbox spawning in one place to tidy things up a bit - all numbers are per level
static const int CONSOLE_MONSTERS_HARD_LIMIT = 50; // Max number of enemies (skeleton, zombie, creeper etc) that the mob spawner will produce
static const int CONSOLE_ANIMALS_HARD_LIMIT = 50; // Max number of animals (cows, sheep, pigs) that the mob spawner will produce
static const int CONSOLE_AMBIENT_HARD_LIMIT = 20; // Ambient mobs
static const int CONSOLE_MONSTERS_HARD_LIMIT = 100; // Max number of enemies (skeleton, zombie, creeper etc) that the mob spawner will produce
static const int CONSOLE_ANIMALS_HARD_LIMIT = 100; // Max number of animals (cows, sheep, pigs) that the mob spawner will produce
static const int CONSOLE_AMBIENT_HARD_LIMIT = 40; // Ambient mobs
static const int MAX_XBOX_CHICKENS = 8; // Max number of chickens that the mob spawner will produce
static const int MAX_XBOX_WOLVES = 8; // Max number of wolves that the mob spawner will produce
@ -20,7 +20,7 @@ public:
static const int MAX_CONSOLE_BOSS = 1; // Max number of bosses (enderdragon/wither)
// 4J Villager breeding/egg limits - villagers are not a MobCategory so these stay hardcoded
static const int MAX_VILLAGERS_WITH_BREEDING = 35;
static const int MAX_VILLAGERS_WITH_BREEDING = 70;
static const int MAX_XBOX_VILLAGERS_WITH_SPAWN_EGG = MAX_VILLAGERS_WITH_BREEDING + 15;
// Breeding headroom above the natural spawn cap. Read at call time so these

View file

@ -30,21 +30,12 @@ DWORD PistonBaseTile::tlsIdx = TlsAlloc();
// For us, that means that if we create a piston next to another one, then one of them gets two events to createPush, the second of which fails, leaving the
// piston in a bad (simultaneously extended & not extended) state.
// 4J - ignoreUpdate is a static in java, implementing as TLS here to make thread safe
bool PistonBaseTile::ignoreUpdate()
{
return (TlsGetValue(tlsIdx) != nullptr);
}
void PistonBaseTile::ignoreUpdate(bool set)
{
TlsSetValue(tlsIdx,(LPVOID)(set?1:0));
}
//I removed the code for ignoreUpdate so the above comment no longer applies ^.^
PistonBaseTile::PistonBaseTile(int id, bool isSticky) : Tile(id, Material::piston, isSolidRender() )
{
// 4J - added initialiser
ignoreUpdate(false);
this->isSticky = isSticky;
setSoundType(SOUND_STONE);
setDestroyTime(0.5f);
@ -158,7 +149,7 @@ void PistonBaseTile::setPlacedBy(Level *level, int x, int y, int z, shared_ptr<L
{
int targetData = getNewFacing(level, x, y, z, dynamic_pointer_cast<Player>(by) );
level->setData(x, y, z, targetData, Tile::UPDATE_CLIENTS);
if (!level->isClientSide && !ignoreUpdate())
if (!level->isClientSide)
{
checkIfExtend(level, x, y, z);
}
@ -166,7 +157,7 @@ void PistonBaseTile::setPlacedBy(Level *level, int x, int y, int z, shared_ptr<L
void PistonBaseTile::neighborChanged(Level *level, int x, int y, int z, int type)
{
if (!level->isClientSide && !ignoreUpdate())
if (!level->isClientSide)
{
checkIfExtend(level, x, y, z);
}
@ -174,7 +165,7 @@ void PistonBaseTile::neighborChanged(Level *level, int x, int y, int z, int type
void PistonBaseTile::onPlace(Level *level, int x, int y, int z)
{
if (!level->isClientSide && level->getTileEntity(x, y, z) == nullptr && !ignoreUpdate())
if (!level->isClientSide && level->getTileEntity(x, y, z) == nullptr)
{
checkIfExtend(level, x, y, z);
}
@ -239,7 +230,6 @@ bool PistonBaseTile::getNeighborSignal(Level *level, int x, int y, int z, int fa
bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1, int facing)
{
ignoreUpdate(true);
if (!level->isClientSide)
{
@ -248,12 +238,10 @@ bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1,
if (extend && param1 == TRIGGER_CONTRACT)
{
level->setData(x, y, z, facing | EXTENDED_BIT, UPDATE_CLIENTS);
ignoreUpdate(false);
return false;
}
else if (!extend && param1 == TRIGGER_EXTEND)
{
ignoreUpdate(false);
return false;
}
}
@ -280,7 +268,6 @@ bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1,
}
if (FourKitBridge::FirePistonExtend(level->dimension->id, x, y, z, facing, pushLength))
{
ignoreUpdate(false);
return false;
}
}
@ -304,7 +291,6 @@ bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1,
}
else
{
ignoreUpdate(false);
return false;
}
PIXEndNamedEvent();
@ -315,7 +301,6 @@ bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1,
if (FourKitBridge::FirePistonRetract(level->dimension->id, x, y, z, facing))
{
level->setData(x, y, z, facing | EXTENDED_BIT, UPDATE_CLIENTS);
ignoreUpdate(false);
return false;
}
#endif
@ -380,9 +365,7 @@ bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1,
level->setTileAndData(x, y, z, Tile::piston_extension_Id, blockData, Tile::UPDATE_ALL);
level->setTileEntity(x, y, z, PistonMovingPiece::newMovingPieceEntity(block, blockData, facing, false, false));
ignoreUpdate(false);
level->removeTile(twoX, twoY, twoZ);
ignoreUpdate(true);
if (block == Tile::slimeBlock->id)
{
@ -458,9 +441,7 @@ bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1,
level->setTileAndData(destX, destY, destZ, Tile::piston_extension_Id, adjData, Tile::UPDATE_NONE);
level->setTileEntity(destX, destY, destZ, PistonMovingPiece::newMovingPieceEntity(adjBlock, adjData, facing, false, false));
ignoreUpdate(false);
level->removeTile(adjX, adjY, adjZ);
ignoreUpdate(true);
level->updateNeighborsAt(adjX, adjY, adjZ, adjBlock);
movedBlocks.push_back({ adjX, adjY, adjZ, adjBlock, adjData });
@ -471,25 +452,19 @@ bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1,
else if (!pistonPiece)
{
stopSharingIfServer(level, x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]); // 4J added
ignoreUpdate(false);
level->removeTile(x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]);
ignoreUpdate(true);
}
PIXEndNamedEvent();
}
else
{
stopSharingIfServer(level, x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]); // 4J added
ignoreUpdate(false);
level->removeTile(x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]);
ignoreUpdate(true);
}
level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_TILE_PISTON_IN, 0.5f, level->random->nextFloat() * 0.15f + 0.6f);
}
ignoreUpdate(false);
return true;
}

View file

@ -27,8 +27,7 @@ private:
static DWORD tlsIdx;
// 4J - was just a static but implemented with TLS for our version
static bool ignoreUpdate();
static void ignoreUpdate(bool set);
//code removed so the above comment no longer applies
public:
PistonBaseTile(int id, bool isSticky);
@ -73,4 +72,4 @@ private:
static void stopSharingIfServer(Level *level, int x, int y, int z); // 4J added
bool createPush(Level *level, int sx, int sy, int sz, int facing);
};
};

View file

@ -1,14 +1,7 @@
# neoLegacy v1.0.4b
# neoLegacy v1.0.5b
### Bug Fixes
- Fixed Podzol bottom face displaying incorrect texture (was using side texture instead of dirt)
### Changes
- Cursor icon now changes when hovering over different UI elements
- Added TU31 parity changes which include:
- Creepers can now be ignited with Flint and Steel
- Village gravel roads now have Cobblestone underneath
- Villagers now transform into Witches when struck by lightning
- Fixed crashing, lagging, and lighting issues caused by expanded world generation.
<img width="784" height="410" alt="roadmap" src="https://github.com/user-attachments/assets/134856ae-b151-4003-aa97-7ecf19ccd278" />