Merge branch 'main' into upstream-merge

# Conflicts:
#	.github/workflows/nightly.yml
#	Minecraft.Server/cmake/sources/Common.cmake
This commit is contained in:
George V. 2026-04-13 17:19:50 +03:00
commit edeb0d2230
No known key found for this signature in database
GPG key ID: 1DB61094F2DD4982
20 changed files with 604 additions and 421 deletions

View file

@ -1,6 +1,9 @@
name: Nightly Release name: Nightly Release
on: on:
push:
branches:
- main
workflow_dispatch: workflow_dispatch:
permissions: permissions:
@ -18,185 +21,144 @@ jobs:
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v6
- name: Setup MSVC - name: Setup MSVC
uses: ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@v1
- name: Setup CMake - name: Setup CMake
uses: lukka/get-cmake@latest uses: lukka/get-cmake@latest
- name: Run CMake - name: Run CMake
uses: lukka/run-cmake@v10 uses: lukka/run-cmake@v10
env: env:
VCPKG_ROOT: "" VCPKG_ROOT: ""
with: with:
configurePreset: windows64 configurePreset: windows64
buildPreset: windows64-release buildPreset: windows64-release
buildPresetAdditionalArgs: "['--target', 'Minecraft.Client']" buildPresetAdditionalArgs: "['--target', 'Minecraft.Client']"
- name: Zip Build - name: Zip Build
shell: pwsh shell: pwsh
run: | run: |
$source = "./build/windows64/Minecraft.Client/Release" $source = "./build/windows64/Minecraft.Client/Release"
$zip = "LCE-Revelations-Client-Win64.zip" $zip = "neoLegacyWindows64.zip"
$topLevel = "LCE-Revelations-Client-Win64" $topLevel = "neoLegacyWindows64"
# Collect files, excluding unwanted extensions # Collect files, excluding unwanted extensions
$files = Get-ChildItem -Path $source -Recurse -File | $files = Get-ChildItem -Path $source -Recurse -File |
Where-Object { $_.Extension -notin '.pch', '.zip', '.ipdb', '.iobj' } Where-Object { $_.Extension -notin '.pch', '.zip', '.ipdb', '.iobj' }
Add-Type -AssemblyName System.IO.Compression Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.FileSystem Add-Type -AssemblyName System.IO.Compression.FileSystem
$basePath = (Resolve-Path $source).Path $basePath = (Resolve-Path $source).Path
$fs = [System.IO.File]::Open($zip, [System.IO.FileMode]::Create) $fs = [System.IO.File]::Open($zip, [System.IO.FileMode]::Create)
try {
$archive = New-Object System.IO.Compression.ZipArchive($fs, [System.IO.Compression.ZipArchiveMode]::Create)
try { try {
# Add directories $archive = New-Object System.IO.Compression.ZipArchive($fs, [System.IO.Compression.ZipArchiveMode]::Create)
Get-ChildItem -Path $basePath -Recurse -Directory | ForEach-Object { try {
$rel = $_.FullName.Substring($basePath.Length).TrimStart('\', '/') # Add directories
$archive.CreateEntry("$topLevel/$($rel -replace '\\','/')/") | Out-Null Get-ChildItem -Path $basePath -Recurse -Directory | ForEach-Object {
} $rel = $_.FullName.Substring($basePath.Length).TrimStart('\', '/')
# Add files $archive.CreateEntry("$topLevel/$($rel -replace '\\','/')/") | Out-Null
foreach ($file in $files) { }
$rel = $file.FullName.Substring($basePath.Length).TrimStart('\', '/') # Add files
$entryName = "$topLevel/$($rel -replace '\\','/')" foreach ($file in $files) {
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile( $rel = $file.FullName.Substring($basePath.Length).TrimStart('\', '/')
$archive, $file.FullName, $entryName, $entryName = "$topLevel/$($rel -replace '\\','/')"
[System.IO.Compression.CompressionLevel]::Optimal [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile(
) | Out-Null $archive, $file.FullName, $entryName,
} [System.IO.Compression.CompressionLevel]::Optimal
} finally { $archive.Dispose() } ) | Out-Null
} finally { $fs.Dispose() } }
} finally { $archive.Dispose() }
} finally { $fs.Dispose() }
Write-Host "Created $zip"
Write-Host "Created $zip" - name: Stage artifacts
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path staging
Copy-Item neoLegacyWindows64.zip staging/
Copy-Item ./build/windows64/Minecraft.Client/Release/Minecraft.Client.exe staging/
- name: Stage artifacts - name: Upload artifacts
shell: pwsh uses: actions/upload-artifact@v6
run: | with:
New-Item -ItemType Directory -Force -Path staging name: client-build
Copy-Item LCE-Revelations-Client-Win64.zip staging/ path: staging/*
Copy-Item ./build/windows64/Minecraft.Client/Release/Minecraft.Client.exe staging/
- name: Upload artifacts
uses: actions/upload-artifact@v6
with:
name: client-build
path: staging/*
build-server: build-server:
name: Build Server name: Build Server
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v6
- name: Setup MSVC - name: Setup MSVC
uses: ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@v1
- name: Setup CMake - name: Setup CMake
uses: lukka/get-cmake@latest uses: lukka/get-cmake@latest
- name: Setup .NET - name: Run CMake
uses: actions/setup-dotnet@v4 uses: lukka/run-cmake@v10
with: env:
global-json-file: global.json VCPKG_ROOT: ""
with:
configurePreset: windows64
buildPreset: windows64-release
buildPresetAdditionalArgs: "['--target', 'Minecraft.Server']"
- name: Run CMake - name: Zip Build
uses: lukka/run-cmake@v10 shell: pwsh
env: run: |
VCPKG_ROOT: "" $source = "./build/windows64/Minecraft.Server/Release"
with: $zip = "neoLegacyServerWindows64.zip"
configurePreset: windows64 $topLevel = "neoLegacyServerWindows64"
buildPreset: windows64-release
buildPresetAdditionalArgs: "['--target', 'Minecraft.Server', '--target', 'Minecraft.Server.FourKit']" $files = Get-ChildItem -Path $source -Recurse -File |
Where-Object { $_.Extension -notin '.pch', '.zip', '.ipdb', '.iobj' }
- name: Zip Build (vanilla)
shell: pwsh Add-Type -AssemblyName System.IO.Compression
run: | Add-Type -AssemblyName System.IO.Compression.FileSystem
$source = "./build/windows64/Minecraft.Server/Release"
$zip = "LCE-Revelations-Server-Win64.zip" $basePath = (Resolve-Path $source).Path
$topLevel = "LCE-Revelations-Server-Win64" $fs = [System.IO.File]::Open($zip, [System.IO.FileMode]::Create)
$files = Get-ChildItem -Path $source -Recurse -File |
Where-Object { $_.Extension -notin '.pch', '.zip', '.ipdb', '.iobj' }
Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.FileSystem
$basePath = (Resolve-Path $source).Path
$fs = [System.IO.File]::Open($zip, [System.IO.FileMode]::Create)
try {
$archive = New-Object System.IO.Compression.ZipArchive($fs, [System.IO.Compression.ZipArchiveMode]::Create)
try { try {
Get-ChildItem -Path $basePath -Recurse -Directory | ForEach-Object { $archive = New-Object System.IO.Compression.ZipArchive($fs, [System.IO.Compression.ZipArchiveMode]::Create)
$rel = $_.FullName.Substring($basePath.Length).TrimStart('\', '/') try {
$archive.CreateEntry("$topLevel/$($rel -replace '\\','/')/") | Out-Null Get-ChildItem -Path $basePath -Recurse -Directory | ForEach-Object {
} $rel = $_.FullName.Substring($basePath.Length).TrimStart('\', '/')
foreach ($file in $files) { $archive.CreateEntry("$topLevel/$($rel -replace '\\','/')/") | Out-Null
$rel = $file.FullName.Substring($basePath.Length).TrimStart('\', '/') }
$entryName = "$topLevel/$($rel -replace '\\','/')" foreach ($file in $files) {
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile( $rel = $file.FullName.Substring($basePath.Length).TrimStart('\', '/')
$archive, $file.FullName, $entryName, $entryName = "$topLevel/$($rel -replace '\\','/')"
[System.IO.Compression.CompressionLevel]::Optimal [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile(
) | Out-Null $archive, $file.FullName, $entryName,
} [System.IO.Compression.CompressionLevel]::Optimal
} finally { $archive.Dispose() } ) | Out-Null
} finally { $fs.Dispose() } }
} finally { $archive.Dispose() }
} finally { $fs.Dispose() }
Write-Host "Created $zip"
Write-Host "Created $zip" - name: Stage artifacts
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path staging
Copy-Item neoLegacyServerWindows64.zip staging/
- name: Zip Build (FourKit) - name: Upload artifacts
shell: pwsh uses: actions/upload-artifact@v6
run: | with:
$source = "./build/windows64/Minecraft.Server.FourKit/Release" name: server-build
$zip = "LCE-Revelations-Server-Win64-FourKit.zip" path: staging/*
$topLevel = "LCE-Revelations-Server-Win64-FourKit"
$files = Get-ChildItem -Path $source -Recurse -File |
Where-Object { $_.Extension -notin '.pch', '.zip', '.ipdb', '.iobj' }
Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.FileSystem
$basePath = (Resolve-Path $source).Path
$fs = [System.IO.File]::Open($zip, [System.IO.FileMode]::Create)
try {
$archive = New-Object System.IO.Compression.ZipArchive($fs, [System.IO.Compression.ZipArchiveMode]::Create)
try {
Get-ChildItem -Path $basePath -Recurse -Directory | ForEach-Object {
$rel = $_.FullName.Substring($basePath.Length).TrimStart('\', '/')
$archive.CreateEntry("$topLevel/$($rel -replace '\\','/')/") | Out-Null
}
foreach ($file in $files) {
$rel = $file.FullName.Substring($basePath.Length).TrimStart('\', '/')
$entryName = "$topLevel/$($rel -replace '\\','/')"
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile(
$archive, $file.FullName, $entryName,
[System.IO.Compression.CompressionLevel]::Optimal
) | Out-Null
}
} finally { $archive.Dispose() }
} finally { $fs.Dispose() }
Write-Host "Created $zip"
- name: Stage artifacts
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path staging
Copy-Item LCE-Revelations-Server-Win64.zip staging/
Copy-Item LCE-Revelations-Server-Win64-FourKit.zip staging/
- name: Upload artifacts
uses: actions/upload-artifact@v6
with:
name: server-build
path: staging/*
release-server: release-server:
name: Release Server name: Release Server
@ -204,63 +166,52 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v6
- name: Download server artifacts - name: Download server artifacts
uses: actions/download-artifact@v7 uses: actions/download-artifact@v7
with: with:
name: server-build name: server-build
path: artifacts path: artifacts
- name: Attest artifacts - name: Attest artifacts
uses: actions/attest-build-provenance@v2 uses: actions/attest-build-provenance@v2
with: with:
subject-path: | subject-path: |
artifacts/LCE-Revelations-Server-Win64.zip artifacts/neoLegacyServerWindows64.zip
artifacts/LCE-Revelations-Server-Win64-FourKit.zip
- name: Get short SHA - name: Get short SHA
id: sha id: sha
run: echo "short=$(echo '${{ github.sha }}' | cut -c1-7)" >> "$GITHUB_OUTPUT" run: echo "short=$(echo '${{ github.sha }}' | cut -c1-7)" >> "$GITHUB_OUTPUT"
- name: Delete old release - name: Delete old release
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release delete Nightly-Dedicated-Server --yes || true run: gh release delete Nightly-Dedicated-Server --yes || true
- name: Delete old tag - name: Delete old tag
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh api repos/${{ github.repository }}/git/refs/tags/Nightly-Dedicated-Server --method DELETE || true run: gh api repos/${{ github.repository }}/git/refs/tags/Nightly-Dedicated-Server --method DELETE || true
- name: Import GPG key - name: Create tag
uses: crazy-max/ghaction-import-gpg@v6 run: |
with: git config user.name "github-actions[bot]"
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} git config user.email "github-actions[bot]@users.noreply.github.com"
passphrase: ${{ secrets.GPG_PASSPHRASE }} git tag -f Nightly-Dedicated-Server -m "Nightly server release ${{ steps.sha.outputs.short }}"
git_user_signingkey: true git push origin Nightly-Dedicated-Server --force
git_tag_gpgsign: true
- name: Create signed tag - name: Create release
run: | env:
git tag -s -f Nightly-Dedicated-Server -m "Nightly server release ${{ steps.sha.outputs.short }}" GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
git push origin Nightly-Dedicated-Server --force run: |
gh release create Nightly-Dedicated-Server artifacts/* \
- name: Create release --title "Server: ${{ steps.sha.outputs.short }}" \
env: --notes "Dedicated Server runtime for Windows64.
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: | Download \`neoLegacyServerWindows64.zip\` and extract it to a folder where you'd like to keep the server runtime." \
gh release create Nightly-Dedicated-Server artifacts/* \ --latest=false
--title "Server: ${{ steps.sha.outputs.short }}" \
--notes "Dedicated Server runtime for Windows64.
Two flavours are attached:
- \`LCE-Revelations-Server-Win64.zip\`: vanilla server, no plugin support, smallest download.
- \`LCE-Revelations-Server-Win64-FourKit.zip\`: server with the FourKit plugin host, bundled .NET 10 runtime, and an empty \`plugins/\` folder ready for plugin authors to drop DLLs into.
Pick the flavour you want and extract it to a folder where you'd like to keep the server runtime." \
--latest=false
release-client: release-client:
name: Release Client name: Release Client
@ -268,97 +219,97 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v6
- name: Download client artifacts - name: Download client artifacts
uses: actions/download-artifact@v7 uses: actions/download-artifact@v7
with: with:
name: client-build name: client-build
path: artifacts path: artifacts
- name: Attest artifacts - name: Attest artifacts
uses: actions/attest-build-provenance@v2 uses: actions/attest-build-provenance@v2
with: with:
subject-path: | subject-path: |
artifacts/LCE-Revelations-Client-Win64.zip artifacts/neoLegacyWindows64.zip
artifacts/Minecraft.Client.exe artifacts/Minecraft.Client.exe
- name: Get short SHA - name: Get short SHA
id: sha id: sha
run: echo "short=$(echo '${{ github.sha }}' | cut -c1-7)" >> "$GITHUB_OUTPUT" run: echo "short=$(echo '${{ github.sha }}' | cut -c1-7)" >> "$GITHUB_OUTPUT"
- name: Delete old release - name: Delete old release
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release delete Nightly --yes || true run: gh release delete Nightly --yes || true
- name: Delete old tag - name: Delete old tag
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh api repos/${{ github.repository }}/git/refs/tags/Nightly --method DELETE || true run: gh api repos/${{ github.repository }}/git/refs/tags/Nightly --method DELETE || true
- name: Import GPG key - name: Create signed tag
uses: crazy-max/ghaction-import-gpg@v6 run: |
with: git config user.name "github-actions[bot]"
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} git config user.email "github-actions[bot]@users.noreply.github.com"
passphrase: ${{ secrets.GPG_PASSPHRASE }} git tag -f Nightly -m "Nightly release ${{ steps.sha.outputs.short }}"
git_user_signingkey: true git push origin Nightly --force
git_tag_gpgsign: true
- name: Create signed tag - name: Write release notes
run: | run: |
git tag -s -f Nightly -m "Nightly release ${{ steps.sha.outputs.short }}" cat > notes.md <<'NOTES'
git push origin Nightly --force # Instructions:
**Newcomers:**
- If this is your first time, download `neoLegacyWindows64.zip` and extract it wherever you would like to keep it.
- I would recommend to set your username prior to launch (create a file called `username.txt`, put your desired username into the file, and save).
- To play, simply run `Minecraft.Client.exe`.
**For those that wish to update their existing installation with the latest build:**
- Download `Minecraft.Client.exe` and `Minecraft.Client.pdb` and copy them over to your existing neoLegacyWindows64 build (overwrite your old version of Minecraft.Client.exe and Minecraft.Client.pdb).
**Steam Deck & Linux:**
- Y'all know the drill. Download the `neoLegacyWindows64.zip`, extract it, add the `Minecraft.Client.exe` as a "Non-Steam Game" within the Steam library, turn on compatibility mode with Proton Experimental, and then run it!
# Multiplayer instructions:
LAN games are natively supported, and any LAN games will appear automatically on the right. However, if you'd like to play with your friends online (and if you don't want to require them to setup a vpn, and/or if you don't want to port forward), I would recommend the following setup. Please keep in mind, you do NOT need to do this to enjoy the game. This is just how I have it setup for me so my friends can join without any hassle:
Prerequisites:
- Premium playit.gg account, costs about $3 USD per month. This is for setting up the tunnel.
- playit.gg agent installed on host PC.
How-to:
- Ensure your playit.gg agent is connected to your playit.gg account
- On the playit.gg website, setup a new tunnel (choose TCP). Ensure the configurable settings are set to the below values, assuming your agent is installed on the same computer as your online neoLegacyMinecraft game is hosted from.
- Configurable settings:
- Local IP: `127.0.0.1`
- Local Port: `25565`
- Proxy Protocol: `None`
- After creating your tunnel, navigate to the "Tunnels" main page. You'll see the IP address and port for your tunnel. This is what your friends will input when adding your server in order to join your online game!
# Why this fork exists:
Changes/additions that stray from the upstream repo (`smartcmd/MinecraftConsoles`:
- See: https://github.com/itsRevela/MinecraftConsoles?tab=readme-ov-file#latest
- I can tweak this fork while staying compatible with the upstream repo without needing to wait on my pull requests to get accepted upstream (while keeping this fork updated with the latest and greatest from upstream)
NOTES
- name: Write release notes - name: Create release
run: | env:
cat > notes.md <<'NOTES' GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Instructions: run: |
**Newcomers:** gh release create Nightly artifacts/* \
- If this is your first time, download `LCE-Revelations-Client-Win64.zip` and extract it wherever you would like to keep it. --title "Client: ${{ steps.sha.outputs.short }}" \
- I would recommend to set your username prior to launch (create a file called `username.txt`, put your desired username into the file, and save). --notes-file notes.md
- To play, simply run `Minecraft.Client.exe`.
**For those that wish to update their existing installation with the latest build:**
- Download `Minecraft.Client.exe` and `Minecraft.Client.pdb` and copy them over to your existing LCE-Revelations-Client-Win64 build (overwrite your old version of Minecraft.Client.exe and Minecraft.Client.pdb).
**Steam Deck & Linux:**
- Y'all know the drill. Download the `LCE-Revelations-Client-Win64.zip`, extract it, add the `Minecraft.Client.exe` as a "Non-Steam Game" within the Steam library, turn on compatibility mode with Proton Experimental, and then run it!
# Multiplayer instructions:
LAN games are natively supported, and any LAN games will appear automatically on the right. However, if you'd like to play with your friends online (and if you don't want to require them to setup a vpn, and/or if you don't want to port forward), I would recommend the following setup. Please keep in mind, you do NOT need to do this to enjoy the game. This is just how I have it setup for me so my friends can join without any hassle:
Prerequisites:
- Premium playit.gg account, costs about $3 USD per month. This is for setting up the tunnel.
- playit.gg agent installed on host PC.
How-to:
- Ensure your playit.gg agent is connected to your playit.gg account
- On the playit.gg website, setup a new tunnel (choose TCP). Ensure the configurable settings are set to the below values, assuming your agent is installed on the same computer as your online LCE Revelations game is hosted from.
- Configurable settings:
- Local IP: `127.0.0.1`
- Local Port: `25565`
- Proxy Protocol: `None`
- After creating your tunnel, navigate to the "Tunnels" main page. You'll see the IP address and port for your tunnel. This is what your friends will input when adding your server in order to join your online game!
NOTES
- name: Create release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release create Nightly artifacts/* \
--title "Client: ${{ steps.sha.outputs.short }}" \
--notes-file notes.md
cleanup: cleanup:
needs: [release-client, release-server] needs: [release-client, release-server]
if: always() if: always()
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Cleanup artifacts - name: Cleanup artifacts
uses: geekyeggo/delete-artifact@v5 uses: geekyeggo/delete-artifact@v5
with: with:
name: | name: |
client-build client-build
server-build server-build

View file

@ -770,14 +770,14 @@ int SoundEngine::GetRandomishTrack(int iStart,int iEnd)
if(m_bHeardTrackA[i]==false) if(m_bHeardTrackA[i]==false)
{ {
bAllTracksHeard=false; bAllTracksHeard=false;
app.DebugPrintf("Not heard all tracks yet\n"); //app.DebugPrintf("Not heard all tracks yet\n");
break; break;
} }
} }
if(bAllTracksHeard) if(bAllTracksHeard)
{ {
app.DebugPrintf("Heard all tracks - resetting the tracking array\n"); //app.DebugPrintf("Heard all tracks - resetting the tracking array\n");
for(size_t i=iStart;i<=iEnd;i++) for(size_t i=iStart;i<=iEnd;i++)
{ {
@ -793,17 +793,17 @@ int SoundEngine::GetRandomishTrack(int iStart,int iEnd)
if(m_bHeardTrackA[iVal]==false) if(m_bHeardTrackA[iVal]==false)
{ {
// not heard this // not heard this
app.DebugPrintf("(%d) Not heard track %d yet, so playing it now\n",i,iVal); //app.DebugPrintf("(%d) Not heard track %d yet, so playing it now\n",i,iVal);
m_bHeardTrackA[iVal]=true; m_bHeardTrackA[iVal]=true;
break; break;
} }
else else
{ {
app.DebugPrintf("(%d) Skipping track %d already heard it recently\n",i,iVal); //app.DebugPrintf("(%d) Skipping track %d already heard it recently\n",i,iVal);
} }
} }
app.DebugPrintf("Select track %d\n",iVal); //app.DebugPrintf("Select track %d\n",iVal);
return iVal; return iVal;
} }
///////////////////////////////////////////// /////////////////////////////////////////////

View file

@ -287,6 +287,9 @@ void UIScene_BookAndQuillMenu::handleInput(int iPad, int key, bool repeat, bool
navigateBack(); navigateBack();
} }
} }
else {
navigateBack();
}
} }
else else
{ {
@ -471,10 +474,13 @@ void UIScene_BookAndQuillMenu::handlePress(F64 controlId, F64 childId)
#endif #endif
break; break;
case eControl_Book: case eControl_Book:
if (signedBook == true) {
break;
}
if (g_KBMInput.IsKBMActive()) { if (g_KBMInput.IsKBMActive()) {
//This does not work when using controller. Why? God knows... //This does not work when using controller. Why? God knows...
this->SetFocusToElement(eControl_Type); this->SetFocusToElement(eControl_Type);
m_typeText.beginDirectEdit(1023, false, L""); m_typeText.beginDirectEdit(1023, signing, data->player->getDisplayName());
} }
else { else {
if (signedBook == true) { if (signedBook == true) {

View file

@ -18,10 +18,6 @@ UIScene_EnchantingMenu::UIScene_EnchantingMenu(int iPad, void *_initData, UILaye
m_enchantButton[1].init(1); m_enchantButton[1].init(1);
m_enchantButton[2].init(2); m_enchantButton[2].init(2);
EnchantingScreenInput *initData = static_cast<EnchantingScreenInput *>(_initData); EnchantingScreenInput *initData = static_cast<EnchantingScreenInput *>(_initData);
m_labelEnchant.init( initData->name.empty() ? app.GetString(IDS_ENCHANT) : initData->name ); m_labelEnchant.init( initData->name.empty() ? app.GetString(IDS_ENCHANT) : initData->name );

View file

@ -21,6 +21,7 @@
#include "LavaParticle.h" #include "LavaParticle.h"
#include "FootstepParticle.h" #include "FootstepParticle.h"
#include "SplashParticle.h" #include "SplashParticle.h"
#include "WaterWakeParticle.h"
#include "SmokeParticle.h" #include "SmokeParticle.h"
#include "RedDustParticle.h" #include "RedDustParticle.h"
#include "BreakingItemParticle.h" #include "BreakingItemParticle.h"
@ -2825,7 +2826,7 @@ shared_ptr<Particle> LevelRenderer::addParticleInternal(ePARTICLE_TYPE eParticle
// 4J - the java code doesn't distance cull these two particle types, we need to implement this behaviour differently as our distance check is // 4J - the java code doesn't distance cull these two particle types, we need to implement this behaviour differently as our distance check is
// mixed up with other things // mixed up with other things
bool distCull = true; bool distCull = true;
if ( (eParticleType == eParticleType_hugeexplosion) || (eParticleType == eParticleType_largeexplode) || (eParticleType == eParticleType_dragonbreath) ) if ( (eParticleType == eParticleType_hugeexplosion) || (eParticleType == eParticleType_largeexplode) || (eParticleType == eParticleType_dragonbreath) || (eParticleType == eParticleType_wake))
{ {
distCull = false; distCull = false;
} }
@ -2998,6 +2999,9 @@ shared_ptr<Particle> LevelRenderer::addParticleInternal(ePARTICLE_TYPE eParticle
case eParticleType_splash: case eParticleType_splash:
particle = std::make_shared<SplashParticle>(lev, x, y, z, xa, ya, za); particle = std::make_shared<SplashParticle>(lev, x, y, z, xa, ya, za);
break; break;
case eParticleType_wake:
particle = std::make_shared<WaterWakeParticle>(lev, x, y, z, xa, ya, za);
break;
case eParticleType_largesmoke: case eParticleType_largesmoke:
particle = std::make_shared<SmokeParticle>(lev, x, y, z, xa, ya, za, 2.5f); particle = std::make_shared<SmokeParticle>(lev, x, y, z, xa, ya, za, 2.5f);
break; break;

View file

@ -12,6 +12,7 @@
#include "../Minecraft.World/net.minecraft.world.level.h" #include "../Minecraft.World/net.minecraft.world.level.h"
#include "../Minecraft.World/StringHelpers.h" #include "../Minecraft.World/StringHelpers.h"
#include "../Minecraft.World/net.minecraft.world.level.dimension.h" #include "../Minecraft.World/net.minecraft.world.level.dimension.h"
#include "../Minecraft.World/InputOutputStream.h"
ResourceLocation ParticleEngine::PARTICLES_LOCATION = ResourceLocation(TN_PARTICLES); ResourceLocation ParticleEngine::PARTICLES_LOCATION = ResourceLocation(TN_PARTICLES);
@ -49,7 +50,6 @@ void ParticleEngine::add(shared_ptr<Particle> p)
break; break;
} }
int list = p->getAlpha() != 1.0f ? TRANSLUCENT_LIST : OPAQUE_LIST; // 4J - Brought forward from Java 1.8 int list = p->getAlpha() != 1.0f ? TRANSLUCENT_LIST : OPAQUE_LIST; // 4J - Brought forward from Java 1.8
if( particles[l][t][list].size() >= maxParticles) if( particles[l][t][list].size() >= maxParticles)
{ {
particles[l][t][list].pop_front(); particles[l][t][list].pop_front();

View file

@ -0,0 +1,47 @@
#include "stdafx.h"
#include "WaterWakeParticle.h"
#include "../Minecraft.World/Random.h"
#include "../Minecraft.World/Mth.h"
#include "../Minecraft.World/JavaMath.h"
#include "../Minecraft.World/net.minecraft.world.level.h"
#include "../Minecraft.World/net.minecraft.world.level.material.h"
#include "../Minecraft.World/net.minecraft.world.level.tile.h"
WaterWakeParticle::WaterWakeParticle(Level *level, double x, double y, double z, double xa, double ya, double za) : Particle(level, x, y, z, 0, 0, 0)
{
xd *= 0.30000001192092896;
yd = random->nextDouble() * 0.2 + 0.1;
zd *= 0.30000001192092896;
rCol = 1.0f;
gCol = 1.0f;
bCol = 1.0f;
setMiscTex(19);
setSize(0.01f, 0.01f);
lifetime = (int)(8.0 / (random->nextDouble() * 0.8 + 0.2));
gravity = 0.0F;
xd = xa;
yd = ya;
zd = za;
}
void WaterWakeParticle::tick()
{
xo = x;
yo = y;
zo = z;
move(xd, yd, zd);
xd *= 0.9800000190734863;
yd *= 0.9800000190734863;
zd *= 0.9800000190734863;
int i = 60 - lifetime;
float f = (float)i * 0.001f;
this->setSize(f, f);
this->setMiscTex(19 + i % 4);
if (lifetime-- <= 0)
{
this->remove();
}
}

View file

@ -0,0 +1,10 @@
#pragma once
#include "Particle.h"
class WaterWakeParticle : public Particle
{
public:
virtual eINSTANCEOF GetType() { return eType_WAKEPARTICLE; }
WaterWakeParticle(Level *level, double x, double y, double z, double xa, double ya, double za);
virtual void tick();
};

View file

@ -717,6 +717,8 @@ set(_MINECRAFT_CLIENT_COMMON_NET_MINECRAFT_CLIENT_PARTICLE
"${CMAKE_CURRENT_SOURCE_DIR}/SpellParticle.h" "${CMAKE_CURRENT_SOURCE_DIR}/SpellParticle.h"
"${CMAKE_CURRENT_SOURCE_DIR}/SplashParticle.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/SplashParticle.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/SplashParticle.h" "${CMAKE_CURRENT_SOURCE_DIR}/SplashParticle.h"
"${CMAKE_CURRENT_SOURCE_DIR}/WaterWakeParticle.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/WaterWakeParticle.h"
"${CMAKE_CURRENT_SOURCE_DIR}/SuspendedParticle.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/SuspendedParticle.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/SuspendedParticle.h" "${CMAKE_CURRENT_SOURCE_DIR}/SuspendedParticle.h"
"${CMAKE_CURRENT_SOURCE_DIR}/SuspendedTownParticle.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/SuspendedTownParticle.cpp"

View file

@ -23,6 +23,7 @@ set(_MINECRAFT_SERVER_COMMON_ROOT
"${_MS_SRC}/../Minecraft.Client/BossMobGuiInfo.cpp" "${_MS_SRC}/../Minecraft.Client/BossMobGuiInfo.cpp"
"${_MS_SRC}/../Minecraft.Client/BreakingItemParticle.cpp" "${_MS_SRC}/../Minecraft.Client/BreakingItemParticle.cpp"
"${_MS_SRC}/../Minecraft.Client/BubbleParticle.cpp" "${_MS_SRC}/../Minecraft.Client/BubbleParticle.cpp"
"${_MS_SRC}/../Minecraft.Client/WaterWakeParticle.cpp"
"${_MS_SRC}/../Minecraft.Client/BufferedImage.cpp" "${_MS_SRC}/../Minecraft.Client/BufferedImage.cpp"
"${_MS_SRC}/../Minecraft.Client/Button.cpp" "${_MS_SRC}/../Minecraft.Client/Button.cpp"
"${_MS_SRC}/../Minecraft.Client/Camera.cpp" "${_MS_SRC}/../Minecraft.Client/Camera.cpp"

View file

@ -292,6 +292,9 @@ enum eINSTANCEOF
eType_FIREWORKSSPARKPARTICLE, eType_FIREWORKSSPARKPARTICLE,
eType_FIREWORKSOVERLAYPARTICLE, eType_FIREWORKSOVERLAYPARTICLE,
//TU 31
eType_WAKEPARTICLE,
// === Tile Entities === // // === Tile Entities === //
eTYPE_TILEENTITY = BIT_TILE_ENTITY, eTYPE_TILEENTITY = BIT_TILE_ENTITY,
@ -503,6 +506,7 @@ public:
classes->push_back( SUBCLASS(eType_SMOKEPARTICLE)->addParent(eTYPE_ENTITY) ); classes->push_back( SUBCLASS(eType_SMOKEPARTICLE)->addParent(eTYPE_ENTITY) );
classes->push_back( SUBCLASS(eType_SNOWSHOVELPARTICLE)->addParent(eTYPE_ENTITY) ); classes->push_back( SUBCLASS(eType_SNOWSHOVELPARTICLE)->addParent(eTYPE_ENTITY) );
classes->push_back( SUBCLASS(eType_SPLASHPARTICLE)->addParent(eTYPE_ENTITY) ); classes->push_back( SUBCLASS(eType_SPLASHPARTICLE)->addParent(eTYPE_ENTITY) );
classes->push_back( SUBCLASS(eType_WAKEPARTICLE)->addParent(eTYPE_ENTITY) );
classes->push_back( SUBCLASS(eType_TAKEANIMATIONPARTICLE)->addParent(eTYPE_ENTITY) ); classes->push_back( SUBCLASS(eType_TAKEANIMATIONPARTICLE)->addParent(eTYPE_ENTITY) );
classes->push_back( SUBCLASS(eType_TERRAINPARTICLE)->addParent(eTYPE_ENTITY) ); classes->push_back( SUBCLASS(eType_TERRAINPARTICLE)->addParent(eTYPE_ENTITY) );
classes->push_back( SUBCLASS(eType_WATERDROPPARTICLE)->addParent(eTYPE_ENTITY) ); classes->push_back( SUBCLASS(eType_WATERDROPPARTICLE)->addParent(eTYPE_ENTITY) );

View file

@ -106,7 +106,6 @@ void EnchantmentMenu::slotsChanged(int a) // 4J used to take a shared_ptr<Contai
} }
m_costsChanged = true; m_costsChanged = true;
alreadyRan = false; alreadyRan = false;
} }
else else
{ {

View file

@ -2,7 +2,7 @@
// 4J Stu Added // 4J Stu Added
// In EnchantmentMenu.java they create an anoymous class while creating some slot. I have moved the content // In EnchantmentMenu.java they create an anoymous class while creating some slot. I have moved the content
// of that anonymous class to here // of that anonymous class to here
#include "Item.h"
#include "Slot.h" #include "Slot.h"
class Container; class Container;
@ -10,7 +10,16 @@ class Container;
class EnchantmentSlot : public Slot class EnchantmentSlot : public Slot
{ {
public: public:
EnchantmentSlot(shared_ptr<Container> container, int id, int x, int y) : Slot(container,id, x, y) {} int slotNum;
virtual bool mayPlace(shared_ptr<ItemInstance> item) {return true;} //stack->getItem()->id == 351 && stack->getItem()->getMaterial() == 11
EnchantmentSlot(shared_ptr<Container> container, int id, int x, int y) : Slot(container, id, x, y) { slotNum = id; }
virtual bool mayPlace(shared_ptr<ItemInstance> item) {
if (slotNum == 0 || (item->id == 351 && Item::items[item->id]->getMaterial() == 11)) {
return true;
}
else {
return false;
}
}
virtual bool mayCombine(shared_ptr<ItemInstance> item) {return false;} // 4J Added virtual bool mayCombine(shared_ptr<ItemInstance> item) {return false;} // 4J Added
}; };

View file

@ -15,9 +15,18 @@
#include "../Minecraft.World/EnchantmentHelper.h" #include "../Minecraft.World/EnchantmentHelper.h"
#include "../Minecraft.World/Enchantment.h" #include "../Minecraft.World/Enchantment.h"
#include "../Minecraft.World/ItemInstance.h" #include "../Minecraft.World/ItemInstance.h"
#include "SynchedEntityData.h"
#include <algorithm> #include <algorithm>
// 4J - added common ctor code.
const int FishingHook::DATA_FLAG_RENDER_CLIENT_FX = 20;
const int FishingHook::DATA_FISH_APPROACH_ANGLE = 21;
const int FishingHook::DATA_WAKE_TIMER = 22;
const int FishingHook::DATA_NIBBLE_TIMER = 23;
const int FishingHook::DATA_FLAG_NIBBLE = 24;
// 4J - added common ctor code.
void FishingHook::_init() void FishingHook::_init()
{ {
// 4J Stu - This function call had to be moved here from the Entity ctor to ensure that // 4J Stu - This function call had to be moved here from the Entity ctor to ensure that
@ -31,14 +40,16 @@ void FishingHook::_init()
inGround = false; inGround = false;
shakeTime = 0; shakeTime = 0;
flightTime = 0; flightTime = 0;
nibble = 0;
// TU 31: Fishing rod now has a random nibble timer between 5 and 30 seconds, instead of a 1/500 chance every tick (plus modifiers). Source: https://minecraft.wiki/w/Fishing // TU 31: Fishing rod now has a random nibble timer between 5 and 30 seconds, instead of a 1/500 chance every tick (plus modifiers). Source: https://minecraft.wiki/w/Fishing
nibbleTimer = random->nextInt(801) + 100;
lureTime = 0;
hookedIn = nullptr; hookedIn = nullptr;
previousItem = nullptr; previousItem = nullptr;
fishApproachAngle = 0.0f;
wakeTimer = 0;
nibble = 0;
nibbleTimer = 0;
lureLevel = 0; lureLevel = 0;
luckLevel = 0; luckLevel = 0;
@ -113,6 +124,11 @@ void FishingHook::getEnchantLevels() {
void FishingHook::defineSynchedData() void FishingHook::defineSynchedData()
{ {
entityData->define(FishingHook::DATA_FLAG_RENDER_CLIENT_FX, (short)0);
entityData->define(FishingHook::DATA_FISH_APPROACH_ANGLE, 0.0f);
entityData->define(FishingHook::DATA_WAKE_TIMER, (short)0);
entityData->define(FishingHook::DATA_NIBBLE_TIMER, (short)0);
entityData->define(FishingHook::DATA_FLAG_NIBBLE, (short)0);
} }
bool FishingHook::shouldRenderAtSqrDistance(double distance) bool FishingHook::shouldRenderAtSqrDistance(double distance)
@ -336,7 +352,7 @@ void FishingHook::tick()
inertia = 0.5f; inertia = 0.5f;
} }
int steps = 5; int steps = 10;
double waterPercentage = 0; double waterPercentage = 0;
for (int i = 0; i < steps; i++) for (int i = 0; i < steps; i++)
{ {
@ -351,72 +367,19 @@ void FishingHook::tick()
if (waterPercentage > 0) if (waterPercentage > 0)
{ {
if (nibble > 0) if (!level->isClientSide) {
{ catchingFish();
nibble--;
}
else
{
if (!(level->canSeeSky(Mth::floor(x), Mth::floor(y) + 1, Mth::floor(z)))) {
// Don't minus the nibbleTimer if the hook obstructed from the sky.
}
// TU 31: Raining affects the nibble timer by random chance rather than being a fixed rate. Source: https://minecraft.wiki/w/Fishing
else if (!(level->isRainingAt( Mth::floor(x), Mth::floor(y) + 1, Mth::floor(z)))) {
nibbleTimer--;
}
else {
if (random->nextInt(4) == 0) {
nibbleTimer -= 2;
}
else {
nibbleTimer--;
}
}
// Only calculate the effect of lure if it hasn't been calculated already.
if (lureTime == 0 && owner != nullptr)
{
lureTime = this->lureLevel * 100;
nibbleTimer -= lureTime;
// if the lure effect causes the nibble timer to go below 0, reset the timer and lure time to recalculate next tick. Source: https://minecraft.wiki/w/Fishing
if (nibbleTimer < 0)
{
nibbleTimer = random->nextInt(801) + 100;
lureTime = 0;
}
}
// Checks if the nibble timer has ran out. Edge case for if it's raining and the nibble timer goes
// below 0 due to the random chance of the rain decreasing the timer by 2 instead of 1.
if (nibbleTimer == 0 || nibbleTimer == -1)
{
nibble = random->nextInt(11) + 30;
nibbleTimer = random->nextInt(801) + 100;
lureTime = 0;
yd -= 0.2f;
playSound(eSoundType_RANDOM_SPLASH, 0.25f, 1 + (random->nextFloat() - random->nextFloat()) * 0.4f);
float yt = static_cast<float>(Mth::floor(bb->y0));
for (int i = 0; i < 1 + bbWidth * 20; i++)
{
float xo = (random->nextFloat() * 2 - 1) * bbWidth;
float zo = (random->nextFloat() * 2 - 1) * bbWidth;
level->addParticle(eParticleType_bubble, x + xo, yt + 1, z + zo, xd, yd - random->nextFloat() * 0.2f, zd);
}
for (int i = 0; i < 1 + bbWidth * 20; i++)
{
float xo = (random->nextFloat() * 2 - 1) * bbWidth;
float zo = (random->nextFloat() * 2 - 1) * bbWidth;
level->addParticle(eParticleType_splash, x + xo, yt + 1, z + zo, xd, yd, zd);
}
}
} }
} }
if (level->isClientSide) {
if (nibble > 0) applyClientFX();
if (entityData->getShort(FishingHook::DATA_FLAG_NIBBLE) != 0)
{
yd -= random->nextFloat() * random->nextFloat() * random->nextFloat() * 0.2;
}
}
else if (nibble > 0)
{ {
yd -= random->nextFloat() * random->nextFloat() * random->nextFloat() * 0.2; yd -= random->nextFloat() * random->nextFloat() * random->nextFloat() * 0.2;
} }
@ -444,6 +407,177 @@ void FishingHook::addAdditonalSaveData(CompoundTag *tag)
tag->putByte(L"inTile", static_cast<byte>(lastTile)); tag->putByte(L"inTile", static_cast<byte>(lastTile));
tag->putByte(L"shake", static_cast<byte>(shakeTime)); tag->putByte(L"shake", static_cast<byte>(shakeTime));
tag->putByte(L"inGround", static_cast<byte>(inGround ? 1 : 0)); tag->putByte(L"inGround", static_cast<byte>(inGround ? 1 : 0));
tag->putFloat(L"fishApproachAngle", fishApproachAngle);
tag->putShort(L"wakeTimer", static_cast<short>(wakeTimer));
tag->putShort(L"nibbleTimer", static_cast<short>(nibbleTimer));
tag->putShort(L"nibble", static_cast<short>(nibble));
}
void FishingHook::catchingFish() {
int timerSubtractor = 1;
// Being under roof increases fishing time
if (!(level->canSeeSky(Mth::floor(x), Mth::floor(y) + 1, Mth::floor(z)) && random->nextInt(2) == 0)) {
timerSubtractor--;
}
// TU 31: Raining affects the nibble timer by random chance rather than being a fixed rate. Source: https://minecraft.wiki/w/Fishing
if (level->isRainingAt( Mth::floor(x), Mth::floor(y) + 1, Mth::floor(z)) && random->nextInt(4) == 0) {
timerSubtractor++;
}
if (nibble > 0)
{
nibble -= 1;
if (nibble <= 0)
{
nibbleTimer = 0;
wakeTimer = 0;
}
}
else
{
if (wakeTimer > 0)
{
wakeTimer -= timerSubtractor;
if (wakeTimer <= 0)
{
yd -= 0.2f;
playSound(eSoundType_RANDOM_SPLASH, 0.25f, 1.0f + (random->nextFloat() - random->nextFloat()) * 0.4f);
nibble = random->nextInt(11) + 30;
}
else
{
fishApproachAngle += (float)(random->nextGaussian() * 4.0);
}
}
else if ( nibbleTimer>0 ) {
nibbleTimer -= timerSubtractor;
if (nibbleTimer <= 0)
{
fishApproachAngle = random->nextFloat() * 360.0f;
wakeTimer = random->nextInt(61) + 20;
}
}
else
{
nibbleTimer = random->nextInt(801) + 100 - lureLevel * 100;
}
}
updateSynchedData();
}
// I guess I have to use UK spelling :(
void FishingHook::updateSynchedData() {
short nibbleFlag = (nibble > 0) ? 1 : 0;
if (nibble > 0 && entityData->getShort(FishingHook::DATA_FLAG_RENDER_CLIENT_FX) != 1) {
entityData->set(FishingHook::DATA_FLAG_RENDER_CLIENT_FX, 1); // Render Nibble FX
}
// Flags and synced data are only updated if they have changed.
else if (wakeTimer > 0 && entityData->getShort(FishingHook::DATA_FLAG_RENDER_CLIENT_FX) != 2) {
entityData->set(FishingHook::DATA_FLAG_RENDER_CLIENT_FX, 2); // Render Wake FX
}
else if (nibbleTimer > 0 && entityData->getShort(FishingHook::DATA_FLAG_RENDER_CLIENT_FX) != 3) {
entityData->set(FishingHook::DATA_FLAG_RENDER_CLIENT_FX, 3); // Render Fishing FX
}
else if (entityData->getShort(FishingHook::DATA_FLAG_RENDER_CLIENT_FX) != 0){
entityData->set(FishingHook::DATA_FLAG_RENDER_CLIENT_FX, 0); // Render Nothing
}
if (entityData->getFloat(FishingHook::DATA_FISH_APPROACH_ANGLE) != fishApproachAngle) {
entityData->set(FishingHook::DATA_FISH_APPROACH_ANGLE, fishApproachAngle);
}
if (entityData->getShort(FishingHook::DATA_NIBBLE_TIMER) != nibbleTimer) {
entityData->set(FishingHook::DATA_NIBBLE_TIMER, nibbleTimer);
}
if (entityData->getShort(FishingHook::DATA_WAKE_TIMER) != wakeTimer) {
entityData->set(FishingHook::DATA_WAKE_TIMER, wakeTimer);
}
// Nibble flag is only updated if it has changed.
if (entityData->getShort(FishingHook::DATA_FLAG_NIBBLE) != nibbleFlag) {
entityData->set(FishingHook::DATA_FLAG_NIBBLE, nibbleFlag);
}
}
void FishingHook::applyClientFX() {
float f;
float particleY;
float particleZ;
float particleX;
float xDir;
float zDir;
float xVel;
float zVel;
float yt = static_cast<float>(Mth::floor(bb->y0) + 1.0);
int clientWakeTimer;
int clientNibbleTimer;
switch (entityData->getShort(FishingHook::DATA_FLAG_RENDER_CLIENT_FX)) {
case 1:
yd -= 0.2f;
playSound(eSoundType_RANDOM_SPLASH, 0.25f, 1.0f + (random->nextFloat() - random->nextFloat()) * 0.4f);
for (int i = 0; i < 1 + bbWidth * 20; i++)
{
level->addParticle(eParticleType_bubble, x, yt, z, bbWidth, 0, bbWidth);
}
for (int i = 0; i < 1 + bbWidth * 20; i++)
{
level->addParticle(eParticleType_wake, x, yt, z, bbWidth, 0, bbWidth);
}
break;
case 2:
f = entityData->getFloat(FishingHook::DATA_FISH_APPROACH_ANGLE) * 0.017453292f;
xDir = Mth::sin(f);
zDir = Mth::cos(f);
clientWakeTimer = entityData->getShort(FishingHook::DATA_WAKE_TIMER);
particleX = x + (xDir * (float)clientWakeTimer * 0.1f);
particleZ = z+ (zDir * (float)clientWakeTimer * 0.1f);
if (random->nextFloat() < 0.15f)
{
level->addParticle(eParticleType_bubble, particleX, yt - 0.10000000149011612, particleZ, xDir, 0.1, zDir);
}
zVel = xDir * 0.04F;
xVel = zDir * 0.04F;
level->addParticle(eParticleType_wake, particleX, yt, particleZ, xVel, 0.01, (-zVel));
level->addParticle(eParticleType_wake, particleX, yt, particleZ, (-xVel), 0.01, zVel);
break;
case 3:
f = 0.15F;
clientNibbleTimer = entityData->getShort(FishingHook::DATA_NIBBLE_TIMER);
if (clientNibbleTimer < 20)
{
f = f + (float)(20 - clientNibbleTimer) * 0.05f;
}
else if (clientNibbleTimer < 40)
{
f = (float)(40 - clientNibbleTimer) * 0.02f;
}
else if (clientNibbleTimer < 60)
{
f = (float)(60 - clientNibbleTimer) * 0.01f;
}
if (random->nextFloat() < f)
{
xDir = random->nextFloat() * 360.0f * 0.017453292f;
zDir = (random->nextFloat() * 45.0f) + 25.0f;
particleX = x + (Mth::sin(xDir) * zDir * 0.1f);
particleY = Mth::floor(bb->y0) + 1.0;
particleZ = z + (Mth::cos(xDir) * zDir * 0.1f);
for (int i = 0; i < 2 + random->nextInt(2); i++)
{
level->addParticle(eParticleType_splash, particleX, particleY, particleZ, 0.10000000149011612, 0.0, 0.10000000149011612);
}
}
break;
}
} }
void FishingHook::readAdditionalSaveData(CompoundTag *tag) void FishingHook::readAdditionalSaveData(CompoundTag *tag)
@ -454,6 +588,11 @@ void FishingHook::readAdditionalSaveData(CompoundTag *tag)
lastTile = tag->getByte(L"inTile") & 0xff; lastTile = tag->getByte(L"inTile") & 0xff;
shakeTime = tag->getByte(L"shake") & 0xff; shakeTime = tag->getByte(L"shake") & 0xff;
inGround = tag->getByte(L"inGround") == 1; inGround = tag->getByte(L"inGround") == 1;
fishApproachAngle = tag->getFloat(L"fishApproachAngle");
wakeTimer = tag->getShort(L"wakeTimer");
nibbleTimer = tag->getShort(L"nibbleTimer");
nibble = tag->getShort(L"nibble");
entityData->set(FishingHook::DATA_FLAG_NIBBLE, (nibble > 0) ? 1 : 0);
} }
float FishingHook::getShadowHeightOffs() float FishingHook::getShadowHeightOffs()
@ -500,7 +639,6 @@ int FishingHook::retrieve()
if (inGround) dmg = 2; if (inGround) dmg = 2;
remove(); remove();
owner->fishing = nullptr;
return dmg; return dmg;
} }

View file

@ -25,14 +25,23 @@ public:
private: private:
int life; int life;
int flightTime; int flightTime;
int nibble;
int nibbleTimer;
int lureTime;
int lureLevel; int lureLevel;
int luckLevel; int luckLevel;
shared_ptr<ItemInstance> previousItem; shared_ptr<ItemInstance> previousItem;
int wakeTimer;
int nibbleTimer;
int nibble;
float fishApproachAngle;
private:
static const int DATA_FLAG_RENDER_CLIENT_FX;
static const int DATA_FISH_APPROACH_ANGLE;
static const int DATA_WAKE_TIMER;
static const int DATA_NIBBLE_TIMER;
static const int DATA_FLAG_NIBBLE;
public: public:
shared_ptr<Entity> hookedIn; shared_ptr<Entity> hookedIn;
@ -61,6 +70,9 @@ public:
virtual void lerpMotion(double xd, double yd, double zd); virtual void lerpMotion(double xd, double yd, double zd);
virtual void tick(); virtual void tick();
virtual void addAdditonalSaveData(CompoundTag *tag); virtual void addAdditonalSaveData(CompoundTag *tag);
void catchingFish();
void updateSynchedData();
void applyClientFX();
virtual void readAdditionalSaveData(CompoundTag *tag); virtual void readAdditionalSaveData(CompoundTag *tag);
virtual float getShadowHeightOffs(); virtual float getShadowHeightOffs();
virtual void getEnchantLevels(); virtual void getEnchantLevels();

View file

@ -381,44 +381,43 @@ std::vector<OceanMonumentPieces::RoomDefinition*> OceanMonumentPieces::MonumentB
entryRoom = grid[ENTRY_INDEX]; entryRoom = grid[ENTRY_INDEX];
for (int x = 0; x < 5; ++x) for (int x = 0; x < 5; ++x)
for (int y = 0; y < 3; ++y) for (int y = 0; y < 3; ++y)
for (int z = 0; z < 5; ++z) for (int z = 0; z < 5; ++z)
{
int idx = Piece::roomIndex(x, y, z);
if (grid[idx] == nullptr) continue;
static const int dx[6] = { 0, 0, 0, 0,-1, 1 };
static const int dy[6] = {-1, 1, 0, 0, 0, 0 };
static const int dz[6] = { 0, 0,-1, 1, 0, 0 };
static const int oppFacing[6] = { 1, 0, 3, 2, 5, 4 };
for (int f = 0; f < 6; ++f)
{ {
int nx = x + dx[f]; int idx = Piece::roomIndex(x, y, z);
int ny = y + dy[f]; if (grid[idx] == nullptr) continue;
int nz = z + dz[f];
if (nx < 0 || nx >= 5 || ny < 0 || ny >= 3 || nz < 0 || nz >= 5) continue;
int nidx = Piece::roomIndex(nx, ny, nz);
if (grid[nidx] == nullptr) continue;
for (int f = 0; f < 6; ++f)
if (nidx <= idx) continue; {
int nx = x + Facing::STEP_X[f];
int ny = y + Facing::STEP_Y[f];
int nz = z + Facing::STEP_Z[f];
if (nx < 0 || nx >= 5 || ny < 0 || ny >= 3 || nz < 0 || nz >= 5) continue;
int nidx = Piece::roomIndex(nx, ny, nz);
if (grid[nidx] == nullptr) continue;
//if (nidx <= idx) continue;
if (nz != z)
{ if (nz != z)
{
int opp = (f % 2 == 0) ? f + 1 : f - 1;
grid[idx]->connectTo(opp, grid[nidx]);
}
else
{
grid[idx]->connectTo(f, grid[nidx]);
int opp = Facing::OPPOSITE_FACING[f];
grid[idx]->connectTo(opp, grid[nidx]);
}
else
{
grid[idx]->connectTo(f, grid[nidx]);
}
} }
} }
}
RoomDefinition* specialUp = new RoomDefinition(1003); RoomDefinition* specialUp = new RoomDefinition(1003);
RoomDefinition* specialWing1 = new RoomDefinition(1001); RoomDefinition* specialWing1 = new RoomDefinition(1001);
@ -1482,15 +1481,15 @@ OceanMonumentPieces::EntryRoom::EntryRoom(int facing, RoomDefinition* room)
bool OceanMonumentPieces::EntryRoom::postProcess(Level* level, Random* random, BoundingBox* chunkBB) bool OceanMonumentPieces::EntryRoom::postProcess(Level* level, Random* random, BoundingBox* chunkBB)
{ {
generateBox(level, chunkBB, 0, 1, 0, 2, 1, 2, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); generateBox(level, chunkBB, 0, 3, 0, 2, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(), false);
generateBox(level, chunkBB, 5, 3, 0, 7, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); generateBox(level, chunkBB, 5, 3, 0, 7, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(), false);
generateBox(level, chunkBB, 6, 2, 0, 7, 2, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); generateBox(level, chunkBB, 0, 2, 0, 1, 2, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(), false);
generateBox(level, chunkBB, 0, 2, 0, 1, 2, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); generateBox(level, chunkBB, 6, 2, 0, 7, 2, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(), false);
generateBox(level, chunkBB, 0, 1, 0, 0, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); generateBox(level, chunkBB, 0, 1, 0, 0, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(), false);
generateBox(level, chunkBB, 7, 1, 0, 7, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); generateBox(level, chunkBB, 7, 1, 0, 7, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(), false);
generateBox(level, chunkBB, 0, 1, 7, 7, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); generateBox(level, chunkBB, 0, 1, 7, 7, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(), false);
generateBox(level, chunkBB, 1, 1, 0, 2, 3, 0, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); generateBox(level, chunkBB, 1, 1, 0, 2, 3, 0, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(), false);
generateBox(level, chunkBB, 5, 1, 0, 6, 3, 0, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); generateBox(level, chunkBB, 5, 1, 0, 6, 3, 0, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(), false);
if (roomDef->hasOpening[F_NORTH]) fillWithAirOrWater(level, chunkBB, 3, 1, 7, 4, 2, 7, false); if (roomDef->hasOpening[F_NORTH]) fillWithAirOrWater(level, chunkBB, 3, 1, 7, 4, 2, 7, false);
if (roomDef->hasOpening[F_WEST]) fillWithAirOrWater(level, chunkBB, 0, 1, 3, 1, 2, 4, false); if (roomDef->hasOpening[F_WEST]) fillWithAirOrWater(level, chunkBB, 0, 1, 3, 1, 2, 4, false);

View file

@ -13,6 +13,7 @@ enum ePARTICLE_TYPE
eParticleType_lava, eParticleType_lava,
eParticleType_footstep, eParticleType_footstep,
eParticleType_splash, eParticleType_splash,
eParticleType_wake,
eParticleType_largesmoke, eParticleType_largesmoke,
eParticleType_reddust, eParticleType_reddust,
eParticleType_snowballpoof, eParticleType_snowballpoof,

View file

@ -3,7 +3,7 @@
This project aims to backport the newer title updates back to Legacy Console Edition (which is based on TU19). This project aims to backport the newer title updates back to Legacy Console Edition (which is based on TU19).
[![Discord](https://img.shields.io/badge/Discord-Join%20Server-5865F2?logo=discord&logoColor=white)](https://discord.gg/D6hEPNYeyn) [![Discord](https://img.shields.io/badge/Discord-Join%20Server-5865F2?logo=discord&logoColor=white)](https://discord.gg/D6hEPNYeyn)
[![Discord](https://img.shields.io/badge/Get_it_on-Emerald_Launcher-3fc724)](https://discord.gg/D6hEPNYeyn) [![Emerald Launcher](https://img.shields.io/badge/Get_it_on-Emerald_Launcher-3fc724)](https://github.com/LCE-Hub/LCE-Emerald-Launcher)
# Our roadmap: # Our roadmap:
![Roadmap](.gitea/roadmap.png) ![Roadmap](.gitea/roadmap.png)

4
configure_cmake.bat Normal file
View file

@ -0,0 +1,4 @@
"C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\VsDevCmd.bat"
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
cd C:\Users\logat\OneDrive\Documents\GitHub\LegacyEvolved
cmake --preset windows64