101 Commits

Author SHA1 Message Date
867114b0f3 1 2026-07-27 15:45:40 +02:00
1a8ead4955 2 2026-07-27 15:45:17 +02:00
dddd69472a ok 2026-07-27 01:33:26 +02:00
881c1188a1 lol 2026-07-27 00:12:58 +02:00
f1ff828027 i 2026-07-26 19:43:51 +02:00
f93521a879 login plugin works yoy 2026-07-26 01:02:27 +02:00
d9dfff3339 1 2026-07-25 21:54:02 +02:00
c62daa9c1c Merge branch 'plugins-support' of https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1 into plugins-support 2026-07-22 23:28:17 +02:00
f6377bc5a2 lol 2026-07-22 23:27:50 +02:00
431b2a2704 add iostream 2026-07-23 00:26:44 +03:00
67acd7f9a6 update 2026-07-21 22:42:28 +02:00
6f1ca8fc3b begin 2026-07-20 14:49:38 +02:00
f7ad5acd33 remove includes for server 2026-07-19 01:04:34 +03:00
444e826d1b aa 2026-07-18 23:41:05 +02:00
6b6ad48617 Merge branch 'dedicated-rewrite' 2026-07-18 23:23:46 +02:00
e43da17d66 oh i didnt know 2026-07-18 23:02:25 +03:00
3fcf3e3418 link WSA with server 2026-07-18 22:47:41 +03:00
8955b6ea47 ADD: server build for windows 2026-07-18 22:32:13 +03:00
4f21343e3b release soon but we need to fix large world in mp 2026-07-18 21:01:13 +02:00
fcf7427fb2 gg fixed 2026-07-18 19:14:16 +02:00
50d1de49e0 FIX: multiplayer leave crash and compilation 2026-07-18 15:25:03 +03:00
3811964689 ffqwfqwfw 2026-07-18 14:02:45 +02:00
26e5376030 FIX: Crash when server is disaibling 2026-07-10 21:45:52 +02:00
d3d9b1a238 anticheat sucks xdxd 2026-07-10 00:59:26 +02:00
f0df3fe257 Server for windows wow 2026-07-10 00:46:36 +02:00
3ebed84cdb FIX: crash while joining to large world server 2026-07-02 16:32:17 +03:00
Shredder
d08948fb00 renable generation features 2026-05-23 06:03:34 +05:00
Shredder
061d6db3a9 add burp1.ogg to fix android compilation 2026-05-23 05:46:11 +05:00
Shredder
346ec7469e merge branch 'main' of https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1 2026-05-23 05:30:27 +05:00
Shredder
d7d887f882 few additions and bug fixes
Added Hand Sway (not an option yet) from b1,8

Fire works properly in multiplayer now and also renders on undead mobs in sunlight now

hopefully fixed bow stuck bug on touchscreen devices

Fire on entites uses updated rendering from b1.6.6

Shadow bug fix attempt the 15th

Added looking at block in debug screen

Zombie Pigman now renders his hat layer

Temporarily disabled most randomlevelsource cave, canyon and tall grass code just for this commit to test performance
2026-05-23 05:29:47 +05:00
ce182b676f Merge pull request 'added missing audio random.burp when finishing a food item' (#14) from sas3/minecraft-pe-0.6.1:main into main
Reviewed-on: #14
2026-05-12 21:50:28 +02:00
b73f7f121d ee 2026-05-12 21:29:17 +02:00
Kolyah35
5e19ef778e FIX: memset ._. 2026-05-12 22:12:52 +03:00
Shredder
4b69a1240a Some fixes
Fixed Missing Lighting calls and GL states which was causing stars to render too early

Split Controls should hopefully work on phones now

Chickens should hopefully lay eggs now
2026-05-12 02:25:04 +05:00
Shredder
8f34fbc1ec It isn't a commit without a linux compilation fail 2026-05-11 05:07:07 +05:00
Shredder
890604256b Fixes and New Additions
Added GUI Styles with 3 options: Java, Pi/Xperia and Pocket

Hopefully fixed touch input eating and breaking blocks bug

Fire should render on all mobs now

Fixed only one side of the first person burning animation being animated

Added Window Scaling Option for PC Users (Hasn't been tested on other platforms

Render Distance is now configurable from the settings menu

Tried to fix shadows again on IOS and Android, hopefully works?

Block Outline Selection now has a thicker outline for better visibility
2026-05-11 04:51:03 +05:00
5bc19c4ab2 FEAT: Ban command, save ops and banned ppl in files
TODO: fix many crashes...
2026-05-09 16:37:11 +02:00
dfb3bf1da7 FIX: render
ty shredder
2026-05-09 14:41:31 +02:00
263118f2e0 Fix 2026-05-09 13:09:45 +02:00
Shredder
792d4b32e7 Fixed Grass Foliage color using foliagecolor.png instead of grasscolor.png
Debug Screen now also renders mob id nametags like in beta java

SkyDarken is now also no longer clamped in Java Fog Style
2026-05-09 06:27:30 +05:00
1d0264a9c5 FEAT: World size 2026-05-09 01:45:19 +02:00
43f0d1f75f server config 2026-05-08 23:42:41 +02:00
Shredder
2da05d94c8 should return some value in the debug stuff so nothing breaks 2026-05-07 14:06:01 +05:00
Shredder
a0e99e2f03 debug screen ifdef case because linux compilation is hell 2026-05-07 13:59:13 +05:00
Shredder
b6ea0c7dc3 this has to be an insanely hacky solution to get it working on linux again 2026-05-07 13:50:08 +05:00
Shredder
620b358ba7 i love when my errors are cryptic 2026-05-07 13:33:57 +05:00
70308d4151 qqqqqq 2026-05-05 21:55:03 +02:00
830549791a 121 2026-05-05 21:51:35 +02:00
27b22d8108 vegetables 2026-05-05 21:41:26 +02:00
4047fd71e1 oi 2026-05-05 21:36:35 +02:00
30dd344208 123 2026-05-05 21:33:28 +02:00
7e9de7a461 fck android build!!! 2026-05-05 21:19:08 +02:00
2465292473 jopa 2026-05-05 21:14:17 +02:00
26b2c196fa :\ 2026-05-05 21:09:42 +02:00
18793a6e05 idk? 2026-05-05 20:40:41 +02:00
Shredder
edc6985a6b opengl and gles and their damn deprecated functions 2026-05-05 01:18:57 +05:00
Shredder
9cd91b1508 should finally work hopefully... 2026-05-05 01:05:57 +05:00
Shredder
9c46d7094c sigh converted to_string calls to sprintf 2026-05-05 00:51:03 +05:00
Shredder
52afff463b left a debug opengl only feature accidentally in, and also hopefully fixed include mess 2026-05-05 00:21:37 +05:00
Shredder
0d23fadc3e how did this even slip past me 2026-05-05 00:13:05 +05:00
Shredder
614e018dc6 fixed merge 2026-05-05 00:05:17 +05:00
Shredder
e346df682c Another Huge Commit my bad - shredder
Restored Java's Debug Screen using partial unused code and ported code, avaliable in options menu as a style

Slight Water texture is now overlayed when in water

Vignette function has been fixed and can now be toggled in options

World Generation now includes Tall Grass and Ferns both

Broken Frame Chart Graph found in the source has now been fixed and enabled when debug screen is turned on

Pie Chart works now and will appear when debug screen is opened

Most changes have not been tested on anything besides windows, will test it
2026-05-04 01:28:27 +05:00
Kolyah35
3e48c7fabd FIX: compilation 2026-05-02 21:31:48 +03:00
de72a9a3b7 all was broken :\ 2026-04-27 23:43:36 +02:00
0645905fc6 eeee it doesnt work 😭 2026-04-27 22:18:18 +02:00
Shredder
31d80aedf8 Massive Java Parity Update - fileshredder
3D/Fancy Clouds have been ported over

Sky Rendering is now an option between Java and PE

Java Sky/Fog color option is now accurate using the original color ramp instead of PE's slightly lower one

Grass Sides are now tinted, and can be toggled in settings

Added stars, the sun, and the moon in the daylight cycle

Sunset color has been added, appears when the sun is rising or falling, buggy on PE's sky rendering option.

Fixed leaves being rendered bright green when foliage tinting was turned off.

Enabled Tall Grass generation code

Tall Grass is now tinted.

Other compile options have to be tested
2026-04-25 04:47:07 +05:00
Kolyah35
4023d70687 FEAT: server-side commands 2026-04-04 01:13:56 +03:00
Kolyah35
4dc7055d9d FIX: make antispeedhack working 2026-03-31 23:34:41 +03:00
Kolyah35
1ec347d5d5 FEAT: Server operators 2026-03-31 00:40:10 +03:00
Kolyah35
5194575092 FEAT: Meet the commands 2026-03-30 14:04:16 +03:00
3cfa2d9ee7 FIX IT AHTUNG AHTUNG ALL DOESNT WORK FIX IT FIX IT FIX IT FIX IT BIG WARNING BIG WARNING 2026-03-29 16:53:46 +02:00
f016f00eab idk?? 2026-03-29 00:16:19 +02:00
Kolyah35
470c28d83a I dont know what im doin please help 2026-03-29 00:36:36 +03:00
4363157cd9 Delete useless class 2026-03-28 21:08:52 +02:00
ba3ed3b4dd i dont see reason of this error 2026-03-28 18:37:02 +02:00
5783fb93f3 forgot to comment 2026-03-28 17:39:37 +02:00
73fb2a2b3d wtf 2026-03-28 17:18:38 +02:00
bcf48eb5e3 FEAT: Damage on server 2026-03-28 16:41:00 +02:00
Kolyah35
f5fecbc928 Merge remote-tracking branch 'refs/remotes/origin/dedicated-rewrite' into dedicated-rewrite 2026-03-27 22:15:26 +03:00
Kolyah35
77d02fcca2 FIX: workbench compatibility 2026-03-27 22:15:03 +03:00
6d696af235 FEAT: taken nickname 2026-03-27 21:08:17 +02:00
Kolyah35
370363f792 Merge remote-tracking branch 'refs/remotes/origin/dedicated-rewrite' into dedicated-rewrite 2026-03-27 21:26:48 +03:00
Kolyah35
61a2349b8b FEAT: Player data saving/loading 2026-03-27 21:26:25 +03:00
eed3a6df61 FEAT: Message for outdated clients 2026-03-27 20:22:05 +02:00
97b0fb4d46 FEAT: New proto check 2026-03-27 20:16:59 +02:00
8be842a8ac FEAT: player anticheat speed 2026-03-27 19:41:54 +02:00
6957f144e1 FIX: Inventory change when cheating items (TODO: Linked slots) 2026-03-27 17:05:50 +02:00
f9d9a0f0f9 FIX: Recheck recipes in MP 2026-03-27 13:47:33 +02:00
Kolyah35
28febb4e63 FIX: tool durablity mismatch 2026-03-27 14:01:49 +03:00
Kolyah35
aeef442f76 FIX: Server-side item remove when crafting 2026-03-27 04:02:27 +03:00
8098ab8906 easy 2026-03-27 02:48:56 +02:00
f0cb6d0b7c Fix compile errors 2026-03-27 02:42:34 +02:00
d1672c0ee2 Merge branch 'dedicated-rewrite' of https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1 into dedicated-rewrite 2026-03-27 02:40:55 +02:00
c234abe3aa FIX: Item crafting 2026-03-27 02:40:52 +02:00
Kolyah35
e4ff7728af Merge remote-tracking branch 'refs/remotes/origin/dedicated-rewrite' into dedicated-rewrite 2026-03-27 03:34:29 +03:00
Kolyah35
41c5bdf243 FIX: The end of item cheating 2026-03-27 03:33:21 +03:00
96e8826f01 FEAT: Crafting on server 2026-03-27 02:14:28 +02:00
db8993683f Merge branch 'dedicated-rewrite' of https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1 into dedicated-rewrite 2026-03-26 22:48:52 +02:00
2c1b5e256e change proto ver 2026-03-26 22:48:50 +02:00
Kolyah35
4beb5cb0f9 i think i fixed player equip 2026-03-26 23:32:09 +03:00
SAS_OP
88ef7f3d17 added missing audio random.burp when finishing a food item 2026-03-25 06:07:49 +03:00
160 changed files with 7002 additions and 1705 deletions

View File

@@ -60,13 +60,16 @@ jobs:
- name: Build - name: Build
working-directory: ${{github.workspace}}/build working-directory: ${{github.workspace}}/build
run: cmake --build . --config $BUILD_TYPE --target MinecraftPE --parallel run: |
cmake --build . --config $BUILD_TYPE --target MinecraftPE --parallel
cmake --build . --config $BUILD_TYPE --target MinecraftPE-server --parallel
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: mcpe-windows name: mcpe-windows
path: | path: |
${{github.workspace}}/build/MinecraftPE-server.exe
${{github.workspace}}/build/MinecraftPE.exe ${{github.workspace}}/build/MinecraftPE.exe
${{github.workspace}}/build/libpng16.dll ${{github.workspace}}/build/libpng16.dll
${{github.workspace}}/build/OpenAL32.dll ${{github.workspace}}/build/OpenAL32.dll
@@ -300,6 +303,12 @@ jobs:
files: mcpe-windows/MinecraftPE.exe mcpe-windows/libpng16.dll mcpe-windows/OpenAL32.dll mcpe-windows/libz.dll files: mcpe-windows/MinecraftPE.exe mcpe-windows/libpng16.dll mcpe-windows/OpenAL32.dll mcpe-windows/libz.dll
dest: minecraftpe-${{ steps.ref.outputs.hash }}-windows.zip dest: minecraftpe-${{ steps.ref.outputs.hash }}-windows.zip
- name: Zip Windows Server Artifacts
uses: vimtor/action-zip@v1.2
with:
files: mcpe-windows/MinecraftPE-server.exe
dest: minecraftpe-server-${{ steps.ref.outputs.hash }}-windows.zip
- name: Zip Linux Artifacts - name: Zip Linux Artifacts
uses: vimtor/action-zip@v1.2 uses: vimtor/action-zip@v1.2
with: with:
@@ -310,7 +319,7 @@ jobs:
uses: vimtor/action-zip@v1.2 uses: vimtor/action-zip@v1.2
with: with:
files: mcpe-linux/MinecraftPE-server files: mcpe-linux/MinecraftPE-server
dest: minecraftpe-server-${{ steps.ref.outputs.hash }}.zip dest: minecraftpe-server-${{ steps.ref.outputs.hash }}-linux.zip
- name: Rename Android Artifacts - name: Rename Android Artifacts
run: | run: |
@@ -343,7 +352,11 @@ jobs:
./data.zip ./data.zip
./minecraftpe-server-${{ steps.ref.outputs.hash }}.zip ./minecraftpe-server-${{ steps.ref.outputs.hash }}.zip
./minecraftpe-${{ steps.ref.outputs.hash }}-windows.zip ./minecraftpe-${{ steps.ref.outputs.hash }}-windows.zip
./minecraftpe-server-${{ steps.ref.outputs.hash }}-windows.zip
./minecraftpe-${{ steps.ref.outputs.hash }}-linux.zip ./minecraftpe-${{ steps.ref.outputs.hash }}-linux.zip
./minecraftpe-${{ steps.ref.outputs.hash }}-android-arm64-v8a.apk ./minecraftpe-${{ steps.ref.outputs.hash }}-android-arm64-v8a.apk
./minecraftpe-${{ steps.ref.outputs.hash }}-android-armeabi-v7a.apk ./minecraftpe-${{ steps.ref.outputs.hash }}-android-armeabi-v7a.apk
./minecraftpe-server-${{ steps.ref.outputs.hash }}-linux.zip
./minecraftpe-${{ steps.ref.outputs.hash }}-android-arm64-v8a.zip
./minecraftpe-${{ steps.ref.outputs.hash }}-android-armeabi-v7a.zip
./minecraftpe-${{ steps.ref.outputs.hash }}-web.zip ./minecraftpe-${{ steps.ref.outputs.hash }}-web.zip

1
.gitignore vendored
View File

@@ -4,7 +4,6 @@ out/
bin/ bin/
lib/ lib/
build-apk/ build-apk/
build-haiku/
cmake-build-*/ cmake-build-*/
CMakeFiles/ CMakeFiles/
CMakeCache.txt CMakeCache.txt

View File

@@ -1,16 +1,11 @@
cmake_minimum_required(VERSION 3.21) cmake_minimum_required(VERSION 3.21)
project(MinecraftPE) project(MinecraftPE)
if(CMAKE_SYSTEM_NAME STREQUAL "Haiku")
set(HAIKU, 1)
endif()
include(cmake/CPM.cmake) include(cmake/CPM.cmake)
set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE) set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_POLICY_VERSION_MINIMUM 3.10) set(CMAKE_POLICY_VERSION_MINIMUM 3.10)
include(cmake/EnumOption.cmake) include(cmake/EnumOption.cmake)
if(EMSCRIPTEN) if(EMSCRIPTEN)
@@ -30,10 +25,6 @@ if (${PLATFORM} STREQUAL "Desktop")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc")
endif() endif()
if(HAIKU)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc -static")
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-c++11-narrowing -Wno-narrowing -Wno-invalid-source-encoding -Wno-reserved-user-defined-literal") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-c++11-narrowing -Wno-narrowing -Wno-invalid-source-encoding -Wno-reserved-user-defined-literal")
endif() endif()
@@ -42,13 +33,11 @@ if (${PLATFORM} STREQUAL "Desktop")
add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_WARNINGS)
include_directories(misc/windows) include_directories(misc/windows)
set(EXTRA_LIBS ws2_32 winhttp) set(EXTRA_LIBS ws2_32 winhttp)
elseif(HAIKU) add_definitions(-DLUA_DL_DLL=1)
find_library(pthread NAMES pthread)
find_library(network NAMES network)
set(EXTRA_LIBS pthread m network)
elseif(UNIX) elseif(UNIX)
find_library(pthread NAMES pthread) find_library(pthread NAMES pthread)
set(EXTRA_LIBS pthread m) set(EXTRA_LIBS pthread m)
add_definitions(-DLUA_USE_DLOPEN=1)
endif() endif()
elseif (${PLATFORM} STREQUAL "Web") elseif (${PLATFORM} STREQUAL "Web")
@@ -56,89 +45,113 @@ elseif (${PLATFORM} STREQUAL "Web")
set(EXTRA_LIBS "idbfs.js") set(EXTRA_LIBS "idbfs.js")
endif() endif()
if(!HAIKU) # I totally shocked
if(${PLATFORM} MATCHES "Web") if(${PLATFORM} MATCHES "Web")
set(PNG_LIB png) set(PNG_LIB png)
set(ZLIB_LIB zlib) set(AL_LIBTYPE "STATIC")
set(AL_LIBTYPE "STATIC")
add_library(zlib INTERFACE IMPORTED) add_library(zlib INTERFACE IMPORTED)
set_target_properties(zlib PROPERTIES set_target_properties(zlib PROPERTIES
INTERFACE_LINK_OPTIONS "-sUSE_ZLIB=1" INTERFACE_LINK_OPTIONS "-sUSE_ZLIB=1"
) )
add_library(png INTERFACE IMPORTED) add_library(png INTERFACE IMPORTED)
set_target_properties(png PROPERTIES set_target_properties(png PROPERTIES
INTERFACE_COMPILE_OPTIONS "-sUSE_LIBPNG=1" INTERFACE_COMPILE_OPTIONS "-sUSE_LIBPNG=1"
INTERFACE_LINK_OPTIONS "-sUSE_LIBPNG=1" INTERFACE_LINK_OPTIONS "-sUSE_LIBPNG=1"
) )
add_library(glfw INTERFACE IMPORTED) add_library(glfw INTERFACE IMPORTED)
set_target_properties(glfw PROPERTIES set_target_properties(glfw PROPERTIES
INTERFACE_LINK_OPTIONS "-sUSE_GLFW=3" INTERFACE_LINK_OPTIONS "-sUSE_GLFW=3"
)
else()
set(PNG_LIB png_shared)
set(ZLIB_LIB zlib)
set(AL_LIB "OpenAL::OpenAL")
set(AL_LIBTYPE "SHARED")
CPMAddPackage(
NAME "zlib"
GIT_REPOSITORY "https://github.com/madler/zlib"
GIT_TAG "v1.3.2"
)
CPMAddPackage(
NAME "libpng"
GIT_REPOSITORY "https://github.com/pnggroup/libpng.git"
GIT_TAG "v1.6.55"
OPTIONS
"ZLIB_ROOT ${zlib_SOURCE_DIR}"
"ZLIB_INCLUDE_DIRS ${zlib_SOURCE_DIR}"
"PNG_TOOLS OFF"
"PNG_TESTS OFF"
)
CPMAddPackage(
NAME "glfw"
GIT_REPOSITORY "https://github.com/glfw/glfw.git"
GIT_TAG "3.4"
EXCLUDE_FROM_ALL TRUE
OPTIONS
"GLFW_BUILD_EXAMPLES OFF"
"GLFW_BUILD_TESTS OFF"
"GLFW_BUILD_DOCS OFF"
)
endif()
CPMAddPackage(
NAME "openal"
GIT_REPOSITORY "https://github.com/kcat/openal-soft.git"
GIT_TAG "1.25.1"
OPTIONS
"ALSOFT_EXAMPLES OFF"
"ALSOFT_TESTS OFF"
"ALSOFT_UTILS OFF"
"LIBTYPE ${AL_LIBTYPE}"
"ALSOFT_ENABLE_MODULES OFF"
"ALSOFT_STATIC_STDCXX ON"
"ALSOFT_STATIC_LIBGCC ON"
) )
else() else()
# alot of these have haikuports specific versions, set(PNG_LIB png_shared)
find_library(glfw NAMES glfw) set(AL_LIBTYPE "SHARED")
find_library(openal NAMES openal)
find_library(png NAMES png)
find_library(zlib NAMES zlib)
set(PNG_LIB png) CPMAddPackage(
set(ZLIB_LIB z) NAME "zlib"
set(AL_LIB openal) GIT_REPOSITORY "https://github.com/madler/zlib"
GIT_TAG "v1.3.2"
)
CPMAddPackage(
NAME "libpng"
GIT_REPOSITORY "https://github.com/pnggroup/libpng.git"
GIT_TAG "v1.6.55"
OPTIONS
"ZLIB_ROOT ${zlib_SOURCE_DIR}"
"ZLIB_INCLUDE_DIRS ${zlib_SOURCE_DIR}"
"PNG_TOOLS OFF"
"PNG_TESTS OFF"
)
CPMAddPackage(
NAME "glfw"
GIT_REPOSITORY "https://github.com/glfw/glfw.git"
GIT_TAG "3.4"
EXCLUDE_FROM_ALL TRUE
OPTIONS
"GLFW_BUILD_EXAMPLES OFF"
"GLFW_BUILD_TESTS OFF"
"GLFW_BUILD_DOCS OFF"
)
CPMAddPackage("gh:halx99/sol2#support-lua-5.5")
CPMAddPackage("gh:lua/lua#master")
add_library(
lua STATIC
${lua_SOURCE_DIR}/lapi.c
${lua_SOURCE_DIR}/lauxlib.c
${lua_SOURCE_DIR}/lbaselib.c
${lua_SOURCE_DIR}/lcode.c
${lua_SOURCE_DIR}/lcorolib.c
${lua_SOURCE_DIR}/lctype.c
${lua_SOURCE_DIR}/ldblib.c
${lua_SOURCE_DIR}/ldebug.c
${lua_SOURCE_DIR}/ldo.c
${lua_SOURCE_DIR}/ldump.c
${lua_SOURCE_DIR}/lfunc.c
${lua_SOURCE_DIR}/lgc.c
${lua_SOURCE_DIR}/linit.c
${lua_SOURCE_DIR}/liolib.c
${lua_SOURCE_DIR}/llex.c
${lua_SOURCE_DIR}/lmathlib.c
${lua_SOURCE_DIR}/lmem.c
${lua_SOURCE_DIR}/loadlib.c
${lua_SOURCE_DIR}/lobject.c
${lua_SOURCE_DIR}/lopcodes.c
${lua_SOURCE_DIR}/loslib.c
${lua_SOURCE_DIR}/lparser.c
${lua_SOURCE_DIR}/lstate.c
${lua_SOURCE_DIR}/lstring.c
${lua_SOURCE_DIR}/lstrlib.c
${lua_SOURCE_DIR}/ltable.c
${lua_SOURCE_DIR}/ltablib.c
${lua_SOURCE_DIR}/ltm.c
${lua_SOURCE_DIR}/lua.c
${lua_SOURCE_DIR}/lundump.c
${lua_SOURCE_DIR}/lutf8lib.c
${lua_SOURCE_DIR}/lvm.c
${lua_SOURCE_DIR}/lzio.c
)
endif() endif()
# TODO: Clear this paths with * CPMAddPackage(
NAME "openal"
GIT_REPOSITORY "https://github.com/kcat/openal-soft.git"
GIT_TAG "1.25.1"
OPTIONS
"ALSOFT_EXAMPLES OFF"
"ALSOFT_TESTS OFF"
"ALSOFT_UTILS OFF"
"LIBTYPE ${AL_LIBTYPE}"
"ALSOFT_ENABLE_MODULES OFF"
"ALSOFT_STATIC_STDCXX ON"
"ALSOFT_STATIC_LIBGCC ON"
)
file(GLOB SERVER_SOURCES file(GLOB SERVER_SOURCES
"project/lib_projects/raknet/jni/RaknetSources/*.cpp" "project/lib_projects/raknet/jni/RaknetSources/*.cpp"
"src/NinecraftApp.cpp" "src/NinecraftApp.cpp"
@@ -177,7 +190,6 @@ file(GLOB SERVER_SOURCES
"src/platform/CThread.cpp" "src/platform/CThread.cpp"
"src/platform/HttpClient.cpp" "src/platform/HttpClient.cpp"
"src/platform/PngLoader.cpp"
"src/platform/time.cpp" "src/platform/time.cpp"
"src/platform/input/Controller.cpp" "src/platform/input/Controller.cpp"
@@ -243,6 +255,9 @@ file(GLOB SERVER_SOURCES
"src/world/level/tile/entity/*.cpp" "src/world/level/tile/entity/*.cpp"
"src/world/phys/HitResult.cpp" "src/world/phys/HitResult.cpp"
"src/commands/*.cpp"
"src/plugins/*.cpp"
) )
file(GLOB CLIENT_SOURCES file(GLOB CLIENT_SOURCES
@@ -326,6 +341,10 @@ file(GLOB CLIENT_SOURCES
"src/AppPlatform_glfw.cpp" "src/AppPlatform_glfw.cpp"
"src/main.cpp" "src/main.cpp"
"src/commands/*.cpp"
"src/plugins/*.cpp"
) )
if (${PLATFORM} STREQUAL "Desktop") if (${PLATFORM} STREQUAL "Desktop")
@@ -333,21 +352,21 @@ if (${PLATFORM} STREQUAL "Desktop")
endif() endif()
# Server # Server
if(UNIX) add_executable("${PROJECT_NAME}-server" ${SERVER_SOURCES})
add_executable("${PROJECT_NAME}-server" ${SERVER_SOURCES}) set_target_properties("${PROJECT_NAME}-server" PROPERTIES ENABLE_EXPORTS TRUE)
target_compile_definitions("${PROJECT_NAME}-server" PUBLIC "STANDALONE_SERVER" "SERVER_PROFILER")
target_compile_definitions("${PROJECT_NAME}-server" PUBLIC "STANDALONE_SERVER" "SERVER_PROFILER") target_include_directories("${PROJECT_NAME}-server" PUBLIC
"${CMAKE_SOURCE_DIR}/src/"
"${lua_SOURCE_DIR}/"
target_include_directories("${PROJECT_NAME}-server" PUBLIC "project/lib_projects/raknet/jni/RaknetSources"
"${CMAKE_SOURCE_DIR}/src/" )
"project/lib_projects/raknet/jni/RaknetSources"
)
target_link_libraries("${PROJECT_NAME}-server" ${EXTRA_LIBS}) target_link_libraries("${PROJECT_NAME}-server" ${CMAKE_THREAD_LIBS_INIT} ${EXTRA_LIBS} lua sol2::sol2)
endif()
add_executable(${PROJECT_NAME} ${CLIENT_SOURCES}) add_executable(${PROJECT_NAME} ${CLIENT_SOURCES})
set_target_properties(${PROJECT_NAME} PROPERTIES ENABLE_EXPORTS TRUE)
target_compile_definitions(${PROJECT_NAME} PUBLIC ${PLATFORM_CPP}) target_compile_definitions(${PROJECT_NAME} PUBLIC ${PLATFORM_CPP})
@@ -357,6 +376,8 @@ target_include_directories(${PROJECT_NAME} PUBLIC
"${openal_SOURCE_DIR}/include" "${openal_SOURCE_DIR}/include"
"${glfw_SOURCE_DIR}/include" "${glfw_SOURCE_DIR}/include"
"lib/include" "lib/include"
"${lua_SOURCE_DIR}/"
) )
if(${PLATFORM} MATCHES "Web") if(${PLATFORM} MATCHES "Web")
@@ -400,16 +421,11 @@ if(${PLATFORM} MATCHES "Web")
endif() endif()
target_compile_definitions(${PROJECT_NAME} PUBLIC "__EMSCRIPTEN__" "NO_SOUND" "NO_NETWORK") target_compile_definitions(${PROJECT_NAME} PUBLIC "__EMSCRIPTEN__" "NO_SOUND" "NO_NETWORK")
else()
target_compile_options(${PROJECT_NAME} PUBLIC
"-O3"
)
endif() endif()
# Client # Client
target_compile_definitions(${PROJECT_NAME} PUBLIC "OPENGL_ES" "NO_EGL" ${PLATFORM}) target_compile_definitions(${PROJECT_NAME} PUBLIC "OPENGL_ES" "NO_EGL" ${PLATFORM})
target_link_libraries(${PROJECT_NAME} zlib ${PNG_LIB} OpenAL::OpenAL glfw ${EXTRA_LIBS} lua sol2::sol2)
target_link_libraries(${PROJECT_NAME} ${ZLIB_LIB} ${PNG_LIB} ${AL_LIB} glfw ${EXTRA_LIBS})
if (OpenSSL_FOUND) if (OpenSSL_FOUND)
target_link_libraries(${PROJECT_NAME} OpenSSL::SSL OpenSSL::Crypto) target_link_libraries(${PROJECT_NAME} OpenSSL::SSL OpenSSL::Crypto)

BIN
data/images/misc/water.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 B

BIN
data/images/terrain/sun.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 B

View File

@@ -161,6 +161,18 @@ options.fogType.vanilla=Vanilla
options.fogType.java=Beta Java options.fogType.java=Beta Java
options.fogType.unused=Unused options.fogType.unused=Unused
options.debugStyle=Debug Menu Style
options.debugStyle.javaBeta=Java Beta
options.debugStyle.custom=Custom
options.beautifulSky=Beautiful Skies
options.useVignette=Vignette Overlay
options.tintedSide=Tint Grass Sides
options.betaSky=Java Beta Sky
options.restoredAnims=Restored Animations options.restoredAnims=Restored Animations
options.normalLighting=Java Beta/Normals Shading options.normalLighting=Java Beta/Normals Shading
@@ -217,6 +229,12 @@ options.fancyGraphics=Fancy graphics
options.renderDebug=Debug render options.renderDebug=Debug render
options.anaglyph3d=3D anaglyph options.anaglyph3d=3D anaglyph
options.windowScale =Window Scaling
options.menuStyle =Menu Style
options.menuStyle.pocket =Pocket Edition
options.menuStyle.xperia =Xperia/Pi
options.menuStyle.java =Java Beta
performance.max=Max FPS performance.max=Max FPS
performance.balanced=Balanced performance.balanced=Balanced

View File

@@ -110,6 +110,7 @@ LOCAL_SRC_FILES := ../../../src/main.cpp \
../../../src/client/renderer/Textures.cpp \ ../../../src/client/renderer/Textures.cpp \
../../../src/client/renderer/TileRenderer.cpp \ ../../../src/client/renderer/TileRenderer.cpp \
../../../src/client/renderer/gles.cpp \ ../../../src/client/renderer/gles.cpp \
../../../src/world/level/LevelConstants.cpp \
../../../src/client/renderer/culling/Frustum.cpp \ ../../../src/client/renderer/culling/Frustum.cpp \
../../../src/client/renderer/entity/ArrowRenderer.cpp \ ../../../src/client/renderer/entity/ArrowRenderer.cpp \
../../../src/client/renderer/entity/ChickenRenderer.cpp \ ../../../src/client/renderer/entity/ChickenRenderer.cpp \
@@ -140,6 +141,12 @@ LOCAL_SRC_FILES := ../../../src/main.cpp \
../../../src/network/Packet.cpp \ ../../../src/network/Packet.cpp \
../../../src/network/RakNetInstance.cpp \ ../../../src/network/RakNetInstance.cpp \
../../../src/network/ServerSideNetworkHandler.cpp \ ../../../src/network/ServerSideNetworkHandler.cpp \
../../../src/commands/Command.cpp \
../../../src/commands/CommandHelp.cpp \
../../../src/commands/CommandKick.cpp \
../../../src/commands/CommandBan.cpp \
../../../src/commands/CommandManager.cpp \
../../../src/commands/CommandOp.cpp \
../../../src/server/ServerLevel.cpp \ ../../../src/server/ServerLevel.cpp \
../../../src/server/ServerPlayer.cpp \ ../../../src/server/ServerPlayer.cpp \
../../../src/util/DataIO.cpp \ ../../../src/util/DataIO.cpp \

View File

@@ -232,6 +232,7 @@ LOCAL_SRC_FILES := ../../../src/main.cpp \
../../../src/world/level/tile/entity/TileEntity.cpp \ ../../../src/world/level/tile/entity/TileEntity.cpp \
../../../src/world/level/tile/entity/FurnaceTileEntity.cpp \ ../../../src/world/level/tile/entity/FurnaceTileEntity.cpp \
../../../src/world/phys/HitResult.cpp ../../../src/world/phys/HitResult.cpp
../../../src/world/level/LevelConstants.cpp
LOCAL_CFLAGS := -Wno-psabi $(LOCAL_CFLAGS) LOCAL_CFLAGS := -Wno-psabi $(LOCAL_CFLAGS)

Binary file not shown.

View File

@@ -129,6 +129,7 @@ public class SoundPlayer
new SoundId(R.raw.eat1, "random.eat"), new SoundId(R.raw.eat1, "random.eat"),
new SoundId(R.raw.eat2, "random.eat"), new SoundId(R.raw.eat2, "random.eat"),
new SoundId(R.raw.eat3, "random.eat"), new SoundId(R.raw.eat3, "random.eat"),
new SoundId(R.raw.burp1, "random.burp"),
new SoundId(R.raw.fuse, "random.fuse"), new SoundId(R.raw.fuse, "random.fuse"),
new SoundId(R.raw.zpig1, "mob.zombiepig.zpig"), new SoundId(R.raw.zpig1, "mob.zombiepig.zpig"),

View File

@@ -1,26 +0,0 @@
#!/bin/bash
mkdir build-haiku
cd build-haiku
cmake ..
make -j10
rm -rf pkg
mkdir pkg
mkdir -p ./pkg/apps/
mkdir -p ./pkg/data/minecraftpe
mkdir -p ./pkg/settings/minecraftpe
mkdir -p ./pkg/data/deskbar/menu/Applications/
mkdir -p ./pkg/data/deskbar/menu/Games/
cp -rv ../project/haiku/pkg ./
cp -v MinecraftPE ./pkg/apps/minecraftpe
cp -v MinecraftPE-server ./pkg/apps/minecraftpe-server
cp -rv data ./pkg/data/minecraftpe
ln -s ../../../../apps/minecraftpe ./pkg/data/deskbar/menu/Applications/minecraftpe
ln -s ../../../../apps/minecraftpe ./pkg/data/deskbar/menu/Games/minecraftpe
package create -C pkg minecraftpe-0.6.1-x86_64.hpkg

View File

@@ -1,27 +0,0 @@
name minecraftpe
version 0.6.1-1
architecture x86_64
summary "Minecraft Pocket Edition"
description "A port of minecraft pocket edition to Haiku"
packager "Li <li@silica.codes>"
vendor "Mojang"
copyrights {
"Copyright (C) 2026 by Mojang"
}
licenses {
"MIT"
}
provides {
minecraftpe = 0.6.1-1
app:minecraftpe = 0.6.1-1
}
requires {
glfw >= 3.3.7-1
openal >= 1.21.1-5
}
global-writable-files {
"settings/minecraftpe" directory keep-old
}
urls {
"https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1/"
}

View File

@@ -140,7 +140,7 @@ RakNet::TimeUS GetTimeUS_Windows( void )
#if _MSC_VER >= 1400 && defined (_M_X64) #if _MSC_VER >= 1400 && defined (_M_X64)
GetProcessAffinityMask(mProc, (PDWORD_PTR)&mProcMask, (PDWORD_PTR)&mSysMask); GetProcessAffinityMask(mProc, (PDWORD_PTR)&mProcMask, (PDWORD_PTR)&mSysMask);
#else #else
GetProcessAffinityMask(mProc, &mProcMask, &mSysMask); GetProcessAffinityMask(mProc, (PDWORD_PTR)&mProcMask, (PDWORD_PTR)&mSysMask);
#endif #endif
mThread = GetCurrentThread(); mThread = GetCurrentThread();

View File

@@ -17,8 +17,8 @@ using namespace RakNet;
#endif #endif
#elif defined(__HAIKU__)
#include <kernel/OS.h>
#else #else
#include <pthread.h> #include <pthread.h>
#endif #endif
@@ -93,10 +93,9 @@ int RakThread::Create( void* start_address( void* ), void *arglist, int priority
#elif defined(__HAIKU__)
thread_id threadHandle = spawn_thread((thread_func)start_address, "RakThread", priority, arglist);
int res = resume_thread(threadHandle);
return res == B_OK ? 0 : 1;
#else #else
pthread_t threadHandle; pthread_t threadHandle;
// Create thread linux // Create thread linux

View File

@@ -142,8 +142,8 @@ void seedMT( unsigned int seed, unsigned int *state, unsigned int *&next, int &l
// so-- that's why the only change I made is to restrict to odd seeds. // so-- that's why the only change I made is to restrict to odd seeds.
// //
register unsigned int x = ( seed | 1U ) & 0xFFFFFFFFU, *s = state; unsigned int x = ( seed | 1U ) & 0xFFFFFFFFU, *s = state;
register int j; int j;
for ( left = 0, *s++ = x, j = N; --j; for ( left = 0, *s++ = x, j = N; --j;
*s++ = ( x *= 69069U ) & 0xFFFFFFFFU ) *s++ = ( x *= 69069U ) & 0xFFFFFFFFU )
@@ -154,8 +154,8 @@ void seedMT( unsigned int seed, unsigned int *state, unsigned int *&next, int &l
unsigned int reloadMT( unsigned int *state, unsigned int *&next, int &left ) unsigned int reloadMT( unsigned int *state, unsigned int *&next, int &left )
{ {
register unsigned int * p0 = state, *p2 = state + 2, *pM = state + M, s0, s1; unsigned int * p0 = state, *p2 = state + 2, *pM = state + M, s0, s1;
register int j; int j;
if ( left < -1 ) if ( left < -1 )
seedMT( 4357U ); seedMT( 4357U );

View File

@@ -42,10 +42,10 @@ SocketLayerOverride *SocketLayer::slo=0;
#endif #endif
#if defined(__HAIKU__)
#include <sys/types.h>
#include <ifaddrs.h>
#endif
@@ -1436,25 +1436,8 @@ RakNet::RakString SocketLayer::GetSubNetForSocketAndIp(SOCKET inSock, RakNet::Ra
} }
} }
return ""; return "";
#elif defined(__HAIKU__)
struct ifaddrs *ifap, *ifa;
getifaddrs (&ifap);
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr && ifa->ifa_addr->sa_family==AF_INET) {
sockaddr_in* sa = (sockaddr_in*)ifa->ifa_addr;
char* ip_addr = inet_ntoa(sa->sin_addr);
if (inIpString == ip_addr) {
sockaddr_in* sa = (sockaddr_in*)ifa->ifa_netmask;
char* netmask = inet_ntoa(sa->sin_addr);
freeifaddrs(ifap);
return netmask;
}
}
}
freeifaddrs(ifap);
return "";
#else #else
int fd,fd2; int fd,fd2;
fd2 = socket__(AF_INET, SOCK_DGRAM, 0); fd2 = socket__(AF_INET, SOCK_DGRAM, 0);
@@ -1665,7 +1648,7 @@ void GetMyIP_Win32( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] )
} }
} }
// #else // #else
/*
void GetMyIP_Linux( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] ) void GetMyIP_Linux( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] )
{ {
struct ifaddrs *ifaddr, *ifa; struct ifaddrs *ifaddr, *ifa;
@@ -1716,7 +1699,7 @@ void GetMyIP_Linux( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] )
freeifaddrs(ifaddr); freeifaddrs(ifaddr);
} }
*/
@@ -1724,10 +1707,10 @@ void SocketLayer::GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_ID
{ {
#if defined(_WIN32) #if defined(_WIN32)
GetMyIP_Win32(addresses); GetMyIP_Win32(addresses);
#elif defined(__HAIKU__)
GetMyIP_Linux(addresses);
#else #else
// GetMyIP_Linux(addresses); // GetMyIP_Linux(addresses);
GetMyIP_Win32(addresses); GetMyIP_Win32(addresses);

View File

@@ -1,9 +1,5 @@
#include "UDPForwarder.h" #include "UDPForwarder.h"
#if defined(__HAIKU__)
#include <sys/select.h>
#endif
#if _RAKNET_SUPPORT_UDPForwarder==1 #if _RAKNET_SUPPORT_UDPForwarder==1
#include "GetTime.h" #include "GetTime.h"

View File

@@ -20,7 +20,6 @@
#include <shellapi.h> #include <shellapi.h>
#endif #endif
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
#include <emscripten/html5.h> #include <emscripten/html5.h>
#endif #endif
@@ -32,19 +31,12 @@ static void png_funcReadFile(png_structp pngPtr, png_bytep data, png_size_t leng
class AppPlatform_glfw: public AppPlatform class AppPlatform_glfw: public AppPlatform
{ {
public: public:
AppPlatform_glfw()
#ifdef __HAIKU__
std::string game_directory = "/system/data/minecraftpe/";
#else
std::string game_directory = "";
#endif
AppPlatform_glfw()
{ {
} }
BinaryBlob readAssetFile(const std::string& filename) override { BinaryBlob readAssetFile(const std::string& filename) override {
FILE* fp = fopen((game_directory + "data/" + filename).c_str(), "r"); FILE* fp = fopen(("data/" + filename).c_str(), "r");
if (!fp) if (!fp)
return BinaryBlob(); return BinaryBlob();
@@ -81,7 +73,7 @@ public:
TextureData out; TextureData out;
std::string filename = textureFolder? (game_directory + "data/images/") + filename_ std::string filename = textureFolder? "data/images/" + filename_
: filename_; : filename_;
std::ifstream source(filename.c_str(), std::ios::binary); std::ifstream source(filename.c_str(), std::ios::binary);

View File

@@ -136,7 +136,7 @@ void NinecraftApp::teardown()
Recipes ::teardownRecipes(); Recipes ::teardownRecipes();
TileEntity::teardownTileEntities(); TileEntity::teardownTileEntities();
#endif #endif
#ifdef WIN32 #if defined(WIN32) && !defined(STANDALONE_SERVER)
ItemRenderer::teardown_static(); ItemRenderer::teardown_static();
if (EntityTileRenderer::instance != NULL) { if (EntityTileRenderer::instance != NULL) {
delete EntityTileRenderer::instance; delete EntityTileRenderer::instance;

View File

@@ -2,18 +2,20 @@
#include "Options.h" #include "Options.h"
#include "client/Options.h" #include "client/Options.h"
#include "client/player/input/IBuildInput.h" #include "client/player/input/IBuildInput.h"
#include "commands/CommandManager.hpp"
#include "platform/input/Keyboard.h" #include "platform/input/Keyboard.h"
#include "world/item/Item.h" #include "world/item/Item.h"
#include "world/item/ItemInstance.h" #include "world/item/ItemInstance.h"
#include <string> #include <string>
#include <cstdlib> #include <cstdlib>
#if defined(APPLE_DEMO_PROMOTION) #if defined(APPLE_DEMO_PROMOTION)
#define NO_NETWORK #define NO_NETWORK
#endif #endif
#if defined(RPI) #if defined(RPI)
#define CREATORMODE #define CREATORMODE
#endif #endif
#include "../network/RakNetInstance.h" #include "../network/RakNetInstance.h"
#include "../network/ClientSideNetworkHandler.h" #include "../network/ClientSideNetworkHandler.h"
@@ -90,12 +92,19 @@
#include "../network/command/CommandServer.h" #include "../network/command/CommandServer.h"
#include "gamemode/CreatorMode.h" #include "gamemode/CreatorMode.h"
#ifndef STANDALONE_SERVER
#include "../world/level/GrassColor.h" #include "../world/level/GrassColor.h"
#include "renderer/LevelRenderer.h"
#include "particle/ParticleEngine.h"
#endif
#include "../world/level/Level.h"
static void checkGlError(const char* tag) { static void checkGlError(const char* tag) {
#ifdef GLDEBUG #ifdef GLDEBUG
while (1) { while (1) {
const int errCode = glGetError(); const int errCode = glGetError();
if (errCode == GL_NO_ERROR) break; if (errCode == GL_NO_ERROR) break;
LOGE("################\nOpenGL-error @ %s : #%d\n", tag, errCode); LOGE("################\nOpenGL-error @ %s : #%d\n", tag, errCode);
} }
@@ -113,7 +122,7 @@ const char* Minecraft::progressMessages[] = {
int Minecraft::customDebugId = Minecraft::CDI_NONE; int Minecraft::customDebugId = Minecraft::CDI_NONE;
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning( disable : 4355 ) // 'this' pointer in initialization list which is perfectly legal #pragma warning( disable : 4355 ) // 'this' pointer in initialization list which is perfectly legal
#endif #endif
bool Minecraft::useAmbientOcclusion = false; bool Minecraft::useAmbientOcclusion = false;
@@ -171,17 +180,18 @@ Minecraft::Minecraft() :
width(1), height(1), width(1), height(1),
//_respawnPlayerTicks(-1), //_respawnPlayerTicks(-1),
#ifdef __APPLE__ #ifdef __APPLE__
_isSuperFast(false), _isSuperFast(false),
#endif #endif
_powerVr(false), _powerVr(false),
commandPort(4711), commandPort(4711),
reserved_d1(0),reserved_d2(0), reserved_d1(0),reserved_d2(0),
reserved_f1(0),reserved_f2(0), options(this) reserved_f1(0),reserved_f2(0), options(this),
m_commandManager()
{ {
//#ifdef ANDROID //#ifdef ANDROID
#if defined(NO_NETWORK) #if defined(NO_NETWORK)
raknetInstance = new IRakNetInstance(); raknetInstance = new IRakNetInstance();
#else #else
raknetInstance = new RakNetInstance(); raknetInstance = new RakNetInstance();
#endif #endif
@@ -257,11 +267,12 @@ void Minecraft::selectLevel( const std::string& levelId, const std::string& leve
void Minecraft::setLevel(Level* level, const std::string& message /* ="" */, LocalPlayer* forceInsertPlayer /* = NULL */) { void Minecraft::setLevel(Level* level, const std::string& message /* ="" */, LocalPlayer* forceInsertPlayer /* = NULL */) {
cameraTargetPlayer = NULL; cameraTargetPlayer = NULL;
LOGI("Seed is %ld\n", level->getSeed());
if (level != NULL) { if (level != NULL) {
LOGI("Seed is %ld\n", level->getSeed());
level->raknetInstance = raknetInstance; level->raknetInstance = raknetInstance;
gameMode->initLevel(level); gameMode->initLevel(level);
if (!player && forceInsertPlayer) if (!player && forceInsertPlayer)
{ {
@@ -276,6 +287,7 @@ void Minecraft::setLevel(Level* level, const std::string& message /* ="" */, Loc
} }
} }
this->level = level; this->level = level;
_hasSignaledGeneratingLevelFinished = false; _hasSignaledGeneratingLevelFinished = false;
#ifdef STANDALONE_SERVER #ifdef STANDALONE_SERVER
const bool threadedLevelCreation = false; const bool threadedLevelCreation = false;
@@ -292,18 +304,18 @@ void Minecraft::setLevel(Level* level, const std::string& message /* ="" */, Loc
// Non-threaded // Non-threaded
generateLevel("Currently not used", level); generateLevel("Currently not used", level);
} }
} else { } else {
player = NULL; player = NULL;
} }
this->lastTickTime = 0; this->lastTickTime = 0;
this->_running = true; this->_running = true;
} }
void Minecraft::leaveGame(bool renameLevel /*=false*/) void Minecraft::leaveGame(bool renameLevel /*=false*/)
{ {
if (isGeneratingLevel || !_hasSignaledGeneratingLevelFinished) if (isGeneratingLevel || !_hasSignaledGeneratingLevelFinished)
return; return;
isGeneratingLevel = false; isGeneratingLevel = false;
bool saveLevel = level && (!level->isClientSide || renameLevel); bool saveLevel = level && (!level->isClientSide || renameLevel);
@@ -359,29 +371,29 @@ void Minecraft::prepareLevel(const std::string& title) {
if (!level->isNew()) if (!level->isNew())
level->setUpdateLights(false); level->setUpdateLights(false);
int Max = CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH; int Max = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_CACHE_WIDTH;
int pp = 0; int pp = 0;
for (int x = 8; x < (CHUNK_CACHE_WIDTH * CHUNK_WIDTH); x += CHUNK_WIDTH) { for (int x = 8; x < (LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_WIDTH); x += LevelConstants::CHUNK_WIDTH) {
for (int z = 8; z < (CHUNK_CACHE_WIDTH * CHUNK_WIDTH); z += CHUNK_WIDTH) { for (int z = 8; z < (LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_WIDTH); z += LevelConstants::CHUNK_WIDTH) {
progressStagePercentage = 100 * pp++ / Max; progressStagePercentage = 100 * pp++ / Max;
//printf("level generation progress %d\n", progressStagePercentage); //printf("level generation progress %d\n", progressStagePercentage);
B.start(); B.start();
level->getTile(x, 64, z); level->getTile(x, 64, z);
B.stop(); B.stop();
L.start(); L.start();
if (level->isNew()) if (level->isNew())
while (level->updateLights()) while (level->updateLights())
; ;
L.stop(); L.stop();
} }
} }
A.stop(); A.stop();
level->setUpdateLights(true); level->setUpdateLights(true);
C.start(); C.start();
for (int x = 0; x < CHUNK_CACHE_WIDTH; x++) for (int x = 0; x < LevelConstants::CHUNK_CACHE_WIDTH; x++)
{ {
for (int z = 0; z < CHUNK_CACHE_WIDTH; z++) for (int z = 0; z < LevelConstants::CHUNK_CACHE_WIDTH; z++)
{ {
LevelChunk* chunk = level->getChunk(x, z); LevelChunk* chunk = level->getChunk(x, z);
if (chunk && !chunk->createdFromSave) if (chunk && !chunk->createdFromSave)
@@ -462,32 +474,33 @@ void Minecraft::update() {
} }
TIMER_POP(); TIMER_POP();
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
if (gameMode != NULL) gameMode->render(timer.a); if (gameMode != NULL) gameMode->render(timer.a);
TIMER_PUSH("sound"); TIMER_PUSH("sound");
soundEngine->update(player, timer.a); soundEngine->update(player, timer.a);
TIMER_POP_PUSH("render"); TIMER_POP_PUSH("render");
gameRenderer->render(timer.a); gameRenderer->render(timer.a);
TIMER_POP(); TIMER_POP();
#else #else
CThread::sleep(1); CThread::sleep(1);
#endif #endif
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
Multitouch::resetThisUpdate(); Multitouch::resetThisUpdate();
#endif #endif
TIMER_POP();
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
TIMER_POP();
checkGlError("Update finished"); checkGlError("Update finished");
if (options.getBooleanValue(OPTIONS_RENDER_DEBUG)) { if (options.getBooleanValue(OPTIONS_RENDER_DEBUG)) {
#ifndef PLATFORM_DESKTOP //#ifndef PLATFORM_DESKTOP
if (!PerfTimer::enabled) { if (!PerfTimer::enabled) {
PerfTimer::reset(); PerfTimer::reset();
PerfTimer::enabled = true; PerfTimer::enabled = true;
} }
_perfRenderer->renderFpsMeter(1); _perfRenderer->renderFpsMeter(1);
checkGlError("render debug"); checkGlError("render debug");
#endif //#endif
} else { } else {
PerfTimer::enabled = false; PerfTimer::enabled = false;
} }
@@ -564,17 +577,17 @@ void Minecraft::tick(int nTick, int maxTick) {
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
textures->loadAndBindTexture("terrain.png"); textures->loadAndBindTexture("terrain.png");
if (!pause && !(screen && !screen->renderGameBehind())) { if (!pause && !(screen && !screen->renderGameBehind())) {
#if !defined(RPI) #if !defined(RPI)
#ifdef __APPLE__ #ifdef __APPLE__
if (isSuperFast()) if (isSuperFast())
#endif #endif
{ {
if (nTick == maxTick) { if (nTick == maxTick) {
TIMER_POP_PUSH("textures"); TIMER_POP_PUSH("textures");
textures->tick(true); textures->tick(true);
} }
} }
#endif #endif
} }
TIMER_POP_PUSH("particles"); TIMER_POP_PUSH("particles");
if (!pause) { if (!pause) {
@@ -636,8 +649,8 @@ void Minecraft::tickInput() {
while (Mouse::next()) { while (Mouse::next()) {
//if (Mouse::getButtonState(MouseAction::ACTION_LEFT)) //if (Mouse::getButtonState(MouseAction::ACTION_LEFT))
// LOGI("mouse-down-at: %d, %d\n", Mouse::getX(), Mouse::getY()); // LOGI("mouse-down-at: %d, %d\n", Mouse::getX(), Mouse::getY());
int passedTime = getTimeMs() - lastTickTime; int passedTime = getTimeMs() - lastTickTime;
if (passedTime > 200) continue; // @note: As long Mouse::clear CLEARS the whole buffer, it's safe to break here if (passedTime > 200) continue; // @note: As long Mouse::clear CLEARS the whole buffer, it's safe to break here
// But since it might be rewritten anyway (and hopefully there aren't a lot of messages, we just continue. // But since it might be rewritten anyway (and hopefully there aren't a lot of messages, we just continue.
const MouseAction& e = Mouse::getEvent(); const MouseAction& e = Mouse::getEvent();
@@ -668,14 +681,14 @@ void Minecraft::tickInput() {
} }
/* /*
if (mouseDiggable && options.useMouseForDigging) { if (mouseDiggable && options.useMouseForDigging) {
if (Mouse::getEventButton() == MouseAction::ACTION_LEFT && Mouse::getEventButtonState()) { if (Mouse::getEventButton() == MouseAction::ACTION_LEFT && Mouse::getEventButtonState()) {
handleMouseClick(MouseAction::ACTION_LEFT); handleMouseClick(MouseAction::ACTION_LEFT);
lastClickTick = ticks; lastClickTick = ticks;
} }
if (Mouse::getEventButton() == MouseAction::ACTION_RIGHT && Mouse::getEventButtonState()) { if (Mouse::getEventButton() == MouseAction::ACTION_RIGHT && Mouse::getEventButtonState()) {
handleMouseClick(MouseAction::ACTION_RIGHT); handleMouseClick(MouseAction::ACTION_RIGHT);
lastClickTick = ticks; lastClickTick = ticks;
} }
} }
*/ */
} }
@@ -696,20 +709,20 @@ void Minecraft::tickInput() {
if (slot >= 0 && slot < gui.getNumSlots()) if (slot >= 0 && slot < gui.getNumSlots())
player->inventory->selectSlot(slot); player->inventory->selectSlot(slot);
#if defined(WIN32) #if defined(WIN32)
if (digit >= 1 && GetAsyncKeyState(VK_CONTROL) < 0) { if (digit >= 1 && GetAsyncKeyState(VK_CONTROL) < 0) {
// Set adventure settings here! // Set adventure settings here!
AdventureSettingsPacket p(level->adventureSettings); AdventureSettingsPacket p(level->adventureSettings);
p.toggle((AdventureSettingsPacket::Flags)(1 << slot)); p.toggle((AdventureSettingsPacket::Flags)(1 << slot));
p.fillIn(level->adventureSettings); p.fillIn(level->adventureSettings);
raknetInstance->send(p); raknetInstance->send(p);
} }
if (digit == 0) { if (digit == 0) {
Pos pos((int)player->x, (int)player->y-1, (int)player->z); Pos pos((int)player->x, (int)player->y-1, (int)player->z);
SetSpawnPositionPacket p(pos); SetSpawnPositionPacket p(pos);
raknetInstance->send(p); raknetInstance->send(p);
} }
#endif #endif
} }
if (key == Keyboard::KEY_LEFT_CTRL) { if (key == Keyboard::KEY_LEFT_CTRL) {
@@ -728,12 +741,27 @@ void Minecraft::tickInput() {
options.toggle(OPTIONS_RENDER_DEBUG); options.toggle(OPTIONS_RENDER_DEBUG);
} }
// TODO: replace it with client /give command :face_vomiting:
// if (key == Keyboard::KEY_F4) {
// player->inventory->add(new ItemInstance(Tile::redBrick));
// player->inventory->add(new ItemInstance(Item::ironIngot, 64));
// player->inventory->add(new ItemInstance(Item::ironIngot, 34));
// player->inventory->add(new ItemInstance(Tile::stonecutterBench));
// player->inventory->add(new ItemInstance(Tile::workBench));
// player->inventory->add(new ItemInstance(Tile::furnace));
// player->inventory->add(new ItemInstance(Tile::wood, 54));
// player->inventory->add(new ItemInstance(Item::stick, 14));
// player->inventory->add(new ItemInstance(Item::coal, 31));
// player->inventory->add(new ItemInstance(Tile::sand, 6));
// }
if (key == Keyboard::KEY_F5) { if (key == Keyboard::KEY_F5) {
options.toggle(OPTIONS_THIRD_PERSON_VIEW); options.toggle(OPTIONS_THIRD_PERSON_VIEW);
/* /*
ImprovedNoise noise; ImprovedNoise noise;
for (int i = 0; i < 16; ++i) for (int i = 0; i < 16; ++i)
printf("%d\t%f\n", i, noise.grad2(i, 3, 8)); printf("%d\t%f\n", i, noise.grad2(i, 3, 8));
*/ */
} }
@@ -746,119 +774,128 @@ void Minecraft::tickInput() {
options.set(OPTIONS_VIEW_DISTANCE, (dst + 1) % 4); options.set(OPTIONS_VIEW_DISTANCE, (dst + 1) % 4);
} }
#ifdef CHEATS #ifdef CHEATS
if (key == Keyboard::KEY_U) { if (key == Keyboard::KEY_U) {
onGraphicsReset(); onGraphicsReset();
player->heal(100); player->heal(100);
}
if (key == Keyboard::KEY_B || key == 108) // Toggle the game mode
setIsCreativeMode(!isCreativeMode());
if (key == Keyboard::KEY_P) // Step forward in time
level->setTime( level->getTime() + 1000);
if (key == Keyboard::KEY_G) {
setScreen(new ArmorScreen());
/*
std::vector<AABB>& boxs = level->getCubes(NULL, AABB(128.1f, 73, 128.1f, 128.9f, 74.9f, 128.9f));
LOGI("boxes: %d\n", (int)boxs.size());
*/
}
if (key == Keyboard::KEY_Y) {
textures->reloadAll();
player->hurtTo(2);
}
if (key == Keyboard::KEY_Z || key == 108) {
for (int i = 0; i < 1; ++i) {
Mob* mob = NULL;
int forceId = 0;//MobTypes::Sheep;
int types[] = {
MobTypes::Sheep,
MobTypes::Pig,
MobTypes::Chicken,
MobTypes::Cow,
};
int mobType = (forceId > 0)? forceId : types[Mth::random(sizeof(types) / sizeof(int))];
mob = MobFactory::CreateMob(mobType, level);
//((Animal*)mob)->setAge(-1000);
float dx = 4 - 8 * Mth::random() + 4 * Mth::sin(Mth::DEGRAD * player->yRot);
float dz = 4 - 8 * Mth::random() + 4 * Mth::cos(Mth::DEGRAD * player->yRot);
if (mob && !MobSpawner::addMob(level, mob, player->x + dx, player->y, player->z + dz, Mth::random()*360, 0, true))
delete mob;
} }
}
if (key == Keyboard::KEY_B || key == 108) // Toggle the game mode if (key == Keyboard::KEY_X) {
setIsCreativeMode(!isCreativeMode()); const EntityList& entities = level->getAllEntities();
for (int i = entities.size()-1; i >= 0; --i) {
if (key == Keyboard::KEY_P) // Step forward in time Entity* e = entities[i];
level->setTime( level->getTime() + 1000); if (!e->isPlayer())
level->removeEntity(e);
if (key == Keyboard::KEY_G) {
setScreen(new ArmorScreen());
/*
std::vector<AABB>& boxs = level->getCubes(NULL, AABB(128.1f, 73, 128.1f, 128.9f, 74.9f, 128.9f));
LOGI("boxes: %d\n", (int)boxs.size());
*/
} }
}
if (key == Keyboard::KEY_Y) { if (key == Keyboard::KEY_C /*|| key == 4*/) {
textures->reloadAll(); player->inventory->clearInventoryWithDefault();
player->hurtTo(2); // @todo: Add saving here for benchmarking
} }
if (key == Keyboard::KEY_Z || key == 108) { if (key == Keyboard::KEY_H) {
for (int i = 0; i < 1; ++i) { setScreen( new PrerenderTilesScreen() );
Mob* mob = NULL; }
int forceId = 0;//MobTypes::Sheep;
int types[] = { if (key == Keyboard::KEY_O) {
MobTypes::Sheep, for (int i = Inventory::MAX_SELECTION_SIZE; i < player->inventory->getContainerSize(); ++i)
MobTypes::Pig, if (player->inventory->getItem(i))
MobTypes::Chicken, player->inventory->dropSlot(i, false);
MobTypes::Cow, }
}; if (key == Keyboard::KEY_M) {
Difficulty difficulty = (Difficulty)options.getIntValue(OPTIONS_DIFFICULTY);
options.set(OPTIONS_DIFFICULTY, (difficulty == Difficulty::PEACEFUL)?
Difficulty::NORMAL : Difficulty::PEACEFUL);
//setIsCreativeMode( !isCreativeMode() );
}
int mobType = (forceId > 0)? forceId : types[Mth::random(sizeof(types) / sizeof(int))]; if (options.getBooleanValue(OPTIONS_RENDER_DEBUG)) {
mob = MobFactory::CreateMob(mobType, level); if (key >= '0' && key <= '9') {
_perfRenderer->debugFpsMeterKeyPress(key - '0');
}
}
#endif
//((Animal*)mob)->setAge(-1000); if (options.getBooleanValue(OPTIONS_RENDER_DEBUG)) {
float dx = 4 - 8 * Mth::random() + 4 * Mth::sin(Mth::DEGRAD * player->yRot); if (key >= '0' && key <= '9') {
float dz = 4 - 8 * Mth::random() + 4 * Mth::cos(Mth::DEGRAD * player->yRot); _perfRenderer->debugFpsMeterKeyPress(key - '0');
if (mob && !MobSpawner::addMob(level, mob, player->x + dx, player->y, player->z + dz, Mth::random()*360, 0, true))
delete mob;
}
} }
}
if (key == Keyboard::KEY_X) {
const EntityList& entities = level->getAllEntities();
for (int i = entities.size()-1; i >= 0; --i) {
Entity* e = entities[i];
if (!e->isPlayer())
level->removeEntity(e);
}
}
if (key == Keyboard::KEY_C /*|| key == 4*/) {
player->inventory->clearInventoryWithDefault();
// @todo: Add saving here for benchmarking
}
if (key == Keyboard::KEY_H) {
setScreen( new PrerenderTilesScreen() );
}
if (key == Keyboard::KEY_O) {
for (int i = Inventory::MAX_SELECTION_SIZE; i < player->inventory->getContainerSize(); ++i)
if (player->inventory->getItem(i))
player->inventory->dropSlot(i, false);
}
if (key == Keyboard::KEY_M) {
Difficulty difficulty = (Difficulty)options.getIntValue(OPTIONS_DIFFICULTY);
options.set(OPTIONS_DIFFICULTY, (difficulty == Difficulty::PEACEFUL)?
Difficulty::NORMAL : Difficulty::PEACEFUL);
//setIsCreativeMode( !isCreativeMode() );
}
if (options.getBooleanValue(OPTIONS_RENDER_DEBUG)) {
if (key >= '0' && key <= '9') {
_perfRenderer->debugFpsMeterKeyPress(key - '0');
}
}
#endif
if (key == Keyboard::KEY_ESCAPE) if (key == Keyboard::KEY_ESCAPE)
pauseGame(false); pauseGame(false);
#ifndef OPENGL_ES #ifdef PLATFORM_DESKTOP
if (key == Keyboard::KEY_P) { if (key == Keyboard::KEY_P) {
static bool isWireFrame = false; static bool isWireFrame = false;
isWireFrame = !isWireFrame; isWireFrame = !isWireFrame;
glPolygonMode(GL_FRONT, isWireFrame? GL_LINE : GL_FILL); glPolygonMode(GL_FRONT, isWireFrame? GL_LINE : GL_FILL);
//glPolygonMode(GL_BACK, isWireFrame? GL_LINE : GL_FILL); //glPolygonMode(GL_BACK, isWireFrame? GL_LINE : GL_FILL);
}
#endif
}
#ifdef WIN32
if (key == Keyboard::KEY_M) {
for (int i = 0; i < 5 * SharedConstants::TicksPerSecond; ++i)
level->tick();
} }
#endif #endif
}
#ifdef WIN32
if (key == Keyboard::KEY_M) {
for (int i = 0; i < 5 * SharedConstants::TicksPerSecond; ++i)
level->tick();
}
#endif
} }
TIMER_POP_PUSH("handlemouse"); TIMER_POP_PUSH("handlemouse");
static bool prevMouseDownLeft = false; static bool prevMouseDownLeft = false;
if (Mouse::getButtonState(MouseAction::ACTION_LEFT) == 0) { if (!useTouchscreen()) {
gameMode->stopDestroyBlock(); if (Mouse::getButtonState(MouseAction::ACTION_LEFT) == 0) {
} gameMode->stopDestroyBlock();
}
if (!Mouse::isButtonDown(MouseAction::ACTION_RIGHT)) { if (!Mouse::isButtonDown(MouseAction::ACTION_RIGHT)) {
gameMode->releaseUsingItem(player); gameMode->releaseUsingItem(player);
}
} }
if (useTouchscreen()) { if (useTouchscreen()) {
@@ -869,6 +906,9 @@ void Minecraft::tickInput() {
handleBuildAction(&bai); handleBuildAction(&bai);
} else { } else {
gameMode->stopDestroyBlock(); gameMode->stopDestroyBlock();
if (player && player->isUsingItem()) {
gameMode->releaseUsingItem(player);
}
} }
} else { } else {
// Desktop: left mouse = destroy/attack // Desktop: left mouse = destroy/attack
@@ -921,35 +961,35 @@ void Minecraft::handleBuildAction(BuildActionIntention* action) {
} }
if(player->isUsingItem()) if(player->isUsingItem())
return; return;
bool mayUse = true; bool mayUse = true;
if (!hitResult.isHit()) { if (!hitResult.isHit()) {
if (action->isRemove() && !gameMode->isCreativeType()) { if (action->isRemove() && !gameMode->isCreativeType()) {
missTime = 10; missTime = 10;
} }
} else if (hitResult.type == ENTITY) { } else if (hitResult.type == ENTITY) {
if (action->isAttack()) { if (action->isAttack()) {
player->swing(); player->swing();
//LOGI("attacking!\n"); //LOGI("attacking!\n");
InteractPacket packet(InteractPacket::Attack, player->entityId, hitResult.entity->entityId); InteractPacket packet(InteractPacket::Attack, player->entityId, hitResult.entity->entityId);
raknetInstance->send(packet); raknetInstance->send(packet);
gameMode->attack(player, hitResult.entity); gameMode->attack(player, hitResult.entity);
} else if (action->isInteract()) { } else if (action->isInteract()) {
if (hitResult.entity->interactPreventDefault()) if (hitResult.entity->interactPreventDefault())
mayUse = false; mayUse = false;
//LOGI("interacting!\n"); //LOGI("interacting!\n");
InteractPacket packet(InteractPacket::Interact, player->entityId, hitResult.entity->entityId); InteractPacket packet(InteractPacket::Interact, player->entityId, hitResult.entity->entityId);
raknetInstance->send(packet); raknetInstance->send(packet);
gameMode->interact(player, hitResult.entity); gameMode->interact(player, hitResult.entity);
} }
} else if (hitResult.type == TILE) { } else if (hitResult.type == TILE) {
int x = hitResult.x; int x = hitResult.x;
int y = hitResult.y; int y = hitResult.y;
int z = hitResult.z; int z = hitResult.z;
int face = hitResult.f; int face = hitResult.f;
int oldTileId = level->getTile(x, y, z); int oldTileId = level->getTile(x, y, z);
Tile* oldTile = Tile::tiles[oldTileId]; Tile* oldTile = Tile::tiles[oldTileId];
//bool tryDestroyBlock = false; //bool tryDestroyBlock = false;
@@ -958,7 +998,7 @@ void Minecraft::handleBuildAction(BuildActionIntention* action) {
return; return;
//LOGI("tile: %s - %d, %d, %d. b: %f - %f\n", oldTile->getDescriptionId().c_str(), x, y, z, oldTile->getBrightness(level, x, y, z), oldTile->getBrightness(level, x, y+1, z)); //LOGI("tile: %s - %d, %d, %d. b: %f - %f\n", oldTile->getDescriptionId().c_str(), x, y, z, oldTile->getBrightness(level, x, y, z), oldTile->getBrightness(level, x, y+1, z));
level->extinguishFire(x, y, z, hitResult.f); level->extinguishFire(x, y, z, hitResult.f);
if (action->isFirstRemove()) { if (action->isFirstRemove()) {
gameMode->startDestroyBlock(x, y, z, hitResult.f); gameMode->startDestroyBlock(x, y, z, hitResult.f);
@@ -968,16 +1008,16 @@ void Minecraft::handleBuildAction(BuildActionIntention* action) {
particleEngine->crack(x, y, z, hitResult.f); particleEngine->crack(x, y, z, hitResult.f);
player->swing(); player->swing();
} }
else { else {
ItemInstance* item = player->inventory->getSelected(); ItemInstance* item = player->inventory->getSelected();
if (gameMode->useItemOn(player, level, item, x, y, z, face, hitResult.pos)) { if (gameMode->useItemOn(player, level, item, x, y, z, face, hitResult.pos)) {
mayUse = false; mayUse = false;
player->swing(); player->swing();
#ifdef RPI #ifdef RPI
} else if (item && item->id == ((Item*)Item::sword_iron)->id) { } else if (item && item->id == ((Item*)Item::sword_iron)->id) {
player->swing(); player->swing();
#endif #endif
} }
if (item && item->count <= 0) { if (item && item->count <= 0) {
player->inventory->clearSlot(player->inventory->selected); player->inventory->clearSlot(player->inventory->selected);
@@ -1003,7 +1043,7 @@ void Minecraft::handleBuildAction(BuildActionIntention* action) {
bool Minecraft::isOnlineClient() bool Minecraft::isOnlineClient()
{ {
return (level != NULL && level->isClientSide); return (level != NULL && level->isClientSide);
} }
bool Minecraft::isOnline() bool Minecraft::isOnline()
@@ -1070,8 +1110,8 @@ void Minecraft::setScreen( Screen* screen )
if (screen->isInGameScreen() && level) { if (screen->isInGameScreen() && level) {
level->saveLevelData(); level->saveLevelData();
level->saveGame(); level->saveGame();
} }
//noRender = false; //noRender = false;
} else { } else {
@@ -1108,7 +1148,7 @@ void Minecraft::releaseMouse()
bool Minecraft::useTouchscreen() { bool Minecraft::useTouchscreen() {
#if defined(TARGET_OS_IPHONE) #if defined(TARGET_OS_IPHONE)
return true; return true;
#elif defined(RPI) #elif defined(RPI)
return false; return false;
#endif #endif
@@ -1119,6 +1159,7 @@ bool Minecraft::supportNonTouchScreen() {
} }
void Minecraft::init() void Minecraft::init()
{ {
LevelChunk::ChunkBlockCount = LevelConstants::CHUNK_BLOCK_COUNT;
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
checkGlError("Init enter"); checkGlError("Init enter");
@@ -1131,7 +1172,8 @@ void Minecraft::init()
textures->addDynamicTexture(new WaterSideTexture()); textures->addDynamicTexture(new WaterSideTexture());
textures->addDynamicTexture(new LavaTexture()); textures->addDynamicTexture(new LavaTexture());
textures->addDynamicTexture(new LavaSideTexture()); textures->addDynamicTexture(new LavaSideTexture());
textures->addDynamicTexture(new FireTexture()); textures->addDynamicTexture(new FireTexture(0));
textures->addDynamicTexture(new FireTexture(1));
gui.texturesLoaded(textures); gui.texturesLoaded(textures);
levelRenderer = new LevelRenderer(this); levelRenderer = new LevelRenderer(this);
@@ -1139,7 +1181,7 @@ void Minecraft::init()
particleEngine = new ParticleEngine(level, textures); particleEngine = new ParticleEngine(level, textures);
// 4j's code for reference // 4j's code for reference
// FoliageColor::init(textures->loadTexturePixels(L"misc/foliagecolor.png")); // FoliageColor::init(textures->loadTexturePixels(L"misc/foliagecolor.png"));
// my code // my code
@@ -1148,14 +1190,18 @@ void Minecraft::init()
// now i can finally initialize foliage color, probably not the best way to handle this but i cant be arsed rn // now i can finally initialize foliage color, probably not the best way to handle this but i cant be arsed rn
FoliageColor::init(foliagePixels); FoliageColor::init(foliagePixels);
TextureId grassId = (textures->loadTexture("misc/foliagecolor.png")); // loading the uh png for foliage color TextureId grassId = (textures->loadTexture("misc/grasscolor.png")); // loading the uh png for foliage color
int* grassPixels = textures->loadTexturePixels(grassId, "misc/foliagecolor.png"); int* grassPixels = textures->loadTexturePixels(grassId, "misc/grasscolor.png");
GrassColor::init(grassPixels); GrassColor::init(grassPixels);
bool tint = options.getBooleanValue(OPTIONS_FOLIAGE_TINT); // finally, toggleable foliage color bool tint = options.getBooleanValue(OPTIONS_FOLIAGE_TINT); // finally, toggleable foliage color
FoliageColor::setUseTint(tint); FoliageColor::setUseTint(tint);
GrassColor::setUseTint(tint); GrassColor::setUseTint(tint);
bool sideTint = options.getBooleanValue(OPTIONS_TINTED_SIDE);
TileRenderer::setUseTint(sideTint);
// Platform specific initialization here // Platform specific initialization here
font = new Font(&options, "font/default8.png", textures); font = new Font(&options, "font/default8.png", textures);
@@ -1164,6 +1210,8 @@ void Minecraft::init()
checkGlError("Init complete"); checkGlError("Init complete");
#endif #endif
PluginsManager::get().init(*this);
options.load(); options.load();
setIsCreativeMode(false); // false means it's Survival Mode setIsCreativeMode(false); // false means it's Survival Mode
@@ -1172,55 +1220,78 @@ void Minecraft::init()
void Minecraft::setSize(int w, int h) { void Minecraft::setSize(int w, int h) {
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
transformResolution(&w, &h); transformResolution(&w, &h);
width = w; width = w;
height = h; height = h;
int screenWidth;
int guiScale = options.getIntValue(OPTIONS_GUI_SCALE); int screenHeight;
//#ifdef PLATFORM_DESKTOP
// determine gui scale, optionally overriding auto if (options.getBooleanValue(OPTIONS_WINDOW_SCALE)){ // scales with resolution using a formula instead of having hardcoded if checks
if (guiScale != 0) { int guiScale = options.getIntValue(OPTIONS_GUI_SCALE);
// manual selection: 1->small, 2->medium, 3->large, 4->larger, 5->largest if (guiScale == 0) {
switch (guiScale) { guiScale = 1000;
case 1: Gui::GuiScale = 2.0f; break;
case 2: Gui::GuiScale = 3.0f; break;
case 3: Gui::GuiScale = 4.0f; break;
case 4: Gui::GuiScale = 5.0f; break;
case 5: Gui::GuiScale = 6.0f; break;
default: Gui::GuiScale = 1.0f; break; // auto
} }
// determine gui scale, optionally overriding auto
Gui::GuiScale = (float)Mth::Min(guiScale, Mth::Max(1, Mth::Min(width / 320, height / 240)));
} else { } else {
// auto compute from resolution
if (width >= 1000) {
#ifdef __APPLE__ int guiScale = options.getIntValue(OPTIONS_GUI_SCALE);
Gui::GuiScale = (width > 2000)? 8.0f : 4.0f;
#else // determine gui scale, optionally overriding auto
Gui::GuiScale = 4.0f; if (guiScale != 0) {
#endif // manual selection: 1->small, 2->medium, 3->large, 4->larger, 5->largest
} switch (guiScale) {
else if (width >= 800) { case 1: Gui::GuiScale = 2.0f; break;
case 2: Gui::GuiScale = 3.0f; break;
case 3: Gui::GuiScale = 4.0f; break;
case 4: Gui::GuiScale = 5.0f; break;
case 5: Gui::GuiScale = 6.0f; break;
default: Gui::GuiScale = 1.0f; break; // auto
}
} else {
// auto compute from resolution
if (width >= 1000) {
#ifdef __APPLE__ #ifdef __APPLE__
Gui::GuiScale = 4.0f; Gui::GuiScale = (width > 2000)? 8.0f : 4.0f;
#else #else
Gui::GuiScale = 3.0f; Gui::GuiScale = 4.0f;
#endif #endif
} }
else if (width >= 400) else if (width >= 800) {
Gui::GuiScale = 2.0f; #ifdef __APPLE__
else Gui::GuiScale = 4.0f;
Gui::GuiScale = 1.0f; #else
Gui::GuiScale = 3.0f;
#endif
}
else if (width >= 400)
Gui::GuiScale = 2.0f;
else
Gui::GuiScale = 1.0f;
}
// if (platform()) {
// float pixelsPerMillimeter = options.getProgressValue(&Option::PIXELS_PER_MILLIMETER);
// pixelCalc.setPixelsPerMillimeter(pixelsPerMillimeter);
// pixelCalcUi.setPixelsPerMillimeter(pixelsPerMillimeter * Gui::InvGuiScale);
// }
} }
Gui::InvGuiScale = 1.0f / Gui::GuiScale;
int screenWidth = (int)(width * Gui::InvGuiScale);
int screenHeight = (int)(height * Gui::InvGuiScale);
// if (platform()) { Gui::InvGuiScale = 1.0f / Gui::GuiScale;
// float pixelsPerMillimeter = options.getProgressValue(&Option::PIXELS_PER_MILLIMETER); screenWidth = (int)(width * Gui::InvGuiScale);
// pixelCalc.setPixelsPerMillimeter(pixelsPerMillimeter); screenHeight = (int)(height * Gui::InvGuiScale);
// pixelCalcUi.setPixelsPerMillimeter(pixelsPerMillimeter * Gui::InvGuiScale);
// }
Config config = createConfig(this); Config config = createConfig(this);
gui.onConfigChanged(config); gui.onConfigChanged(config);
@@ -1253,9 +1324,9 @@ void Minecraft::reloadOptions() {
LOGI("Reloading-options\n"); LOGI("Reloading-options\n");
// @todo @fix Android and iOS behaves a bit differently when leaving // @todo @fix Android and iOS behaves a bit differently when leaving
// an options screen (Android recreates OpenGL surface) // an options screen (Android recreates OpenGL surface)
setSize(width, height); setSize(width, height);
} }
void Minecraft::_reloadInput() { void Minecraft::_reloadInput() {
@@ -1266,17 +1337,17 @@ void Minecraft::_reloadInput() {
if (useTouchHolder) { if (useTouchHolder) {
inputHolder = new TouchInputHolder(this, &options); inputHolder = new TouchInputHolder(this, &options);
} else { } else {
#if defined(ANDROID) || defined(__APPLE__) #if defined(ANDROID) || defined(__APPLE__)
inputHolder = new CustomInputHolder( inputHolder = new CustomInputHolder(
new XperiaPlayInput(&options), new XperiaPlayInput(&options),
new ControllerTurnInput(2, ControllerTurnInput::MODE_DELTA), new ControllerTurnInput(2, ControllerTurnInput::MODE_DELTA),
new IBuildInput()); new IBuildInput());
#else #else
inputHolder = new CustomInputHolder( inputHolder = new CustomInputHolder(
new KeyboardInput(&options), new KeyboardInput(&options),
new MouseTurnInput(MouseTurnInput::MODE_DELTA, width/2, height/2), new MouseTurnInput(MouseTurnInput::MODE_DELTA, width/2, height/2),
new MouseBuildInput()); new MouseBuildInput());
#endif #endif
} }
mouseHandler.setTurnInput(inputHolder->getTurnInput()); mouseHandler.setTurnInput(inputHolder->getTurnInput());
@@ -1329,11 +1400,8 @@ bool Minecraft::joinMultiplayerFromString( const std::string& server )
ip = server; ip = server;
} }
printf("%s \n", port.c_str());
if (isLookingForMultiplayer && netCallback) { if (isLookingForMultiplayer && netCallback) {
isLookingForMultiplayer = false; isLookingForMultiplayer = false;
printf("test");
int portNum = atoi(port.c_str()); int portNum = atoi(port.c_str());
return raknetInstance->connect(ip.c_str(), portNum); return raknetInstance->connect(ip.c_str(), portNum);
} }
@@ -1341,18 +1409,18 @@ bool Minecraft::joinMultiplayerFromString( const std::string& server )
} }
void Minecraft::hostMultiplayer(int port) { void Minecraft::hostMultiplayer(int port) {
// Tear down last instance // Tear down last instance
raknetInstance->disconnect(); raknetInstance->disconnect();
delete netCallback; delete netCallback;
netCallback = NULL; netCallback = NULL;
#if !defined(NO_NETWORK) #if !defined(NO_NETWORK)
netCallback = new ServerSideNetworkHandler(this, raknetInstance); netCallback = new ServerSideNetworkHandler(this, raknetInstance);
#ifdef STANDALONE_SERVER #ifdef STANDALONE_SERVER
raknetInstance->host("Server", port, 16); raknetInstance->host("Server", port, 16);
#else #else
raknetInstance->host(options.getStringValue(OPTIONS_USERNAME), port); raknetInstance->host(options.getStringValue(OPTIONS_USERNAME), port);
#endif #endif
#endif #endif
} }
@@ -1406,10 +1474,10 @@ void Minecraft::_levelGenerated()
player->resetPos(false); player->resetPos(false);
} }
if (level && level->dimension) { if (level && level->dimension) {
// For example, if you want FogType or any other option
level->dimension->FogType = options.getBooleanValue(OPTIONS_FOG_TYPE); level->dimension->FogType = options.getIntValue(OPTIONS_FOG_TYPE);
} }
this->cameraTargetPlayer = player; this->cameraTargetPlayer = player;
@@ -1437,6 +1505,34 @@ void Minecraft::_levelGenerated()
_hasSignaledGeneratingLevelFinished = true; _hasSignaledGeneratingLevelFinished = true;
} }
std::string Minecraft::gatherStats1() {
#ifndef STANDALONE_SERVER
return levelRenderer->gatherStats1();
#endif
return "Blank";
}
std::string Minecraft::gatherStats2() {
#ifndef STANDALONE_SERVER
return levelRenderer->gatherStats2();
#endif
return "Blank";
}
std::string Minecraft::gatherStats3() {
#ifndef STANDALONE_SERVER
return ("P: " + particleEngine->countParticles() + ". T: " + (level->gatherStats()));
#endif
return "Blank";
}
std::string Minecraft::gatherStats4() {
return level->gatherChunkSourceStats();
}
Player* Minecraft::respawnPlayer(int playerId) { Player* Minecraft::respawnPlayer(int playerId) {
for (unsigned int i = 0; i < level->players.size(); ++i) { for (unsigned int i = 0; i < level->players.size(); ++i) {
if (level->players[i]->entityId == playerId) { if (level->players[i]->entityId == playerId) {
@@ -1523,12 +1619,12 @@ LevelStorageSource* Minecraft::getLevelSource()
void Minecraft::audioEngineOn() { void Minecraft::audioEngineOn() {
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
soundEngine->enable(true); soundEngine->enable(true);
#endif #endif
} }
void Minecraft::audioEngineOff() { void Minecraft::audioEngineOff() {
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
soundEngine->enable(false); soundEngine->enable(false);
#endif #endif
} }
@@ -1599,17 +1695,25 @@ void Minecraft::optionUpdated(OptionId option, bool value ) {
} }
void Minecraft::optionUpdated(OptionId option, float value ) { void Minecraft::optionUpdated(OptionId option, float value ) {
// #ifndef STANDALONE_SERVER // #ifndef STANDALONE_SERVER
// if(option == OPTIONS_PIXELS_PER_MILLIMETER) { // if(option == OPTIONS_PIXELS_PER_MILLIMETER) {
// pixelCalcUi.setPixelsPerMillimeter(value * Gui::InvGuiScale); // pixelCalcUi.setPixelsPerMillimeter(value * Gui::InvGuiScale);
// pixelCalc.setPixelsPerMillimeter(value); // pixelCalc.setPixelsPerMillimeter(value);
// } // }
// #endif // #endif
} }
void Minecraft::optionUpdated(OptionId option, int value ) { void Minecraft::optionUpdated(OptionId option, int value ) {
if(option == OPTIONS_GUI_SCALE) { if(option == OPTIONS_GUI_SCALE) {
// reapply screen scaling using current window size // reapply screen scaling using current window size
setSize(width, height); setSize(width, height);
} }
}
void Minecraft::addMessage(const std::string& msg) {
#ifndef STANDALONE_SERVER
gui.addMessage(msg);
#else
LOGI("%s \n", msg.c_str());
#endif
} }

View File

@@ -2,6 +2,9 @@
#define NET_MINECRAFT_CLIENT__Minecraft_H__ #define NET_MINECRAFT_CLIENT__Minecraft_H__
#include "Options.h" #include "Options.h"
#include "commands/CommandManager.hpp"
#include <plugins/PluginsManager.hpp>
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
#include "MouseHandler.h" #include "MouseHandler.h"
#include "gui/Gui.h" #include "gui/Gui.h"
@@ -87,6 +90,14 @@ public:
void update(); void update();
std::string gatherStats1();
std::string gatherStats2();
std::string gatherStats4();
std::string gatherStats3();
void tick(int nTick, int maxTick); void tick(int nTick, int maxTick);
void tickInput(); void tickInput();
@@ -120,11 +131,17 @@ public:
void optionUpdated(OptionId option, bool value); void optionUpdated(OptionId option, bool value);
void optionUpdated(OptionId option, float value); void optionUpdated(OptionId option, float value);
void optionUpdated(OptionId option, int value); void optionUpdated(OptionId option, int value);
int getTicks() { return ticks; }
void addMessage(const std::string& msg);
#ifdef __APPLE__ #ifdef __APPLE__
bool _isSuperFast; bool _isSuperFast;
bool isSuperFast() { return _isSuperFast; } bool isSuperFast() { return _isSuperFast; }
#endif #endif
CommandManager& commandManager() { return m_commandManager; }
protected: protected:
void _levelGenerated(); void _levelGenerated();
@@ -197,7 +214,8 @@ public:
std::string externalCacheStoragePath; std::string externalCacheStoragePath;
protected: protected:
Timer timer; Timer timer;
// @note @attn @warn: this is dangerous as fuck!
// @note @attn @warn: this is dangerous as fuck!
volatile bool isGeneratingLevel; volatile bool isGeneratingLevel;
bool _hasSignaledGeneratingLevelFinished; bool _hasSignaledGeneratingLevelFinished;
@@ -225,6 +243,8 @@ private:
PerfRenderer* _perfRenderer; PerfRenderer* _perfRenderer;
CommandServer* _commandServer; CommandServer* _commandServer;
CommandManager m_commandManager;
}; };
#endif /*NET_MINECRAFT_CLIENT__Minecraft_H__*/ #endif /*NET_MINECRAFT_CLIENT__Minecraft_H__*/

View File

@@ -58,6 +58,10 @@ OptionBool ambientOcclusion("ao", true);
OptionBool useNormalLighting("normalLighting", true); OptionBool useNormalLighting("normalLighting", true);
OptionBool beautifulSky("beautifulSky", true);
OptionBool useVignette("useVignette", true);
OptionBool useTouchscreen("useTouchscreen", true); OptionBool useTouchscreen("useTouchscreen", true);
OptionBool serverVisible("servervisible", true); OptionBool serverVisible("servervisible", true);
@@ -68,10 +72,20 @@ OptionInt fogType("fogType", 0, 0, 2);
OptionBool javaHud("javaHud", false); OptionBool javaHud("javaHud", false);
OptionBool betaSky("betaSky", false);
OptionBool tintedSide("tintedSide", false);
OptionBool blockOutline("blockOutline", false); OptionBool blockOutline("blockOutline", false);
OptionBool restoredAnims("restoredAnims", true); OptionBool restoredAnims("restoredAnims", true);
OptionInt debugStyle("debugStyle", 0, 0, 1);
OptionInt menuStyle("menuStyle",0, 0, 2);
OptionBool windowScale("windowScale", false);
OptionInt keyForward("key.forward", Keyboard::KEY_W); OptionInt keyForward("key.forward", Keyboard::KEY_W);
OptionInt keyLeft("key.left", Keyboard::KEY_A); OptionInt keyLeft("key.left", Keyboard::KEY_A);
OptionInt keyBack("key.back", Keyboard::KEY_S); OptionInt keyBack("key.back", Keyboard::KEY_S);
@@ -124,6 +138,7 @@ void Options::initTable() {
m_options[OPTIONS_GUI_SCALE] = &guiScale; m_options[OPTIONS_GUI_SCALE] = &guiScale;
m_options[OPTIONS_WINDOW_SCALE] = &windowScale;
m_options[OPTIONS_SKIN] = &skin; m_options[OPTIONS_SKIN] = &skin;
m_options[OPTIONS_USERNAME] = &username; m_options[OPTIONS_USERNAME] = &username;
@@ -150,12 +165,18 @@ void Options::initTable() {
m_options[OPTIONS_BLOCK_OUTLINE] = &blockOutline; m_options[OPTIONS_BLOCK_OUTLINE] = &blockOutline;
m_options[OPTIONS_VIGNETTE] = &useVignette;
m_options[OPTIONS_BEAUTIFUL_SKY] = &beautifulSky;
m_options[OPTIONS_NORMAL_LIGHTING] = &useNormalLighting; m_options[OPTIONS_NORMAL_LIGHTING] = &useNormalLighting;
m_options[OPTIONS_RESTORED_ANIMS] = &restoredAnims; m_options[OPTIONS_RESTORED_ANIMS] = &restoredAnims;
m_options[OPTIONS_SERVER_VISIBLE] = &serverVisible; m_options[OPTIONS_SERVER_VISIBLE] = &serverVisible;
m_options[OPTIONS_MENU_STYLE] = &menuStyle;
m_options[OPTIONS_KEY_FORWARD] = &keyForward; m_options[OPTIONS_KEY_FORWARD] = &keyForward;
m_options[OPTIONS_KEY_LEFT] = &keyLeft; m_options[OPTIONS_KEY_LEFT] = &keyLeft;
m_options[OPTIONS_KEY_BACK] = &keyBack; m_options[OPTIONS_KEY_BACK] = &keyBack;
@@ -183,6 +204,12 @@ void Options::initTable() {
// more options yay // more options yay
m_options[OPTIONS_FOG_TYPE] = &fogType; m_options[OPTIONS_FOG_TYPE] = &fogType;
m_options[OPTIONS_DEBUG_STYLE] = &debugStyle;
m_options[OPTIONS_BETA_SKY] = &betaSky;
m_options[OPTIONS_TINTED_SIDE] = &tintedSide;
m_options[OPTIONS_JAVA_HUD] = &javaHud; m_options[OPTIONS_JAVA_HUD] = &javaHud;
m_options[OPTIONS_AUTOJUMP] = &autoJump; m_options[OPTIONS_AUTOJUMP] = &autoJump;

View File

@@ -37,6 +37,7 @@ enum OptionId {
OPTIONS_BAR_ON_TOP, OPTIONS_BAR_ON_TOP,
OPTIONS_ALLOW_SPRINT, OPTIONS_ALLOW_SPRINT,
OPTIONS_AUTOJUMP, OPTIONS_AUTOJUMP,
OPTIONS_WINDOW_SCALE,
// Graphics // Graphics
OPTIONS_RENDER_DEBUG, OPTIONS_RENDER_DEBUG,
@@ -51,6 +52,7 @@ enum OptionId {
OPTIONS_FANCY_GRAPHICS, OPTIONS_FANCY_GRAPHICS,
OPTIONS_NORMAL_LIGHTING, OPTIONS_NORMAL_LIGHTING,
// Cheats / debug // Cheats / debug
OPTIONS_FLY_SPEED, OPTIONS_FLY_SPEED,
OPTIONS_CAMERA_SPEED, OPTIONS_CAMERA_SPEED,
@@ -90,6 +92,13 @@ enum OptionId {
OPTIONS_FOG_TYPE, OPTIONS_FOG_TYPE,
OPTIONS_JAVA_HUD, OPTIONS_JAVA_HUD,
OPTIONS_RESTORED_ANIMS, OPTIONS_RESTORED_ANIMS,
OPTIONS_TINTED_SIDE,
OPTIONS_BETA_SKY,
OPTIONS_BEAUTIFUL_SKY,
OPTIONS_VIGNETTE,
OPTIONS_DEBUG_STYLE,
OPTIONS_COMPLETE_LIGHTING,
OPTIONS_MENU_STYLE,
// Should be last! // Should be last!
OPTIONS_COUNT OPTIONS_COUNT
}; };

View File

@@ -18,8 +18,6 @@ OptionsFile::OptionsFile() {
settingsPath = "options.txt"; settingsPath = "options.txt";
#elif defined(__EMSCRIPTEN__) #elif defined(__EMSCRIPTEN__)
settingsPath = "/games/com.mojang/options.txt"; settingsPath = "/games/com.mojang/options.txt";
#elif defined(__HAIKU__)
settingsPath = "/system/settings/minecraftpe/options.txt";
#else #else
settingsPath = "options.txt"; settingsPath = "options.txt";
#endif #endif

View File

@@ -90,8 +90,12 @@ bool GameMode::useItemOn(Player* player, Level* level, ItemInstance* item, int x
float clickY = hit.y - y; float clickY = hit.y - y;
float clickZ = hit.z - z; float clickZ = hit.z - z;
if (level->isClientSide) { if (level->isClientSide) {
LOGI("%f %f %f \n", player->x, player->y, player->z);
item = player->inventory->getSelected(); item = player->inventory->getSelected();
UseItemPacket packet(x, y, z, face, item, player->entityId, clickX, clickY, clickZ); UseItemPacket packet(x, y, z, face, item, player->entityId, clickX, clickY, clickZ, player->x, player->y, player->z,
player->bb.x0, player->bb.y0, player->bb.z0, player->bb.x1, player->bb.y1, player->bb.z1);
minecraft->raknetInstance->send(packet); minecraft->raknetInstance->send(packet);
} }
int t = level->getTile(x, y, z); int t = level->getTile(x, y, z);
@@ -100,7 +104,7 @@ bool GameMode::useItemOn(Player* player, Level* level, ItemInstance* item, int x
return true; return true;
if (item == NULL) return false; if (item == NULL) return false;
if(isCreativeType()) { if (isCreativeType()) {
int aux = item->getAuxValue(); int aux = item->getAuxValue();
int count = item->count; int count = item->count;
bool success = item->useOn(player, level, x, y, z, face, clickX, clickY, clickZ); bool success = item->useOn(player, level, x, y, z, face, clickX, clickY, clickZ);
@@ -117,7 +121,8 @@ bool GameMode::useItem( Player* player, Level* level, ItemInstance* item ) {
ItemInstance* itemInstance = item->use(level, player); ItemInstance* itemInstance = item->use(level, player);
if(level->isClientSide) { if(level->isClientSide) {
UseItemPacket packet(item, player->entityId, player->aimDirection); UseItemPacket packet(item, player->entityId, player->aimDirection, player->x, player->y, player->z,
player->bb.x0, player->bb.y0, player->bb.z0, player->bb.x1, player->bb.y1, player->bb.z1);
minecraft->raknetInstance->send(packet); minecraft->raknetInstance->send(packet);
} }
if (itemInstance != item || (itemInstance != NULL && itemInstance->count != oldCount)) { if (itemInstance != item || (itemInstance != NULL && itemInstance->count != oldCount)) {

View File

@@ -68,6 +68,7 @@ bool SurvivalMode::destroyBlock( int x, int y, int z, int face ) {
minecraft->player->inventory->clearSlot(minecraft->player->inventory->selected); minecraft->player->inventory->clearSlot(minecraft->player->inventory->selected);
} }
} }
if (changed && couldDestroy) { if (changed && couldDestroy) {
ItemInstance instance(t, 1, data); ItemInstance instance(t, 1, data);
Tile::tiles[t]->playerDestroy(minecraft->level, minecraft->player, x, y, z, data); Tile::tiles[t]->playerDestroy(minecraft->level, minecraft->player, x, y, z, data);

View File

@@ -7,6 +7,7 @@
#include "screens/ConsoleScreen.h" #include "screens/ConsoleScreen.h"
#include "../Minecraft.h" #include "../Minecraft.h"
#include "../player/LocalPlayer.h" #include "../player/LocalPlayer.h"
#include "../renderer/Chunk.h"
#include "../renderer/Tesselator.h" #include "../renderer/Tesselator.h"
#include "../renderer/TileRenderer.h" #include "../renderer/TileRenderer.h"
#include "../renderer/LevelRenderer.h" #include "../renderer/LevelRenderer.h"
@@ -103,10 +104,10 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) {
} }
} }
// @todo - Shredder: I added this here but currently viginette is broken so i cant do much about it. // viginette has been fixed, was due to gl_blend not being enabled, my bad
// if (minecraft->options.getBooleanValue(OPTIONS_FANCY_GRAPHICS)){ if (minecraft->options.getBooleanValue(OPTIONS_FANCY_GRAPHICS) && minecraft->options.getBooleanValue(OPTIONS_VIGNETTE)){
// this->renderVignette(this->minecraft->player->getBrightness(a), screenWidth, screenHeight); renderVignette(this->minecraft->player->getBrightness(a), screenWidth, screenHeight);
// } }
// shredder end // shredder end
if(minecraft->player->getSleepTimer() > 0) { if(minecraft->player->getSleepTimer() > 0) {
@@ -121,6 +122,9 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) {
if (!minecraft->options.getBooleanValue(OPTIONS_HIDEGUI)) { if (!minecraft->options.getBooleanValue(OPTIONS_HIDEGUI)) {
renderToolBar(a, ySlot, screenWidth); renderToolBar(a, ySlot, screenWidth);
// font->drawShadow("Minecraft - Pocket Edition ", 2, 2, 0xffffffff);
// font->drawShadow("This is a demo, not the finished product", 2, 10 + 2, 0xffffffff);
glEnable(GL_BLEND); glEnable(GL_BLEND);
bool isChatting = (minecraft->screen && (dynamic_cast<ChatScreen*>(minecraft->screen) || dynamic_cast<ConsoleScreen*>(minecraft->screen))); bool isChatting = (minecraft->screen && (dynamic_cast<ChatScreen*>(minecraft->screen) || dynamic_cast<ConsoleScreen*>(minecraft->screen)));
unsigned int max = 10; unsigned int max = 10;
@@ -220,58 +224,58 @@ void Gui::handleClick(int button, int x, int y) {
} }
} }
void Gui::handleKeyPressed(int key) void Gui::handleKeyPressed(int key)
{ {
bool isChatting = (minecraft->screen && (dynamic_cast<ChatScreen*>(minecraft->screen) || dynamic_cast<ConsoleScreen*>(minecraft->screen))); bool isChatting = (minecraft->screen && (dynamic_cast<ChatScreen*>(minecraft->screen) || dynamic_cast<ConsoleScreen*>(minecraft->screen)));
if (isChatting) { if (isChatting) {
// Allow scrolling the chat history with the mouse/keyboard when chat is open // Allow scrolling the chat history with the mouse/keyboard when chat is open
if (key == 38) { // VK_UP if (key == 38) { // VK_UP
scrollChat(1); scrollChat(1);
return; return;
} else if (key == 40) { // VK_DOWN } else if (key == 40) { // VK_DOWN
scrollChat(-1); scrollChat(-1);
return; return;
} else if (key == 33) { // VK_PRIOR (Page Up) } else if (key == 33) { // VK_PRIOR (Page Up)
// Scroll by a page // Scroll by a page
int screenHeight = (int)(minecraft->height * InvGuiScale); int screenHeight = (int)(minecraft->height * InvGuiScale);
int maxVisible = (screenHeight - 48) / 9; int maxVisible = (screenHeight - 48) / 9;
scrollChat(maxVisible); scrollChat(maxVisible);
return; return;
} else if (key == 34) { // VK_NEXT (Page Down) } else if (key == 34) { // VK_NEXT (Page Down)
int screenHeight = (int)(minecraft->height * InvGuiScale); int screenHeight = (int)(minecraft->height * InvGuiScale);
int maxVisible = (screenHeight - 48) / 9; int maxVisible = (screenHeight - 48) / 9;
scrollChat(-maxVisible); scrollChat(-maxVisible);
return; return;
}
} }
}
if (key == Keyboard::KEY_F1) { if (key == Keyboard::KEY_F1) {
minecraft->options.toggle(OPTIONS_HIDEGUI); minecraft->options.toggle(OPTIONS_HIDEGUI);
} }
if (key == 99) if (key == 99)
{
if (minecraft->player->inventory->selected > 0)
{ {
minecraft->player->inventory->selected--; if (minecraft->player->inventory->selected > 0)
{
minecraft->player->inventory->selected--;
}
}
else if (key == 4)
{
if (minecraft->player->inventory->selected < (getNumSlots() - 2))
{
minecraft->player->inventory->selected++;
}
}
else if (key == 100)
{
minecraft->screenChooser.setScreen(SCREEN_BLOCKSELECTION);
}
else if (key == minecraft->options.getIntValue(OPTIONS_KEY_DROP))
{
minecraft->player->inventory->dropSlot(minecraft->player->inventory->selected, false);
} }
} }
else if (key == 4)
{
if (minecraft->player->inventory->selected < (getNumSlots() - 2))
{
minecraft->player->inventory->selected++;
}
}
else if (key == 100)
{
minecraft->screenChooser.setScreen(SCREEN_BLOCKSELECTION);
}
else if (key == minecraft->options.getIntValue(OPTIONS_KEY_DROP))
{
minecraft->player->inventory->dropSlot(minecraft->player->inventory->selected, false);
}
}
void Gui::scrollChat(int delta) { void Gui::scrollChat(int delta) {
if (delta == 0) if (delta == 0)
@@ -360,6 +364,7 @@ void Gui::renderVignette(float br, int w, int h) {
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glDepthMask(false); glDepthMask(false);
glEnable(GL_BLEND);
glBlendFunc2(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); glBlendFunc2(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
glColor4f2(tbr, tbr, tbr, 1); glColor4f2(tbr, tbr, tbr, 1);
@@ -376,6 +381,7 @@ void Gui::renderVignette(float br, int w, int h) {
t.draw(); t.draw();
glDepthMask(true); glDepthMask(true);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glColor4f2(1, 1, 1, 1); glColor4f2(1, 1, 1, 1);
glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
} }
@@ -726,13 +732,20 @@ void Gui::onLevelGenerated() {
void Gui::renderDebugInfo() { void Gui::renderDebugInfo() {
// FPS counter (updates once per second) // FPS counter (updates once per second)
static float fps = 0.0f; static int fps = 0;
static float fpsLastTime = 0.0f; static int fpsLastTime = 0;
static int fpsFrames = 0; static int fpsFrames = 0;
static int displayChunkUpdates = 0;
float now = getTimeS(); float now = getTimeS();
fpsFrames++; fpsFrames++;
if (now - fpsLastTime >= 1.0f) { if (now - fpsLastTime >= 1) {
fps = fpsFrames / (now - fpsLastTime); fps = fpsFrames / (now - fpsLastTime);
displayChunkUpdates = Chunk::updates;
// 3. RESET the actual game counter to 0 for the next second
Chunk::updates = 0;
fpsFrames = 0; fpsFrames = 0;
fpsLastTime = now; fpsLastTime = now;
} }
@@ -742,7 +755,6 @@ void Gui::renderDebugInfo() {
// Position // Position
float px = p->x, py = p->y - p->heightOffset, pz = p->z; float px = p->x, py = p->y - p->heightOffset, pz = p->z;
posTranslator.to(px, py, pz);
int bx = (int)floorf(px), by = (int)floorf(py), bz = (int)floorf(pz); int bx = (int)floorf(px), by = (int)floorf(py), bz = (int)floorf(pz);
int cx = bx >> 4, cz = bz >> 4; int cx = bx >> 4, cz = bz >> 4;
@@ -769,7 +781,70 @@ void Gui::renderDebugInfo() {
long day = worldTime / Level::TICKS_PER_DAY; long day = worldTime / Level::TICKS_PER_DAY;
long seed = lvl ? lvl->getSeed() : 0; long seed = lvl ? lvl->getSeed() : 0;
// Block looking at
std::string CurrentTile = "Air";
if (minecraft->hitResult.type == TILE) {
int LookingX = minecraft->hitResult.x;
int LookingY = minecraft->hitResult.y;
int LookingZ = minecraft->hitResult.z;
int tileID = minecraft->level->getTile(LookingX, LookingY, LookingZ);
if (tileID > 0 && tileID < 256){
Tile* LookingTile = Tile::tiles[tileID];
if (LookingTile != NULL) {
CurrentTile = LookingTile->getDescriptionId();
} else {
CurrentTile = "Unknown Tile";
}
} else {
CurrentTile = "Air";
}
}
// Build lines (NULL entry = blank gap) // Build lines (NULL entry = blank gap)
Font* font = minecraft->font;
// @todo - add our own debug screen as an option alongside the restored java one, why does renderdebug have to be so jank - shredder
// if java beta's restored debug menu is enabled
if (minecraft->options.getIntValue(OPTIONS_DEBUG_STYLE) == 0){
char buf[128];
sprintf(buf, "Minecraft - Pocket Edition (%d fps, %d chunk updates)", (int)fps, displayChunkUpdates);
font->drawShadow(buf, 2, 2, 0xffffff);
font->drawShadow(minecraft->gatherStats1(), 2, 12, 0xFFFFFF);
font->drawShadow(minecraft->gatherStats2(), 2, 22, 0xFFFFFF);
font->drawShadow(minecraft->gatherStats3(), 2, 32, 0xFFFFFF);
font->drawShadow(minecraft->gatherStats4(), 2, 42, 0xFFFFFF);
sprintf(buf, "x: %.8f", minecraft->player->x);
drawString(font, buf, 2, 64, 0xE0E0E0);
sprintf(buf, "y: %.8f", minecraft->player->y);
drawString(font, buf, 2, 72, 0xE0E0E0);
sprintf(buf, "z: %.8f", minecraft->player->z);
drawString(font, buf, 2, 80, 0xE0E0E0);
sprintf(buf, "f: %d",Mth::floor(minecraft->player->yRot * 4.0f / 360.0f + 0.5) & 0x3);
drawString(font, buf, 2, 88, 0xE0E0E0);
sprintf(buf, "Seed: %.ld", lvl->getSeed());
drawString(font, buf, 2, 104, 0xE0E0E0);
sprintf(buf, "Dimension: %d (%s)", lvl->dimension->id, lvl->dimension->getDimension().c_str());
drawString(font, buf, 2, 114, 0xE0E0E0);
sprintf(buf, "Biome: %s", biomeName);
drawString(font, buf, 2, 124, 0xE0E0E0);
sprintf(buf, "Looking at: %s", CurrentTile.c_str());
drawString(font, buf, 2, 134, 0xE0E0E0);
}
else if (minecraft->options.getIntValue(OPTIONS_DEBUG_STYLE) == 1){
static char ln[8][96]; static char ln[8][96];
sprintf(ln[0], "Minecraft PE 0.6.1 alpha (mcpe64)"); sprintf(ln[0], "Minecraft PE 0.6.1 alpha (mcpe64)");
sprintf(ln[1], "%.1f fps", fps); sprintf(ln[1], "%.1f fps", fps);
@@ -784,7 +859,7 @@ void Gui::renderDebugInfo() {
const float LH = (float)Font::DefaultLineHeight; // 10 font-pixels const float LH = (float)Font::DefaultLineHeight; // 10 font-pixels
const float MGN = 2.0f; // left/top margin in font-pixels const float MGN = 2.0f; // left/top margin in font-pixels
const float PAD = 2.0f; // horizontal padding for background const float PAD = 2.0f; // horizontal padding for background
Font* font = minecraft->font; // Font* font = minecraft->font;
// 1) Draw semi-transparent background boxes behind each line // 1) Draw semi-transparent background boxes behind each line
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
@@ -807,6 +882,7 @@ void Gui::renderDebugInfo() {
font->draw(ln[i], MGN, y, col); font->draw(ln[i], MGN, y, col);
} }
t.endOverrideAndDraw(); t.endOverrideAndDraw();
}
} }
void Gui::renderPlayerList(Font* font, int screenWidth, int screenHeight) { void Gui::renderPlayerList(Font* font, int screenWidth, int screenHeight) {

View File

@@ -36,7 +36,7 @@ void OptionsItem::render( Minecraft* minecraft, int xm, int ym ) {
} }
text += ": " + scaleText; text += ": " + scaleText;
} }
if (m_optionId == OPTIONS_FOG_TYPE) { if (m_optionId == OPTIONS_FOG_TYPE) {
int value = minecraft->options.getIntValue(OPTIONS_FOG_TYPE); int value = minecraft->options.getIntValue(OPTIONS_FOG_TYPE);
std::string scaleText; std::string scaleText;
switch (value) { switch (value) {
@@ -46,6 +46,38 @@ void OptionsItem::render( Minecraft* minecraft, int xm, int ym ) {
} }
text += ": " + scaleText; text += ": " + scaleText;
} }
if (m_optionId == OPTIONS_DEBUG_STYLE) {
int value = minecraft->options.getIntValue(OPTIONS_DEBUG_STYLE);
std::string scaleText;
switch (value) {
case 0: scaleText = I18n::get("options.debugStyle.javaBeta"); break;
case 1: scaleText = I18n::get("options.debugStyle.custom"); break;
case 2: scaleText = I18n::get("options.fogType.unused"); break;
}
text += ": " + scaleText;
}
if (m_optionId == OPTIONS_MENU_STYLE) {
int value = minecraft->options.getIntValue(OPTIONS_MENU_STYLE);
std::string scaleText;
switch (value) {
case 0: scaleText = I18n::get("options.menuStyle.pocket"); break;
case 1: scaleText = I18n::get("options.menuStyle.xperia"); break;
case 2: scaleText = I18n::get("options.menuStyle.java"); break;
}
text += ": " + scaleText;
}
if (m_optionId == OPTIONS_VIEW_DISTANCE) {
int value = minecraft->options.getIntValue(OPTIONS_VIEW_DISTANCE);
std::string scaleText;
switch (value) {
case 0: scaleText = I18n::get("options.renderDistance.far"); break;
case 1: scaleText = I18n::get("options.renderDistance.normal"); break;
case 2: scaleText = I18n::get("options.renderDistance.short"); break;
case 3: scaleText = I18n::get("options.renderDistance.tiny"); break;
default: scaleText = "Debug"; break;
}
text += ": " + scaleText;
}
minecraft->font->draw(text, (float)x, (float)y + yOffset, 0x909090, false); minecraft->font->draw(text, (float)x, (float)y + yOffset, 0x909090, false);
super::render(minecraft, xm, ym); super::render(minecraft, xm, ym);

View File

@@ -8,6 +8,7 @@
#include "../../../network/ServerSideNetworkHandler.h" #include "../../../network/ServerSideNetworkHandler.h"
#include "../../../network/packet/ChatPacket.h" #include "../../../network/packet/ChatPacket.h"
#include "../../../platform/log.h" #include "../../../platform/log.h"
#include "util/StringUtils.h"
#include <sstream> #include <sstream>
#include <cstdlib> #include <cstdlib>
@@ -54,141 +55,37 @@ void ConsoleScreen::charPressed(char inputChar)
_input += inputChar; _input += inputChar;
} }
// ---------------------------------------------------------------------------
// execute: run _input as a command, print result, close screen
// ---------------------------------------------------------------------------
void ConsoleScreen::execute() void ConsoleScreen::execute()
{ {
if (!minecraft->level) return;
if (_input.empty()) { if (_input.empty()) {
minecraft->setScreen(NULL); return minecraft->setScreen(NULL);
return;
} }
if (_input[0] == '/') { // if (_input[0] == '/') {
// Command // // Command
std::string result = processCommand(_input); // _input = Util::stringTrim(_input.substr(1));
if (!result.empty())
minecraft->gui.addMessage(result); // std::istringstream iss(minecraft->commandManager().execute(*minecraft, *minecraft->player, _input));
} else { // for (std::string line; std::getline(iss, line); ) {
// Chat message: <name> message // minecraft->gui.addMessage(line);
std::string msg = std::string("<") + minecraft->player->name + "> " + _input; // }
// } else {
// @ai @rewrite
if (minecraft->netCallback && minecraft->raknetInstance->isServer()) { if (minecraft->netCallback && minecraft->raknetInstance->isServer()) {
// Hosting a LAN game: displayGameMessage shows locally + broadcasts MessagePacket to clients static_cast<ServerSideNetworkHandler*>(minecraft->netCallback)->displayGameMessage(_input);
static_cast<ServerSideNetworkHandler*>(minecraft->netCallback)->displayGameMessage(msg);
} else if (minecraft->netCallback) { } else if (minecraft->netCallback) {
// Connected client: send ChatPacket to server; server echoes it back as MessagePacket ChatPacket chatPkt(_input);
ChatPacket chatPkt(msg);
minecraft->raknetInstance->send(chatPkt); minecraft->raknetInstance->send(chatPkt);
} else { } else {
// Singleplayer: show locally only minecraft->gui.addMessage("<" + minecraft->player->name + "> " + _input);
minecraft->gui.addMessage(msg);
} }
} // }
minecraft->setScreen(NULL); minecraft->setScreen(NULL);
} }
// ---------------------------------------------------------------------------
// processCommand
// ---------------------------------------------------------------------------
static std::string trim(const std::string& s) {
size_t a = s.find_first_not_of(" \t");
if (a == std::string::npos) return "";
size_t b = s.find_last_not_of(" \t");
return s.substr(a, b - a + 1);
}
std::string ConsoleScreen::processCommand(const std::string& raw)
{
// strip leading '/'
std::string line = raw;
if (!line.empty() && line[0] == '/') line = line.substr(1);
line = trim(line);
// tokenise
std::vector<std::string> args;
{
std::istringstream ss(line);
std::string tok;
while (ss >> tok) args.push_back(tok);
}
if (args.empty()) return "";
Level* level = minecraft->level;
if (!level) return "No level loaded.";
// -----------------------------------------------------------------------
// /time ...
// -----------------------------------------------------------------------
if (args[0] == "time") {
if (args.size() < 2)
return "Usage: /time <add|set|query> ...";
const std::string& sub = args[1];
// -- time add <value> -----------------------------------------------
if (sub == "add") {
if (args.size() < 3) return "Usage: /time add <value>";
long delta = std::atol(args[2].c_str());
long newTime = level->getTime() + delta;
level->setTime(newTime);
std::ostringstream out;
out << "Set the time to " << (newTime % Level::TICKS_PER_DAY);
return out.str();
}
// -- time set <value|day|night|noon|midnight> -----------------------
if (sub == "set") {
if (args.size() < 3) return "Usage: /time set <value|day|night|noon|midnight>";
const std::string& val = args[2];
long t = -1;
if (val == "day") t = 1000;
else if (val == "noon") t = 6000;
else if (val == "night") t = 13000;
else if (val == "midnight") t = 18000;
else {
// numeric — accept positive integers only
bool numeric = true;
for (char c : val)
if (!std::isdigit((unsigned char)c)) { numeric = false; break; }
if (!numeric) return std::string("Unknown value: ") + val;
t = std::atol(val.c_str());
}
// Preserve the total day count so only the time-of-day changes
long dayCount = level->getTime() / Level::TICKS_PER_DAY;
long newTime = dayCount * Level::TICKS_PER_DAY + (t % Level::TICKS_PER_DAY);
level->setTime(newTime);
std::ostringstream out;
out << "Set the time to " << t;
return out.str();
}
// -- time query <daytime|gametime|day> ------------------------------
if (sub == "query") {
if (args.size() < 3) return "Usage: /time query <daytime|gametime|day>";
const std::string& what = args[2];
long total = level->getTime();
long daytime = total % Level::TICKS_PER_DAY;
long day = total / Level::TICKS_PER_DAY;
std::ostringstream out;
if (what == "daytime") { out << "The time of day is " << daytime; }
else if (what == "gametime") { out << "The game time is " << total; }
else if (what == "day") { out << "The day is " << day; }
else return std::string("Unknown query: ") + what;
return out.str();
}
return "Unknown sub-command. Usage: /time <add|set|query> ...";
}
return std::string("Unknown command: /") + args[0];
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// render // render
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@@ -25,7 +25,6 @@ public:
private: private:
void execute(); void execute();
std::string processCommand(const std::string& cmd);
std::string _input; std::string _input;
int _cursorBlink; // tick counter for cursor blink int _cursorBlink; // tick counter for cursor blink

View File

@@ -23,12 +23,15 @@ DeathScreen::~DeathScreen()
void DeathScreen::init() void DeathScreen::init()
{ {
if (/* minecraft->useTouchscreen() */ true) { if (minecraft->options.getIntValue(OPTIONS_MENU_STYLE) == 0) {
bRespawn = new Touch::TButton(1, "Respawn!"); bRespawn = new Touch::TButton(1, "Respawn!");
bTitle = new Touch::TButton(2, "Main menu"); bTitle = new Touch::TButton(2, "Main menu");
} else { } else if (minecraft->options.getIntValue(OPTIONS_MENU_STYLE) == 1) {
bRespawn = new Button(1, "Respawn!"); bRespawn = new Button(1, "Respawn!");
bTitle = new Button(2, "Main menu"); bTitle = new Button(2, "Main menu");
} else {
bRespawn = new Button(1, 0, 0, 200, 20, "Respawn");
bTitle = new Button(2, 0, 0, 200, 20, "Title menu");
} }
buttons.push_back(bRespawn); buttons.push_back(bRespawn);
buttons.push_back(bTitle); buttons.push_back(bTitle);
@@ -39,13 +42,23 @@ void DeathScreen::init()
void DeathScreen::setupPositions() void DeathScreen::setupPositions()
{ {
bRespawn->width = bTitle->width = width / 4; if (minecraft->options.getIntValue(OPTIONS_MENU_STYLE) == 2){
bRespawn->width = 200;
bTitle->width = 200;
int centerX = (width / 2) - (bRespawn->width / 2);
bRespawn->x = centerX;
bTitle->x = centerX;
bRespawn->y = (height / 2);
bTitle->y = bRespawn->y + 24;
} else {
bRespawn->width = bTitle->width = width / 4;
bRespawn->y = bTitle->y = height / 2; bRespawn->y = bTitle->y = height / 2;
bRespawn->x = width/2 - bRespawn->width - 10; bRespawn->x = width/2 - bRespawn->width - 10;
bTitle->x = width/2 + 10; bTitle->x = width/2 + 10;
}
LOGI("xyz: %d, %d (%d, %d)\n", bTitle->x, bTitle->y, width, height); // LOGI("xyz: %d, %d (%d, %d)\n", bTitle->x, bTitle->y, width, height);
} }
void DeathScreen::tick() { void DeathScreen::tick() {
@@ -56,10 +69,20 @@ void DeathScreen::render( int xm, int ym, float a )
{ {
fillGradient(0, 0, width, height, 0x60500000, 0xa0803030); fillGradient(0, 0, width, height, 0x60500000, 0xa0803030);
if (minecraft->options.getIntValue(OPTIONS_MENU_STYLE) == 2){
glPushMatrix2();
glScalef2(2, 2, 2);
drawCenteredString(font, "Game over!", width / 2 / 2, height / 8, 0xffffff);
glPopMatrix2();
std::stringstream ss;
ss << "Score: &e" << minecraft->player->getScore();
drawCenteredString(font, ss.str(), width / 2, (height / 4) + 32, 0xffffff);
} else {
glPushMatrix2(); glPushMatrix2();
glScalef2(2, 2, 2); glScalef2(2, 2, 2);
drawCenteredString(font, "You died!", width / 2 / 2, height / 8, 0xffffff); drawCenteredString(font, "You died!", width / 2 / 2, height / 8, 0xffffff);
glPopMatrix2(); glPopMatrix2();
}
if (_tick >= WAIT_TICKS) if (_tick >= WAIT_TICKS)
Screen::render(xm, ym, a); Screen::render(xm, ym, a);

View File

@@ -12,6 +12,7 @@
#include "../../renderer/Textures.h" #include "../../renderer/Textures.h"
#include "../../gamemode/GameMode.h" #include "../../gamemode/GameMode.h"
#include "ArmorScreen.h" #include "ArmorScreen.h"
#include "crafting/WorkbenchScreen.h"
#include "../components/Button.h" #include "../components/Button.h"
#if defined(__APPLE__) #if defined(__APPLE__)
@@ -27,7 +28,8 @@ IngameBlockSelectionScreen::IngameBlockSelectionScreen()
InventoryRows(1), InventoryRows(1),
InventoryCols(1), InventoryCols(1),
InventorySize(1), InventorySize(1),
bArmor(1, "Armor") bArmor(1, "Armor"),
bCrafting(1, "Crafting")
{ {
} }
@@ -43,6 +45,19 @@ void IngameBlockSelectionScreen::init()
(float)getSlotPosX(InventoryCols) + 4, (float)getSlotPosX(InventoryCols) + 4,
(float)getSlotPosY(InventoryRows) + 4); (float)getSlotPosY(InventoryRows) + 4);
if (!minecraft->isCreativeMode()) {
bArmor.width = 42;
bCrafting.width = 42;
bArmor.x = 0;
bArmor.y = height - bArmor.height;
bCrafting.x = 0;
bCrafting.y = height - bCrafting.height - 30;
buttons.push_back(&bArmor);
buttons.push_back(&bCrafting);
}
ItemInstance* selected = inventory->getSelected(); ItemInstance* selected = inventory->getSelected();
if (!selected || selected->isNull()) { if (!selected || selected->isNull()) {
selectedItem = 0; selectedItem = 0;
@@ -58,13 +73,6 @@ void IngameBlockSelectionScreen::init()
} }
if (!isAllowed(selectedItem)) if (!isAllowed(selectedItem))
selectedItem = 0; selectedItem = 0;
if (!minecraft->isCreativeMode()) {
bArmor.width = 42;
bArmor.x = 0;
bArmor.y = height - bArmor.height;
buttons.push_back(&bArmor);
}
} }
void IngameBlockSelectionScreen::removed() void IngameBlockSelectionScreen::removed()
@@ -124,7 +132,7 @@ void IngameBlockSelectionScreen::renderSlots()
//w.printEvery(1000, "render-blocksel"); //w.printEvery(1000, "render-blocksel");
glDisable2(GL_RESCALE_NORMAL); glDisable2(GL_RESCALE_NORMAL);
Lighting::turnOn(minecraft); Lighting::turnOff();
} }
int IngameBlockSelectionScreen::getSlotPosX(int slotX) { int IngameBlockSelectionScreen::getSlotPosX(int slotX) {
@@ -249,7 +257,7 @@ void IngameBlockSelectionScreen::mouseClicked(int x, int y, int buttonNum)
//minecraft->soundEngine->playUI("random.click", 1, 1); //minecraft->soundEngine->playUI("random.click", 1, 1);
} else { } else {
_pendingQuit = !_area.isInside((float)x, (float)y) _pendingQuit = !_area.isInside((float)x, (float)y)
&& !bArmor.isInside(x, y); && !bArmor.isInside(x, y) && !bCrafting.isInside(x, y);
} }
} }
if (!_pendingQuit) if (!_pendingQuit)
@@ -338,5 +346,8 @@ void IngameBlockSelectionScreen::buttonClicked( Button* button )
if (button == &bArmor) { if (button == &bArmor) {
minecraft->setScreen(new ArmorScreen()); minecraft->setScreen(new ArmorScreen());
} }
if (button == &bCrafting) {
minecraft->setScreen(new WorkbenchScreen(Recipe::SIZE_2X2));
}
super::buttonClicked(button); super::buttonClicked(button);
} }

View File

@@ -52,6 +52,7 @@ private:
bool _pendingQuit; bool _pendingQuit;
Button bArmor; Button bArmor;
Button bCrafting;
RectangleArea _area; RectangleArea _area;
}; };

View File

@@ -197,6 +197,7 @@ void OptionsScreen::generateOptionScreens() {
optionPanes[1]->addOptionItem(OPTIONS_DIFFICULTY, minecraft) optionPanes[1]->addOptionItem(OPTIONS_DIFFICULTY, minecraft)
.addOptionItem(OPTIONS_SERVER_VISIBLE, minecraft) .addOptionItem(OPTIONS_SERVER_VISIBLE, minecraft)
.addOptionItem(OPTIONS_THIRD_PERSON_VIEW, minecraft) .addOptionItem(OPTIONS_THIRD_PERSON_VIEW, minecraft)
.addOptionItem(OPTIONS_WINDOW_SCALE, minecraft)
.addOptionItem(OPTIONS_GUI_SCALE, minecraft) .addOptionItem(OPTIONS_GUI_SCALE, minecraft)
.addOptionItem(OPTIONS_SENSITIVITY, minecraft) .addOptionItem(OPTIONS_SENSITIVITY, minecraft)
.addOptionItem(OPTIONS_MUSIC_VOLUME, minecraft) .addOptionItem(OPTIONS_MUSIC_VOLUME, minecraft)
@@ -223,19 +224,26 @@ void OptionsScreen::generateOptionScreens() {
// .addOptionItem(&Option::ANAGLYPH, minecraft) // .addOptionItem(&Option::ANAGLYPH, minecraft)
.addOptionItem(OPTIONS_LIMIT_FRAMERATE, minecraft) .addOptionItem(OPTIONS_LIMIT_FRAMERATE, minecraft)
.addOptionItem(OPTIONS_VSYNC, minecraft) .addOptionItem(OPTIONS_VSYNC, minecraft)
.addOptionItem(OPTIONS_VIEW_DISTANCE, minecraft)
.addOptionItem(OPTIONS_RENDER_DEBUG, minecraft) .addOptionItem(OPTIONS_RENDER_DEBUG, minecraft)
.addOptionItem(OPTIONS_ANAGLYPH_3D, minecraft) .addOptionItem(OPTIONS_ANAGLYPH_3D, minecraft)
.addOptionItem(OPTIONS_VIEW_BOBBING, minecraft) .addOptionItem(OPTIONS_VIEW_BOBBING, minecraft)
.addOptionItem(OPTIONS_AMBIENT_OCCLUSION, minecraft) .addOptionItem(OPTIONS_AMBIENT_OCCLUSION, minecraft)
.addOptionItem(OPTIONS_NORMAL_LIGHTING, minecraft); .addOptionItem(OPTIONS_NORMAL_LIGHTING, minecraft)
.addOptionItem(OPTIONS_BEAUTIFUL_SKY, minecraft)
.addOptionItem(OPTIONS_VIGNETTE, minecraft);
optionPanes[4]->addOptionItem(OPTIONS_ALLOW_SPRINT, minecraft) optionPanes[4]->addOptionItem(OPTIONS_ALLOW_SPRINT, minecraft)
.addOptionItem(OPTIONS_BAR_ON_TOP, minecraft) .addOptionItem(OPTIONS_BAR_ON_TOP, minecraft)
.addOptionItem(OPTIONS_MENU_STYLE, minecraft)
.addOptionItem(OPTIONS_RPI_CURSOR, minecraft) .addOptionItem(OPTIONS_RPI_CURSOR, minecraft)
.addOptionItem(OPTIONS_FOLIAGE_TINT, minecraft) .addOptionItem(OPTIONS_FOLIAGE_TINT, minecraft)
.addOptionItem(OPTIONS_TINTED_SIDE, minecraft)
.addOptionItem(OPTIONS_JAVA_HUD, minecraft) .addOptionItem(OPTIONS_JAVA_HUD, minecraft)
.addOptionItem(OPTIONS_FOG_TYPE, minecraft) .addOptionItem(OPTIONS_FOG_TYPE, minecraft)
.addOptionItem(OPTIONS_RESTORED_ANIMS, minecraft); .addOptionItem(OPTIONS_BETA_SKY, minecraft)
.addOptionItem(OPTIONS_RESTORED_ANIMS, minecraft)
.addOptionItem(OPTIONS_DEBUG_STYLE, minecraft);
} }

View File

@@ -10,18 +10,18 @@
#include "client/gui/screens/OptionsScreen.h" #include "client/gui/screens/OptionsScreen.h"
PauseScreen::PauseScreen(bool wasBackPaused) PauseScreen::PauseScreen(bool wasBackPaused)
: saveStep(0), : saveStep(0),
visibleTime(0), visibleTime(0),
bContinue(0), bContinue(0),
bQuit(0), bQuit(0),
bOptions(0), bOptions(0),
bQuitAndSaveLocally(0), bQuitAndSaveLocally(0),
bServerVisibility(0), bServerVisibility(0),
// bThirdPerson(0), // bThirdPerson(0),
wasBackPaused(wasBackPaused), wasBackPaused(wasBackPaused),
// bSound(OPTIONS_SOUND_VOLUME, 1, 0), // bSound(OPTIONS_SOUND_VOLUME, 1, 0),
bThirdPerson(OPTIONS_THIRD_PERSON_VIEW), bThirdPerson(OPTIONS_THIRD_PERSON_VIEW),
bHideGui(OPTIONS_HIDEGUI) bHideGui(OPTIONS_HIDEGUI)
{ {
ImageDef def; ImageDef def;
def.setSrc(IntRectangle(160, 144, 39, 31)); def.setSrc(IntRectangle(160, 144, 39, 31));
@@ -34,7 +34,7 @@ PauseScreen::PauseScreen(bool wasBackPaused)
// bSound.setImageDef(def, true); // bSound.setImageDef(def, true);
defSrc.y += defSrc.h; defSrc.y += defSrc.h;
bThirdPerson.setImageDef(def, true); bThirdPerson.setImageDef(def, true);
bHideGui.setImageDef(def, true); bHideGui.setImageDef(def, true);
//void setImageDef(ImageDef& imageDef, bool setButtonSize); //void setImageDef(ImageDef& imageDef, bool setButtonSize);
} }
@@ -44,24 +44,31 @@ PauseScreen::~PauseScreen() {
delete bQuitAndSaveLocally; delete bQuitAndSaveLocally;
delete bServerVisibility; delete bServerVisibility;
delete bOptions; delete bOptions;
// delete bThirdPerson; // delete bThirdPerson;
} }
void PauseScreen::init() { void PauseScreen::init() {
if (/* minecraft->useTouchscreen() */ true) { if (minecraft->options.getIntValue(OPTIONS_MENU_STYLE) == 0) {
bContinue = new Touch::TButton(1, "Back to game"); bContinue = new Touch::TButton(1, "Back to game");
bOptions = new Touch::TButton(5, "Options"); bOptions = new Touch::TButton(5, "Options");
bQuit = new Touch::TButton(2, "Quit to title"); bQuit = new Touch::TButton(2, "Quit to title");
bQuitAndSaveLocally = new Touch::TButton(3, "Quit and copy map"); bQuitAndSaveLocally = new Touch::TButton(3, "Quit and copy map");
bServerVisibility = new Touch::TButton(4, ""); bServerVisibility = new Touch::TButton(4, "");
// bThirdPerson = new Touch::TButton(5, "Toggle 3:rd person view"); // bThirdPerson = new Touch::TButton(5, "Toggle 3:rd person view");
} else { } else if (minecraft->options.getIntValue(OPTIONS_MENU_STYLE) == 1) {
bContinue = new Button(1, "Back to game"); bContinue = new Button(1, "Back to game");
bOptions = new Button(5, "Options"); bOptions = new Button(5, "Options");
bQuit = new Button(2, "Quit to title"); bQuit = new Button(2, "Quit to title");
bQuitAndSaveLocally = new Button(3, "Quit and copy map"); bQuitAndSaveLocally = new Button(3, "Quit and copy map");
bServerVisibility = new Button(4, ""); bServerVisibility = new Button(4, "");
// bThirdPerson = new Button(5, "Toggle 3:rd person view"); // bThirdPerson = new Button(5, "Toggle 3:rd person view");
} else {
bContinue = new Button(1, 0, 0, 200, 20, "Back to game");
bServerVisibility = new Button(4, 0, 0, 200, 20, "");
bOptions = new Button(5, 0, 0, 200, 20, "Options...");
bQuit = new Button(2, 0, 0, 200, 20, "Save and quit to title");
bQuitAndSaveLocally = new Button(3, 0, 0, 200, 20, "Copy and quit map");
// bThirdPerson = new Button(5, "Toggle 3:rd person view");
} }
buttons.push_back(bContinue); buttons.push_back(bContinue);
@@ -72,12 +79,12 @@ void PauseScreen::init() {
bHideGui.updateImage(&minecraft->options); bHideGui.updateImage(&minecraft->options);
// buttons.push_back(&bSound); // buttons.push_back(&bSound);
buttons.push_back(&bThirdPerson); buttons.push_back(&bThirdPerson);
//buttons.push_back(&bHideGui); //buttons.push_back(&bHideGui);
// If Back wasn't pressed, set up additional items (more than Quit to menu // If Back wasn't pressed, set up additional items (more than Quit to menu
// and Back to game) here // and Back to game) here
#if !defined(APPLE_DEMO_PROMOTION) && !defined(RPI) #if !defined(APPLE_DEMO_PROMOTION) && !defined(RPI)
if (true || !wasBackPaused) { if (true || !wasBackPaused) {
if (minecraft->raknetInstance) { if (minecraft->raknetInstance) {
if (minecraft->raknetInstance->isServer()) { if (minecraft->raknetInstance->isServer()) {
@@ -85,14 +92,14 @@ void PauseScreen::init() {
buttons.push_back(bServerVisibility); buttons.push_back(bServerVisibility);
} }
else { else {
#if !defined(DEMO_MODE) #if !defined(DEMO_MODE)
buttons.push_back(bQuitAndSaveLocally); buttons.push_back(bQuitAndSaveLocally);
#endif #endif
} }
} }
} }
#endif #endif
// buttons.push_back(bThirdPerson); // buttons.push_back(bThirdPerson);
for (unsigned int i = 0; i < buttons.size(); ++i) { for (unsigned int i = 0; i < buttons.size(); ++i) {
// if (buttons[i] == &bSound) continue; // if (buttons[i] == &bSound) continue;
@@ -103,27 +110,48 @@ void PauseScreen::init() {
} }
void PauseScreen::setupPositions() { void PauseScreen::setupPositions() {
saveStep = 0; saveStep = 0;
int yBase = 16; int yBase = 16;
if (minecraft->options.getIntValue(OPTIONS_MENU_STYLE) == 2){
yBase = 50;
bContinue->width = bOptions->width = bQuit->width = /*bThirdPerson->w =*/ 160; bContinue->width = bOptions->width = bQuit->width = /*bThirdPerson->w =*/ 200;
bQuitAndSaveLocally->width = bServerVisibility->width = 160; bQuitAndSaveLocally->width = bServerVisibility->width = 200;
bContinue->x = (width - bContinue->width) / 2; bContinue->x = (width - bContinue->width) / 2;
bContinue->y = yBase + 32 * 1; bContinue->y = yBase + 24 * 1;
bOptions->x = (width - bOptions->width) / 2; bQuitAndSaveLocally->x = bServerVisibility->x = (width - bQuitAndSaveLocally->width) / 2;
bOptions->y = yBase + 32 * 2; bQuitAndSaveLocally->y = bServerVisibility->y = yBase + 24 * 2;
bQuit->x = (width - bQuit->width) / 2; bOptions->x = (width - bOptions->width) / 2;
bQuit->y = yBase + 32 * 3; bOptions->y = yBase + 24 * 3 + 24;
bQuit->x = (width - bQuit->width) / 2;
bQuit->y = yBase + 24 * 4 + 24;
} else {
bContinue->width = bOptions->width = bQuit->width = /*bThirdPerson->w =*/ 160;
bQuitAndSaveLocally->width = bServerVisibility->width = 160;
bContinue->x = (width - bContinue->width) / 2;
bContinue->y = yBase + 32 * 1;
bOptions->x = (width - bOptions->width) / 2;
bOptions->y = yBase + 32 * 2;
bQuit->x = (width - bQuit->width) / 2;
bQuit->y = yBase + 32 * 3;
#if APPLE_DEMO_PROMOTION #if APPLE_DEMO_PROMOTION
bQuit->y += 16; bQuit->y += 16;
#endif #endif
bQuitAndSaveLocally->x = bServerVisibility->x = (width - bQuitAndSaveLocally->width) / 2; bQuitAndSaveLocally->x = bServerVisibility->x = (width - bQuitAndSaveLocally->width) / 2;
bQuitAndSaveLocally->y = bServerVisibility->y = yBase + 32 * 4; bQuitAndSaveLocally->y = bServerVisibility->y = yBase + 32 * 4;
}
// bSound.y = bThirdPerson.y = 8; // bSound.y = bThirdPerson.y = 8;
// bSound.x = 4; // bSound.x = 4;
@@ -161,9 +189,9 @@ void PauseScreen::buttonClicked(Button* button) {
minecraft->setScreen(NULL); minecraft->setScreen(NULL);
//minecraft->grabMouse(); //minecraft->grabMouse();
} }
if (button->id == bQuit->id) { if (button->id == bQuit->id) {
minecraft->leaveGame(); minecraft->leaveGame();
} }
if (button->id == bQuitAndSaveLocally->id) { if (button->id == bQuitAndSaveLocally->id) {
minecraft->leaveGame(true); minecraft->leaveGame(true);
} }
@@ -197,5 +225,5 @@ void PauseScreen::updateServerVisibilityText()
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) minecraft->netCallback; ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) minecraft->netCallback;
bServerVisibility->msg = ss->allowsIncomingConnections()? bServerVisibility->msg = ss->allowsIncomingConnections()?
"Server is visible" "Server is visible"
: "Server is invisible"; : "Server is invisible";
} }

View File

@@ -21,7 +21,7 @@ Screen* ScreenChooser::createScreen( ScreenId id )
Screen* screen = NULL; Screen* screen = NULL;
// :sob: // :sob:
if (/* _mc->useTouchscreen() */ true) { if (_mc->options.getIntValue(OPTIONS_MENU_STYLE) == 0) {
switch (id) { switch (id) {
case SCREEN_STARTMENU: screen = new Touch::StartMenuScreen(); break; case SCREEN_STARTMENU: screen = new Touch::StartMenuScreen(); break;
case SCREEN_SELECTWORLD: screen = new Touch::SelectWorldScreen();break; case SCREEN_SELECTWORLD: screen = new Touch::SelectWorldScreen();break;

View File

@@ -23,49 +23,62 @@
// Some kind of default settings, might be overridden in ::init // Some kind of default settings, might be overridden in ::init
StartMenuScreen::StartMenuScreen() StartMenuScreen::StartMenuScreen()
: bHost( 2, 0, 0, 160, 24, "Start Game"),
bJoin( 3, 0, 0, 160, 24, "Join Game"),
bOptions( 4, 0, 0, 160, 24, "Options"),
bQuit( 5, "")
{ {
} }
StartMenuScreen::~StartMenuScreen() StartMenuScreen::~StartMenuScreen()
{ {
delete bHost;
delete bJoin;
delete bOptions;
delete bQuit;
} }
void StartMenuScreen::init() void StartMenuScreen::init()
{ {
bJoin.active = bHost.active = bOptions.active = true; if (minecraft->options.getIntValue(OPTIONS_MENU_STYLE) == 2){
bHost = new Button( 2, 0, 0, 200, 20, "Singleplayer");
bJoin = new Button( 3, 0, 0, 200, 20, "Multiplayer");
bOptions = new Button( 4, 0, 0, 200, 20, "Options...");
bQuit = new Button( 5, 0, 0, 200, 20, "Ouit Game");
} else {
bHost = new Button( 2, 0, 0, 160, 24, "Start Game");
bJoin = new Button( 3, 0, 0, 160, 24, "Join Game");
bOptions = new Button( 4, 0, 0, 160, 24, "Options");
bQuit = new Button( 5, 0, 0, 160, 24, "Ouit Game");
}
bJoin->active = bHost->active = bOptions->active = true;
if (minecraft->options.getStringValue(OPTIONS_USERNAME).empty()) { if (minecraft->options.getStringValue(OPTIONS_USERNAME).empty()) {
return; // tick() will redirect to UsernameScreen return; // tick() will redirect to UsernameScreen
} }
buttons.push_back(&bHost); buttons.push_back(bHost);
buttons.push_back(&bJoin); buttons.push_back(bJoin);
//buttons.push_back(&bTest); //buttons.push_back(&bTest);
buttons.push_back(bQuit);
tabButtons.push_back(&bHost); tabButtons.push_back(bHost);
tabButtons.push_back(&bJoin); tabButtons.push_back(bJoin);
tabButtons.push_back(bQuit);
#ifndef RPI #ifndef RPI
buttons.push_back(&bOptions); buttons.push_back(bOptions);
tabButtons.push_back(&bOptions); tabButtons.push_back(bOptions);
#endif #endif
// add quit button (top right X icon) match OptionsScreen style //// add quit button (top right X icon) match OptionsScreen style
{ //{
ImageDef def; // ImageDef def;
def.name = "gui/touchgui.png"; // def.name = "gui/touchgui.png";
def.width = 34; // def.width = 34;
def.height = 26; // def.height = 26;
def.setSrc(IntRectangle(150, 0, (int)def.width, (int)def.height)); // def.setSrc(IntRectangle(150, 0, (int)def.width, (int)def.height));
bQuit.setImageDef(def, true); // bQuit.setImageDef(def, true);
bQuit.scaleWhenPressed = false; // bQuit.scaleWhenPressed = false;
buttons.push_back(&bQuit); // buttons.push_back(&bQuit);
// don't include in tab navigation // // don't include in tab navigation
} //}
copyright = "\xffMojang AB";//. Do not distribute!"; copyright = "\xffMojang AB";//. Do not distribute!";
@@ -93,20 +106,30 @@ void StartMenuScreen::init()
} }
void StartMenuScreen::setupPositions() { void StartMenuScreen::setupPositions() {
int yBase = height / 2; if (minecraft->options.getIntValue(OPTIONS_MENU_STYLE) == 2){
int yBase = (height / 2) - 20;
bHost.y = yBase; bHost->y = yBase;
bJoin.y = bHost.y + 24 + 4; bJoin->y = bHost->y + 24;
bOptions.y = bJoin.y + 24 + 4; bOptions->y = bJoin->y + 24;
bQuit->y = bOptions->y + 24;
} else {
int yBase = height / 2;
bHost->y = yBase;
bJoin->y = bHost->y + 24 + 4;
bOptions->y = bJoin->y + 24 + 4;
bQuit->y = bOptions->y + 24 + 4;
}
// Center buttons // Center buttons
bHost.x = (width - bHost.width) / 2; bHost->x = (width - bHost->width) / 2;
bJoin.x = (width - bJoin.width) / 2; bJoin->x = (width - bJoin->width) / 2;
bOptions.x = (width - bOptions.width) / 2; bOptions->x = (width - bOptions->width) / 2;
bQuit->x = (width - bQuit->width) / 2;
// position quit icon at top-right (use image-defined size) //// position quit icon at top-right (use image-defined size)
bQuit.x = width - bQuit.width; //bQuit.x = width - bQuit.width;
bQuit.y = 0; //bQuit.y = 0;
} }
void StartMenuScreen::tick() { void StartMenuScreen::tick() {
@@ -114,7 +137,7 @@ void StartMenuScreen::tick() {
void StartMenuScreen::buttonClicked(Button* button) { void StartMenuScreen::buttonClicked(Button* button) {
if (button->id == bHost.id) if (button->id == bHost->id)
{ {
#if defined(DEMO_MODE) || defined(APPLE_DEMO_PROMOTION) #if defined(DEMO_MODE) || defined(APPLE_DEMO_PROMOTION)
minecraft->setScreen( new SimpleChooseLevelScreen("_DemoLevel") ); minecraft->setScreen( new SimpleChooseLevelScreen("_DemoLevel") );
@@ -122,16 +145,16 @@ void StartMenuScreen::buttonClicked(Button* button) {
minecraft->screenChooser.setScreen(SCREEN_SELECTWORLD); minecraft->screenChooser.setScreen(SCREEN_SELECTWORLD);
#endif #endif
} }
if (button->id == bJoin.id) if (button->id == bJoin->id)
{ {
minecraft->locateMultiplayer(); minecraft->locateMultiplayer();
minecraft->screenChooser.setScreen(SCREEN_JOINGAME); minecraft->screenChooser.setScreen(SCREEN_JOINGAME);
} }
if (button->id == bOptions.id) if (button->id == bOptions->id)
{ {
minecraft->setScreen(new OptionsScreen()); minecraft->setScreen(new OptionsScreen());
} }
if (button == &bQuit) if (button->id == bQuit->id)
{ {
minecraft->quit(); minecraft->quit();
} }

View File

@@ -23,10 +23,10 @@ public:
bool isInGameScreen(); bool isInGameScreen();
private: private:
Button bHost; Button* bHost;
Button bJoin; Button* bJoin;
Button bOptions; Button* bOptions;
ImageButton bQuit; // X button in top-right corner Button* bQuit;
std::string copyright; std::string copyright;
int copyrightPosX; int copyrightPosX;

View File

@@ -16,7 +16,12 @@
#include "../../../../world/level/Level.h" #include "../../../../world/level/Level.h"
#include "../../../../world/item/DyePowderItem.h" #include "../../../../world/item/DyePowderItem.h"
#include "../../../../world/item/crafting/Recipe.h" #include "../../../../world/item/crafting/Recipe.h"
#include "network/RakNetInstance.h"
#include "network/packet/WantCreatePacket.h"
#include "platform/input/Keyboard.h" #include "platform/input/Keyboard.h"
#include <cstdint>
#include <iostream>
#include <string>
static NinePatchLayer* guiPaneFrame = NULL; static NinePatchLayer* guiPaneFrame = NULL;
@@ -193,6 +198,26 @@ void PaneCraftingScreen::setupPositions() {
} }
void PaneCraftingScreen::tick() { void PaneCraftingScreen::tick() {
if (minecraft->isOnline()) {
// TODO: Make better algorithm
static std::map<uint8_t, uint16_t> oldMap = {};
std::map<uint8_t, uint16_t> newMap = {};
for (int i = Inventory::MAX_SELECTION_SIZE; i < minecraft->player->inventory->getContainerSize(); ++i) {
auto itm = minecraft->player->inventory->getItem(i);
if (itm != NULL) {
newMap[itm->id] += itm->count;
}
}
if (oldMap != newMap) {
oldMap = newMap;
newMap = {};
recheckRecipes();
}
}
if (pane) pane->tick(); if (pane) pane->tick();
} }
@@ -439,25 +464,29 @@ void PaneCraftingScreen::craftSelectedItem()
ItemInstance resultItem = currentItem->item; ItemInstance resultItem = currentItem->item;
if (minecraft->player) { if (minecraft->player) {
if (minecraft->isOnline()) {
WantCreatePacket packet(minecraft->player->entityId, resultItem.count, resultItem.getAuxValue(), resultItem.id);
minecraft->raknetInstance->send(packet);
}
// Remove all items required for the recipe and ... // Remove all items required for the recipe and ...
for (unsigned int i = 0; i < currentItem->neededItems.size(); ++i) { for (unsigned int i = 0; i < currentItem->neededItems.size(); ++i) {
CItem::ReqItem& req = currentItem->neededItems[i]; CItem::ReqItem& req = currentItem->neededItems[i];
// If the recipe allows any aux-value as ingredients, first deplete // If the recipe allows any aux-value as ingredients, first deplete
// aux == 0 from inventory. Since I'm not sure if this always is // aux == 0 from inventory. Since I'm not sure if this always is
// correct, let's only do it for ingredient sandstone for now. // correct, let's only do it for ingredient sandstone for now.
ItemInstance toRemove = req.item; ItemInstance toRemove = req.item;
if (Tile::sandStone->id == req.item.id if (Tile::sandStone->id == req.item.id
&& Recipe::ANY_AUX_VALUE == req.item.getAuxValue()) { && Recipe::ANY_AUX_VALUE == req.item.getAuxValue()) {
toRemove.setAuxValue(0); toRemove.setAuxValue(0);
toRemove.count = minecraft->player->inventory->removeResource(toRemove, true); toRemove.count = minecraft->player->inventory->removeResource(toRemove, true);
toRemove.setAuxValue(Recipe::ANY_AUX_VALUE); toRemove.setAuxValue(Recipe::ANY_AUX_VALUE);
} }
if (toRemove.count > 0) { if (toRemove.count > 0) {
minecraft->player->inventory->removeResource(toRemove); minecraft->player->inventory->removeResource(toRemove);
} }
} }
// ... add the new one! (in this order, to fill empty slots better) // ... add the new one! (in this order, to fill empty slots better)
// if it doesn't fit, throw it on the ground! // if it doesn't fit, throw it on the ground!

View File

@@ -40,10 +40,9 @@ HumanoidModel::HumanoidModel( float g /*= 0*/, float yOffset /*= 0*/, int texW /
head.addBox(-4, -8, -4, 8, 8, 8, g); // Head head.addBox(-4, -8, -4, 8, 8, 8, g); // Head
head.setPos(0, 0 + yOffset, 0); head.setPos(0, 0 + yOffset, 0);
if (modernSkin) { hair.addBox(-4, -8, -4, 8, 8, 8, g + 0.5f); // Outer head layer (hat)
hair.addBox(-4, -8, -4, 8, 8, 8, g + 0.5f); // Outer head layer (hat) hair.setPos(0, 0 + yOffset, 0);
hair.setPos(0, 0 + yOffset, 0);
}
body.addBox(-4, 0, -2, 8, 12, 4, g); // Body body.addBox(-4, 0, -2, 8, 12, 4, g); // Body
body.setPos(0, 0 + yOffset, 0); body.setPos(0, 0 + yOffset, 0);
@@ -99,17 +98,17 @@ void HumanoidModel::render(Entity* e, float time, float r, float bob, float yRot
setupAnim(time, r, bob, yRot, xRot, scale); setupAnim(time, r, bob, yRot, xRot, scale);
// Sync overlay with head rotation/position // Sync overlay with head rotation/position
if (texWidth == 64 && texHeight == 64) {
hair.xRot = head.xRot; hair.xRot = head.xRot;
hair.yRot = head.yRot; hair.yRot = head.yRot;
hair.zRot = head.zRot; hair.zRot = head.zRot;
hair.y = head.y; hair.y = head.y;
}
head.render(scale); head.render(scale);
if (texWidth == 64 && texHeight == 64) {
hair.render(scale); hair.render(scale);
}
body.render(scale); body.render(scale);
arm0.render(scale); arm0.render(scale);
arm1.render(scale); arm1.render(scale);
@@ -123,12 +122,12 @@ void HumanoidModel::render( HumanoidModel* model, float scale )
head.yRot = model->head.yRot; head.yRot = model->head.yRot;
head.y = model->head.y; head.y = model->head.y;
head.xRot = model->head.xRot; head.xRot = model->head.xRot;
if (texWidth == 64 && texHeight == 64) {
hair.yRot = head.yRot; hair.yRot = head.yRot;
hair.xRot = head.xRot; hair.xRot = head.xRot;
hair.zRot = head.zRot; hair.zRot = head.zRot;
hair.y = head.y; hair.y = head.y;
}
arm0.xRot = model->arm0.xRot; arm0.xRot = model->arm0.xRot;
arm0.zRot = model->arm0.zRot; arm0.zRot = model->arm0.zRot;
@@ -273,7 +272,7 @@ void HumanoidModel::onGraphicsReset()
arm1.onGraphicsReset(); arm1.onGraphicsReset();
leg0.onGraphicsReset(); leg0.onGraphicsReset();
leg1.onGraphicsReset(); leg1.onGraphicsReset();
//hair.onGraphicsReset(); hair.onGraphicsReset();
} }
//void renderHair(float scale) { //void renderHair(float scale) {

View File

@@ -355,7 +355,11 @@ LocalPlayer::LocalPlayer(Minecraft* minecraft, Level* level, const std::string&
armorTypeHash(0), armorTypeHash(0),
sprinting(false), sprinting(false),
sprintDoubleTapTimer(0), sprintDoubleTapTimer(0),
prevForwardHeld(false) prevForwardHeld(false),
xBob(0.0f),
yBob(0.0f),
xBobO(0.0f),
yBobO(0.0f)
{ {
this->dimension = dimension; this->dimension = dimension;
_init(); _init();
@@ -456,7 +460,7 @@ void LocalPlayer::tick() {
{ {
sentInventoryItemId = newItemId; sentInventoryItemId = newItemId;
sentInventoryItemData = newItemData; sentInventoryItemData = newItemData;
PlayerEquipmentPacket packet(entityId, newItemId, newItemData); PlayerEquipmentPacket packet(entityId, newItemId, newItemData, inventory->selected, inventory->getSlot(newItemId, newItemData));
minecraft->raknetInstance->send(packet); minecraft->raknetInstance->send(packet);
} }
} }
@@ -550,6 +554,10 @@ void LocalPlayer::aiStep() {
//if (onGround && abilities.flying) //if (onGround && abilities.flying)
// abilities.flying = false; // abilities.flying = false;
yBobO = yBob;
xBobO = xBob;
xBob += (xRot - xBob) * 0.5;
yBob += (yRot - yBob) * 0.5;
if (interpolateOnly()) if (interpolateOnly())
updateAi(); updateAi();

View File

@@ -22,6 +22,10 @@ public:
virtual void reset(); virtual void reset();
void tick(); void tick();
float yBob, xBob; // shredder added from b1.8/4j for the hand swaying animation
float yBobO, xBobO; // shredder added from b1.8/4j for the hand swaying animation
void move(float xa, float ya, float za); void move(float xa, float ya, float za);
void aiStep(); void aiStep();

View File

@@ -101,12 +101,22 @@ void GameRenderer::setupCamera(float a, int eye) {
float stereoScale = 0.07f; float stereoScale = 0.07f;
if (mc->options.getBooleanValue(OPTIONS_ANAGLYPH_3D)) glTranslatef2(-(eye * 2 - 1) * stereoScale, 0, 0); if (mc->options.getBooleanValue(OPTIONS_ANAGLYPH_3D)) glTranslatef2(-(eye * 2 - 1) * stereoScale, 0, 0);
if (zoom != 1) { if (mc->options.getBooleanValue(OPTIONS_BETA_SKY)){
glTranslatef2((float) zoom_x, (float) -zoom_y, 0); if (zoom != 1) {
glScalef2(zoom, zoom, 1); glTranslatef2((float) zoom_x, (float) -zoom_y, 0);
gluPerspective(_setupCameraFov = getFov(a, true), mc->width / (float) mc->height, 0.05f, renderDistance); glScalef2(zoom, zoom, 1);
gluPerspective(_setupCameraFov = getFov(a, true), mc->width / (float) mc->height, 0.05f, renderDistance * 2.0f);
} else {
gluPerspective(_setupCameraFov = getFov(a, true), mc->width / (float) mc->height, 0.05f, renderDistance * 2.0f);
}
} else { } else {
gluPerspective(_setupCameraFov = getFov(a, true), mc->width / (float) mc->height, 0.05f, renderDistance); if (zoom != 1) {
glTranslatef2((float) zoom_x, (float) -zoom_y, 0);
glScalef2(zoom, zoom, 1);
gluPerspective(_setupCameraFov = getFov(a, true), mc->width / (float) mc->height, 0.05f, renderDistance);
} else {
gluPerspective(_setupCameraFov = getFov(a, true), mc->width / (float) mc->height, 0.05f, renderDistance);
}
} }
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
@@ -272,8 +282,7 @@ void GameRenderer::renderLevel(float a) {
screenScissorArea.w, screenScissorArea.h); screenScissorArea.w, screenScissorArea.h);
} }
glEnable2(GL_FOG);
setupFog(1);
if (mc->options.getBooleanValue(OPTIONS_AMBIENT_OCCLUSION)) { if (mc->options.getBooleanValue(OPTIONS_AMBIENT_OCCLUSION)) {
glShadeModel2(GL_SMOOTH); glShadeModel2(GL_SMOOTH);
@@ -286,10 +295,29 @@ void GameRenderer::renderLevel(float a) {
TIMER_POP_PUSH("culling"); TIMER_POP_PUSH("culling");
mc->levelRenderer->cull(&frustum, a); mc->levelRenderer->cull(&frustum, a);
mc->levelRenderer->updateDirtyChunks(cameraEntity, false); mc->levelRenderer->updateDirtyChunks(cameraEntity, false);
// this sky rendering code below was originally before the frustrum and culling stuff but sunset color breaks for some reason in that place, so i moved i after those two - shredder
// if(mc->options.getBooleanValue(OPTIONS_FANCY_GRAPHICS)) {
setupFog(-1);
TIMER_POP_PUSH("sky");
// @TODO - EXTREME JANK BELOW, it works but i have to do heavy cleanup here, also to test if the glfogf commands even affect fog in anyway.
if(mc->options.getBooleanValue(OPTIONS_BETA_SKY) && (mc->options.getIntValue(OPTIONS_VIEW_DISTANCE) < 2)){
levelRenderer->renderSky(a); // how java renders the sky instead of how pe doing prepareandrenderclouds.
} else if (!mc->options.getBooleanValue(OPTIONS_BETA_SKY)){
glFogf(GL_FOG_START, renderDistance * 0.2f);
glFogf(GL_FOG_END, renderDistance *0.75);
glFogf(GL_FOG_START, renderDistance * 0.6f);
glFogf(GL_FOG_END, renderDistance);
}
// }
glEnable2(GL_FOG);
setupFog(1);
// MCPE renders clouds using this, but this method breaks 3d clouds and also breaks 2d clouds transparency viewed from above, add as a Legacy Sky or Fast Sky option. - shredder
if(!mc->options.getBooleanValue(OPTIONS_BETA_SKY)){
if(mc->options.getBooleanValue(OPTIONS_FANCY_GRAPHICS)) { if(mc->options.getBooleanValue(OPTIONS_FANCY_GRAPHICS)) {
prepareAndRenderClouds(levelRenderer, a); prepareAndRenderClouds(levelRenderer, a);
} }
}
setupFog(0); setupFog(0);
glEnable2(GL_FOG); glEnable2(GL_FOG);
@@ -297,7 +325,9 @@ void GameRenderer::renderLevel(float a) {
mc->textures->loadAndBindTexture("terrain.png"); mc->textures->loadAndBindTexture("terrain.png");
Lighting::turnOff(); Lighting::turnOff();
glDisable2(GL_ALPHA_TEST); // glDisable2(GL_ALPHA_TEST); // vanilla pe disables alpha test here, i renable it so grass side textures dont become opaque - shredder
glEnable2(GL_ALPHA_TEST); //
glDisable2(GL_BLEND); glDisable2(GL_BLEND);
glEnable2(GL_CULL_FACE); glEnable2(GL_CULL_FACE);
TIMER_POP_PUSH("terrain-0"); TIMER_POP_PUSH("terrain-0");
@@ -317,12 +347,15 @@ void GameRenderer::renderLevel(float a) {
Lighting::turnOff(); Lighting::turnOff();
glDisable2(GL_BLEND); glDisable2(GL_BLEND);
glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Lighting::turnOff();
setupFog(0); setupFog(0);
glEnable2(GL_BLEND); glEnable2(GL_BLEND);
glDisable2(GL_CULL_FACE); glDisable2(GL_CULL_FACE);
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE); // @TODO commenting this out fixes Ice transparency and clouds are no longer visilbe underwater like normal beta - shredder
glDisable2(GL_ALPHA_TEST); glDisable2(GL_ALPHA_TEST);
mc->textures->loadAndBindTexture("terrain.png"); mc->textures->loadAndBindTexture("terrain.png");
// @TODO - below is a commented out double render system that fixes ice transparency, but probs harm performance, add it as an option - shredder
//if (mc->options.fancyGraphics) { //if (mc->options.fancyGraphics) {
// glColorMask(false, false, false, false); // glColorMask(false, false, false, false);
// int visibleWaterChunks = levelRenderer->render(cameraEntity, 1, a); // int visibleWaterChunks = levelRenderer->render(cameraEntity, 1, a);
@@ -365,11 +398,14 @@ void GameRenderer::renderLevel(float a) {
} }
glDisable2(GL_FOG); glDisable2(GL_FOG);
// // Normally this is commented out, but this is how java does it and should fix both 2d/3d clouds, a
// setupFog(0); if(mc->options.getBooleanValue(OPTIONS_BETA_SKY)){
// glEnable2(GL_FOG); setupFog(0);
//// levelRenderer->renderClouds(a); glEnable2(GL_FOG);
// glDisable2(GL_FOG); levelRenderer->renderClouds(a);
glDisable2(GL_FOG);
}
// SHREDDER END
setupFog(1); setupFog(1);
if (zoom == 1 && !mc->options.getBooleanValue(OPTIONS_HIDEGUI)) { if (zoom == 1 && !mc->options.getBooleanValue(OPTIONS_HIDEGUI)) {
@@ -654,7 +690,7 @@ void GameRenderer::pick(float a) {
float range = mc->gameMode->getPickRange(); float range = mc->gameMode->getPickRange();
bool isPicking = true; bool isPicking = true;
bool freeform = mc->useTouchscreen(); //&& !mc->options.getBooleanValue(OPTIONS_IS_JOY_TOUCH_AREA); bool freeform = mc->useTouchscreen() && !mc->options.getBooleanValue(OPTIONS_IS_JOY_TOUCH_AREA);
if (freeform) { if (freeform) {
isPicking = updateFreeformPickDirection(a, pickDirection); isPicking = updateFreeformPickDirection(a, pickDirection);

View File

@@ -280,6 +280,9 @@ void ItemInHandRenderer::render( float a )
float h = oHeight + (height - oHeight) * a; float h = oHeight + (height - oHeight) * a;
Player* player = mc->player; Player* player = mc->player;
// if (selectedTile==NULL) return; // if (selectedTile==NULL) return;
LocalPlayer* localPlayer = (LocalPlayer*)(player);
float xr = player->xRotO + (player->xRot - player->xRotO) * a; // shredder added for hand swaying
glPushMatrix2(); glPushMatrix2();
glRotatef2(player->xRotO + (player->xRot - player->xRotO) * a, 1, 0, 0); glRotatef2(player->xRotO + (player->xRot - player->xRotO) * a, 1, 0, 0);
@@ -288,6 +291,16 @@ void ItemInHandRenderer::render( float a )
Lighting::turnOn(mc); Lighting::turnOn(mc);
glPopMatrix2(); glPopMatrix2();
if (localPlayer) // shredder added, basically does the hand swaying animation from b1.8
{
float xrr = localPlayer->xBobO + (localPlayer->xBob - localPlayer->xBobO) * a;
float yrr = localPlayer->yBobO + (localPlayer->yBob - localPlayer->yBobO) * a;
// 4J - was using player->xRot and yRot directly here rather than interpolating between old & current with a
float yr = player->yRotO + (player->yRot - player->yRotO) * a;
glRotatef((xr - xrr) * 0.1f, 1, 0, 0);
glRotatef((yr - yrr) * 0.1f, 0, 1, 0);
}
float br = mc->level->getBrightness(Mth::floor(player->x), Mth::floor(player->y), Mth::floor(player->z)); float br = mc->level->getBrightness(Mth::floor(player->x), Mth::floor(player->y), Mth::floor(player->z));
ItemInstance* item;// = selectedItem; ItemInstance* item;// = selectedItem;
@@ -443,10 +456,10 @@ void ItemInHandRenderer::renderScreenEffect( float a )
} }
} }
// if (mc->player->isUnderLiquid(Material::water)) { if (mc->player->isUnderLiquid(Material::water)) {
//mc->textures->loadAndBindTexture("misc/water.png"); mc->textures->loadAndBindTexture("misc/water.png");
// renderWater(a); renderWater(a);
// } }
glEnable2(GL_ALPHA_TEST); glEnable2(GL_ALPHA_TEST);
} }

View File

@@ -26,6 +26,7 @@
#include "../../client/player/LocalPlayer.h" #include "../../client/player/LocalPlayer.h"
#include "../../world/level/GrassColor.h" #include "../../world/level/GrassColor.h"
#include "Lighting.h"
#ifdef GFX_SMALLER_CHUNKS #ifdef GFX_SMALLER_CHUNKS
/* static */ const int LevelRenderer::CHUNK_SIZE = 8; /* static */ const int LevelRenderer::CHUNK_SIZE = 8;
@@ -68,7 +69,7 @@ LevelRenderer::LevelRenderer( Minecraft* mc)
destroyProgress(0) destroyProgress(0)
{ {
#ifdef OPENGL_ES #ifdef OPENGL_ES
int maxChunksWidth = 2 * LEVEL_WIDTH / CHUNK_SIZE + 1; int maxChunksWidth = 2 * LevelConstants::LEVEL_WIDTH / CHUNK_SIZE + 1;
numListsOrBuffers = maxChunksWidth * maxChunksWidth * (128/CHUNK_SIZE) * 3; numListsOrBuffers = maxChunksWidth * maxChunksWidth * (128/CHUNK_SIZE) * 3;
chunkBuffers = new GLuint[numListsOrBuffers]; chunkBuffers = new GLuint[numListsOrBuffers];
glGenBuffers2(numListsOrBuffers, chunkBuffers); glGenBuffers2(numListsOrBuffers, chunkBuffers);
@@ -76,6 +77,9 @@ LevelRenderer::LevelRenderer( Minecraft* mc)
//for (int i = 0; i < numListsOrBuffers; ++i) printf("bufId %d: %d\t", i, chunkBuffers[i]); //for (int i = 0; i < numListsOrBuffers; ++i) printf("bufId %d: %d\t", i, chunkBuffers[i]);
glGenBuffers2(1, &skyBuffer); glGenBuffers2(1, &skyBuffer);
glGenBuffers2(1, &voidBuffer);
glGenBuffers2(1, &starBuffer);
generateStars();
generateSky(); generateSky();
#else #else
int maxChunksWidth = 1024 / CHUNK_SIZE; int maxChunksWidth = 1024 / CHUNK_SIZE;
@@ -94,6 +98,8 @@ LevelRenderer::~LevelRenderer()
#ifdef OPENGL_ES #ifdef OPENGL_ES
glDeleteBuffers(numListsOrBuffers, chunkBuffers); glDeleteBuffers(numListsOrBuffers, chunkBuffers);
glDeleteBuffers(1, &skyBuffer); glDeleteBuffers(1, &skyBuffer);
glDeleteBuffers(1, &voidBuffer);
glDeleteBuffers(1, &starBuffer);
delete[] chunkBuffers; delete[] chunkBuffers;
#else #else
glDeleteLists(numListsOrBuffers, chunkLists); glDeleteLists(numListsOrBuffers, chunkLists);
@@ -121,6 +127,25 @@ void LevelRenderer::generateSky() {
} }
t.end(true, skyBuffer); t.end(true, skyBuffer);
yy = (float) (-16);
t.begin();
// pretty much the same thing as the sky one above except uses inverted values to generate the void plane.
voidVertexCount = 0;
for (int xx = -s * d; xx <= s * d; xx += s) {
for (int zz = -s * d; zz <= s * d; zz += s) {
t.vertex((float) xx + 0, yy, (float) zz + s);
t.vertex((float)(xx + s), yy, (float) zz + s);
t.vertex((float)(xx + s), yy, (float)(zz + 0));
t.vertex((float) xx + 0, yy, (float)(zz + 0));
//LOGI("x, z: %d, %d\n", xx, zz);
voidVertexCount += 4;
}
}
t.end(true, voidBuffer);
//LOGI("skyvertexcount: %d\n", skyVertexCount); //LOGI("skyvertexcount: %d\n", skyVertexCount);
//glEndList(); //glEndList();
} }
@@ -146,10 +171,6 @@ void LevelRenderer::setLevel( Level* level )
level->addListener(this); level->addListener(this);
allChanged(); allChanged();
} }
if (mc->options.getBooleanValue(OPTIONS_AMBIENT_OCCLUSION)) {
mc->useAmbientOcclusion = !mc->useAmbientOcclusion;
allChanged();
}
} }
void LevelRenderer::allChanged() void LevelRenderer::allChanged()
@@ -168,6 +189,9 @@ void LevelRenderer::allChanged()
FoliageColor::setUseTint(tint); FoliageColor::setUseTint(tint);
GrassColor::setUseTint(tint); GrassColor::setUseTint(tint);
bool sideTint = mc->options.getBooleanValue(OPTIONS_TINTED_SIDE);
TileRenderer::setUseTint(sideTint);
int dist = (512 >> 3) << (3 - lastViewDistance); int dist = (512 >> 3) << (3 - lastViewDistance);
if (lastViewDistance <= 2 && mc->isPowerVR()) if (lastViewDistance <= 2 && mc->isPowerVR())
@@ -325,6 +349,37 @@ int LevelRenderer::render( Mob* player, int layer, float alpha )
allChanged(); allChanged();
} }
bool SmoothLightState = mc->options.getBooleanValue(OPTIONS_AMBIENT_OCCLUSION);
if (SmoothLightState != mc->useAmbientOcclusion){
mc->useAmbientOcclusion = SmoothLightState;
allChanged();
}
bool tint = mc->options.getBooleanValue(OPTIONS_FOLIAGE_TINT);
if (tint != LastTint) {
LastTint = tint;
FoliageColor::setUseTint(tint);
GrassColor::setUseTint(tint);
allChanged();
}
bool sideTint = mc->options.getBooleanValue(OPTIONS_TINTED_SIDE);
if (sideTint != LastSideTint) {
LastSideTint = sideTint;
TileRenderer::setUseTint(sideTint);
allChanged();
}
TIMER_PUSH("sortchunks"); TIMER_PUSH("sortchunks");
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
@@ -513,15 +568,15 @@ void LevelRenderer::render(const AABB& b) const
{ {
Tesselator& t = Tesselator::instance; Tesselator& t = Tesselator::instance;
// glColor4f2(1, 1, 1, 1); // glColor4f2(1, 1, 1, 1);
// textures->loadAndBindTexture("terrain.png"); // uh need to check java - shredder // textures->loadAndBindTexture("terrain.png"); // uh need to check java - shredder
//t.begin(); //t.begin();
// t.color(255, 255, 255, 255); // again not needed, for some reason the vanilla source code tints it... white? maybe this was used for something else in MCPE's dev at one point? - shredder // t.color(255, 255, 255, 255); // again not needed, for some reason the vanilla source code tints it... white? maybe this was used for something else in MCPE's dev at one point? - shredder
// t.offset(((Mob*)mc->player)->getPos(0).negated()); // why does this even exist normally, it just makes the thing... not render
// t.offset(((Mob*)mc->player)->getPos(0).negated()); // why does this even exist normally, it just makes the thing... not render
glLineWidth(2.0f); // make it more thick - shredder
t.begin(GL_LINE_STRIP); t.begin(GL_LINE_STRIP);
t.vertex(b.x0, b.y0, b.z0); t.vertex(b.x0, b.y0, b.z0);
t.vertex(b.x1, b.y0, b.z0); t.vertex(b.x1, b.y0, b.z0);
@@ -1009,13 +1064,66 @@ std::string LevelRenderer::gatherStats1() {
} }
// //
// /*public*/ std::string gatherStats2() { std::string LevelRenderer::gatherStats2() {
// return "E: " + renderedEntities + "/" + totalEntities + ". B: " + culledEntities + ", I: " + ((totalEntities - culledEntities) - renderedEntities); std::stringstream ss;
// } ss << "E: "<< renderedEntities << "/" << totalEntities << ". B: " << culledEntities << ", I: " << (totalEntities - culledEntities) - renderedEntities <<"\n";
return ss.str();
}
// //
// int[] toRender = new int[50000]; // int[] toRender = new int[50000];
// IntBuffer resultBuffer = MemoryTracker.createIntBuffer(64); // IntBuffer resultBuffer = MemoryTracker.createIntBuffer(64);
void LevelRenderer::generateStars() {
// ported from java beta again,
// converted the doubles into floats to be consistent, shouldnt affect much - shredder
Random random = Random(10842L);
Tesselator& t = Tesselator::instance;
t.begin();
starVertexCount = 0;
for (int i = 0; i < 1500; i++) {
float d = random.nextFloat() * 2.0F - 1.0F;
float e = random.nextFloat() * 2.0F - 1.0F;
float f = random.nextFloat() * 2.0F - 1.0F;
float g = 0.25F + random.nextFloat() * 0.25F;
float h = d * d + e * e + f * f;
if (h < 1.0 && h > 0.01) {
h = 1.0 / Mth::sqrt(h);
d *= h;
e *= h;
f *= h;
float j = d * 100.0;
float k = e * 100.0;
float l = f * 100.0;
float m = Mth::atan2(d, f);
float n = Mth::sin(m);
float o = Mth::cos(m);
float p = Mth::atan2(Mth::sqrt(d * d + f * f), e);
float q = Mth::sin(p);
float r = Mth::cos(p);
float s = random.nextDouble() * Mth::PI * 2.0;
float t2 = Mth::sin(s);
float u = Mth::cos(s);
for (int v = 0; v < 4; v++) {
float w = 0.0;
float x = ((v & 2) - 1) * g;
float y = ((v + 1 & 2) - 1) * g;
float aa = x * u - y * t2;
float ab = y * u + x * t2;
float ad = aa * q + w * r;
float ae = w * q - aa * r;
float af = ae * n - ab * o;
float ah = ab * n + ae * o;
t.vertex(j + af, k + ad, l + ah);
}
starVertexCount += 4;
}
}
t.end(true, starBuffer);
}
void LevelRenderer::renderSky(float alpha) { void LevelRenderer::renderSky(float alpha) {
if (mc->level->dimension->foggy) return; if (mc->level->dimension->foggy) return;
@@ -1036,19 +1144,125 @@ void LevelRenderer::renderSky(float alpha) {
} }
glColor4f2(sr, sg, Mth::Min(1.0f, sb), 1); glColor4f2(sr, sg, Mth::Min(1.0f, sb), 1);
//Tesselator& t = Tesselator::instance; Tesselator& t = Tesselator::instance;
// @TODO shredder - should not enable or disable depth mask if using legacy sky because mcpe sky rendering is awful and will render clouds above terrain
if(mc->options.getBooleanValue(OPTIONS_BETA_SKY)){
glDepthMask(false);
}
glEnable2(GL_FOG); glEnable2(GL_FOG);
glColor4f2(sr, sg, sb, 1.0f); glColor4f2(sr, sg, sb, 1.0f);
#ifdef OPENGL_ES #ifdef OPENGL_ES
drawArrayVT(skyBuffer, skyVertexCount); drawArrayVT(skyBuffer, skyVertexCount);
#endif #endif
glEnable2(GL_TEXTURE_2D); glDisable(GL_FOG);
glDisable(GL_ALPHA_TEST);
// re ported this again from beta 1.6.6, thanks to the mcpe 0.1 decomp team's code for some bit of help about the void layer - shredder
// Sunrise
if (mc->options.getBooleanValue(OPTIONS_BEAUTIFUL_SKY)) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Lighting::turnOff();
float* c = level->dimension->getSunriseColor(level->getTimeOfDay(alpha), alpha);
if (c != nullptr)
{
glDisable(GL_TEXTURE_2D);
// glShadeModel(GL_SMOOTH); //
glPushMatrix();
glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
glRotatef(level->getTimeOfDay(alpha) > 0.5f ? 180 : 0, 0.0f, 0.0f, 1.0f);
t.begin(GL_TRIANGLE_FAN);
t.color(c[0], c[1], c[2], c[3]);
t.vertex(0.0f, 100.0f, 0.0f);
t.color(c[0], c[1], c[2], 0.0f);
int steps = 16;
for (int i = 0; i <= steps; i++)
{
float a = i * 3.1415927f * 2.0f / steps;
float sin = Mth::sin(a);
float cos = Mth::cos(a);
t.vertex((sin * 120.0f), (cos * 120.0f), (-cos * 40.0f * c[3]));
}
t.draw();
glPopMatrix();
// glShadeModel(GL_FLAT); //
}
// gets the time of day and rotates the sun and moon png based on the time
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glPushMatrix();
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glTranslatef(sc.x, sc.y, sc.z);
glRotatef(0.0f, 0.0f, 0.0f, 1.0f);
glRotatef(level->getTimeOfDay(alpha) * 360.0f, 1.0f, 0.0f, 0.0f);
float ss = 30.0f;
textures->loadAndBindTexture("terrain/sun.png");
t.begin();
t.vertexUV(-ss, 100.0f, -ss, 0.0f, 0.0f);
t.vertexUV(ss, 100.0f, -ss, 1.0f, 0.0f);
t.vertexUV(ss, 100.0f, ss, 1.0f, 1.0f);
t.vertexUV(-ss, 100.0f, ss, 0.0f, 1.0f);
t.draw();
ss = 20.0f;
textures->loadAndBindTexture("terrain/moon.png");
t.begin();
t.vertexUV(-ss, -100.0f, ss, 1.0f, 1.0f);
t.vertexUV(ss, -100.0f, ss, 0.0f, 1.0f);
t.vertexUV(ss, -100.0f, -ss, 0.0f, 0.0f);
t.vertexUV(-ss, -100.0f, -ss, 1.0f, 0.0f);
t.draw();
glDisable(GL_TEXTURE_2D);
float a = level->getStarBrightness(alpha);
if (a > 0.0f)
{
glColor4f(a, a, a, a);
drawArrayVT(starBuffer, starVertexCount);
}
}
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glDisable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glEnable(GL_FOG);
glPopMatrix();
// ported over void plane (the blue bottom plane seen in java) because pocket edition lacks it @TODO test if it's buggy - shredder
// glColor3f(sc.x * 0.2f + 0.04f, sc.y * 0.2f + 0.04f, sc.z * 0.6f + 0.1f);
glColor4f(sc.x * 0.2f + 0.04f, sc.y * 0.2f + 0.04f, sc.z * 0.6f + 0.1f, 1.0f);
glDisable(GL_TEXTURE_2D);
if(mc->options.getBooleanValue(OPTIONS_BETA_SKY)){
drawArrayVT(voidBuffer, voidVertexCount);
}
glEnable(GL_TEXTURE_2D);
// @TODO shredder - should not enable or disable depth mask if using legacy sky because mcpe sky rendering is awful and will render clouds above terrain
if(mc->options.getBooleanValue(OPTIONS_BETA_SKY)){
glDepthMask(true);
}
} }
void LevelRenderer::renderClouds( float alpha ) { void LevelRenderer::renderClouds( float alpha ) {
//if (!mc->level->dimension->isNaturalDimension()) return; //if (!mc->level->dimension->isNaturalDimension()) return;
if (mc->options.getBooleanValue(OPTIONS_FANCY_GRAPHICS) && mc->options.getBooleanValue(OPTIONS_BETA_SKY)){
renderAdvancedClouds(alpha);
return;
}
glEnable2(GL_TEXTURE_2D); glEnable2(GL_TEXTURE_2D);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
float yOffs = (float) (mc->player->yOld + (mc->player->y - mc->player->yOld) * alpha); float yOffs = (float) (mc->player->yOld + (mc->player->y - mc->player->yOld) * alpha);
@@ -1097,58 +1311,195 @@ void LevelRenderer::renderClouds( float alpha ) {
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
} }
void LevelRenderer::renderAdvancedClouds(float alpha) {
// ported from java beta, tesselation code for the 3d clouds, renders broken if mcpe sky rendering option is used - shredder
glDisable(GL_CULL_FACE);
float px = mc->player->xOld + (mc->player->x - mc->player->xOld) * alpha;
float py = mc->player->yOld + (mc->player->y - mc->player->yOld) * alpha;
float pz = mc->player->zOld + (mc->player->z - mc->player->zOld) * alpha;
Tesselator& t = Tesselator::instance;
float ss = 12.0f;
float h = 4.0f;
float cloudTime = (float)ticks + alpha;
float xo = (px + cloudTime * 0.03f) / ss;
float zo = pz / ss + 0.33f;
float yy = 108.0f - py + 0.33f;
int xWraps = Mth::floor(xo / 2048.0);
int zWraps = Mth::floor(zo / 2048.0);
xo -= xWraps * 2048;
zo -= zWraps * 2048;
textures->loadAndBindTexture("environment/clouds.png");
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Vec3 cc = level->getCloudColor(alpha);
float cr = cc.x;
float cg = cc.y;
float cb = cc.z;
float uvScale = 1.0f / 256.0f;
float uo = (float)Mth::floor(xo) * uvScale;
float vo = (float)Mth::floor(zo) * uvScale;
float xOffs = (float)(xo - Mth::floor(xo));
float zOffs = (float)(zo - Mth::floor(zo));
int D = 8;
int radius = 3;
float e = 1.0f / 1024.0f;
glPushMatrix();
glScalef(ss, 1.0f, ss);
for (int pass = 0; pass < 2; pass++) {
if (pass == 0) glColorMask(false, false, false, false);
else glColorMask(true, true, true, true);
for (int xPos = -radius + 1; xPos <= radius; xPos++) {
for (int zPos = -radius + 1; zPos <= radius; zPos++) {
t.begin();
float xx = (float)(xPos * D);
float zz = (float)(zPos * D);
float xp = xx - xOffs;
float zp = zz - zOffs;
if (yy > -h - 1.0f) {
t.color(cr * 0.7f, cg * 0.7f, cb * 0.7f, 0.8f);
t.normal(0.0f, -1.0f, 0.0f);
t.vertexUV(xp + 0, yy + 0, zp + D, (xx + 0) * uvScale + uo, (zz + D) * uvScale + vo);
t.vertexUV(xp + D, yy + 0, zp + D, (xx + D) * uvScale + uo, (zz + D) * uvScale + vo);
t.vertexUV(xp + D, yy + 0, zp + 0, (xx + D) * uvScale + uo, (zz + 0) * uvScale + vo);
t.vertexUV(xp + 0, yy + 0, zp + 0, (xx + 0) * uvScale + uo, (zz + 0) * uvScale + vo);
}
if (yy <= h + 1.0f) {
t.color(cr, cg, cb, 0.8f);
t.normal(0.0f, 1.0f, 0.0f);
t.vertexUV(xp + 0, yy + h - e, zp + D, (xx + 0) * uvScale + uo, (zz + D) * uvScale + vo);
t.vertexUV(xp + D, yy + h - e, zp + D, (xx + D) * uvScale + uo, (zz + D) * uvScale + vo);
t.vertexUV(xp + D, yy + h - e, zp + 0, (xx + D) * uvScale + uo, (zz + 0) * uvScale + vo);
t.vertexUV(xp + 0, yy + h - e, zp + 0, (xx + 0) * uvScale + uo, (zz + 0) * uvScale + vo);
}
t.color(cr * 0.9f, cg * 0.9f, cb * 0.9f, 0.8f);
if (xPos > -1) {
t.normal(-1.0f, 0.0f, 0.0f);
for (int i = 0; i < D; i++) {
t.vertexUV(xp + i + 0, yy + 0, zp + D, (xx + i + 0.5f) * uvScale + uo, (zz + D) * uvScale + vo);
t.vertexUV(xp + i + 0, yy + h, zp + D, (xx + i + 0.5f) * uvScale + uo, (zz + D) * uvScale + vo);
t.vertexUV(xp + i + 0, yy + h, zp + 0, (xx + i + 0.5f) * uvScale + uo, (zz + 0) * uvScale + vo);
t.vertexUV(xp + i + 0, yy + 0, zp + 0, (xx + i + 0.5f) * uvScale + uo, (zz + 0) * uvScale + vo);
}
}
if (xPos <= 1) {
t.normal(1.0f, 0.0f, 0.0f);
for (int i = 0; i < D; i++) {
t.vertexUV(xp + i + 1 - e, yy + 0, zp + D, (xx + i + 0.5f) * uvScale + uo, (zz + D) * uvScale + vo);
t.vertexUV(xp + i + 1 - e, yy + h, zp + D, (xx + i + 0.5f) * uvScale + uo, (zz + D) * uvScale + vo);
t.vertexUV(xp + i + 1 - e, yy + h, zp + 0, (xx + i + 0.5f) * uvScale + uo, (zz + 0) * uvScale + vo);
t.vertexUV(xp + i + 1 - e, yy + 0, zp + 0, (xx + i + 0.5f) * uvScale + uo, (zz + 0) * uvScale + vo);
}
}
t.color(cr * 0.8f, cg * 0.8f, cb * 0.8f, 0.8f);
if (zPos > -1) {
t.normal(0.0f, 0.0f, -1.0f);
for (int i = 0; i < D; i++) {
t.vertexUV(xp + 0, yy + h, zp + i + 0, (xx + 0) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
t.vertexUV(xp + D, yy + h, zp + i + 0, (xx + D) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
t.vertexUV(xp + D, yy + 0, zp + i + 0, (xx + D) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
t.vertexUV(xp + 0, yy + 0, zp + i + 0, (xx + 0) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
}
}
if (zPos <= 1) {
t.normal(0.0f, 0.0f, 1.0f);
for (int i = 0; i < D; i++) {
t.vertexUV(xp + 0, yy + h, zp + i + 1 - e, (xx + 0) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
t.vertexUV(xp + D, yy + h, zp + i + 1 - e, (xx + D) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
t.vertexUV(xp + D, yy + 0, zp + i + 1 - e, (xx + D) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
t.vertexUV(xp + 0, yy + 0, zp + i + 1 - e, (xx + 0) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo);
}
}
t.endOverrideAndDraw();
}
}
}
glPopMatrix();
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glDisable(GL_BLEND);
glEnable(GL_CULL_FACE);
}
void LevelRenderer::playSound(const std::string& name, float x, float y, float z, float volume, float pitch) { void LevelRenderer::playSound(const std::string& name, float x, float y, float z, float volume, float pitch) {
// @todo: deny sounds here if sound is off (rather than waiting 'til SoundEngine) // @todo: deny sounds here if sound is off (rather than waiting 'til SoundEngine)
float dd = 16; float dd = 16;
if (volume > 1) dd *= volume; if (volume > 1) dd *= volume;
if (mc->cameraTargetPlayer->distanceToSqr(x, y, z) < dd * dd) { if (mc->cameraTargetPlayer != NULL && mc->cameraTargetPlayer->distanceToSqr(x, y, z) < dd * dd) {
mc->soundEngine->play(name, x, y, z, volume, pitch); mc->soundEngine->play(name, x, y, z, volume, pitch);
} }
} }
void LevelRenderer::addParticle(const std::string& name, float x, float y, float z, float xa, float ya, float za, int data) { void LevelRenderer::addParticle(const std::string& name, float x, float y, float z, float xa, float ya, float za, int data) {
if (mc->cameraTargetPlayer != NULL) {
float xd = mc->cameraTargetPlayer->x - x;
float yd = mc->cameraTargetPlayer->y - y;
float zd = mc->cameraTargetPlayer->z - z;
float distanceSquared = xd * xd + yd * yd + zd * zd;
float xd = mc->cameraTargetPlayer->x - x; //Particle* p = NULL;
float yd = mc->cameraTargetPlayer->y - y; //if (name == "hugeexplosion") p = new HugeExplosionSeedParticle(level, x, y, z, xa, ya, za);
float zd = mc->cameraTargetPlayer->z - z; //else if (name == "largeexplode") p = new HugeExplosionParticle(textures, level, x, y, z, xa, ya, za);
float distanceSquared = xd * xd + yd * yd + zd * zd;
//Particle* p = NULL; //if (p) {
//if (name == "hugeexplosion") p = new HugeExplosionSeedParticle(level, x, y, z, xa, ya, za); // if (distanceSquared < 32 * 32) {
//else if (name == "largeexplode") p = new HugeExplosionParticle(textures, level, x, y, z, xa, ya, za); // mc->particleEngine->add(p);
// } else { delete p; }
// return;
//}
//if (p) { const float particleDistance = 16;
// if (distanceSquared < 32 * 32) { if (distanceSquared > particleDistance * particleDistance) return;
// mc->particleEngine->add(p);
// } else { delete p; }
// return;
//}
const float particleDistance = 16; //static Stopwatch sw;
if (distanceSquared > particleDistance * particleDistance) return; //sw.start();
//static Stopwatch sw; if (name == "bubble") mc->particleEngine->add(new BubbleParticle(level, x, y, z, xa, ya, za));
//sw.start(); else if (name == "crit") mc->particleEngine->add(new CritParticle2(level, x, y, z, xa, ya, za));
else if (name == "smoke") mc->particleEngine->add(new SmokeParticle(level, x, y, z, xa, ya, za));
//else if (name == "note") mc->particleEngine->add(new NoteParticle(level, x, y, z, xa, ya, za));
else if (name == "explode") mc->particleEngine->add(new ExplodeParticle(level, x, y, z, xa, ya, za));
else if (name == "flame") mc->particleEngine->add(new FlameParticle(level, x, y, z, xa, ya, za));
else if (name == "lava") mc->particleEngine->add(new LavaParticle(level, x, y, z));
//else if (name == "splash") mc->particleEngine->add(new SplashParticle(level, x, y, z, xa, ya, za));
else if (name == "largesmoke") mc->particleEngine->add(new SmokeParticle(level, x, y, z, xa, ya, za, 2.5f));
else if (name == "reddust") mc->particleEngine->add(new RedDustParticle(level, x, y, z, xa, ya, za));
else if (name == "iconcrack") mc->particleEngine->add(new BreakingItemParticle(level, x, y, z, xa, ya, za, Item::items[data]));
else if (name == "snowballpoof") mc->particleEngine->add(new BreakingItemParticle(level, x, y, z, Item::snowBall));
//else if (name == "snowballpoof") mc->particleEngine->add(new BreakingItemParticle(level, x, y, z, Item::snowBall));
//else if (name == "slime") mc->particleEngine->add(new BreakingItemParticle(level, x, y, z, Item::slimeBall));
//else if (name == "heart") mc->particleEngine->add(new HeartParticle(level, x, y, z, xa, ya, za));
if (name == "bubble") mc->particleEngine->add(new BubbleParticle(level, x, y, z, xa, ya, za)); //sw.stop();
else if (name == "crit") mc->particleEngine->add(new CritParticle2(level, x, y, z, xa, ya, za)); //sw.printEvery(50, "add-particle-string");
else if (name == "smoke") mc->particleEngine->add(new SmokeParticle(level, x, y, z, xa, ya, za)); }
//else if (name == "note") mc->particleEngine->add(new NoteParticle(level, x, y, z, xa, ya, za));
else if (name == "explode") mc->particleEngine->add(new ExplodeParticle(level, x, y, z, xa, ya, za));
else if (name == "flame") mc->particleEngine->add(new FlameParticle(level, x, y, z, xa, ya, za));
else if (name == "lava") mc->particleEngine->add(new LavaParticle(level, x, y, z));
//else if (name == "splash") mc->particleEngine->add(new SplashParticle(level, x, y, z, xa, ya, za));
else if (name == "largesmoke") mc->particleEngine->add(new SmokeParticle(level, x, y, z, xa, ya, za, 2.5f));
else if (name == "reddust") mc->particleEngine->add(new RedDustParticle(level, x, y, z, xa, ya, za));
else if (name == "iconcrack") mc->particleEngine->add(new BreakingItemParticle(level, x, y, z, xa, ya, za, Item::items[data]));
else if (name == "snowballpoof") mc->particleEngine->add(new BreakingItemParticle(level, x, y, z, Item::snowBall));
//else if (name == "snowballpoof") mc->particleEngine->add(new BreakingItemParticle(level, x, y, z, Item::snowBall));
//else if (name == "slime") mc->particleEngine->add(new BreakingItemParticle(level, x, y, z, Item::slimeBall));
//else if (name == "heart") mc->particleEngine->add(new HeartParticle(level, x, y, z, xa, ya, za));
//sw.stop();
//sw.printEvery(50, "add-particle-string");
} }
/* /*
@@ -1259,6 +1610,7 @@ void LevelRenderer::renderHitSelect( Player* player, const HitResult& h, int mod
void LevelRenderer::onGraphicsReset() void LevelRenderer::onGraphicsReset()
{ {
generateStars();
generateSky(); generateSky();
// Get new buffers // Get new buffers

View File

@@ -43,7 +43,9 @@ public:
void renderDebug(const AABB& b, float a) const; void renderDebug(const AABB& b, float a) const;
void renderSky(float alpha); void renderSky(float alpha);
void generateStars();
void renderClouds(float alpha); void renderClouds(float alpha);
void renderAdvancedClouds(float alpha);
void renderEntities(Vec3 cam, Culler* culler, float a); void renderEntities(Vec3 cam, Culler* culler, float a);
void renderSameAsLast(int layer, float alpha); void renderSameAsLast(int layer, float alpha);
void renderHit(Player* player, const HitResult& h, int mode, /*ItemInstance*/void* inventoryItem, float a); void renderHit(Player* player, const HitResult& h, int mode, /*ItemInstance*/void* inventoryItem, float a);
@@ -67,6 +69,7 @@ public:
void levelEvent(Player* source, int type, int x, int y, int z, int data); void levelEvent(Player* source, int type, int x, int y, int z, int data);
std::string gatherStats1(); std::string gatherStats1();
std::string gatherStats2();
void render(const AABB& b) const; void render(const AABB& b) const;
void onGraphicsReset(); void onGraphicsReset();
@@ -116,6 +119,9 @@ private:
// shredder added again... // shredder added again...
int lastFogType; int lastFogType;
bool LastTint;
bool LastSideTint;
int ticks; int ticks;
int starList, skyList, darkList; int starList, skyList, darkList;
@@ -124,6 +130,12 @@ private:
GLuint skyBuffer; GLuint skyBuffer;
int skyVertexCount; int skyVertexCount;
GLuint voidBuffer;
int voidVertexCount;
GLuint starBuffer;
int starVertexCount;
// /*public*/ std::vector<TileEntity*> renderableTileEntities; // /*public*/ std::vector<TileEntity*> renderableTileEntities;
Textures* textures; Textures* textures;
// /*private*/ TileRenderer tileRenderer; // /*private*/ TileRenderer tileRenderer;

View File

@@ -19,8 +19,10 @@
#include "tileentity/TileEntityRenderer.h" #include "tileentity/TileEntityRenderer.h"
#include "EntityTileRenderer.h" #include "EntityTileRenderer.h"
TileRenderer::TileRenderer( LevelSource* level /* = NULL */ ) bool TileRenderer::sideTinting = false;
: level(level),
TileRenderer::TileRenderer(LevelSource* level /* = NULL */ )
: level(level),
fixedTexture(-1), fixedTexture(-1),
xFlipTexture(false), xFlipTexture(false),
noCulling(false), noCulling(false),
@@ -58,6 +60,11 @@ bool TileRenderer::tesselateBlockInWorld( Tile* tt, int x, int y, int z, float r
float c2 = 0.8f; float c2 = 0.8f;
float c3 = 0.6f; float c3 = 0.6f;
// added these to get biome color and save it before its overriden - shredder
float biomeR = r;
float biomeG = g;
float biomeB = b;
float r11 = c11 * r; float r11 = c11 * r;
float g11 = c11 * g; float g11 = c11 * g;
@@ -101,6 +108,10 @@ bool TileRenderer::tesselateBlockInWorld( Tile* tt, int x, int y, int z, float r
if (tt->zz0 > 0) br = centerBrightness; if (tt->zz0 > 0) br = centerBrightness;
t.color(r2 * br, g2 * br, b2 * br); t.color(r2 * br, g2 * br, b2 * br);
renderNorth(tt, xf, yf, zf, tt->getTexture(level, x, y, z, 2)); renderNorth(tt, xf, yf, zf, tt->getTexture(level, x, y, z, 2));
if ((tt->getTexture(level, x, y, z, 2) == 3) && sideTinting) { // checking if the texture from terrain.png is the normal grass side texture
t.color(c2 * br * biomeR, c2 * br * biomeG, c2 * br * biomeB);
renderNorth(tt, xf, yf, zf, 38); // rendering an extra face over the side of the cube that is a grayscale grass fringe tinted by t.color using biome colors, kinda inefficient
}
changed = true; changed = true;
} }
@@ -109,6 +120,10 @@ bool TileRenderer::tesselateBlockInWorld( Tile* tt, int x, int y, int z, float r
if (tt->zz1 < 1) br = centerBrightness; if (tt->zz1 < 1) br = centerBrightness;
t.color(r2 * br, g2 * br, b2 * br); t.color(r2 * br, g2 * br, b2 * br);
renderSouth(tt, xf, yf, zf, tt->getTexture(level, x, y, z, 3)); renderSouth(tt, xf, yf, zf, tt->getTexture(level, x, y, z, 3));
if ((tt->getTexture(level, x, y, z, 3) == 3) && sideTinting){ // checking if the texture from terrain.png is the normal grass side texture
t.color(c2 * br * biomeR, c2 * br * biomeG, c2 * br * biomeB);
renderSouth(tt, xf, yf, zf, 38); // rendering an extra face over the side of the cube that is a grayscale grass fringe tinted by t.color using biome colors, kinda inefficient
}
changed = true; changed = true;
} }
@@ -117,6 +132,10 @@ bool TileRenderer::tesselateBlockInWorld( Tile* tt, int x, int y, int z, float r
if (tt->xx0 > 0) br = centerBrightness; if (tt->xx0 > 0) br = centerBrightness;
t.color(r3 * br, g3 * br, b3 * br); t.color(r3 * br, g3 * br, b3 * br);
renderWest(tt, xf, yf, zf, tt->getTexture(level, x, y, z, 4)); renderWest(tt, xf, yf, zf, tt->getTexture(level, x, y, z, 4));
if ((tt->getTexture(level, x, y, z, 4) == 3) && sideTinting) { // checking if the texture from terrain.png is the normal grass side texture
t.color(c2 * br * biomeR, c2 * br * biomeG, c2 * br * biomeB);
renderWest(tt, xf, yf, zf, 38); // rendering an extra face over the side of the cube that is a grayscale grass fringe tinted by t.color using biome colors, kinda inefficient
}
changed = true; changed = true;
} }
@@ -125,6 +144,10 @@ bool TileRenderer::tesselateBlockInWorld( Tile* tt, int x, int y, int z, float r
if (tt->xx1 < 1) br = centerBrightness; if (tt->xx1 < 1) br = centerBrightness;
t.color(r3 * br, g3 * br, b3 * br); t.color(r3 * br, g3 * br, b3 * br);
renderEast(tt, xf, yf, zf, tt->getTexture(level, x, y, z, 5)); renderEast(tt, xf, yf, zf, tt->getTexture(level, x, y, z, 5));
if ((tt->getTexture(level, x, y, z, 5) == 3) && sideTinting) { // checking if the texture from terrain.png is the normal grass side texture
t.color(c2 * br * biomeR, c2 * br * biomeG, c2 * br * biomeB);
renderEast(tt, xf, yf, zf, 38); // rendering an extra face over the side of the cube that is a grayscale grass fringe tinted by t.color using biome colors, kinda inefficient
}
changed = true; changed = true;
} }
@@ -148,38 +171,38 @@ bool TileRenderer::tesselateInWorld( Tile* tt, int x, int y, int z )
return tesselateBlockInWorld(tt, x, y, z); return tesselateBlockInWorld(tt, x, y, z);
} else if (shape == Tile::SHAPE_WATER) { } else if (shape == Tile::SHAPE_WATER) {
return tesselateWaterInWorld(tt, x, y, z); return tesselateWaterInWorld(tt, x, y, z);
} else if (shape == Tile::SHAPE_CACTUS) { } else if (shape == Tile::SHAPE_CACTUS) {
return tesselateCactusInWorld(tt, x, y, z); return tesselateCactusInWorld(tt, x, y, z);
} else if (shape == Tile::SHAPE_CROSS_TEXTURE) { } else if (shape == Tile::SHAPE_CROSS_TEXTURE) {
return tesselateCrossInWorld(tt, x, y, z); return tesselateCrossInWorld(tt, x, y, z);
} else if(shape == Tile::SHAPE_STEM) { } else if(shape == Tile::SHAPE_STEM) {
return tesselateStemInWorld(tt, x, y, z); return tesselateStemInWorld(tt, x, y, z);
} else if (shape == Tile::SHAPE_ROWS) { } else if (shape == Tile::SHAPE_ROWS) {
return tesselateRowInWorld(tt, x, y, z); return tesselateRowInWorld(tt, x, y, z);
} else if (shape == Tile::SHAPE_TORCH) { } else if (shape == Tile::SHAPE_TORCH) {
return tesselateTorchInWorld(tt, x, y, z); return tesselateTorchInWorld(tt, x, y, z);
} else if (shape == Tile::SHAPE_FIRE) { } else if (shape == Tile::SHAPE_FIRE) {
return tesselateFireInWorld(tt, x, y, z); return tesselateFireInWorld(tt, x, y, z);
//} else if (shape == Tile::SHAPE_RED_DUST) { //} else if (shape == Tile::SHAPE_RED_DUST) {
// return tesselateDustInWorld(tt, x, y, z); // return tesselateDustInWorld(tt, x, y, z);
} else if (shape == Tile::SHAPE_LADDER) { } else if (shape == Tile::SHAPE_LADDER) {
return tesselateLadderInWorld(tt, x, y, z); return tesselateLadderInWorld(tt, x, y, z);
} else if (shape == Tile::SHAPE_DOOR) { } else if (shape == Tile::SHAPE_DOOR) {
return tesselateDoorInWorld(tt, x, y, z); return tesselateDoorInWorld(tt, x, y, z);
//} else if (shape == Tile::SHAPE_RAIL) { //} else if (shape == Tile::SHAPE_RAIL) {
// return tesselateRailInWorld(tt, x, y, z); // return tesselateRailInWorld(tt, x, y, z);
} else if (shape == Tile::SHAPE_STAIRS) { } else if (shape == Tile::SHAPE_STAIRS) {
return tesselateStairsInWorld((StairTile*)tt, x, y, z); return tesselateStairsInWorld((StairTile*)tt, x, y, z);
} else if (shape == Tile::SHAPE_FENCE) { } else if (shape == Tile::SHAPE_FENCE) {
return tesselateFenceInWorld((FenceTile*)tt, x, y, z); return tesselateFenceInWorld((FenceTile*)tt, x, y, z);
} else if (shape == Tile::SHAPE_FENCE_GATE) { } else if (shape == Tile::SHAPE_FENCE_GATE) {
return tesselateFenceGateInWorld((FenceGateTile*) tt, x, y, z); return tesselateFenceGateInWorld((FenceGateTile*) tt, x, y, z);
//} else if (shape == Tile::SHAPE_LEVER) { //} else if (shape == Tile::SHAPE_LEVER) {
// return tesselateLeverInWorld(tt, x, y, z); // return tesselateLeverInWorld(tt, x, y, z);
//} else if (shape == Tile::SHAPE_BED) { //} else if (shape == Tile::SHAPE_BED) {
// return tesselateBedInWorld(tt, x, y, z); // return tesselateBedInWorld(tt, x, y, z);
//} else if (shape == Tile::SHAPE_DIODE) { //} else if (shape == Tile::SHAPE_DIODE) {
// return tesselateDiodeInWorld(tt, x, y, z); // return tesselateDiodeInWorld(tt, x, y, z);
} else if (shape == Tile::SHAPE_IRON_FENCE) { } else if (shape == Tile::SHAPE_IRON_FENCE) {
return tesselateThinFenceInWorld((ThinFenceTile*) tt, x, y, z); return tesselateThinFenceInWorld((ThinFenceTile*) tt, x, y, z);
} else if(shape == Tile::SHAPE_BED) { } else if(shape == Tile::SHAPE_BED) {
@@ -340,82 +363,82 @@ bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z )
if ( Tile::fire->canBurn( level, x - 1, y, z ) ) if ( Tile::fire->canBurn( level, x - 1, y, z ) )
{ {
t.vertexUV( ( float )( x + r ), ( float )( y + h + yo ), ( float )( z + t.vertexUV( ( float )( x + r ), ( float )( y + h + yo ), ( float )( z +
1.0f ), ( float )( u1 ), ( float )( v0 ) ); 1.0f ), ( float )( u1 ), ( float )( v0 ) );
t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z +
1.0f ), ( float )( u1 ), ( float )( v1 ) ); 1.0f ), ( float )( u1 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z +
0.0f ), ( float )( u0 ), ( float )( v1 ) ); 0.0f ), ( float )( u0 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + r ), ( float )( y + h + yo ), ( float )( z + t.vertexUV( ( float )( x + r ), ( float )( y + h + yo ), ( float )( z +
0.0f ), ( float )( u0 ), ( float )( v0 ) ); 0.0f ), ( float )( u0 ), ( float )( v0 ) );
t.vertexUV( ( float )( x + r ), ( float )( y + h + yo ), ( float )( z + t.vertexUV( ( float )( x + r ), ( float )( y + h + yo ), ( float )( z +
0.0f ), ( float )( u0 ), ( float )( v0 ) ); 0.0f ), ( float )( u0 ), ( float )( v0 ) );
t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z +
0.0f ), ( float )( u0 ), ( float )( v1 ) ); 0.0f ), ( float )( u0 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z +
1.0f ), ( float )( u1 ), ( float )( v1 ) ); 1.0f ), ( float )( u1 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + r ), ( float )( y + h + yo ), ( float )( z + t.vertexUV( ( float )( x + r ), ( float )( y + h + yo ), ( float )( z +
1.0f ), ( float )( u1 ), ( float )( v0 ) ); 1.0f ), ( float )( u1 ), ( float )( v0 ) );
} }
if ( Tile::fire->canBurn( level, x + 1, y, z ) ) if ( Tile::fire->canBurn( level, x + 1, y, z ) )
{ {
t.vertexUV( ( float )( x + 1 - r ), ( float )( y + h + yo ), ( float )( z + t.vertexUV( ( float )( x + 1 - r ), ( float )( y + h + yo ), ( float )( z +
0.0f ), ( float )( u0 ), ( float )( v0 ) ); 0.0f ), ( float )( u0 ), ( float )( v0 ) );
t.vertexUV( ( float )( x + 1 - 0 ), ( float )( y + 0 + yo ), ( float )( z + t.vertexUV( ( float )( x + 1 - 0 ), ( float )( y + 0 + yo ), ( float )( z +
0.0f ), ( float )( u0 ), ( float )( v1 ) ); 0.0f ), ( float )( u0 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 1 - 0 ), ( float )( y + 0 + yo ), ( float )( z + t.vertexUV( ( float )( x + 1 - 0 ), ( float )( y + 0 + yo ), ( float )( z +
1.0f ), ( float )( u1 ), ( float )( v1 ) ); 1.0f ), ( float )( u1 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 1 - r ), ( float )( y + h + yo ), ( float )( z + t.vertexUV( ( float )( x + 1 - r ), ( float )( y + h + yo ), ( float )( z +
1.0f ), ( float )( u1 ), ( float )( v0 ) ); 1.0f ), ( float )( u1 ), ( float )( v0 ) );
t.vertexUV( ( float )( x + 1.0f - r ), ( float )( y + h + yo ), ( float )( z + t.vertexUV( ( float )( x + 1.0f - r ), ( float )( y + h + yo ), ( float )( z +
1.0f ), ( float )( u1 ), ( float )( v0 ) ); 1.0f ), ( float )( u1 ), ( float )( v0 ) );
t.vertexUV( ( float )( x + 1.0f - 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + t.vertexUV( ( float )( x + 1.0f - 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z +
1.0f ), ( float )( u1 ), ( float )( v1 ) ); 1.0f ), ( float )( u1 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 1.0f - 0 ), ( float )( y + 0.0f + yo ), ( float )( z + t.vertexUV( ( float )( x + 1.0f - 0 ), ( float )( y + 0.0f + yo ), ( float )( z +
0.0f ), ( float )( u0 ), ( float )( v1 ) ); 0.0f ), ( float )( u0 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 1.0f - r ), ( float )( y + h + yo ), ( float )( z + t.vertexUV( ( float )( x + 1.0f - r ), ( float )( y + h + yo ), ( float )( z +
0.0f ), ( float )( u0 ), ( float )( v0 ) ); 0.0f ), ( float )( u0 ), ( float )( v0 ) );
} }
if ( Tile::fire->canBurn( level, x, y, z - 1 ) ) if ( Tile::fire->canBurn( level, x, y, z - 1 ) )
{ {
t.vertexUV( ( float )( x + 0.0f ), ( float )( y + h + yo ), ( float )( z + t.vertexUV( ( float )( x + 0.0f ), ( float )( y + h + yo ), ( float )( z +
r ), ( float )( u1 ), ( float )( v0 ) ); r ), ( float )( u1 ), ( float )( v0 ) );
t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z +
0.0f ), ( float )( u1 ), ( float )( v1 ) ); 0.0f ), ( float )( u1 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 1.0f ), ( float )( y + 0.0f + yo ), ( float )( z + t.vertexUV( ( float )( x + 1.0f ), ( float )( y + 0.0f + yo ), ( float )( z +
0.0f ), ( float )( u0 ), ( float )( v1 ) ); 0.0f ), ( float )( u0 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 1.0f ), ( float )( y + h + yo ), ( float )( z + t.vertexUV( ( float )( x + 1.0f ), ( float )( y + h + yo ), ( float )( z +
r ), ( float )( u0 ), ( float )( v0 ) ); r ), ( float )( u0 ), ( float )( v0 ) );
t.vertexUV( ( float )( x + 1.0f ), ( float )( y + h + yo ), ( float )( z + t.vertexUV( ( float )( x + 1.0f ), ( float )( y + h + yo ), ( float )( z +
r ), ( float )( u0 ), ( float )( v0 ) ); r ), ( float )( u0 ), ( float )( v0 ) );
t.vertexUV( ( float )( x + 1.0f ), ( float )( y + 0.0f + yo ), ( float )( z + t.vertexUV( ( float )( x + 1.0f ), ( float )( y + 0.0f + yo ), ( float )( z +
0.0f ), ( float )( u0 ), ( float )( v1 ) ); 0.0f ), ( float )( u0 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z +
0.0f ), ( float )( u1 ), ( float )( v1 ) ); 0.0f ), ( float )( u1 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 0.0f ), ( float )( y + h + yo ), ( float )( z + t.vertexUV( ( float )( x + 0.0f ), ( float )( y + h + yo ), ( float )( z +
r ), ( float )( u1 ), ( float )( v0 ) ); r ), ( float )( u1 ), ( float )( v0 ) );
} }
if ( Tile::fire->canBurn( level, x, y, z + 1 ) ) if ( Tile::fire->canBurn( level, x, y, z + 1 ) )
{ {
t.vertexUV( ( float )( x + 1.0f ), ( float )( y + h + yo ), ( float )( z + 1.0f - t.vertexUV( ( float )( x + 1.0f ), ( float )( y + h + yo ), ( float )( z + 1.0f -
r ), ( float )( u0 ), ( float )( v0 ) ); r ), ( float )( u0 ), ( float )( v0 ) );
t.vertexUV( ( float )( x + 1.0f ), ( float )( y + 0.0f + yo ), ( float )( z + 1.0f - t.vertexUV( ( float )( x + 1.0f ), ( float )( y + 0.0f + yo ), ( float )( z + 1.0f -
0.0f ), ( float )( u0 ), ( float )( v1 ) ); 0.0f ), ( float )( u0 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + 1.0f - t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + 1.0f -
0.0f ), ( float )( u1 ), ( float )( v1 ) ); 0.0f ), ( float )( u1 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 0.0f ), ( float )( y + h + yo ), ( float )( z + 1.0f - t.vertexUV( ( float )( x + 0.0f ), ( float )( y + h + yo ), ( float )( z + 1.0f -
r ), ( float )( u1 ), ( float )( v0 ) ); r ), ( float )( u1 ), ( float )( v0 ) );
t.vertexUV( ( float )( x + 0.0f ), ( float )( y + h + yo ), ( float )( z + 1.0f - t.vertexUV( ( float )( x + 0.0f ), ( float )( y + h + yo ), ( float )( z + 1.0f -
r ), ( float )( u1 ), ( float )( v0 ) ); r ), ( float )( u1 ), ( float )( v0 ) );
t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + 1.0f - t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + 1.0f -
0.0f ), ( float )( u1 ), ( float )( v1 ) ); 0.0f ), ( float )( u1 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 1.0f ), ( float )( y + 0.0f + yo ), ( float )( z + 1.0f - t.vertexUV( ( float )( x + 1.0f ), ( float )( y + 0.0f + yo ), ( float )( z + 1.0f -
0.0f ), ( float )( u0 ), ( float )( v1 ) ); 0.0f ), ( float )( u0 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 1.0f ), ( float )( y + h + yo ), ( float )( z + 1.0f - t.vertexUV( ( float )( x + 1.0f ), ( float )( y + h + yo ), ( float )( z + 1.0f -
r ), ( float )( u0 ), ( float )( v0 ) ); r ), ( float )( u0 ), ( float )( v0 ) );
} }
if ( Tile::fire->canBurn( level, x, y + 1.0f, z ) ) if ( Tile::fire->canBurn( level, x, y + 1.0f, z ) )
{ {
@@ -440,13 +463,13 @@ bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z )
if ( ( ( x + y + z ) & 1 ) == 0 ) if ( ( ( x + y + z ) & 1 ) == 0 )
{ {
t.vertexUV( ( float )( x0_ ), ( float )( y + h ), ( float )( z + t.vertexUV( ( float )( x0_ ), ( float )( y + h ), ( float )( z +
0 ), ( float )( u1 ), ( float )( v0 ) ); 0 ), ( float )( u1 ), ( float )( v0 ) );
t.vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z + t.vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z +
0 ), ( float )( u1 ), ( float )( v1 ) ); 0 ), ( float )( u1 ), ( float )( v1 ) );
t.vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z + t.vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z +
1 ), ( float )( u0 ), ( float )( v1 ) ); 1 ), ( float )( u0 ), ( float )( v1 ) );
t.vertexUV( ( float )( x0_ ), ( float )( y + h ), ( float )( z + t.vertexUV( ( float )( x0_ ), ( float )( y + h ), ( float )( z +
1 ), ( float )( u0 ), ( float )( v0 ) ); 1 ), ( float )( u0 ), ( float )( v0 ) );
u0 = (xt) / 256.0f; u0 = (xt) / 256.0f;
u1 = (xt + 15.99f) / 256.0f; u1 = (xt + 15.99f) / 256.0f;
@@ -454,24 +477,24 @@ bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z )
v1 = (yt + 15.99f) / 256.0f; v1 = (yt + 15.99f) / 256.0f;
t.vertexUV( ( float )( x1_ ), ( float )( y + h ), ( float )( z + t.vertexUV( ( float )( x1_ ), ( float )( y + h ), ( float )( z +
1.0f ), ( float )( u1 ), ( float )( v0 ) ); 1.0f ), ( float )( u1 ), ( float )( v0 ) );
t.vertexUV( ( float )( x1 ), ( float )( y + 0.0f ), ( float )( z + t.vertexUV( ( float )( x1 ), ( float )( y + 0.0f ), ( float )( z +
1.0f ), ( float )( u1 ), ( float )( v1 ) ); 1.0f ), ( float )( u1 ), ( float )( v1 ) );
t.vertexUV( ( float )( x1 ), ( float )( y + 0.0f ), ( float )( z + t.vertexUV( ( float )( x1 ), ( float )( y + 0.0f ), ( float )( z +
0 ), ( float )( u0 ), ( float )( v1 ) ); 0 ), ( float )( u0 ), ( float )( v1 ) );
t.vertexUV( ( float )( x1_ ), ( float )( y + h ), ( float )( z + t.vertexUV( ( float )( x1_ ), ( float )( y + h ), ( float )( z +
0 ), ( float )( u0 ), ( float )( v0 ) ); 0 ), ( float )( u0 ), ( float )( v0 ) );
} }
else else
{ {
t.vertexUV( ( float )( x + 0.0f ), ( float )( y + t.vertexUV( ( float )( x + 0.0f ), ( float )( y +
h ), ( float )( z1_ ), ( float )( u1 ), ( float )( v0 ) ); h ), ( float )( z1_ ), ( float )( u1 ), ( float )( v0 ) );
t.vertexUV( ( float )( x + 0.0f ), ( float )( y + t.vertexUV( ( float )( x + 0.0f ), ( float )( y +
0.0f ), ( float )( z1 ), ( float )( u1 ), ( float )( v1 ) ); 0.0f ), ( float )( z1 ), ( float )( u1 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 1.0f ), ( float )( y + t.vertexUV( ( float )( x + 1.0f ), ( float )( y +
0.0f ), ( float )( z1 ), ( float )( u0 ), ( float )( v1 ) ); 0.0f ), ( float )( z1 ), ( float )( u0 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 1.0f ), ( float )( y + t.vertexUV( ( float )( x + 1.0f ), ( float )( y +
h ), ( float )( z1_ ), ( float )( u0 ), ( float )( v0 ) ); h ), ( float )( z1_ ), ( float )( u0 ), ( float )( v0 ) );
u0 = (xt) / 256.0f; u0 = (xt) / 256.0f;
u1 = (xt + 15.99f) / 256.0f; u1 = (xt + 15.99f) / 256.0f;
@@ -479,13 +502,13 @@ bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z )
v1 = (yt + 15.99f) / 256.0f; v1 = (yt + 15.99f) / 256.0f;
t.vertexUV( ( float )( x + 1.0f ), ( float )( y + t.vertexUV( ( float )( x + 1.0f ), ( float )( y +
h ), ( float )( z0_ ), ( float )( u1 ), ( float )( v0 ) ); h ), ( float )( z0_ ), ( float )( u1 ), ( float )( v0 ) );
t.vertexUV( ( float )( x + 1.0f ), ( float )( y + t.vertexUV( ( float )( x + 1.0f ), ( float )( y +
0.0f ), ( float )( z0 ), ( float )( u1 ), ( float )( v1 ) ); 0.0f ), ( float )( z0 ), ( float )( u1 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 0.0f ), ( float )( y + t.vertexUV( ( float )( x + 0.0f ), ( float )( y +
0.0f ), ( float )( z0 ), ( float )( u0 ), ( float )( v1 ) ); 0.0f ), ( float )( z0 ), ( float )( u0 ), ( float )( v1 ) );
t.vertexUV( ( float )( x + 0.0f ), ( float )( y + t.vertexUV( ( float )( x + 0.0f ), ( float )( y +
h ), ( float )( z0_ ), ( float )( u0 ), ( float )( v0 ) ); h ), ( float )( z0_ ), ( float )( u0 ), ( float )( v0 ) );
} }
} }
} }
@@ -958,46 +981,46 @@ float TileRenderer::getWaterHeight( int x, int y, int z, const Material* m )
} }
void TileRenderer::renderBlock(Tile* tt, LevelSource* level, int x, int y, int z) { void TileRenderer::renderBlock(Tile* tt, LevelSource* level, int x, int y, int z) {
float c10 = 0.5f; float c10 = 0.5f;
float c11 = 1; float c11 = 1;
float c2 = 0.8f; float c2 = 0.8f;
float c3 = 0.6f; float c3 = 0.6f;
Tesselator& t = Tesselator::instance; Tesselator& t = Tesselator::instance;
t.begin(); t.begin();
float center = tt->getBrightness(level, x, y, z); float center = tt->getBrightness(level, x, y, z);
float br = tt->getBrightness(level, x, y - 1, z); float br = tt->getBrightness(level, x, y - 1, z);
if (br < center) br = center; if (br < center) br = center;
t.color(c10 * br, c10 * br, c10 * br); t.color(c10 * br, c10 * br, c10 * br);
renderFaceDown(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(0)); renderFaceDown(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(0));
br = tt->getBrightness(level, x, y + 1, z); br = tt->getBrightness(level, x, y + 1, z);
if (br < center) br = center; if (br < center) br = center;
t.color(c11 * br, c11 * br, c11 * br); t.color(c11 * br, c11 * br, c11 * br);
renderFaceUp(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(1)); renderFaceUp(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(1));
br = tt->getBrightness(level, x, y, z - 1); br = tt->getBrightness(level, x, y, z - 1);
if (br < center) br = center; if (br < center) br = center;
t.color(c2 * br, c2 * br, c2 * br); t.color(c2 * br, c2 * br, c2 * br);
renderNorth(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(2)); renderNorth(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(2));
br = tt->getBrightness(level, x, y, z + 1); br = tt->getBrightness(level, x, y, z + 1);
if (br < center) br = center; if (br < center) br = center;
t.color(c2 * br, c2 * br, c2 * br); t.color(c2 * br, c2 * br, c2 * br);
renderSouth(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(3)); renderSouth(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(3));
br = tt->getBrightness(level, x - 1, y, z); br = tt->getBrightness(level, x - 1, y, z);
if (br < center) br = center; if (br < center) br = center;
t.color(c3 * br, c3 * br, c3 * br); t.color(c3 * br, c3 * br, c3 * br);
renderWest(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(4)); renderWest(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(4));
br = tt->getBrightness(level, x + 1, y, z); br = tt->getBrightness(level, x + 1, y, z);
if (br < center) br = center; if (br < center) br = center;
t.color(c3 * br, c3 * br, c3 * br); t.color(c3 * br, c3 * br, c3 * br);
renderEast(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(5)); renderEast(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(5));
t.draw(); t.draw();
} }
bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusion( Tile* tt, int pX, int pY, int pZ, float pBaseRed, float pBaseGreen, float pBaseBlue ) bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusion( Tile* tt, int pX, int pY, int pZ, float pBaseRed, float pBaseGreen, float pBaseBlue )
@@ -1197,6 +1220,15 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusion( Tile* tt, int pX,
c4g *= ll4; c4g *= ll4;
c4b *= ll4; c4b *= ll4;
renderNorth(tt, (float) pX, (float) pY, (float) pZ, tt->getTexture(level, pX, pY, pZ, 2)); renderNorth(tt, (float) pX, (float) pY, (float) pZ, tt->getTexture(level, pX, pY, pZ, 2));
if (tt->getTexture(level, pX, pY, pZ, 2) == 3 && sideTinting)
{
c1r *= pBaseRed; c1g *= pBaseGreen; c1b *= pBaseBlue;
c2r *= pBaseRed; c2g *= pBaseGreen; c2b *= pBaseBlue;
c3r *= pBaseRed; c3g *= pBaseGreen; c3b *= pBaseBlue;
c4r *= pBaseRed; c4g *= pBaseGreen; c4b *= pBaseBlue;
renderNorth(tt, (float) pX, (float) pY, (float) pZ, 38);
}
i = true; i = true;
} }
if ((noCulling) || (tt->shouldRenderFace(level, pX, pY, pZ + 1, 3))) { if ((noCulling) || (tt->shouldRenderFace(level, pX, pY, pZ + 1, 3))) {
@@ -1250,6 +1282,15 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusion( Tile* tt, int pX,
c4g *= ll4; c4g *= ll4;
c4b *= ll4; c4b *= ll4;
renderSouth(tt, (float) pX, (float) pY, (float) pZ, tt->getTexture(level, pX, pY, pZ, 3)); renderSouth(tt, (float) pX, (float) pY, (float) pZ, tt->getTexture(level, pX, pY, pZ, 3));
if (tt->getTexture(level, pX, pY, pZ, 3) == 3 && sideTinting)
{
c1r *= pBaseRed; c1g *= pBaseGreen; c1b *= pBaseBlue;
c2r *= pBaseRed; c2g *= pBaseGreen; c2b *= pBaseBlue;
c3r *= pBaseRed; c3g *= pBaseGreen; c3b *= pBaseBlue;
c4r *= pBaseRed; c4g *= pBaseGreen; c4b *= pBaseBlue;
renderSouth(tt, (float) pX, (float) pY, (float) pZ, 38);
}
i = true; i = true;
} }
if ((noCulling) || (tt->shouldRenderFace(level, pX - 1, pY, pZ, 4))) { if ((noCulling) || (tt->shouldRenderFace(level, pX - 1, pY, pZ, 4))) {
@@ -1302,6 +1343,15 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusion( Tile* tt, int pX,
c4g *= ll4; c4g *= ll4;
c4b *= ll4; c4b *= ll4;
renderWest(tt, (float) pX, (float) pY, (float) pZ, tt->getTexture(level, pX, pY, pZ, 4)); renderWest(tt, (float) pX, (float) pY, (float) pZ, tt->getTexture(level, pX, pY, pZ, 4));
if (tt->getTexture(level, pX, pY, pZ, 4) == 3 && sideTinting)
{
c1r *= pBaseRed; c1g *= pBaseGreen; c1b *= pBaseBlue;
c2r *= pBaseRed; c2g *= pBaseGreen; c2b *= pBaseBlue;
c3r *= pBaseRed; c3g *= pBaseGreen; c3b *= pBaseBlue;
c4r *= pBaseRed; c4g *= pBaseGreen; c4b *= pBaseBlue;
renderWest(tt, (float) pX, (float) pY, (float) pZ, 38);
}
i = true; i = true;
} }
if ((noCulling) || (tt->shouldRenderFace(level, pX + 1, pY, pZ, 5))) { if ((noCulling) || (tt->shouldRenderFace(level, pX + 1, pY, pZ, 5))) {
@@ -1355,6 +1405,15 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusion( Tile* tt, int pX,
c4b *= ll4; c4b *= ll4;
renderEast(tt, (float) pX, (float) pY, (float) pZ, tt->getTexture(level, pX, pY, pZ, 5)); renderEast(tt, (float) pX, (float) pY, (float) pZ, tt->getTexture(level, pX, pY, pZ, 5));
if (tt->getTexture(level, pX, pY, pZ, 5) == 3 && sideTinting)
{
c1r *= pBaseRed; c1g *= pBaseGreen; c1b *= pBaseBlue;
c2r *= pBaseRed; c2g *= pBaseGreen; c2b *= pBaseBlue;
c3r *= pBaseRed; c3g *= pBaseGreen; c3b *= pBaseBlue;
c4r *= pBaseRed; c4g *= pBaseGreen; c4b *= pBaseBlue;
renderEast(tt, (float) pX, (float) pY, (float) pZ, 38);
}
i = true; i = true;
} }
applyAmbienceOcclusion = false; applyAmbienceOcclusion = false;
@@ -1362,124 +1421,124 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusion( Tile* tt, int pX,
} }
bool TileRenderer::tesselateCactusInWorld(Tile* tt, int x, int y, int z) { bool TileRenderer::tesselateCactusInWorld(Tile* tt, int x, int y, int z) {
int col = tt->getColor(level, x, y, z); int col = tt->getColor(level, x, y, z);
float r = ((col >> 16) & 0xff) / 255.0f; float r = ((col >> 16) & 0xff) / 255.0f;
float g = ((col >> 8) & 0xff) / 255.0f; float g = ((col >> 8) & 0xff) / 255.0f;
float b = ((col) & 0xff) / 255.0f; float b = ((col) & 0xff) / 255.0f;
return tesselateCactusInWorld(tt, x, y, z, r, g, b); return tesselateCactusInWorld(tt, x, y, z, r, g, b);
} }
bool TileRenderer::tesselateCactusInWorld(Tile* tt, int x, int y, int z, float r, float g, float b) { bool TileRenderer::tesselateCactusInWorld(Tile* tt, int x, int y, int z, float r, float g, float b) {
Tesselator& t = Tesselator::instance; Tesselator& t = Tesselator::instance;
bool changed = false; bool changed = false;
float c10 = 0.5f; float c10 = 0.5f;
float c11 = 1; float c11 = 1;
float c2 = 0.8f; float c2 = 0.8f;
float c3 = 0.6f; float c3 = 0.6f;
float r10 = c10 * r; float r10 = c10 * r;
float r11 = c11 * r; float r11 = c11 * r;
float r2 = c2 * r; float r2 = c2 * r;
float r3 = c3 * r; float r3 = c3 * r;
float g10 = c10 * g; float g10 = c10 * g;
float g11 = c11 * g; float g11 = c11 * g;
float g2 = c2 * g; float g2 = c2 * g;
float g3 = c3 * g; float g3 = c3 * g;
float b10 = c10 * b; float b10 = c10 * b;
float b11 = c11 * b; float b11 = c11 * b;
float b2 = c2 * b; float b2 = c2 * b;
float b3 = c3 * b; float b3 = c3 * b;
float s = 1 / 16.0f; float s = 1 / 16.0f;
const float X = (float)x; const float X = (float)x;
const float Y = (float)y; const float Y = (float)y;
const float Z = (float)z; const float Z = (float)z;
float centerBrightness = tt->getBrightness(level, x, y, z); float centerBrightness = tt->getBrightness(level, x, y, z);
if (noCulling || tt->shouldRenderFace(level, x, y - 1, z, 0)) { if (noCulling || tt->shouldRenderFace(level, x, y - 1, z, 0)) {
float br = tt->getBrightness(level, x, y - 1, z); float br = tt->getBrightness(level, x, y - 1, z);
// if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br =
// Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; // Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS;
t.color(r10 * br, g10 * br, b10 * br); t.color(r10 * br, g10 * br, b10 * br);
renderFaceDown(tt, X, Y, Z, tt->getTexture(level, x, y, z, 0)); renderFaceDown(tt, X, Y, Z, tt->getTexture(level, x, y, z, 0));
changed = true; changed = true;
} }
if (noCulling || tt->shouldRenderFace(level, x, y + 1, z, 1)) { if (noCulling || tt->shouldRenderFace(level, x, y + 1, z, 1)) {
float br = tt->getBrightness(level, x, y + 1, z); float br = tt->getBrightness(level, x, y + 1, z);
if (tt->yy1 != 1 && !tt->material->isLiquid()) br = centerBrightness; if (tt->yy1 != 1 && !tt->material->isLiquid()) br = centerBrightness;
// if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br =
// Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; // Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS;
t.color(r11 * br, g11 * br, b11 * br); t.color(r11 * br, g11 * br, b11 * br);
renderFaceUp(tt, X, Y, Z, tt->getTexture(level, x, y, z, 1)); renderFaceUp(tt, X, Y, Z, tt->getTexture(level, x, y, z, 1));
changed = true; changed = true;
} }
if (noCulling || tt->shouldRenderFace(level, x, y, z - 1, 2)) { if (noCulling || tt->shouldRenderFace(level, x, y, z - 1, 2)) {
float br = tt->getBrightness(level, x, y, z - 1); float br = tt->getBrightness(level, x, y, z - 1);
if (tt->zz0 > 0) br = centerBrightness; if (tt->zz0 > 0) br = centerBrightness;
// if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br =
// Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; // Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS;
t.color(r2 * br, g2 * br, b2 * br); t.color(r2 * br, g2 * br, b2 * br);
t.addOffset(0, 0, s); t.addOffset(0, 0, s);
renderNorth(tt, X, Y, Z, tt->getTexture(level, x, y, z, 2)); renderNorth(tt, X, Y, Z, tt->getTexture(level, x, y, z, 2));
t.addOffset(0, 0, -s); t.addOffset(0, 0, -s);
changed = true; changed = true;
} }
if (noCulling || tt->shouldRenderFace(level, x, y, z + 1, 3)) { if (noCulling || tt->shouldRenderFace(level, x, y, z + 1, 3)) {
float br = tt->getBrightness(level, x, y, z + 1); float br = tt->getBrightness(level, x, y, z + 1);
if (tt->zz1 < 1) br = centerBrightness; if (tt->zz1 < 1) br = centerBrightness;
// if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br =
// Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; // Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS;
t.color(r2 * br, g2 * br, b2 * br); t.color(r2 * br, g2 * br, b2 * br);
t.addOffset(0, 0, -s); t.addOffset(0, 0, -s);
renderSouth(tt, X, Y, Z, tt->getTexture(level, x, y, z, 3)); renderSouth(tt, X, Y, Z, tt->getTexture(level, x, y, z, 3));
t.addOffset(0, 0, s); t.addOffset(0, 0, s);
changed = true; changed = true;
} }
if (noCulling || tt->shouldRenderFace(level, x - 1, y, z, 4)) { if (noCulling || tt->shouldRenderFace(level, x - 1, y, z, 4)) {
float br = tt->getBrightness(level, x - 1, y, z); float br = tt->getBrightness(level, x - 1, y, z);
if (tt->xx0 > 0) br = centerBrightness; if (tt->xx0 > 0) br = centerBrightness;
// if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br =
// Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; // Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS;
t.color(r3 * br, g3 * br, b3 * br); t.color(r3 * br, g3 * br, b3 * br);
t.addOffset(s, 0, 0); t.addOffset(s, 0, 0);
renderWest(tt, X, Y, Z, tt->getTexture(level, x, y, z, 4)); renderWest(tt, X, Y, Z, tt->getTexture(level, x, y, z, 4));
t.addOffset(-s, 0, 0); t.addOffset(-s, 0, 0);
changed = true; changed = true;
} }
if (noCulling || tt->shouldRenderFace(level, x + 1, y, z, 5)) { if (noCulling || tt->shouldRenderFace(level, x + 1, y, z, 5)) {
float br = tt->getBrightness(level, x + 1, y, z); float br = tt->getBrightness(level, x + 1, y, z);
if (tt->xx1 < 1) br = centerBrightness; if (tt->xx1 < 1) br = centerBrightness;
// if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br =
// Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; // Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS;
t.color(r3 * br, g3 * br, b3 * br); t.color(r3 * br, g3 * br, b3 * br);
t.addOffset(-s, 0, 0); t.addOffset(-s, 0, 0);
renderEast(tt, X, Y, Z, tt->getTexture(level, x, y, z, 5)); renderEast(tt, X, Y, Z, tt->getTexture(level, x, y, z, 5));
t.addOffset(s, 0, 0); t.addOffset(s, 0, 0);
changed = true; changed = true;
} }
return changed; return changed;
} }
bool TileRenderer::tesselateFenceInWorld(FenceTile* tt, int x, int y, int z) { bool TileRenderer::tesselateFenceInWorld(FenceTile* tt, int x, int y, int z) {
bool changed = true; bool changed = true;
float a = 6 / 16.0f; float a = 6 / 16.0f;
float b = 10 / 16.0f; float b = 10 / 16.0f;
tt->setShape(a, 0, a, b, 1, b); tt->setShape(a, 0, a, b, 1, b);
tesselateBlockInWorld(tt, x, y, z); tesselateBlockInWorld(tt, x, y, z);
bool vertical = false; bool vertical = false;
bool horizontal = false; bool horizontal = false;
bool l = tt->connectsTo(level, x - 1, y, z); bool l = tt->connectsTo(level, x - 1, y, z);
bool r = tt->connectsTo(level, x + 1, y, z); bool r = tt->connectsTo(level, x + 1, y, z);
@@ -1487,42 +1546,42 @@ bool TileRenderer::tesselateFenceInWorld(FenceTile* tt, int x, int y, int z) {
bool d = tt->connectsTo(level, x, y, z + 1); bool d = tt->connectsTo(level, x, y, z + 1);
if (l || r) vertical = true; if (l || r) vertical = true;
if (u || d) horizontal = true; if (u || d) horizontal = true;
if (!vertical && !horizontal) vertical = true; if (!vertical && !horizontal) vertical = true;
a = 7 / 16.0f; a = 7 / 16.0f;
b = 9 / 16.0f; b = 9 / 16.0f;
float h0 = 12 / 16.0f; float h0 = 12 / 16.0f;
float h1 = 15 / 16.0f; float h1 = 15 / 16.0f;
float x0 = l ? 0 : a; float x0 = l ? 0 : a;
float x1 = r ? 1 : b; float x1 = r ? 1 : b;
float z0 = u ? 0 : a; float z0 = u ? 0 : a;
float z1 = d ? 1 : b; float z1 = d ? 1 : b;
if (vertical) { if (vertical) {
tt->setShape(x0, h0, a, x1, h1, b); tt->setShape(x0, h0, a, x1, h1, b);
tesselateBlockInWorld(tt, x, y, z); tesselateBlockInWorld(tt, x, y, z);
} }
if (horizontal) { if (horizontal) {
tt->setShape(a, h0, z0, b, h1, z1); tt->setShape(a, h0, z0, b, h1, z1);
tesselateBlockInWorld(tt, x, y, z); tesselateBlockInWorld(tt, x, y, z);
} }
h0 = 6 / 16.0f; h0 = 6 / 16.0f;
h1 = 9 / 16.0f; h1 = 9 / 16.0f;
if (vertical) { if (vertical) {
tt->setShape(x0, h0, a, x1, h1, b); tt->setShape(x0, h0, a, x1, h1, b);
tesselateBlockInWorld(tt, x, y, z); tesselateBlockInWorld(tt, x, y, z);
} }
if (horizontal) { if (horizontal) {
tt->setShape(a, h0, z0, b, h1, z1); tt->setShape(a, h0, z0, b, h1, z1);
tesselateBlockInWorld(tt, x, y, z); tesselateBlockInWorld(tt, x, y, z);
} }
tt->setShape(0, 0, 0, 1, 1, 1); tt->setShape(0, 0, 0, 1, 1, 1);
return changed; return changed;
} }
bool TileRenderer::tesselateFenceGateInWorld(FenceGateTile* tt, int x, int y, int z) { bool TileRenderer::tesselateFenceGateInWorld(FenceGateTile* tt, int x, int y, int z) {
@@ -2403,110 +2462,110 @@ void TileRenderer::renderTile( Tile* tile, int data )
t.addOffset(s, 0, 0); t.addOffset(s, 0, 0);
t.draw(); t.draw();
t.offset(0, 0, 0);//0.5f, 0.5f, 0.5f); t.offset(0, 0, 0);//0.5f, 0.5f, 0.5f);
} else if (shape == Tile::SHAPE_ROWS) { } else if (shape == Tile::SHAPE_ROWS) {
t.begin(); t.begin();
t.normal(0, -1, 0); t.normal(0, -1, 0);
tesselateRowTexture(tile, data, -0.5f, -0.5f, -0.5f); tesselateRowTexture(tile, data, -0.5f, -0.5f, -0.5f);
//} else if (shape == Tile::SHAPE_TORCH) { //} else if (shape == Tile::SHAPE_TORCH) {
//// t.begin(); //// t.begin();
//// t.normal(0, -1, 0); //// t.normal(0, -1, 0);
/// tesselateTorch(tile, -0.5f, -0.5f, -0.5f, 0, 0); /// tesselateTorch(tile, -0.5f, -0.5f, -0.5f, 0, 0);
//// t.end(); //// t.end();
} else if (shape == Tile::SHAPE_ENTITYTILE_ANIMATED) { } else if (shape == Tile::SHAPE_ENTITYTILE_ANIMATED) {
EntityTileRenderer::instance->render(tile, data, 1.0f); EntityTileRenderer::instance->render(tile, data, 1.0f);
//glEnable(GL_RESCALE_NORMAL); //glEnable(GL_RESCALE_NORMAL);
} else if (shape == Tile::SHAPE_STAIRS) { } else if (shape == Tile::SHAPE_STAIRS) {
t.addOffset(-0.5f, -0.5f, -0.5f); t.addOffset(-0.5f, -0.5f, -0.5f);
t.begin(); t.begin();
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
if (i == 0) tile->setShape(0, 0, 0, 1, 1, 0.5f); if (i == 0) tile->setShape(0, 0, 0, 1, 1, 0.5f);
if (i == 1) tile->setShape(0, 0, 0.5f, 1, 0.5f, 1); if (i == 1) tile->setShape(0, 0, 0.5f, 1, 0.5f, 1);
t.normal(0.0f, -1.0f, 0.0f); t.normal(0.0f, -1.0f, 0.0f);
renderFaceDown(tile, 0, 0, 0, tile->getTexture(0)); renderFaceDown(tile, 0, 0, 0, tile->getTexture(0));
t.normal(0.0f, 1.0f, 0.0f); t.normal(0.0f, 1.0f, 0.0f);
renderFaceUp(tile, 0, 0, 0, tile->getTexture(1)); renderFaceUp(tile, 0, 0, 0, tile->getTexture(1));
t.normal(0.0f, 0.0f, -1.0f); t.normal(0.0f, 0.0f, -1.0f);
renderNorth(tile, 0, 0, 0, tile->getTexture(2)); renderNorth(tile, 0, 0, 0, tile->getTexture(2));
t.normal(0.0f, 0.0f, 1.0f); t.normal(0.0f, 0.0f, 1.0f);
renderSouth(tile, 0, 0, 0, tile->getTexture(3)); renderSouth(tile, 0, 0, 0, tile->getTexture(3));
t.normal(-1.0f, 0.0f, 0.0f); t.normal(-1.0f, 0.0f, 0.0f);
renderWest(tile, 0, 0, 0, tile->getTexture(4)); renderWest(tile, 0, 0, 0, tile->getTexture(4));
t.normal(1.0f, 0.0f, 0.0f); t.normal(1.0f, 0.0f, 0.0f);
renderEast(tile, 0, 0, 0, tile->getTexture(5)); renderEast(tile, 0, 0, 0, tile->getTexture(5));
}
t.draw();
t.addOffset(0.5f, 0.5f, 0.5f);
} }
else if (shape == Tile::SHAPE_FENCE) { t.draw();
t.addOffset(-0.5f, -0.5f, -0.5f); t.addOffset(0.5f, 0.5f, 0.5f);
t.begin(); }
for (int i = 0; i < 4; i++) { else if (shape == Tile::SHAPE_FENCE) {
float w = 2 / 16.0f; t.addOffset(-0.5f, -0.5f, -0.5f);
if (i == 0) tile->setShape(0.5f - w, 0, 0, 0.5f + w, 1, w * 2); t.begin();
if (i == 1) tile->setShape(0.5f - w, 0, 1 - w * 2, 0.5f + w, 1, 1); for (int i = 0; i < 4; i++) {
w = 1 / 16.0f; float w = 2 / 16.0f;
if (i == 2) tile->setShape(0.5f - w, 1 - w * 3, -w * 2, 0.5f + w, 1 - w, 1 + w * 2); if (i == 0) tile->setShape(0.5f - w, 0, 0, 0.5f + w, 1, w * 2);
if (i == 3) tile->setShape(0.5f - w, 0.5f - w * 3, -w * 2, 0.5f + w, 0.5f - w, 1 + w * 2); if (i == 1) tile->setShape(0.5f - w, 0, 1 - w * 2, 0.5f + w, 1, 1);
w = 1 / 16.0f;
if (i == 2) tile->setShape(0.5f - w, 1 - w * 3, -w * 2, 0.5f + w, 1 - w, 1 + w * 2);
if (i == 3) tile->setShape(0.5f - w, 0.5f - w * 3, -w * 2, 0.5f + w, 0.5f - w, 1 + w * 2);
t.normal(0.0f, -1.0f, 0.0f); t.normal(0.0f, -1.0f, 0.0f);
renderFaceDown(tile, 0, 0, 0, tile->getTexture(0)); renderFaceDown(tile, 0, 0, 0, tile->getTexture(0));
t.normal(0.0f, 1.0f, 0.0f); t.normal(0.0f, 1.0f, 0.0f);
renderFaceUp(tile, 0, 0, 0, tile->getTexture(1)); renderFaceUp(tile, 0, 0, 0, tile->getTexture(1));
t.normal(0.0f, 0.0f, -1.0f); t.normal(0.0f, 0.0f, -1.0f);
renderNorth(tile, 0, 0, 0, tile->getTexture(2)); renderNorth(tile, 0, 0, 0, tile->getTexture(2));
t.normal(0.0f, 0.0f, 1.0f); t.normal(0.0f, 0.0f, 1.0f);
renderSouth(tile, 0, 0, 0, tile->getTexture(3)); renderSouth(tile, 0, 0, 0, tile->getTexture(3));
t.normal(-1.0f, 0.0f, 0.0f); t.normal(-1.0f, 0.0f, 0.0f);
renderWest(tile, 0, 0, 0, tile->getTexture(4)); renderWest(tile, 0, 0, 0, tile->getTexture(4));
t.normal(1.0f, 0.0f, 0.0f); t.normal(1.0f, 0.0f, 0.0f);
renderEast(tile, 0, 0, 0, tile->getTexture(5)); renderEast(tile, 0, 0, 0, tile->getTexture(5));
}
t.draw();
t.addOffset(0.5f, 0.5f, 0.5f);
tile->setShape(0, 0, 0, 1, 1, 1);
} else if (shape == Tile::SHAPE_FENCE_GATE) {
t.addOffset(-0.5f, -0.5f, -0.5f);
t.begin();
for (int i = 0; i < 3; i++) {
float w = 1 / 16.0f;
if (i == 0) tile->setShape(0.5f - w, .3f, 0, 0.5f + w, 1, w * 2);
if (i == 1) tile->setShape(0.5f - w, .3f, 1 - w * 2, 0.5f + w, 1, 1);
if (i == 2) tile->setShape(0.5f - w, .5f, w * 2, 0.5f + w, 1 - w, 1 - w * 2);
t.normal(0.0f, -1.0f, 0.0f);
renderFaceDown(tile, 0, 0, 0, tile->getTexture(0));
t.normal(0.0f, 1.0f, 0.0f);
renderFaceUp(tile, 0, 0, 0, tile->getTexture(1));
t.normal(0.0f, 0.0f, -1.0f);
renderNorth(tile, 0, 0, 0, tile->getTexture(2));
t.normal(0.0f, 0.0f, 1.0f);
renderSouth(tile, 0, 0, 0, tile->getTexture(3));
t.normal(-1.0f, 0.0f, 0.0f);
renderWest(tile, 0, 0, 0, tile->getTexture(4));
t.normal(1.0f, 0.0f, 0.0f);
renderEast(tile, 0, 0, 0, tile->getTexture(5));
}
t.draw();
t.addOffset(0.5f, 0.5f, 0.5f);
tile->setShape(0, 0, 0, 1, 1, 1);
} }
t.draw();
t.addOffset(0.5f, 0.5f, 0.5f);
tile->setShape(0, 0, 0, 1, 1, 1);
} else if (shape == Tile::SHAPE_FENCE_GATE) {
t.addOffset(-0.5f, -0.5f, -0.5f);
t.begin();
for (int i = 0; i < 3; i++) {
float w = 1 / 16.0f;
if (i == 0) tile->setShape(0.5f - w, .3f, 0, 0.5f + w, 1, w * 2);
if (i == 1) tile->setShape(0.5f - w, .3f, 1 - w * 2, 0.5f + w, 1, 1);
if (i == 2) tile->setShape(0.5f - w, .5f, w * 2, 0.5f + w, 1 - w, 1 - w * 2);
t.normal(0.0f, -1.0f, 0.0f);
renderFaceDown(tile, 0, 0, 0, tile->getTexture(0));
t.normal(0.0f, 1.0f, 0.0f);
renderFaceUp(tile, 0, 0, 0, tile->getTexture(1));
t.normal(0.0f, 0.0f, -1.0f);
renderNorth(tile, 0, 0, 0, tile->getTexture(2));
t.normal(0.0f, 0.0f, 1.0f);
renderSouth(tile, 0, 0, 0, tile->getTexture(3));
t.normal(-1.0f, 0.0f, 0.0f);
renderWest(tile, 0, 0, 0, tile->getTexture(4));
t.normal(1.0f, 0.0f, 0.0f);
renderEast(tile, 0, 0, 0, tile->getTexture(5));
}
t.draw();
t.addOffset(0.5f, 0.5f, 0.5f);
tile->setShape(0, 0, 0, 1, 1, 1);
}
} }

View File

@@ -10,6 +10,7 @@ class ThinFenceTile;
class StairTile; class StairTile;
class LevelSource; class LevelSource;
class Material; class Material;
class Minecraft;
class TileRenderer class TileRenderer
{ {
@@ -60,6 +61,10 @@ public:
void renderTile(Tile* tile, int data); void renderTile(Tile* tile, int data);
void renderGuiTile(Tile* tile, int data); void renderGuiTile(Tile* tile, int data);
static void setUseTint(bool value) {
sideTinting = value;
}
static bool canRender(int renderShape); static bool canRender(int renderShape);
private: private:
float getWaterHeight(int x, int y, int z, const Material* m); float getWaterHeight(int x, int y, int z, const Material* m);
@@ -68,6 +73,7 @@ private:
int fixedTexture; int fixedTexture;
bool xFlipTexture; bool xFlipTexture;
bool noCulling; bool noCulling;
static bool sideTinting;
bool applyAmbienceOcclusion; bool applyAmbienceOcclusion;
float ll000, llx00, ll0y0, ll00z, llX00, ll0Y0, ll00Z; float ll000, llx00, ll0y0, ll00z, llX00, ll0Y0, ll00Z;

View File

@@ -130,10 +130,11 @@ void EntityRenderer::postRender(Entity* entity, float x, float y, float z, float
if (pow > 0) { if (pow > 0) {
renderShadow(entity, x, y, z, pow, a); renderShadow(entity, x, y, z, pow, a);
} }
//}
if (entity->isOnFire()) renderFlame(entity, x, y, z, a);
} }
if (entity->isOnFire()) renderFlame(entity, x, y, z, a);
} }
// duplicate renderflame below is the pre b1.6.6 way flame rendered on player and mobs, probs gonna make it an option. - shredder
/*
void EntityRenderer::renderFlame(Entity* e, float x, float y, float z, float a) { void EntityRenderer::renderFlame(Entity* e, float x, float y, float z, float a) {
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
int tex = ((Tile*)Tile::fire)->tex; int tex = ((Tile*)Tile::fire)->tex;
@@ -179,6 +180,75 @@ void EntityRenderer::renderFlame(Entity* e, float x, float y, float z, float a)
glPopMatrix2(); glPopMatrix2();
glEnable2(GL_LIGHTING); glEnable2(GL_LIGHTING);
} }
*/
// new renderflame ported from b1.6.6, fixes player height offset and also uses the newer style - shredder
void EntityRenderer::renderFlame(Entity* e, float x, float y, float z, float a) {
glDisable(GL_LIGHTING);
int tex = ((Tile*)Tile::fire)->tex;
int xt = (tex & 0xf) << 4;
int yt = tex & 0xf0;
float u0 = (xt) / 256.0f;
float u1 = (xt + 15.99f) / 256.0f;
float v0 = (yt) / 256.0f;
float v1 = (yt + 15.99f) / 256.0f;
glPushMatrix2();
glTranslatef2((float) x, (float) y, (float) z);
float s = e->bbWidth * 1.4f;
glScalef2(s, s, s);
bindTexture("terrain.png");
Tesselator& t = Tesselator::instance;
float r = 0.5f;
float xo = 0.0f;
float h = e->bbHeight / s;
float yo = (float)(e->y - e->bb.y0) / s;
glRotatef2(-entityRenderDispatcher->playerRotY, 0, 1, 0);
glTranslatef2(0, 0, -0.3f + ((int) h) * 0.02f);
glColor4f2(1, 1, 1, 1);
float zo = 0.0f;
int cycle_counter = 0;
t.begin();
while (h > 0.0f) {
float current_u0 = u0;
float current_u1 = u1;
float current_v0 = v0;
float current_v1 = v1;
if (cycle_counter % 2 != 0) {
current_v0 = (yt + 16) / 256.0f;
current_v1 = (yt + 16 + 15.99f) / 256.0f;
}
if ((cycle_counter / 2) % 2 == 0) {
float tmp = current_u1;
current_u1 = current_u0;
current_u0 = tmp;
}
t.vertexUV(r - xo, 0.0f - yo, zo, current_u1, current_v1);
t.vertexUV(-r - xo, 0.0f - yo, zo, current_u0, current_v1);
t.vertexUV(-r - xo, 1.4f - yo, zo, current_u0, current_v0);
t.vertexUV(r - xo, 1.4f - yo, zo, current_u1, current_v0);
h -= 0.45f;
yo -= 0.45f;
r *= 0.9f;
zo += 0.03f;
cycle_counter++;
}
t.draw();
glPopMatrix2();
glEnable2(GL_LIGHTING);
}
void EntityRenderer::renderShadow(Entity* e, float x, float y, float z, float pow, float a) { // void EntityRenderer::renderShadow(Entity* e, float x, float y, float z, float pow, float a) { //
glEnable2(GL_BLEND); glEnable2(GL_BLEND);
@@ -187,8 +257,12 @@ void EntityRenderer::renderShadow(Entity* e, float x, float y, float z, float po
//Textures* textures = entityRenderDispatcher->textures; //Textures* textures = entityRenderDispatcher->textures;
//textures->bind(textures->loadTexture("%clamp%/environment/shadow.png")); //textures->bind(textures->loadTexture("%clamp%/environment/shadow.png"));
Textures* textures = entityRenderDispatcher->textures; Textures* textures = entityRenderDispatcher->textures;
textures->loadAndBindTexture("/misc/shadow.png");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Level* level = getLevel(); Level* level = getLevel();
@@ -221,14 +295,13 @@ void EntityRenderer::renderShadow(Entity* e, float x, float y, float z, float po
renderTileShadow(Tile::tiles[t], x, y + e->getShadowHeightOffs(), z, xt, yt, zt, pow, r, xo, yo + e->getShadowHeightOffs(), zo); renderTileShadow(Tile::tiles[t], x, y + e->getShadowHeightOffs(), z, xt, yt, zt, pow, r, xo, yo + e->getShadowHeightOffs(), zo);
} }
} }
textures->loadAndBindTexture(("/misc/shadow.png"));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
tt.draw(); tt.draw();
glColor4f2(1, 1, 1, 1); glColor4f2(1, 1, 1, 1);
glDisable2(GL_BLEND); glDisable2(GL_BLEND);
glDepthMask(true); glDepthMask(true);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
} }
Level* EntityRenderer::getLevel() { Level* EntityRenderer::getLevel() {

View File

@@ -187,10 +187,12 @@ void MobRenderer::scale(Mob* mob, float a) {
} }
void MobRenderer::renderName(Mob* mob, float x, float y, float z) { void MobRenderer::renderName(Mob* mob, float x, float y, float z) {
/*
std::stringstream ss; ss << mob->entityId; std::stringstream ss; ss << mob->entityId;
if (entityRenderDispatcher->minecraft->options.getBooleanValue(OPTIONS_RENDER_DEBUG)) {
renderNameTag(mob, ss.str(), x, y, z, 64); renderNameTag(mob, ss.str(), x, y, z, 64);
*/ }
} }
void MobRenderer::renderNameTag(Mob* mob, const std::string& name, float x, float y, float z, int maxDist) { void MobRenderer::renderNameTag(Mob* mob, const std::string& name, float x, float y, float z, int maxDist) {
@@ -205,13 +207,19 @@ void MobRenderer::renderNameTag(Mob* mob, const std::string& name, float x, floa
float s = 1 / 60.0f * size; float s = 1 / 60.0f * size;
glPushMatrix2(); glPushMatrix2();
glTranslatef2((float) x + 0, (float) y + 1.0f /*2.3f*/, (float) z); if (mob->isPlayer()){
glTranslatef2((float) x + 0, (float) y + 1.0f, (float) z);
} else {
glTranslatef2((float) x + 0, (float) y + 2.3f, (float) z);
}
glRotatef2(-entityRenderDispatcher->playerRotY, 0, 1, 0); glRotatef2(-entityRenderDispatcher->playerRotY, 0, 1, 0);
glRotatef2(entityRenderDispatcher->playerRotX, 1, 0, 0); glRotatef2(entityRenderDispatcher->playerRotX, 1, 0, 0);
glScalef2(-s, -s, s); glScalef2(-s, -s, s);
glDisable(GL_LIGHTING);
glDepthMask(false); glDepthMask(false);
glDisable2(GL_DEPTH_TEST); glDisable2(GL_DEPTH_TEST);
glEnable2(GL_BLEND); glEnable2(GL_BLEND);
@@ -235,6 +243,7 @@ void MobRenderer::renderNameTag(Mob* mob, const std::string& name, float x, floa
glDepthMask(true); glDepthMask(true);
font->draw(name, (float) fnameWidth, 0, 0xffffffff); font->draw(name, (float) fnameWidth, 0, 0xffffffff);
glEnable(GL_LIGHTING);
glDisable2(GL_BLEND); glDisable2(GL_BLEND);
glColor4f2(1, 1, 1, 1); glColor4f2(1, 1, 1, 1);
glPopMatrix2(); glPopMatrix2();

View File

@@ -77,10 +77,10 @@ void PlayerRenderer::render(Entity* mob_, float x, float y, float z, float rot,
model = desired; model = desired;
humanoidModel = desired; humanoidModel = desired;
} }
// LOGI("[PlayerRenderer] %s: skin=%s, modelTex=%dx%d, desired=%s\n", // don't log it always, only for debug - shredder /* LOGI("[PlayerRenderer] %s: skin=%s, modelTex=%dx%d, desired=%s\n",
// ((Player*)mob)->name.c_str(), mob->getTexture().c_str(), ((Player*)mob)->name.c_str(), mob->getTexture().c_str(),
// humanoidModel->texWidth, humanoidModel->texHeight, humanoidModel->texWidth, humanoidModel->texHeight,
// (desired == playerModel64 ? "64" : "32")); (desired == playerModel64 ? "64" : "32")); */
HumanoidMobRenderer::render(mob_, x, y, z, rot, a); HumanoidMobRenderer::render(mob_, x, y, z, rot, a);
} }

View File

@@ -393,8 +393,8 @@ void LavaSideTexture::tick() {
} }
} }
FireTexture::FireTexture() FireTexture::FireTexture(int id)
: super(((Tile*)Tile::fire)->tex), : super(((Tile*)Tile::fire)->tex + id * 16),
_tick(0), _tick(0),
_frame(0) _frame(0)
{ {

View File

@@ -106,7 +106,7 @@ class FireTexture: public DynamicTexture
float* heata; float* heata;
public: public:
FireTexture(); FireTexture(int id);
~FireTexture(); ~FireTexture();
void tick(); void tick();

View File

@@ -111,6 +111,7 @@
#include "data/eat1.pcm" #include "data/eat1.pcm"
#include "data/eat2.pcm" #include "data/eat2.pcm"
#include "data/eat3.pcm" #include "data/eat3.pcm"
#include "data/burp1.pcm"
#include "data/fuse.pcm" #include "data/fuse.pcm"
SoundDesc SA_cloth1((char*)PCM_cloth1); SoundDesc SA_cloth1((char*)PCM_cloth1);
@@ -221,6 +222,7 @@ SoundDesc SA_creeperdeath((char*)PCM_creeperdeath);
SoundDesc SA_eat1((char*)PCM_eat1); SoundDesc SA_eat1((char*)PCM_eat1);
SoundDesc SA_eat2((char*)PCM_eat2); SoundDesc SA_eat2((char*)PCM_eat2);
SoundDesc SA_eat3((char*)PCM_eat3); SoundDesc SA_eat3((char*)PCM_eat3);
SoundDesc SA_burp1((char*)PCM_burp1);
SoundDesc SA_fuse((char*)PCM_fuse); SoundDesc SA_fuse((char*)PCM_fuse);
#endif /*!PRE_ANDROID23 && !__APPLE__*/ #endif /*!PRE_ANDROID23 && !__APPLE__*/

View File

@@ -172,6 +172,7 @@ extern SoundDesc SA_creeperdeath;
extern SoundDesc SA_eat1; extern SoundDesc SA_eat1;
extern SoundDesc SA_eat2; extern SoundDesc SA_eat2;
extern SoundDesc SA_eat3; extern SoundDesc SA_eat3;
extern SoundDesc SA_burp1;
extern SoundDesc SA_fuse; extern SoundDesc SA_fuse;
#endif /*!PRE_ANDROID23 && !__APPLE__*/ #endif /*!PRE_ANDROID23 && !__APPLE__*/

View File

@@ -144,6 +144,7 @@ void SoundEngine::init( Minecraft* mc, Options* options )
sounds.add("random.eat", SA_eat1); sounds.add("random.eat", SA_eat1);
sounds.add("random.eat", SA_eat2); sounds.add("random.eat", SA_eat2);
sounds.add("random.eat", SA_eat3); sounds.add("random.eat", SA_eat3);
sounds.add("random.burp", SA_burp1);
sounds.add("random.fuse", SA_fuse); sounds.add("random.fuse", SA_fuse);
#endif #endif

View File

@@ -227,6 +227,7 @@ void SoundEngine::init( Minecraft* mc, Options* options )
sounds.add( "random.eat", _pp("eat1")); sounds.add( "random.eat", _pp("eat1"));
sounds.add( "random.eat", _pp("eat2")); sounds.add( "random.eat", _pp("eat2"));
sounds.add( "random.eat", _pp("eat3")); sounds.add( "random.eat", _pp("eat3"));
sounds.add( "random.burp", _pp("burp1"));
sounds.add( "random.fuse", _pp("fuse")); sounds.add( "random.fuse", _pp("fuse"));
sounds.add( "step.cloth", _pp("cloth1")); sounds.add( "step.cloth", _pp("cloth1"));

File diff suppressed because it is too large Load Diff

10
src/commands/Command.cpp Normal file
View File

@@ -0,0 +1,10 @@
#include "Command.hpp"
#include "world/level/Level.h"
#include <client/Minecraft.h>
bool Command::isPlayerOp(Minecraft& mc, Player& player) {
std::string nicknameLower = player.name;
std::transform(nicknameLower.begin(), nicknameLower.end(), nicknameLower.begin(), ::tolower);
return mc.level->ops.find(nicknameLower) != mc.level->ops.end();
}

28
src/commands/Command.hpp Normal file
View File

@@ -0,0 +1,28 @@
#pragma once
#include <string>
#include <vector>
enum CommandFlags {
COMMAND_FLAG_SINGLEPLAYER_ONLY = (1 << 1),
COMMAND_FLAG_NO_ARGS = (1 << 2),
};
class Minecraft;
class Player;
class Command {
public:
const std::string& getName() { return m_name; }
const CommandFlags getFlags() { return m_flags; }
bool isPlayerOp(Minecraft& mc, Player& player);
virtual std::string execute(Minecraft& mc, Player& player, const std::vector<std::string>& args) = 0;
virtual std::string help(Minecraft& mc) = 0;
protected:
Command(const std::string& name, CommandFlags flags = (CommandFlags)0) : m_name(name), m_flags(flags) {}
const std::string m_name;
const CommandFlags m_flags;
};

View File

@@ -0,0 +1,49 @@
#include "CommandBan.hpp"
#include "commands/Command.hpp"
#include "network/RakNetInstance.h"
#include "raknet/RakPeerInterface.h"
#include "world/level/Level.h"
#include <algorithm>
#include <client/Minecraft.h>
#include <network/packet/LoginStatusPacket.h>
CommandBan::CommandBan() : Command("ban") {}
std::string CommandBan::execute(Minecraft& mc, Player& player, const std::vector<std::string>& args) {
if (!isPlayerOp(mc, player)) {
return "You aren't enough priveleged to run this command";
}
if (args.empty()) {
return help(mc);
}
std::string nicknameLower = args[0];
std::transform(nicknameLower.begin(), nicknameLower.end(), nicknameLower.begin(), ::tolower);
auto it = std::find_if(mc.level->players.begin(), mc.level->players.end(), [nicknameLower] (auto& it) -> bool {
std::string lower = it->name;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
return lower == nicknameLower;
});
if (it != mc.level->players.end()) {
if (*it == (Player*)mc.player) {
return "banip: you can't ban urself lol";
}
} else {
for (auto& banned : mc.level->bannedPpl) {
if (nicknameLower == banned) {
return args[0] + " already banned!";
}
}
}
mc.level->bannedPpl.insert(nicknameLower);
return "ban: successfully banned player " + args[0];
}
std::string CommandBan::help(Minecraft& mc) {
return "Usage: /ban <player>";
}

View File

@@ -0,0 +1,9 @@
#include "Command.hpp"
class CommandBan : public Command {
public:
CommandBan();
std::string execute(Minecraft& mc, Player& player, const std::vector<std::string>& args);
std::string help(Minecraft& mc);
};

View File

@@ -0,0 +1,65 @@
#include "CommandBanIp.hpp"
#include "commands/Command.hpp"
#include "network/RakNetInstance.h"
#include "raknet/RakPeerInterface.h"
#include "world/level/Level.h"
#include <algorithm>
#include <client/Minecraft.h>
CommandBanIp::CommandBanIp() : Command("banip") {}
std::string CommandBanIp::execute(Minecraft& mc, Player& player, const std::vector<std::string>& args) {
if (!isPlayerOp(mc, player)) {
return "You aren't enough priveleged to run this command";
}
if (args.empty()) {
return help(mc);
}
std::string nicknameLower = args[0];
std::transform(nicknameLower.begin(), nicknameLower.end(), nicknameLower.begin(), ::tolower);
auto it = std::find_if(mc.level->players.begin(), mc.level->players.end(), [nicknameLower] (auto& it) -> bool {
std::string lower = it->name;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
return lower == nicknameLower;
});
std::string clientIp;
if (it != mc.level->players.end()) {
if (*it == (Player*)mc.player) {
return "banip: you can't ban urself lol";
}
RakNet::SystemAddress sysAddress = mc.raknetInstance->getPeer()->GetSystemAddressFromGuid((*it)->owner);
char ip[32];
sysAddress.ToString(false, ip);
clientIp = ip;
auto sourceId = (*it)->owner;
(*it)->reallyRemoveIfPlayer = true;
mc.level->removeEntity((*it));
mc.raknetInstance->getPeer()->CloseConnection(sourceId, true);
} else {
for (auto& banned : mc.level->bannedIps) {
if (clientIp == banned) {
return args[0] + " already banned!";
}
}
clientIp = args[0];
}
mc.level->bannedIps.insert(clientIp);
return "banip: successfully banned player by ip " + args[0];
}
std::string CommandBanIp::help(Minecraft& mc) {
return "Usage: /banip <player>";
}

View File

@@ -0,0 +1,9 @@
#include "Command.hpp"
class CommandBanIp : public Command {
public:
CommandBanIp();
std::string execute(Minecraft& mc, Player& player, const std::vector<std::string>& args);
std::string help(Minecraft& mc);
};

View File

@@ -0,0 +1,35 @@
#include "CommandHelp.hpp"
#include "commands/Command.hpp"
#include "CommandManager.hpp"
#include <client/Minecraft.h>
#include <sstream>
CommandHelp::CommandHelp() : Command("help") {}
std::string CommandHelp::execute(Minecraft& mc, Player& player, const std::vector<std::string>& args) {
if (args.empty()) {
auto cmds = mc.commandManager().getListAllCommands();
std::ostringstream output;
output << "List of all commands:" << std::endl;
for (auto& cmd : cmds) {
output << " - " + cmd << std::endl;;
}
return output.str();
}
Command* cmd = mc.commandManager().getCommand(args[0]);
if (cmd != nullptr) {
return cmd->help(mc);
}
return "help: command " + args[0] + " not found";
}
std::string CommandHelp::help(Minecraft& mc) {
return "Usage: /help <command>";
}

View File

@@ -0,0 +1,9 @@
#include "Command.hpp"
class CommandHelp : public Command {
public:
CommandHelp();
std::string execute(Minecraft& mc, Player& player, const std::vector<std::string>& args);
std::string help(Minecraft& mc);
};

View File

@@ -0,0 +1,48 @@
#include "CommandKick.hpp"
#include "commands/Command.hpp"
#include "network/RakNetInstance.h"
#include "raknet/RakPeerInterface.h"
#include "world/level/Level.h"
#include <algorithm>
#include <client/Minecraft.h>
CommandKick::CommandKick() : Command("kick") {}
std::string CommandKick::execute(Minecraft& mc, Player& player, const std::vector<std::string>& args) {
if (!isPlayerOp(mc, player)) {
return "You aren't enough priveleged to run this command";
}
if (args.empty()) {
return help(mc);
}
std::string nicknameLower = args[0];
std::transform(nicknameLower.begin(), nicknameLower.end(), nicknameLower.begin(), ::tolower);
auto it = std::find_if(mc.level->players.begin(), mc.level->players.end(), [args, nicknameLower] (auto& it) -> bool {
std::string lower = it->name;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
return lower == nicknameLower;
});
if (it == mc.level->players.end()) {
return "kick: can't find player with name " + args[0];
}
if (*it == (Player*)mc.player) {
return "kick: you can't kick urself lol";
}
auto sourceId = (*it)->owner;
(*it)->reallyRemoveIfPlayer = true;
mc.level->removeEntity((*it));
mc.raknetInstance->getPeer()->CloseConnection(sourceId, true);
return "kick: successfully kicked player " + args[0];
}
std::string CommandKick::help(Minecraft& mc) {
return "Usage: /kick <player>";
}

View File

@@ -0,0 +1,9 @@
#include "Command.hpp"
class CommandKick : public Command {
public:
CommandKick();
std::string execute(Minecraft& mc, Player& player, const std::vector<std::string>& args);
std::string help(Minecraft& mc);
};

View File

@@ -0,0 +1,79 @@
#include "CommandManager.hpp"
#include <algorithm>
#include <string>
#include <vector>
#include "client/Minecraft.h"
#include "commands/Command.hpp"
#include "commands/CommandHelp.hpp"
#include "commands/CommandKick.hpp"
#include "commands/CommandOp.hpp"
#include "commands/CommandBan.hpp"
#include "commands/CommandBanIp.hpp"
#include "commands/CommandPardon.hpp"
#include "network/packet/ChatPacket.h"
#include "network/RakNetInstance.h"
#include "world/level/Level.h"
CommandManager::CommandManager() {
registerAllCommands();
}
void CommandManager::registerAllCommands() {
m_commands.push_back(new CommandHelp());
m_commands.push_back(new CommandKick());
m_commands.push_back(new CommandOp());
m_commands.push_back(new CommandBan());
m_commands.push_back(new CommandBanIp());
m_commands.push_back(new CommandPardon());
}
std::vector<std::string> CommandManager::getListAllCommands() {
std::vector<std::string> ret;
for (auto& cmd : m_commands) {
ret.push_back(cmd->getName());
}
return ret;
}
std::string CommandManager::execute(Minecraft& mc, Player& player, const std::string& input) {
std::istringstream ss(input);
std::string cmd;
ss >> cmd;
auto it = std::find_if(m_commands.begin(), m_commands.end(), [cmd](auto& it) -> bool {
return it->getName() == cmd;
});
if (it == m_commands.end()) {
return "Command /" + cmd + " not found";
}
std::vector<std::string> args;
std::string tok;
while (ss >> tok) args.push_back(tok);
if (!mc.level->isClientSide || (*it)->getFlags() & CommandFlags::COMMAND_FLAG_SINGLEPLAYER_ONLY) {
return (*it)->execute(mc, player, args);
} else {
ChatPacket packet("/" + input);
mc.raknetInstance->send(packet);
}
return "";
}
Command* CommandManager::getCommand(const std::string& name) {
auto it = std::find_if(m_commands.begin(), m_commands.end(), [name](auto& it) -> bool {
return it->getName() == name;
});
if (it == m_commands.end()) {
return *it;
}
return nullptr;
}

View File

@@ -0,0 +1,21 @@
#pragma once
#include <string>
#include <vector>
#include "Command.hpp"
class CommandManager {
public:
CommandManager();
std::vector<std::string> getListAllCommands();
std::string execute(Minecraft& mc, Player& player, const std::string& input);
Command* getCommand(const std::string& name);
private:
void registerAllCommands();
std::vector<Command*> m_commands;
};

View File

@@ -0,0 +1,31 @@
#include "CommandOp.hpp"
#include "commands/Command.hpp"
#include "world/level/Level.h"
#include <algorithm>
#include <client/Minecraft.h>
CommandOp::CommandOp() : Command("op") {}
std::string CommandOp::execute(Minecraft& mc, Player& player, const std::vector<std::string>& args) {
if (!isPlayerOp(mc, player)) {
return "You aren't enough priveleged to run this command";
}
if (args.empty()) {
return help(mc);
}
std::string nicknameLower = args[0];
std::transform(nicknameLower.begin(), nicknameLower.end(), nicknameLower.begin(), ::tolower);
if (mc.level->ops.find(nicknameLower) != mc.level->ops.end()) {
return "op: player " + args[0] + " already opped";
}
mc.level->ops.emplace(nicknameLower);
return "op: successfully opped player " + args[0];
}
std::string CommandOp::help(Minecraft& mc) {
return "Usage: /op <player>";
}

View File

@@ -0,0 +1,9 @@
#include "Command.hpp"
class CommandOp : public Command {
public:
CommandOp();
std::string execute(Minecraft& mc, Player& player, const std::vector<std::string>& args);
std::string help(Minecraft& mc);
};

View File

@@ -0,0 +1,40 @@
#include "CommandPardon.hpp"
#include "commands/Command.hpp"
#include "network/RakNetInstance.h"
#include "raknet/RakPeerInterface.h"
#include "world/level/Level.h"
#include <algorithm>
#include <client/Minecraft.h>
CommandPardon::CommandPardon() : Command("pardon") {}
std::string CommandPardon::execute(Minecraft& mc, Player& player, const std::vector<std::string>& args) {
if (!isPlayerOp(mc, player)) {
return "You aren't enough priveleged to run this command";
}
if (args.empty()) {
return help(mc);
}
std::string nicknameLower = args[0];
std::transform(nicknameLower.begin(), nicknameLower.end(), nicknameLower.begin(), ::tolower);
if (mc.level->bannedPpl.find(nicknameLower) != mc.level->bannedPpl.end()) {
mc.level->bannedPpl.erase(nicknameLower);
return "pardon: successfully unbanned player " + args[0];
}
if (mc.level->bannedIps.find(nicknameLower) != mc.level->bannedIps.end()) {
mc.level->bannedIps.erase(nicknameLower);
return "pardon: successfully unbanned ip " + args[0];
}
return "Player/Ip doesnt banned";
}
std::string CommandPardon::help(Minecraft& mc) {
return "Usage: /pardon <player>";
}

View File

@@ -0,0 +1,9 @@
#include "Command.hpp"
class CommandPardon : public Command {
public:
CommandPardon();
std::string execute(Minecraft& mc, Player& player, const std::vector<std::string>& args);
std::string help(Minecraft& mc);
};

View File

@@ -1,25 +1,30 @@
#include <fstream>
#include <iostream> #include <iostream>
#include "NinecraftApp.h" #include "NinecraftApp.h"
#include "AppPlatform.h" #include "AppPlatform.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include <signal.h>
#ifdef __linux__
#include <unistd.h> #include <unistd.h>
#endif
#include "world/level/LevelSettings.h" #include "world/level/LevelSettings.h"
#include "world/level/Level.h" #include "world/level/Level.h"
#include "server/ArgumentsSettings.h" #include "server/ArgumentsSettings.h"
#include "platform/time.h" #include "platform/time.h"
#include "SharedConstants.h" #include "SharedConstants.h"
#include "world/level/LevelConstants.h"
#include <plugins/PluginsManager.hpp>
#define MAIN_CLASS NinecraftApp #define MAIN_CLASS NinecraftApp
static App* g_app = 0; static App* g_app = 0;
static int g_exitCode = 0; static int g_exitCode = 0;
void signal_callback_handler(int signum) { void signal_callback_handler(int signum) {
std::cout << "Signum caught: " << signum << std::endl; std::cout << "Signum caught: " << signum << std::endl;
if(signum == 2 || signum == 3){ // SIGINT || SIGQUIT
if(g_app != 0) { if (signum == 2 || signum == 3) { // SIGINT || SIGQUIT
if (g_app != 0) {
g_app->quit(); g_app->quit();
} else { } else {
exit(g_exitCode); exit(g_exitCode);
@@ -27,47 +32,242 @@ void signal_callback_handler(int signum) {
} }
} }
std::string findStringInConfig(std::string line, std::string config) {
auto valuePos = config.find(line);
if (line.empty()) {
throw std::runtime_error("Key cannot be empty");
}
if (valuePos == std::string::npos) {
throw std::runtime_error("Cannot find value");
}
std::string valueStr = "";
valuePos += 1 + line.size();
while (true) {
auto sym = config.at(valuePos);
if (sym == '\n') {
break;
}
if (valuePos == config.size()) {
throw std::runtime_error("Cannot find end of the line");
}
valueStr += sym;
valuePos++;
}
return valueStr;
}
int main(int numArguments, char* pszArgs[]) { int main(int numArguments, char* pszArgs[]) {
ArgumentsSettings aSettings(numArguments, pszArgs); std::ifstream serverProperties("server.properties");
if(aSettings.getShowHelp()) {
ArgumentsSettings defaultSettings(0, NULL); int port = 0;
printf("Minecraft Pockect Edition Server %s\n", Common::getGameVersionString("").c_str()); int gamemode = 0;
printf("-------------------------------------------------------\n"); int worldSize = 0;
printf("--cachepath - Path to where the server can store temp stuff (not sure if this is used) [default: \"%s\"]\n", defaultSettings.getCachePath().c_str());
printf("--externalpath - The path to the place where the server should store the levels. [default: \"%s\"]\n", defaultSettings.getExternalPath().c_str()); std::string levelDir = "";
printf("--levelname - The name of the server [default: \"%s\"]\n", defaultSettings.getLevelName().c_str()); std::string cachePath = "";
printf("--leveldir - The name of the server [default: \"%s\"]\n", defaultSettings.getLevelDir().c_str()); std::string externalPath = "";
printf("--help - Shows this message.\n"); std::string levelName = "";
printf("--port - The port to run the server on. [default: %d]\n", defaultSettings.getPort());
printf("--serverkey - The key that the server should use for API calls. [default: \"%s\"]\n", defaultSettings.getServerKey().c_str()); if (serverProperties.is_open()) {
printf("-------------------------------------------------------\n"); std::string propString;
return 0; std::string line;
while (std::getline(serverProperties, line)) {
propString += line;
propString += "\n";
}
if (propString.empty()) {
throw std::runtime_error("Config cannot be empty");
}
port = std::stoi(findStringInConfig("port", propString));
worldSize = std::stoi(findStringInConfig("world-size", propString));
if (worldSize < 16 || worldSize > 32) {
throw std::runtime_error("Incorrect world size.");
}
LevelConstants::CHUNK_CACHE_WIDTH = worldSize;
LevelConstants::LEVEL_WIDTH = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_WIDTH;
LevelConstants::LEVEL_DEPTH = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_DEPTH;
cachePath = findStringInConfig("level-cachepath", propString);
externalPath = findStringInConfig("level-externalpath", propString);
levelName = findStringInConfig("level-name", propString);
levelDir = findStringInConfig("level-dir", propString);
std::string gamemodeStr = findStringInConfig("gamemode", propString);
if (gamemodeStr == "survival") {
gamemode = GameType::Survival;
} else if (gamemodeStr == "creative") {
gamemode = GameType::Creative;
} else {
gamemode = GameType::Survival;
}
printf("%d %s %s %d %d\n", port, cachePath.c_str(), externalPath.c_str(), gamemode, LevelConstants::CHUNK_CACHE_WIDTH);
} else {
std::ofstream defaultProperties("server.properties");
if (defaultProperties.is_open()) {
ArgumentsSettings defaultSettings(0, NULL);
std::stringstream buffer;
buffer << "// MCPE Server properties" << std::endl;
buffer << "port=" << defaultSettings.getPort() << std::endl;
buffer << "level-dir=" << defaultSettings.getLevelDir() << std::endl;
buffer << "level-cachepath=" << defaultSettings.getCachePath() << std::endl;
buffer << "level-externalpath=" << defaultSettings.getExternalPath() << std::endl;
buffer << "gamemode=survival" << std::endl;
buffer << "level-name=" << defaultSettings.getLevelName() << std::endl;
buffer << "world-size=16" << std::endl;
defaultProperties << buffer.str();
printf("%s \n", buffer.str().c_str());
printf("Edit a config file first!\n");
defaultProperties.close();
exit(0);
} else {
throw std::runtime_error("Cannot create default config.");
}
} }
printf("Level Name: %s\n", aSettings.getLevelName().c_str());
printf("Level Name: %s\n", levelName.c_str());
AppContext appContext; AppContext appContext;
appContext.platform = new AppPlatform(); appContext.platform = new AppPlatform();
App* app = new MAIN_CLASS(); App* app = new MAIN_CLASS();
signal(SIGINT, signal_callback_handler); signal(SIGINT, signal_callback_handler);
g_app = app; g_app = app;
((MAIN_CLASS*)g_app)->externalStoragePath = aSettings.getExternalPath(); ((MAIN_CLASS*)g_app)->externalStoragePath = externalPath;
((MAIN_CLASS*)g_app)->externalCacheStoragePath = aSettings.getCachePath(); ((MAIN_CLASS*)g_app)->externalCacheStoragePath = cachePath;
g_app->init(appContext); g_app->init(appContext);
LevelSettings settings(getEpochTimeS(), GameType::Creative); LevelSettings settings(getEpochTimeS(), gamemode);
float startTime = getTimeS(); float startTime = getTimeS();
((MAIN_CLASS*)g_app)->selectLevel(aSettings.getLevelDir(), aSettings.getLevelName(), settings); ((MAIN_CLASS*)g_app)->selectLevel(levelDir, levelName, settings);
((MAIN_CLASS*)g_app)->hostMultiplayer(aSettings.getPort()); ((MAIN_CLASS*)g_app)->hostMultiplayer(port);
PluginsManager::get().loadPlugins();
// Reading ops
std::ifstream ops("ops.txt");
if (ops.is_open()) {
std::string line;
while (std::getline(ops, line)) {
if (!line.empty()) {
((MAIN_CLASS*)g_app)->level->ops.insert(line);
}
}
} else {
std::ofstream opsDefault("ops.txt");
if (!opsDefault.is_open()) {
throw std::runtime_error("Cannot create ops list.");
}
}
// Reading banned ppl
std::ifstream banned("banned-players.txt");
if (banned.is_open()) {
std::string line;
while (std::getline(banned, line)) {
if (!line.empty()) {
((MAIN_CLASS*)g_app)->level->bannedPpl.insert(line);
}
}
} else {
std::ofstream bannedPpl("banned-players.txt");
if (!bannedPpl.is_open()) {
throw std::runtime_error("Cannot create banned players list.");
}
}
std::ifstream bannedIps("banned-ips.txt");
if (bannedIps.is_open()) {
std::string line;
while (std::getline(bannedIps, line)) {
if (!line.empty()) {
((MAIN_CLASS*)g_app)->level->bannedIps.insert(line);
}
}
} else {
std::ofstream bannedIp("banned-ips.txt");
if (!bannedIp.is_open()) {
throw std::runtime_error("Cannot create banned players list.");
}
}
std::cout << "Level has been generated in " << getTimeS() - startTime << std::endl; std::cout << "Level has been generated in " << getTimeS() - startTime << std::endl;
((MAIN_CLASS*)g_app)->level->saveLevelData(); ((MAIN_CLASS*)g_app)->level->saveLevelData();
std::cout << "Level has been saved!" << std::endl; std::cout << "Level has been saved!" << std::endl;
PluginsManager::get().emit("ServerLoaded");
while(!app->wantToQuit()) { while(!app->wantToQuit()) {
app->update(); app->update();
//pthread_yield(); //pthread_yield();
sleepMs(20); sleepMs(20);
} }
std::ofstream opsWrite("ops.txt");
if (opsWrite.is_open()) {
for (auto& op : ((MAIN_CLASS*)g_app)->level->ops) {
opsWrite << op << std::endl;
}
opsWrite.close();
} else {
throw std::runtime_error("Cannot open ops list.");
}
std::ofstream bannedWrite("banned-players.txt");
if (bannedWrite.is_open()) {
for (auto& banned : ((MAIN_CLASS*)g_app)->level->bannedPpl) {
bannedWrite << banned << std::endl;
}
bannedWrite.close();
} else {
throw std::runtime_error("Cannot open banned players list.");
}
std::ofstream bannedIpsWrite("banned-ips.txt");
if (bannedIpsWrite.is_open()) {
for (auto& banned : ((MAIN_CLASS*)g_app)->level->bannedIps) {
bannedIpsWrite << banned << std::endl;
}
bannedIpsWrite.close();
} else {
throw std::runtime_error("Cannot open banned players list.");
}
PluginsManager::get().emit("ServerShutdown");
((MAIN_CLASS*)g_app)->level->saveLevelData(); ((MAIN_CLASS*)g_app)->level->saveLevelData();
delete app; delete app;
appContext.platform->finish(); appContext.platform->finish();
delete appContext.platform; delete appContext.platform;

View File

@@ -191,13 +191,8 @@ int main(void) {
App* app = new MAIN_CLASS(); App* app = new MAIN_CLASS();
g_app = app; g_app = app;
#ifdef __HAIKU__
((MAIN_CLASS*)g_app)->externalStoragePath = "/system/settings/minecraftpe";
((MAIN_CLASS*)g_app)->externalCacheStoragePath = "/system/settings/minecraftpe";
#else
((MAIN_CLASS*)g_app)->externalStoragePath = "."; ((MAIN_CLASS*)g_app)->externalStoragePath = ".";
((MAIN_CLASS*)g_app)->externalCacheStoragePath = "."; ((MAIN_CLASS*)g_app)->externalCacheStoragePath = ".";
#endif
g_app->init(appContext); g_app->init(appContext);
g_app->setSize(appContext.platform->getScreenWidth(), appContext.platform->getScreenHeight()); g_app->setSize(appContext.platform->getScreenWidth(), appContext.platform->getScreenHeight());

View File

@@ -1,6 +1,7 @@
#include "ClientSideNetworkHandler.h" #include "ClientSideNetworkHandler.h"
#include "client/Options.h" #include "client/Options.h"
#include "network/packet/LoginStatusPacket.h"
#include "packet/PacketInclude.h" #include "packet/PacketInclude.h"
#include "RakNetInstance.h" #include "RakNetInstance.h"
#include "../world/level/chunk/ChunkSource.h" #include "../world/level/chunk/ChunkSource.h"
@@ -10,6 +11,9 @@
#include "../world/entity/player/Inventory.h" #include "../world/entity/player/Inventory.h"
#include "../client/Minecraft.h" #include "../client/Minecraft.h"
#include "../client/gamemode/GameMode.h" #include "../client/gamemode/GameMode.h"
#include "world/item/ItemInstance.h"
#include "world/level/LevelConstants.h"
#include <cstddef>
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
#include "../client/gui/screens/DisconnectionScreen.h" #include "../client/gui/screens/DisconnectionScreen.h"
#endif #endif
@@ -42,6 +46,9 @@ ClientSideNetworkHandler::ClientSideNetworkHandler(Minecraft* minecraft, IRakNet
requestNextChunkPosition(0), requestNextChunkPosition(0),
requestNextChunkIndex(0) requestNextChunkIndex(0)
{ {
NumRequestChunks = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_CACHE_WIDTH;
requestNextChunkIndexList.resize(NumRequestChunks);
chunksLoaded.resize(NumRequestChunks);
rakPeer = raknetInstance->getPeer(); rakPeer = raknetInstance->getPeer();
} }
@@ -59,7 +66,7 @@ void ClientSideNetworkHandler::requestNextChunk()
//LOGI("requesting chunks @ (%d, %d)\n", chunk.x, chunk.y); //LOGI("requesting chunks @ (%d, %d)\n", chunk.x, chunk.y);
//raknetInstance->send(new RequestChunkPacket(requestNextChunkPosition % CHUNK_CACHE_WIDTH, requestNextChunkPosition / CHUNK_CACHE_WIDTH)); //raknetInstance->send(new RequestChunkPacket(requestNextChunkPosition % LevelConstants::CHUNK_CACHE_WIDTH, requestNextChunkPosition / LevelConstants::CHUNK_CACHE_WIDTH));
requestNextChunkIndex++; requestNextChunkIndex++;
requestNextChunkPosition++; requestNextChunkPosition++;
} }
@@ -67,16 +74,16 @@ void ClientSideNetworkHandler::requestNextChunk()
bool ClientSideNetworkHandler::areAllChunksLoaded() bool ClientSideNetworkHandler::areAllChunksLoaded()
{ {
return (requestNextChunkPosition >= (CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH)); return (requestNextChunkPosition >= (LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_CACHE_WIDTH));
} }
bool ClientSideNetworkHandler::isChunkLoaded(int x, int z) bool ClientSideNetworkHandler::isChunkLoaded(int x, int z)
{ {
if (x < 0 || x >= CHUNK_CACHE_WIDTH || z < 0 || z >= CHUNK_CACHE_WIDTH) { if (x < 0 || x >= LevelConstants::CHUNK_CACHE_WIDTH || z < 0 || z >= LevelConstants::CHUNK_CACHE_WIDTH) {
LOGE("Error: Tried to request chunk (%d, %d)\n", x, z); LOGE("Error: Tried to request chunk (%d, %d)\n", x, z);
return true; return true;
} }
return chunksLoaded[x * CHUNK_CACHE_WIDTH + z]; return chunksLoaded[x * LevelConstants::CHUNK_CACHE_WIDTH + z];
//return areAllChunksLoaded(); //return areAllChunksLoaded();
} }
@@ -86,7 +93,7 @@ void ClientSideNetworkHandler::onConnect(const RakNet::RakNetGUID& hostGuid)
serverGuid = hostGuid; serverGuid = hostGuid;
clearChunksLoaded(); clearChunksLoaded();
LoginPacket packet(minecraft->options.getStringValue(OPTIONS_USERNAME).c_str(), SharedConstants::NetworkProtocolVersion); LoginPacket packet(minecraft->options.getStringValue(OPTIONS_USERNAME).c_str(), SharedConstants::NetworkProtocolVersion, true);
raknetInstance->send(packet); raknetInstance->send(packet);
} }
@@ -97,6 +104,11 @@ void ClientSideNetworkHandler::onUnableToConnect()
void ClientSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& guid) void ClientSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& guid)
{ {
LevelConstants::CHUNK_CACHE_WIDTH = 16;
LevelConstants::LEVEL_WIDTH = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_WIDTH;
LevelConstants::LEVEL_DEPTH = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_DEPTH;
// TODO: Good disconnecting
LOGI("onDisconnect\n"); LOGI("onDisconnect\n");
if (level) if (level)
{ {
@@ -109,9 +121,13 @@ void ClientSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& guid)
} }
} }
} }
#ifndef STANDALONE_SERVER minecraft->leaveGame();
minecraft->gui.addMessage("Disconnected from server"); // minecraft->setLevel(NULL);
#endif // #ifndef STANDALONE_SERVER
// minecraft->gui.addMessage("Disconnected from server");
// // TODO: screen with error
// minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
// #endif
} }
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginStatusPacket* packet) { void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginStatusPacket* packet) {
@@ -130,6 +146,18 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginSta
LOGI("Disconnect! Server is outdated!\n"); LOGI("Disconnect! Server is outdated!\n");
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
minecraft->setScreen(new DisconnectionScreen("Could not connect: Outdated server!")); minecraft->setScreen(new DisconnectionScreen("Could not connect: Outdated server!"));
#endif
}
if (packet->status == LoginStatus::Failed_TakenNickname) {
LOGI("Disconnect! Nickname is taken!\n");
#ifndef STANDALONE_SERVER
minecraft->setScreen(new DisconnectionScreen("Could not connect: Nickname is taken!"));
#endif
}
if (packet->status == LoginStatus::Failed_Banned) {
LOGI("Disconnect! You're banned from this server!\n");
#ifndef STANDALONE_SERVER
minecraft->setScreen(new DisconnectionScreen("Could not connect: You're banned from this server!"));
#endif #endif
} }
} }
@@ -146,6 +174,19 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, StartGam
} }
#endif #endif
// @todo @note i think its trash
// we can put it directly to selectLevel?
if (packet->chunkCacheWidth != 0) {
printf("lol \n");
LevelConstants::CHUNK_CACHE_WIDTH = packet->chunkCacheWidth;
LevelConstants::LEVEL_WIDTH = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_WIDTH;
LevelConstants::LEVEL_DEPTH = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_DEPTH;
LevelChunk::ChunkBlockCount = LevelConstants::CHUNK_BLOCK_COUNT;
}
NumRequestChunks = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_CACHE_WIDTH;
requestNextChunkIndexList.resize(NumRequestChunks);
chunksLoaded.resize(NumRequestChunks);
const std::string& levelId = LevelStorageSource::TempLevelId; const std::string& levelId = LevelStorageSource::TempLevelId;
LevelStorageSource* storageSource = minecraft->getLevelSource(); LevelStorageSource* storageSource = minecraft->getLevelSource();
storageSource->deleteLevel(levelId); storageSource->deleteLevel(levelId);
@@ -182,7 +223,7 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, SetTimeP
if (!level) if (!level)
return; return;
LOGI("SetTimePacket\n"); // LOGI("SetTimePacket\n");
level->setTime(packet->time); level->setTime(packet->time);
} }
@@ -238,7 +279,7 @@ void ClientSideNetworkHandler::handle( const RakNet::RakNetGUID& source, AddPain
} }
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AddMobPacket* packet) void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AddMobPacket* packet)
{ {
LOGI("AddMobPacket (%p)\n", level); // LOGI("AddMobPacket (%p)\n", level);
if (!level) { if (!level) {
LOGW("Trying to add a mob with no level!\n"); LOGW("Trying to add a mob with no level!\n");
@@ -324,7 +365,7 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RemoveEn
if (!level) return; if (!level) return;
Entity* entity = level->getEntity(packet->entityId); Entity* entity = level->getEntity(packet->entityId);
LOGI("RemoveEntityPacket %p %p, %d\n", entity, minecraft->player, entity?(int)(entity->isPlayer()): -1); // LOGI("RemoveEntityPacket %p %p, %d\n", entity, minecraft->player, entity?(int)(entity->isPlayer()): -1);
if (!entity) return; if (!entity) return;
level->removeEntity(entity); level->removeEntity(entity);
@@ -344,6 +385,7 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AddItemE
} }
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, TakeItemEntityPacket* packet) { void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, TakeItemEntityPacket* packet) {
// printf("TakeItemEntityPacket \n");
if (!level) return; if (!level) return;
Entity* e = level->getEntity(packet->itemId); Entity* e = level->getEntity(packet->itemId);
@@ -386,6 +428,54 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MovePlay
} }
} }
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, SendInventoryPacket* packet) {
if (!level) return;
if (packet->entityId == minecraft->player->entityId) {
auto items = packet->items;
minecraft->player->inventory->replace(items);
for (int i = 0; i < packet->linkedSlot.size(); i++) {
minecraft->player->inventory->linkSlot(i, packet->linkedSlot[i].inventorySlot, true);
LOGI("%i -> %i\n", packet->linkedSlot[i].inventorySlot, i);
}
}
}
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, TakeItemPacket* packet) {
if (!level) return;
LOGI("TakeItemPacket\n");
ItemInstance* item = new ItemInstance();
item->count = packet->count;
item->id = packet->itemId;
item->setAuxValue(packet->auxValue);
// if (minecraft->player->entityId == packet->playerId) {
if (!minecraft->player->inventory->add(item)) {
minecraft->player->drop(new ItemInstance(*item), false);
}
// }
}
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RemoveItemPacket* packet) {
// Idk how it works...
if (!level) return;
ItemInstance item;
item.count = packet->count;
item.id = packet->itemId;
item.setAuxValue(packet->auxValue);
// if (minecraft->player->entityId == packet->playerId) {
minecraft->player->inventory->removeResource(item);
// }
}
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MoveEntityPacket* packet) void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MoveEntityPacket* packet)
{ {
if (!level) if (!level)
@@ -475,19 +565,19 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ChunkDat
//unsigned char* blockIds = chunk->getBlockData(); //unsigned char* blockIds = chunk->getBlockData();
DataLayer& blockData = chunk->data; DataLayer& blockData = chunk->data;
const int setSize = LEVEL_HEIGHT / 8; const int setSize = LevelConstants::LEVEL_HEIGHT / 8;
const int setShift = 4; // power of LEVEL_HEIGHT / 8 const int setShift = 4; // power of LevelConstants::LEVEL_HEIGHT / 8
bool recalcHeight = false; bool recalcHeight = false;
int x0 = 16, x1 = 0, z0 = 16, z1 = 0, y0 = LEVEL_HEIGHT, y1 = 0; int x0 = 16, x1 = 0, z0 = 16, z1 = 0, y0 = LevelConstants::LEVEL_HEIGHT, y1 = 0;
int rx = packet->x << 4; int rx = packet->x << 4;
int rz = packet->z << 4; int rz = packet->z << 4;
unsigned char readBlockBuffer[setSize]; unsigned char* readBlockBuffer = new unsigned char[setSize];
unsigned char readDataBuffer[setSize / 2]; unsigned char* readDataBuffer = new unsigned char[setSize / 2];
for (int i = 0; i < CHUNK_COLUMNS; i++) for (int i = 0; i < LevelConstants::CHUNK_COLUMNS; i++)
{ {
unsigned char updateBits = 0; unsigned char updateBits = 0;
packet->chunkData.Read(updateBits); packet->chunkData.Read(updateBits);
@@ -496,8 +586,8 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ChunkDat
{ {
recalcHeight = true; recalcHeight = true;
int colX = (i % CHUNK_WIDTH); int colX = (i % LevelConstants::CHUNK_WIDTH);
int colZ = (i / CHUNK_WIDTH); int colZ = (i / LevelConstants::CHUNK_WIDTH);
int colDataPosition = colX << 11 | colZ << 7; int colDataPosition = colX << 11 | colZ << 7;
for (int set = 0; set < 8; set++) for (int set = 0; set < 8; set++)
@@ -531,30 +621,33 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ChunkDat
{ {
y0 = ((1 << set) << setShift); y0 = ((1 << set) << setShift);
} }
if (((1 << set) << setShift) + (LEVEL_HEIGHT / 8) - 1 > y1) if (((1 << set) << setShift) + (LevelConstants::LEVEL_HEIGHT / 8) - 1 > y1)
{ {
y1 = ((1 << set) << setShift) + (LEVEL_HEIGHT / 8) - 1; y1 = ((1 << set) << setShift) + (LevelConstants::LEVEL_HEIGHT / 8) - 1;
} }
} }
if ((i % CHUNK_WIDTH) < x0) if ((i % LevelConstants::CHUNK_WIDTH) < x0)
{ {
x0 = (i % CHUNK_WIDTH); x0 = (i % LevelConstants::CHUNK_WIDTH);
} }
if ((i % CHUNK_WIDTH) > x1) if ((i % LevelConstants::CHUNK_WIDTH) > x1)
{ {
x1 = (i % CHUNK_WIDTH); x1 = (i % LevelConstants::CHUNK_WIDTH);
} }
if ((i / CHUNK_WIDTH) < z0) if ((i / LevelConstants::CHUNK_WIDTH) < z0)
{ {
z0 = (i / CHUNK_WIDTH); z0 = (i / LevelConstants::CHUNK_WIDTH);
} }
if ((i / CHUNK_WIDTH) > z1) if ((i / LevelConstants::CHUNK_WIDTH) > z1)
{ {
z1 = (i / CHUNK_WIDTH); z1 = (i / LevelConstants::CHUNK_WIDTH);
} }
} }
} }
delete[] readBlockBuffer;
delete[] readDataBuffer;
if (recalcHeight) if (recalcHeight)
{ {
// chunk->recalcHeightmap(); // chunk->recalcHeightmap();
@@ -579,7 +672,7 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ChunkDat
//chunk->terrainPopulated = true; //chunk->terrainPopulated = true;
chunk->unsaved = false; chunk->unsaved = false;
chunksLoaded[packet->x * CHUNK_CACHE_WIDTH + packet->z] = true; chunksLoaded[packet->x * LevelConstants::CHUNK_CACHE_WIDTH + packet->z] = true;
if (areAllChunksLoaded()) if (areAllChunksLoaded())
{ {
@@ -627,18 +720,18 @@ void ClientSideNetworkHandler::arrangeRequestChunkOrder() {
clearChunksLoaded(); clearChunksLoaded();
// Default sort is around center of the world // Default sort is around center of the world
int cx = CHUNK_CACHE_WIDTH / 2; int cx = LevelConstants::CHUNK_CACHE_WIDTH / 2;
int cz = CHUNK_CACHE_WIDTH / 2; int cz = LevelConstants::CHUNK_CACHE_WIDTH / 2;
// If player exists, let's sort around him // If player exists, let's sort around him
Player* p = minecraft? minecraft->player : NULL; Player* p = minecraft? minecraft->player : NULL;
if (p) { if (p) {
cx = Mth::floor(p->x / (float)CHUNK_WIDTH); cx = Mth::floor(p->x / (float)LevelConstants::CHUNK_WIDTH);
cz = Mth::floor(p->z / (float)CHUNK_DEPTH); cz = Mth::floor(p->z / (float)LevelConstants::CHUNK_DEPTH);
} }
_ChunkSorter sorter(cx, cz); _ChunkSorter sorter(cx, cz);
std::sort(requestNextChunkIndexList, requestNextChunkIndexList + NumRequestChunks, sorter); std::sort(requestNextChunkIndexList.begin(), requestNextChunkIndexList.end(), sorter);
} }
void ClientSideNetworkHandler::levelGenerated(Level* level) void ClientSideNetworkHandler::levelGenerated(Level* level)
@@ -728,7 +821,7 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, SetEntit
if (!level) if (!level)
return; return;
LOGI("SetEntityDataPacket\n"); // LOGI("SetEntityDataPacket\n");
Entity* e = level->getEntity(packet->id); Entity* e = level->getEntity(packet->id);
if (e) { if (e) {
@@ -782,6 +875,10 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AnimateP
} }
} }
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, WantCreatePacket* packet)
{
}
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UseItemPacket* packet) void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UseItemPacket* packet)
{ {
} }
@@ -791,6 +888,7 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, SetHealt
if (!level || !minecraft->player) if (!level || !minecraft->player)
return; return;
printf("SetHealthPacket \n");
minecraft->player->hurtTo(packet->health); minecraft->player->hurtTo(packet->health);
} }
@@ -886,7 +984,11 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, Containe
void ClientSideNetworkHandler::handle( const RakNet::RakNetGUID& source, ChatPacket* packet ) void ClientSideNetworkHandler::handle( const RakNet::RakNetGUID& source, ChatPacket* packet )
{ {
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
minecraft->gui.displayClientMessage(packet->message); // minecraft->gui.displayClientMessage(packet->message);
std::istringstream iss(packet->message);
for (std::string line; std::getline(iss, line); ) {
minecraft->gui.addMessage(line);
}
#endif #endif
} }
@@ -919,8 +1021,8 @@ void ClientSideNetworkHandler::clearChunksLoaded()
{ {
// Init the chunk positions // Init the chunk positions
for (int i = 0; i < NumRequestChunks; ++i) { for (int i = 0; i < NumRequestChunks; ++i) {
requestNextChunkIndexList[i].x = i/CHUNK_WIDTH; requestNextChunkIndexList[i].x = i / LevelConstants::CHUNK_WIDTH;
requestNextChunkIndexList[i].y = i%CHUNK_WIDTH; requestNextChunkIndexList[i].y = i % LevelConstants::CHUNK_WIDTH;
chunksLoaded[i] = false; chunksLoaded[i] = false;
} }
} }

View File

@@ -77,6 +77,11 @@ public:
virtual void handle(const RakNet::RakNetGUID& source, ChatPacket* packet); virtual void handle(const RakNet::RakNetGUID& source, ChatPacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, AdventureSettingsPacket* packet); virtual void handle(const RakNet::RakNetGUID& source, AdventureSettingsPacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, SignUpdatePacket* packet); virtual void handle(const RakNet::RakNetGUID& source, SignUpdatePacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, RemoveItemPacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, TakeItemPacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, WantCreatePacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, SendInventoryPacket* packet);
private: private:
void requestNextChunk(); void requestNextChunk();
@@ -97,11 +102,11 @@ private:
BlockUpdateList bufferedBlockUpdates; BlockUpdateList bufferedBlockUpdates;
int requestNextChunkPosition; int requestNextChunkPosition;
static const int NumRequestChunks = CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH; int NumRequestChunks;
int requestNextChunkIndex; int requestNextChunkIndex;
IntPair requestNextChunkIndexList[NumRequestChunks]; std::vector<IntPair> requestNextChunkIndexList;
bool chunksLoaded[NumRequestChunks]; std::vector<bool> chunksLoaded;
}; };
#endif #endif

View File

@@ -1,33 +0,0 @@
#include "NATPunchHandler.h"
#include "../raknet/TCPInterface.h"
#include "../raknet/HTTPConnection.h"
#include "PHPDirectoryServer2.h"
using namespace RakNet;
NATPuchHandler::NATPuchHandler() {
tcpInterface = new TCPInterface;
}
NATPuchHandler::~NATPuchHandler() {
delete tcpInterface;
}
void NATPuchHandler::initialize() {
tcpInterface->Start(0, 64);
}
void NATPuchHandler::registerToGameList(const RakNet::RakString& serverName, int port) {
HTTPConnection httpConnection;
httpConnection.Init(tcpInterface, "johanbernhardsson.se");
PHPDirectoryServer2 directoryServer;
directoryServer.Init(&httpConnection, "/DirectoryServer.php");
directoryServer.UploadTable("", serverName, port, true);
}
void NATPuchHandler::removeFromGameList() {
}
void NATPuchHandler::close() {
}

View File

@@ -1,24 +0,0 @@
#ifndef _MINECRAFT_NETWORK_NATPUNCHHANDLER_H_
#define _MINECRAFT_NETWORK_NATPUNCHHANDLER_H_
#include "../raknet/TCPInterface.h"
#include "../raknet/RakString.h"
class NATPuchHandler {
public:
enum NATPuchHandlerStatus {
NATPuchInitilized = 0,
NATPuchFetchingServerList = 1,
NATPuchConnecting = 2,
NATPuchConnected = 3,
NATPuchDissconnected = 4
};
NATPuchHandler();
~NATPuchHandler();
void initialize();
void registerToGameList(const RakNet::RakString& serverName, int port);
void removeFromGameList();
void close();
private:
RakNet::TCPInterface *tcpInterface;
};
#endif /* _MINECRAFT_NETWORK_NATPUNCHHANDLER_H_ */

View File

@@ -18,6 +18,8 @@ class RemovePlayerPacket;
class RemoveEntityPacket; class RemoveEntityPacket;
class MoveEntityPacket; class MoveEntityPacket;
//class TeleportEntityPacket; //class TeleportEntityPacket;
class RemoveItemPacket;
class TakeItemPacket;
class MovePlayerPacket; class MovePlayerPacket;
class PlaceBlockPacket; class PlaceBlockPacket;
class RemoveBlockPacket; class RemoveBlockPacket;
@@ -48,6 +50,7 @@ class ContainerClosePacket;
class ContainerSetSlotPacket; class ContainerSetSlotPacket;
class ContainerSetDataPacket; class ContainerSetDataPacket;
class ContainerSetContentPacket; class ContainerSetContentPacket;
class WantCreatePacket;
class ChatPacket; class ChatPacket;
class SignUpdatePacket; class SignUpdatePacket;
class Minecraft; class Minecraft;
@@ -119,6 +122,9 @@ public:
virtual void handle(const RakNet::RakNetGUID& source, SignUpdatePacket* packet) {} virtual void handle(const RakNet::RakNetGUID& source, SignUpdatePacket* packet) {}
virtual void handle(const RakNet::RakNetGUID& source, AdventureSettingsPacket* packet) {} virtual void handle(const RakNet::RakNetGUID& source, AdventureSettingsPacket* packet) {}
virtual void handle(const RakNet::RakNetGUID& source, AnimatePacket* packet) {} virtual void handle(const RakNet::RakNetGUID& source, AnimatePacket* packet) {}
virtual void handle(const RakNet::RakNetGUID& source, RemoveItemPacket* packet) {}
virtual void handle(const RakNet::RakNetGUID& source, TakeItemPacket* packet) {}
virtual void handle(const RakNet::RakNetGUID& source, WantCreatePacket* packet) {}
// //
// Common implementation for Client and Server // Common implementation for Client and Server

View File

@@ -2,6 +2,7 @@
#include "Packet.h" #include "Packet.h"
#include "../world/level/chunk/LevelChunk.h" #include "../world/level/chunk/LevelChunk.h"
#include "network/packet/TakeItemPacket.h"
#include "packet/PacketInclude.h" #include "packet/PacketInclude.h"
Packet::Packet() Packet::Packet()
@@ -41,6 +42,12 @@ Packet* MinecraftPackets::createPacket(int id)
case PACKET_ADDITEMENTITY: case PACKET_ADDITEMENTITY:
packet = new AddItemEntityPacket(); packet = new AddItemEntityPacket();
break; break;
case PACKET_REMOVEITEM:
packet = new RemoveItemPacket();
break;
case PACKET_TAKEITEM:
packet = new TakeItemPacket();
break;
case PACKET_TAKEITEMENTITY: case PACKET_TAKEITEMENTITY:
packet = new TakeItemEntityPacket(); packet = new TakeItemEntityPacket();
break; break;
@@ -68,6 +75,9 @@ Packet* MinecraftPackets::createPacket(int id)
case PACKET_RESPAWN: case PACKET_RESPAWN:
packet = new RespawnPacket(); packet = new RespawnPacket();
break; break;
case PACKET_WANTCREATEITEM:
packet = new WantCreatePacket();
break;
case PACKET_REMOVEENTITY: case PACKET_REMOVEENTITY:
packet = new RemoveEntityPacket(); packet = new RemoveEntityPacket();
break; break;

View File

@@ -33,6 +33,9 @@ enum MinecraftPacketIds
PACKET_REMOVEENTITY, PACKET_REMOVEENTITY,
PACKET_ADDITEMENTITY, PACKET_ADDITEMENTITY,
PACKET_TAKEITEMENTITY, PACKET_TAKEITEMENTITY,
PACKET_TAKEITEM,
PACKET_REMOVEITEM,
PACKET_WANTCREATEITEM,
PACKET_MOVEENTITY, PACKET_MOVEENTITY,
PACKET_MOVEENTITY_POS, PACKET_MOVEENTITY_POS,

View File

@@ -173,6 +173,7 @@ bool RakNetInstance::isMyLocalGuid(const RakNet::RakNetGUID& guid)
void RakNetInstance::runEvents(NetEventCallback* callback) void RakNetInstance::runEvents(NetEventCallback* callback)
{ {
RakNet::Packet* currentEvent; RakNet::Packet* currentEvent;
bool disconnect = false;
while ((currentEvent = rakPeer->Receive()) != NULL) while ((currentEvent = rakPeer->Receive()) != NULL)
{ {
@@ -200,6 +201,7 @@ void RakNetInstance::runEvents(NetEventCallback* callback)
case ID_DISCONNECTION_NOTIFICATION: case ID_DISCONNECTION_NOTIFICATION:
case ID_CONNECTION_LOST: case ID_CONNECTION_LOST:
callback->onDisconnect(currentEvent->guid); callback->onDisconnect(currentEvent->guid);
disconnect = true;
break; break;
case ID_UNCONNECTED_PONG: case ID_UNCONNECTED_PONG:
{ {
@@ -233,8 +235,9 @@ void RakNetInstance::runEvents(NetEventCallback* callback)
} }
} }
} }
if (!disconnect) {
rakPeer->DeallocatePacket(currentEvent); rakPeer->DeallocatePacket(currentEvent);
}
//delete activeBitStream; //delete activeBitStream;
} }

View File

@@ -5,6 +5,16 @@
#include "../world/entity/player/Inventory.h" #include "../world/entity/player/Inventory.h"
#include "../world/Container.h" #include "../world/Container.h"
#include "../world/inventory/BaseContainerMenu.h" #include "../world/inventory/BaseContainerMenu.h"
#include "network/packet/ChatPacket.h"
#include "network/packet/ContainerSetSlotPacket.h"
#include "network/packet/LoginStatusPacket.h"
#include "network/packet/MovePlayerPacket.h"
#include "network/packet/RemoveBlockPacket.h"
#include "network/packet/SendInventoryPacket.h"
#include "network/packet/UpdateBlockPacket.h"
#include "network/packet/RemoveItemPacket.h"
#include "network/packet/TakeItemPacket.h"
#include "network/packet/WantCreatePacket.h"
#include "packet/PacketInclude.h" #include "packet/PacketInclude.h"
#include "RakNetInstance.h" #include "RakNetInstance.h"
@@ -13,11 +23,24 @@
#include "../client/gamemode/GameMode.h" #include "../client/gamemode/GameMode.h"
#include "../raknet/RakPeerInterface.h" #include "../raknet/RakPeerInterface.h"
#include "../raknet/PacketPriority.h" #include "../raknet/PacketPriority.h"
#include "platform/log.h"
#include "util/Mth.h"
#include "util/StringUtils.h"
#include "world/item/ItemInstance.h"
#include "world/level/LevelConstants.h"
#include "world/level/storage/LevelStorage.h"
#include "world/phys/Vec3.h"
#include "world/item/crafting/Recipe.h"
#include "world/item/crafting/Recipes.h"
#include <cstddef>
#include <cstdio>
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
#include "../client/sound/SoundEngine.h" #include "../client/sound/SoundEngine.h"
#endif #endif
#include "../server/ServerPlayer.h" #include "../server/ServerPlayer.h"
#include "../world/entity/item/FallingTile.h" #include "../world/entity/item/FallingTile.h"
#include <plugins/LuaPlayer.hpp>
#include <plugins/MessageEvent.hpp>
#define TIMES(x) for(int itc ## __LINE__ = 0; itc ## __LINE__ < x; ++ itc ## __LINE__) #define TIMES(x) for(int itc ## __LINE__ = 0; itc ## __LINE__ < x; ++ itc ## __LINE__)
@@ -53,11 +76,11 @@ void ServerSideNetworkHandler::tileChanged(int x, int y, int z)
Packet* ServerSideNetworkHandler::getAddPacketFromEntity( Entity* entity ) { Packet* ServerSideNetworkHandler::getAddPacketFromEntity( Entity* entity ) {
if (entity->isMob() && !entity->isPlayer()) { //@fix: This code is duplicated. See if it can be unified. if (entity->isMob() && !entity->isPlayer()) { //@fix: This code is duplicated. See if it can be unified.
if (minecraft->player) { // if (minecraft->player) {
// I guess this should always be true, but it crashed somewhere in this // I guess this should always be true, but it crashed somewhere in this
// function once and I only see this one as a potential problem // function once and I only see this one as a potential problem
return new AddMobPacket((Mob*)entity); return new AddMobPacket((Mob*)entity);
} // }
} }
else if (entity->isPlayer()) { else if (entity->isPlayer()) {
@@ -134,9 +157,62 @@ void ServerSideNetworkHandler::displayGameMessage(const std::string& message)
raknetInstance->send(packet); raknetInstance->send(packet);
} }
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MessagePacket* packet)
{
auto player = getPlayer(source);
if (player == nullptr) return; // @todo maybe kick?
auto msg = std::string(packet->message.C_String());
MessageEvent event;
event.m_decline = false;
PluginsManager::get().emit("Message", LuaPlayer(source), msg, event);
if (!event.m_decline) {
if (packet->message[0] == '/') {
// This is a command
auto cmd = Util::stringTrim(msg.substr(1));
if (PluginsManager::get().emitCommands(cmd, source)) {
ChatPacket resp(minecraft->commandManager().execute(*minecraft, *player, cmd));
return sendPrivate(resp, source);
} else {
return;
}
}
displayGameMessage("<" + player->name + "> " + msg);
}
}
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ChatPacket* packet) void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ChatPacket* packet)
{ {
displayGameMessage(packet->message); auto player = getPlayer(source);
if (player == nullptr) return; // @todo maybe kick?
MessageEvent event;
event.m_decline = false;
PluginsManager::get().emit("Message", LuaPlayer(source), packet->message, event);
if (!event.m_decline) {
if (packet->message[0] == '/') {
// This is a command
auto cmd = Util::stringTrim(packet->message.substr(1));
if (PluginsManager::get().emitCommands(cmd, source)) {
ChatPacket resp(minecraft->commandManager().execute(*minecraft, *player, cmd));
return sendPrivate(resp, source);
} else {
return;
}
}
displayGameMessage("<" + player->name + "> " + packet->message);
}
} }
void ServerSideNetworkHandler::onNewClient(const RakNet::RakNetGUID& clientGuid) void ServerSideNetworkHandler::onNewClient(const RakNet::RakNetGUID& clientGuid)
@@ -156,6 +232,9 @@ void ServerSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& guid)
if (player->owner == guid) if (player->owner == guid)
{ {
PluginsManager::get().emit("PlayerDisconnect", LuaPlayer(guid));
minecraft->level->getLevelStorage()->savePlayer(*player);
std::string message = player->name; std::string message = player->name;
message += " disconnected from the game"; message += " disconnected from the game";
displayGameMessage(message); displayGameMessage(message);
@@ -186,8 +265,42 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginPac
// //
bool oldClient = packet->clientNetworkVersion < SharedConstants::NetworkProtocolLowestSupportedVersion; bool oldClient = packet->clientNetworkVersion < SharedConstants::NetworkProtocolLowestSupportedVersion;
bool oldServer = packet->clientNetworkLowestSupportedVersion > SharedConstants::NetworkProtocolVersion; bool oldServer = packet->clientNetworkLowestSupportedVersion > SharedConstants::NetworkProtocolVersion;
if (oldClient || oldServer) if (oldClient || oldServer || !packet->newProto)
loginStatus = oldClient? LoginStatus::Failed_ClientOld : LoginStatus::Failed_ServerOld; loginStatus = oldClient || !packet->newProto? LoginStatus::Failed_ClientOld : LoginStatus::Failed_ServerOld;
std::string nicknameLower = packet->clientName.C_String();
std::transform(nicknameLower.begin(), nicknameLower.end(), nicknameLower.begin(), ::tolower);
RakNet::SystemAddress sysAddress = rakPeer->GetSystemAddressFromGuid(source);
char clientIp[32];
sysAddress.ToString(false, clientIp);
for (int i = 0; i < level->players.size(); i++) {
ServerPlayer* player = (ServerPlayer*) level->players.at(i);
std::string clientLower = player->name;
std::transform(clientLower.begin(), clientLower.end(), clientLower.begin(), ::tolower);
// @todo to lower case
if (nicknameLower == clientLower) {
loginStatus = packet->newProto ? LoginStatus::Failed_TakenNickname : LoginStatus::Failed_ClientOld;
break;
}
}
for (auto& banned : level->bannedPpl) {
if (nicknameLower == banned) {
loginStatus = packet->newProto ? LoginStatus::Failed_Banned : LoginStatus::Failed_ClientOld;
break;
}
}
for (auto& banned : level->bannedIps) {
if (clientIp == banned) {
loginStatus = packet->newProto ? LoginStatus::Failed_Banned : LoginStatus::Failed_ClientOld;
break;
}
}
RakNet::BitStream bitStream; RakNet::BitStream bitStream;
LoginStatusPacket(loginStatus).write(&bitStream); LoginStatusPacket(loginStatus).write(&bitStream);
@@ -199,13 +312,16 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginPac
// //
// Valid client version // Valid client version
// //
Player* newPlayer = new ServerPlayer(minecraft, level);
Player* newPlayer = new ServerPlayer(minecraft, level, packet->newProto);
minecraft->gameMode->initAbilities(newPlayer->abilities); minecraft->gameMode->initAbilities(newPlayer->abilities);
newPlayer->owner = source; newPlayer->owner = source;
newPlayer->name = packet->clientName.C_String(); newPlayer->name = packet->clientName.C_String();
_pendingPlayers.push_back(newPlayer); _pendingPlayers.push_back(newPlayer);
LOGI("Adding new player... isCreative: %i\n", minecraft->isCreativeMode());
// Reset the player so he doesn't spawn inside blocks // Reset the player so he doesn't spawn inside blocks
while (newPlayer->y > 0) { while (newPlayer->y > 0) {
newPlayer->setPos(newPlayer->x, newPlayer->y, newPlayer->z); newPlayer->setPos(newPlayer->x, newPlayer->y, newPlayer->z);
@@ -228,7 +344,8 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginPac
level->getLevelData()->getGeneratorVersion(), level->getLevelData()->getGeneratorVersion(),
gameType, gameType,
newPlayer->entityId, newPlayer->entityId,
newPlayer->x, newPlayer->y - newPlayer->heightOffset, newPlayer->z newPlayer->x, newPlayer->y - newPlayer->heightOffset, newPlayer->z,
LevelConstants::CHUNK_CACHE_WIDTH
).write(&bitStream); ).write(&bitStream);
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false); rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
@@ -288,7 +405,6 @@ void ServerSideNetworkHandler::onReady_ClientGeneration(const RakNet::RakNetGUID
#else #else
LOGW("%s joined the game\n", newPlayer->name.c_str()); LOGW("%s joined the game\n", newPlayer->name.c_str());
#endif #endif
// Send all Entities to the new player // Send all Entities to the new player
for (unsigned int i = 0; i < level->entities.size(); ++i) { for (unsigned int i = 0; i < level->entities.size(); ++i) {
Entity* e = level->entities[i]; Entity* e = level->entities[i];
@@ -301,6 +417,36 @@ void ServerSideNetworkHandler::onReady_ClientGeneration(const RakNet::RakNetGUID
} }
} }
if (!minecraft->level->getLevelStorage()->loadPlayer(*newPlayer)) {
LOGW("Failed to load %s data\n", newPlayer->name.c_str());
}
// Credits to EpikIzCool
bitStream.Reset();
MovePlayerPacket mv(newPlayer->entityId, newPlayer->x, newPlayer->y - newPlayer->heightOffset,
newPlayer->z, newPlayer->xRot, newPlayer->yRot);
mv.write(&bitStream);
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
bitStream.Reset();
SetHealthPacket hp(newPlayer->health);
hp.write(&bitStream);
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
if (newPlayer->hasRespawnPosition()) {
bitStream.Reset();
SetSpawnPositionPacket sp(newPlayer->getRespawnPosition());
sp.write(&bitStream);
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
}
bitStream.Reset();
SendInventoryPacket(newPlayer, false).write(&bitStream);
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
// Additional packets // Additional packets
// * set spawn // * set spawn
/* /*
@@ -314,6 +460,8 @@ void ServerSideNetworkHandler::onReady_ClientGeneration(const RakNet::RakNetGUID
bitStream.Reset(); bitStream.Reset();
AddPlayerPacket(newPlayer).write(&bitStream); AddPlayerPacket(newPlayer).write(&bitStream);
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, true); rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, true);
PluginsManager::get().emit("PlayerJoin", LuaPlayer(source));
} }
// //
@@ -339,9 +487,32 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MovePlay
{ {
if (!level) return; if (!level) return;
//LOGI("MovePlayerPacket\n"); // LOGI("MovePlayerPacket\n");
if (Entity* entity = level->getEntity(packet->entityId)) if (Entity* entity = level->getEntity(packet->entityId)) {
{ ServerPlayer* player = (ServerPlayer*) getPlayer(source);
// int timeElapsed = minecraft->getTicks() - player->getLastMoveTicks();
// if (timeElapsed > 0) {
// float dist = player->distanceTo(packet->x, player->y, packet->z);
// float speed = dist / (minecraft->getTicks() - player->getLastMoveTicks());
// player->setLastMoveTicks(minecraft->getTicks());
// float maxSpeed = (minecraft->isCreativeMode()) ? 1.65f : 1.f;
// if (speed > maxSpeed) {
// MovePlayerPacket refuse(player->entityId, player->x, player->y, player->z, player->xRot, player->yRot);
// return raknetInstance->send(refuse);
// }
// }
PluginsManager::get().emit(
"PlayerMovement",
LuaPlayer(source),
packet->x, packet->y, packet->z, packet->yRot, packet->xRot, // newPos
player->x, player->y, player->z, player->yRot, player->xRot // oldPos
);
entity->xd = entity->yd = entity->zd = 0; entity->xd = entity->yd = entity->zd = 0;
entity->lerpTo(packet->x, packet->y, packet->z, packet->yRot, packet->xRot, 3); entity->lerpTo(packet->x, packet->y, packet->z, packet->yRot, packet->xRot, 3);
@@ -350,7 +521,7 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MovePlay
} }
} }
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RemoveBlockPacket* packet){ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RemoveBlockPacket* packet) {
if (!level) return; if (!level) return;
Player* player = getPlayer(source); Player* player = getPlayer(source);
@@ -368,12 +539,31 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RemoveBl
if (oldTile != NULL && changed) { if (oldTile != NULL && changed) {
level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, oldTile->soundType->getBreakSound(), (oldTile->soundType->getVolume() + 1) / 2, oldTile->soundType->getPitch() * 0.8f); level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, oldTile->soundType->getBreakSound(), (oldTile->soundType->getVolume() + 1) / 2, oldTile->soundType->getPitch() * 0.8f);
if (minecraft->gameMode->isSurvivalType() && player->canDestroy(oldTile)) if (minecraft->gameMode->isSurvivalType() && player->canDestroy(oldTile)) {
//oldTile->spawnResources(level, x, y, z, data, 1); //@todo // From SurvivalMode.cpp
// Why tf i have to copy this shit from SurvivalMode class
// Why SurvivalMode class locked to LOCAL MINECRAFT PLAYER :sob: :sob: :sob: :sob: :sob: :sob: :sob: :sob:
// @fix @warn @ahtung @alert
ItemInstance* item = player->inventory->getSelected();
if (item != NULL) {
item->mineBlock(oldTile->id, x, y, z);
if (item->count == 0) {
//item->snap(minecraft->player);
player->inventory->clearSlot(player->inventory->selected);
}
}
// oldTile->spawnResources(level, x, y, z, data, 1); //@todo
oldTile->playerDestroy(level, player, x, y, z, data); oldTile->playerDestroy(level, player, x, y, z, data);
}
oldTile->destroy(level, x, y, z, data); oldTile->destroy(level, x, y, z, data);
// RemoveEntityPacket packet(e->entityId);
// redistributePacket(&packet, rakPeer->GetMyGUID());
} }
LOGI("Remove block [%i, %i, %i]\n", packet->x, packet->y, packet->z);
} }
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RequestChunkPacket* packet) void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RequestChunkPacket* packet)
@@ -403,6 +593,8 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RequestC
raknetInstance->send(source, p); raknetInstance->send(source, p);
} }
} }
// LOGI("Requested chunk [%i, %i]\n", packet->x, packet->z);
} }
void ServerSideNetworkHandler::levelGenerated( Level* level ) void ServerSideNetworkHandler::levelGenerated( Level* level )
@@ -429,23 +621,31 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, PlayerEq
if (!player) return; if (!player) return;
if (rakPeer->GetMyGUID() == player->owner) return; if (rakPeer->GetMyGUID() == player->owner) return;
LOGI("Equip item: id %i aux %i\n", packet->itemId, packet->itemAuxValue);
// override the player's inventory // override the player's inventory
//int slot = player->inventory->getSlot(packet->itemId, packet->itemAuxValue); int slot = player->inventory->getSlot(packet->itemId, packet->itemAuxValue);
int slot = Inventory::MAX_SELECTION_SIZE;
if (slot >= 0) { if (slot >= 0 && slot != packet->inventorySlot && packet->itemId != 0) {
if (packet->itemId == 0) { LOGW("PlayerEquipmentPacket: Item in player inventory but slots doesn't match!");
player->inventory->clearSlot(slot); packet->inventorySlot = slot;
} else {
// @note: 128 is an ugly hack for depletable items.
// @todo: fix
ItemInstance newItem(packet->itemId, 128, packet->itemAuxValue);
player->inventory->replaceSlot(slot, &newItem);
}
player->inventory->moveToSelectedSlot(slot, true);
redistributePacket(packet, source);
} else {
LOGW("Warning: Remote player doesn't have his thing, Odd!\n");
} }
if (slot < 0 && packet->itemId != 0) {
LOGW("PlayerEquipmentPacket: Remote player doesn't have his thing (or crafted it)!\n");
SendInventoryPacket newInventory (player, false);
raknetInstance->send(newInventory);
return;
}
player->inventory->selectSlot(packet->selectedSlot);
player->inventory->linkSlot(packet->selectedSlot, packet->inventorySlot, true);
player->inventory->print();
redistributePacket(packet, source);
} }
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, PlayerArmorEquipmentPacket* packet) { void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, PlayerArmorEquipmentPacket* packet) {
@@ -455,6 +655,8 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, PlayerAr
if (!player) return; if (!player) return;
if (rakPeer->GetMyGUID() == player->owner) return; if (rakPeer->GetMyGUID() == player->owner) return;
// LOGI("Equip armor: %i %i %i %i\n", packet->head, packet->torso, packet->legs, packet->feet);
packet->fillIn(player); packet->fillIn(player);
redistributePacket(packet, source); redistributePacket(packet, source);
} }
@@ -466,6 +668,8 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, Interact
Entity* entity = level->getEntity(packet->targetId); Entity* entity = level->getEntity(packet->targetId);
if (src && entity && src->isPlayer()) if (src && entity && src->isPlayer())
{ {
LOGI("Interact: source %i target %i\n", packet->sourceId, packet->targetId);
Player* player = (Player*) src; Player* player = (Player*) src;
if (InteractPacket::Attack == packet->action) { if (InteractPacket::Attack == packet->action) {
player->swing(); player->swing();
@@ -506,14 +710,75 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AnimateP
} }
redistributePacket(packet, source); redistributePacket(packet, source);
} }
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, WantCreatePacket* packet) {
LOGI("WantCreatePacket\n");
Entity* entity = level->getEntity(packet->playerId);
if (entity && entity->isPlayer()) {
Player* p = (Player*)entity;
auto playerInv = p->inventory;
ItemInstance wantCreate;
wantCreate.id = packet->itemId;
wantCreate.count = packet->count;
wantCreate.setAuxValue(packet->auxValue);
Recipe* recipe = Recipes::getInstance()->getRecipeFor(wantCreate);
std::vector<ItemInstance> items = recipe->getItemPack().getItemInstances();
std::vector<int> checkForExists = {};
for (int i = Inventory::MAX_SELECTION_SIZE; i < p->inventory->getContainerSize(); ++i) {
auto itm = p->inventory->getItem(i);
if (itm != NULL) {
for (int y = 0; y < items.size(); y++) {
auto itmRecipe = items.at(y);
if (itmRecipe.id == itm->id && itm->count >= itmRecipe.count) {
checkForExists.push_back(itm->id);
}
}
}
}
if (checkForExists.empty()) {
return;
}
for (int i = 0; i < items.size(); i++) {
auto item = items.at(i);
auto it = std::find(checkForExists.begin(), checkForExists.end(), item.id);
if (it == checkForExists.end() && checkForExists.size() > 1) {
return;
}
}
for (int i = 0; i < items.size(); i++) {
p->inventory->removeResource(ItemInstance(items.at(i).id, items.at(i).count, items.at(i).getAuxValue()));
}
// TakeItemPacket itemAdd(p->entityId, wantCreate.count, wantCreate.getAuxValue(), wantCreate.id);
// raknetInstance->send(source, itemAdd);
p->inventory->add(new ItemInstance(wantCreate.id, wantCreate.count, wantCreate.getAuxValue()));
}
}
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UseItemPacket* packet) void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UseItemPacket* packet)
{ {
if (!level) return; if (!level) return;
LOGI("UseItemPacket\n"); LOGI("UseItemPacket: id %i data %i\n", packet->itemId, packet->itemData);
Entity* entity = level->getEntity(packet->entityId); Entity* entity = level->getEntity(packet->entityId);
if (entity && entity->isPlayer()) { if (entity && entity->isPlayer()) {
LOGI("%f %f %f \n", entity->x, entity->y, entity->z);
Player* player = (Player*) entity; Player* player = (Player*) entity;
int x = packet->x, y = packet->y, z = packet->z; int x = packet->x, y = packet->y, z = packet->z;
Tile* t = Tile::tiles[level->getTile(x, y, z)]; Tile* t = Tile::tiles[level->getTile(x, y, z)];
@@ -522,7 +787,41 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UseItemP
if (t && t->use(level, x, y, z, player)) return; if (t && t->use(level, x, y, z, player)) return;
if (packet->item.isNull()) return; if (packet->item.isNull()) return;
ItemInstance* item = &packet->item; ItemInstance* packetItem = &packet->item;
int slot = player->inventory->getSlot(packet->itemId, packet->itemData);
if (slot < 0) {
LOGW("UseItemPacket: Player doesn't have this item!\n");
auto pos = Vec3(packet->x, packet->y, packet->z);
if (ItemInstance::isBlock(packetItem)) {
LOGI("UseItemPacket: This is even block!!!\n");
pos.x += packet->clickX;
pos.y += packet->clickY;
pos.z += packet->clickZ;
}
UpdateBlockPacket refuse(pos.x, pos.y, pos.z, level->getTile(pos.x, pos.y, pos.z), level->getData(pos.x, pos.y, pos.z));
raknetInstance->send(refuse);
return;
}
ItemInstance* item = player->inventory->getItem(slot);
player->x = packet->playerX;
player->y = packet->playerY;
player->z = packet->playerZ;
player->bb.x0 = packet->playerX0;
player->bb.y0 = packet->playerY0;
player->bb.z0 = packet->playerZ0;
player->bb.x1 = packet->playerX1;
player->bb.y1 = packet->playerY1;
player->bb.z1 = packet->playerZ1;
if(packet->face == 255) { if(packet->face == 255) {
// Special case: x,y,z means direction-of-action // Special case: x,y,z means direction-of-action
@@ -534,6 +833,10 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UseItemP
Vec3(packet->clickX + packet->x, packet->clickY + packet->y, packet->clickZ + packet->z)); Vec3(packet->clickX + packet->x, packet->clickY + packet->y, packet->clickZ + packet->z));
} }
if (item && item->count <= 0) {
player->inventory->clearSlot(slot);
}
//LOGW("Use Item not working! Out of synch?\n"); //LOGW("Use Item not working! Out of synch?\n");
// Don't have to redistribute (ugg.. this will mess up), cause tileUpdated is sent // Don't have to redistribute (ugg.. this will mess up), cause tileUpdated is sent
@@ -544,6 +847,8 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UseItemP
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, EntityEventPacket* packet) { void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, EntityEventPacket* packet) {
if (!level) return; if (!level) return;
LOGI("EntityEventPacket: id %i\n", packet->eventId);
if (Entity* e = level->getEntity(packet->entityId)) if (Entity* e = level->getEntity(packet->entityId))
e->handleEntityEvent(packet->eventId); e->handleEntityEvent(packet->eventId);
} }
@@ -577,6 +882,11 @@ void ServerSideNetworkHandler::handle( const RakNet::RakNetGUID& source, SendInv
{ {
if (!level) return; if (!level) return;
LOGI("SendInventoryPacket:\n");
for (int i = 0; i < packet->numItems; i++) {
LOGI("\t %i: %s (%i)\n", i, packet->items.at(i).getName().c_str(), packet->items.at(i).count);
}
Entity* entity = level->getEntity(packet->entityId); Entity* entity = level->getEntity(packet->entityId);
if (entity && entity->isPlayer()) { if (entity && entity->isPlayer()) {
Player* p = (Player*)entity; Player* p = (Player*)entity;
@@ -592,15 +902,27 @@ void ServerSideNetworkHandler::handle( const RakNet::RakNetGUID& source, DropIte
{ {
if (!level) return; if (!level) return;
LOGI("DropItemPacket\n");
Entity* entity = level->getEntity(packet->entityId); Entity* entity = level->getEntity(packet->entityId);
if (entity && entity->isPlayer()) { if (entity && entity->isPlayer()) {
Player* p = (Player*)entity; Player* p = (Player*)entity;
p->drop(new ItemInstance(packet->item), packet->dropType != 0); // p->drop(new ItemInstance(packet->item), packet->dropType != 0);
int slot = p->inventory->getSlot(packet->item.id, packet->item.getAuxValue());
if (slot < 0) {
LOGW("DropItemPacket: player doesn't have these items!\n");
return;
}
p->inventory->dropSlot(slot, false, packet->dropType != 0);
} }
} }
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ContainerClosePacket* packet) { void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ContainerClosePacket* packet) {
if (!level) return; if (!level) return;
LOGI("ContainerClosePacket\n");
Player* p = findPlayer(level, &source); Player* p = findPlayer(level, &source);
if (!p) return; if (!p) return;
@@ -612,6 +934,16 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, Containe
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ContainerSetSlotPacket* packet) { void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ContainerSetSlotPacket* packet) {
if (!level) return; if (!level) return;
const char* type = "unknown";
switch (packet->setType) {
case ContainerSetSlotPacket::SETTYPE_ADD: type = "add"; break;
case ContainerSetSlotPacket::SETTYPE_SET: type = "set"; break;
case ContainerSetSlotPacket::SETTYPE_TAKE: type = "take"; break;
};
LOGI("ContainerSetSlot: slot %i item %s type %s\n", packet->slot, packet->item.getName().c_str(), type);
Player* p = findPlayer(level, &source); Player* p = findPlayer(level, &source);
if (!p) return; if (!p) return;
@@ -619,12 +951,80 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, Containe
LOGW("User has no container!\n"); LOGW("User has no container!\n");
return; return;
} }
if (p->containerMenu->containerId != packet->containerId)
{ if (p->containerMenu->containerId != packet->containerId) {
LOGW("Wrong container id: %d vs %d\n", p->containerMenu->containerId, packet->containerId); LOGW("Wrong container id: %d vs %d\n", p->containerMenu->containerId, packet->containerId);
return; return;
} }
if (packet->item.count > 64) {
LOGW("ContainerSetSlotPacket: player tried to put more than 64");
return;
}
auto contItems = p->containerMenu->getItems();
// find same item in player inventory (used not in all cases)
int invSlot = p->inventory->getSlot(packet->item.id, packet->item.getAuxValue());
auto invItem = p->inventory->getItem(invSlot);
if (contItems.at(packet->slot).id == 0 && packet->item.id != 0) {
LOGI("ContainerSetSlotPacket: player tried to put items to slot %i\n", packet->slot);
if (invSlot < 0) {
LOGW("ContainerSetSlotPacket: player doesn't have this item\n");
return;
}
if (invItem->count < packet->item.count) {
LOGW("ContainerSetSlotPacket: player tried to put more than he have\n");
packet->item.count = invItem->count;
}
invItem->count -= packet->item.count;
if (invItem->count <= 0) {
p->inventory->removeItem(invItem);
}
} else if(contItems.at(packet->slot).id == packet->item.id) {
int deltaItem = packet->item.count - contItems.at(packet->slot).count;
if (deltaItem > 0) {
LOGI("ContainerSetSlotPacket: player tried to add %i items to slot %i\n", deltaItem, packet->slot);
auto invItem = p->inventory->getItem(invSlot);
if (invSlot < 0) {
LOGW("ContainerSetSlotPacket: player doesn't have this item\n");
return;
}
if (invItem->count < deltaItem) {
LOGW("ContainerSetSlotPacket: player tried to put more than he have");
packet->item.count -= (deltaItem - invItem->count);
deltaItem = invItem->count;
}
invItem->count -= deltaItem;
if (invItem->count <= 0) {
p->inventory->removeItem(invItem);
}
} else if (deltaItem < 0) {
LOGW("ContainerSetSlotPacket: player tried to take %i items from slot %i\n", -deltaItem, packet->slot);
p->inventory->add(new ItemInstance(packet->item.getItem(), -deltaItem, contItems.at(packet->slot).getAuxValue()));
}
} else if(contItems.at(packet->slot).id && !packet->item.id) {
LOGI("ContainerSetSlotPacket: player tried to take all items from slot %i\n", packet->slot);
packet->item.count = 0;
packet->item.setAuxValue(0);
p->inventory->add(new ItemInstance(contItems.at(packet->slot).getItem(), contItems.at(packet->slot).count, contItems.at(packet->slot).getAuxValue()));
} else {
LOGW("ContainerSetSlotPacket: illegal container operation in slot %i\n", packet->slot);
return;
}
if (ContainerType::FURNACE == p->containerMenu->containerType) { if (ContainerType::FURNACE == p->containerMenu->containerType) {
//LOGI("Server:Setting slot %d: %s\n", packet->slot, packet->item.toString().c_str()); //LOGI("Server:Setting slot %d: %s\n", packet->slot, packet->item.toString().c_str());
p->containerMenu->setSlot(packet->slot, &packet->item); p->containerMenu->setSlot(packet->slot, &packet->item);
@@ -635,6 +1035,8 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, Containe
p->containerMenu->setSlot(packet->slot, &packet->item); p->containerMenu->setSlot(packet->slot, &packet->item);
//p->containerMenu->setSlot(packet->slot, packet->item.isNull()? NULL : &packet->item); //p->containerMenu->setSlot(packet->slot, packet->item.isNull()? NULL : &packet->item);
} }
p->inventory->print();
} }
void ServerSideNetworkHandler::handle( const RakNet::RakNetGUID& source, SetHealthPacket* packet ) void ServerSideNetworkHandler::handle( const RakNet::RakNetGUID& source, SetHealthPacket* packet )
@@ -657,6 +1059,8 @@ void ServerSideNetworkHandler::handle( const RakNet::RakNetGUID& source, SignUpd
if (!level) if (!level)
return; return;
LOGI("SignUpdate: [%i, %i, %i]\n", packet->x, packet->y, packet->z);
TileEntity* te = level->getTileEntity(packet->x, packet->y, packet->z); TileEntity* te = level->getTileEntity(packet->x, packet->y, packet->z);
if (TileEntity::isType(te, TileEntityType::Sign)) { if (TileEntity::isType(te, TileEntityType::Sign)) {
SignTileEntity* ste = (SignTileEntity*) te; SignTileEntity* ste = (SignTileEntity*) te;
@@ -713,3 +1117,9 @@ Player* ServerSideNetworkHandler::getPlayer( const RakNet::RakNetGUID& source )
if (source == level->players[i]->owner) return level->players[i]; if (source == level->players[i]->owner) return level->players[i];
return NULL; return NULL;
} }
void ServerSideNetworkHandler::sendPrivate(Packet& packet, const RakNet::RakNetGUID& source) {
RakNet::BitStream bitStream;
packet.write(&bitStream);
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
}

View File

@@ -58,6 +58,8 @@ public:
virtual void handle(const RakNet::RakNetGUID& source, ContainerClosePacket* packet); virtual void handle(const RakNet::RakNetGUID& source, ContainerClosePacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, SignUpdatePacket* packet); virtual void handle(const RakNet::RakNetGUID& source, SignUpdatePacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, ChatPacket* packet); virtual void handle(const RakNet::RakNetGUID& source, ChatPacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, MessagePacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, WantCreatePacket* packet);
bool allowsIncomingConnections() { return _allowIncoming; } bool allowsIncomingConnections() { return _allowIncoming; }
void allowIncomingConnections(bool doAllow); void allowIncomingConnections(bool doAllow);
@@ -65,13 +67,21 @@ public:
Player* popPendingPlayer(const RakNet::RakNetGUID& source); Player* popPendingPlayer(const RakNet::RakNetGUID& source);
void displayGameMessage(const std::string& message); void displayGameMessage(const std::string& message);
private:
/** /**
* @brief Send packet to all players * @brief Send packet to all players
*/ */
void redistributePacket(Packet* packet, const RakNet::RakNetGUID& fromPlayer); void redistributePacket(Packet* packet, const RakNet::RakNetGUID& fromPlayer);
/**
* @brief Send packer private with GUID
*/
void sendPrivate(Packet& packet, const RakNet::RakNetGUID& source);
Player* getPlayer(const RakNet::RakNetGUID& source); Player* getPlayer(const RakNet::RakNetGUID& source);
private:
Minecraft* minecraft; Minecraft* minecraft;
Level* level; Level* level;
IRakNetInstance* raknetInstance; IRakNetInstance* raknetInstance;

View File

@@ -236,9 +236,9 @@ std::string CommandServer::parse(ConnectedClient& client, const std::string& s)
if (x0 < 0) x0 = 0; if (x0 < 0) x0 = 0;
if (y0 < 0) y0 = 0; if (y0 < 0) y0 = 0;
if (z0 < 0) z0 = 0; if (z0 < 0) z0 = 0;
if (x1 >= LEVEL_WIDTH ) x1 = LEVEL_WIDTH - 1; if (x1 >= LevelConstants::LEVEL_WIDTH ) x1 = LevelConstants::LEVEL_WIDTH - 1;
if (y1 >= LEVEL_HEIGHT) y1 = LEVEL_HEIGHT - 1; if (y1 >= LevelConstants::LEVEL_HEIGHT) y1 = LevelConstants::LEVEL_HEIGHT - 1;
if (z1 >= LEVEL_DEPTH ) z1 = LEVEL_DEPTH - 1; if (z1 >= LevelConstants::LEVEL_DEPTH ) z1 = LevelConstants::LEVEL_DEPTH - 1;
for (int y = y0; y <= y1; ++y) for (int y = y0; y <= y1; ++y)
for (int z = z0; z <= z1; ++z) for (int z = z0; z <= z1; ++z)
@@ -456,7 +456,7 @@ std::string CommandServer::parse(ConnectedClient& client, const std::string& s)
sw.start(); sw.start();
// Save a cuboid around the player // Save a cuboid around the player
const int CSize = CHUNK_CACHE_WIDTH; const int CSize = LevelConstants::CHUNK_CACHE_WIDTH;
int cx = (int)e->x / CSize; int cx = (int)e->x / CSize;
int cz = (int)e->z / CSize; int cz = (int)e->z / CSize;
@@ -504,7 +504,7 @@ bool CommandServer::handleCheckpoint(bool doRestore ) {
const int cz = restorePos.z; const int cz = restorePos.z;
const int y0 = restorePos.y; const int y0 = restorePos.y;
const int y1 = y0 + RestoreHeight; const int y1 = y0 + RestoreHeight;
const int CSize = CHUNK_CACHE_WIDTH; const int CSize = LevelConstants::CHUNK_CACHE_WIDTH;
const int numChunkBytes = RestoreHeight * CSize * CSize * 20 / 8; const int numChunkBytes = RestoreHeight * CSize * CSize * 20 / 8;
if (!restoreBuffer) { if (!restoreBuffer) {

View File

@@ -33,18 +33,18 @@ public:
unsigned char* blockIds = chunk->getBlockData(); unsigned char* blockIds = chunk->getBlockData();
DataLayer& blockData = chunk->data; DataLayer& blockData = chunk->data;
const int setSize = LEVEL_HEIGHT / 8; const int setSize = LevelConstants::LEVEL_HEIGHT / 8;
const int setShift = 4; // power of LEVEL_HEIGHT / 8 const int setShift = 4; // power of LevelConstants::LEVEL_HEIGHT / 8
chunkData.Reset(); chunkData.Reset();
for (int i = 0; i < CHUNK_COLUMNS; i++) for (int i = 0; i < LevelConstants::CHUNK_COLUMNS; i++)
{ {
unsigned char updateBits = chunk->updateMap[i]; unsigned char updateBits = chunk->updateMap[i];
chunkData.Write(updateBits); chunkData.Write(updateBits);
if (updateBits > 0) if (updateBits > 0)
{ {
int colDataPosition = (i % CHUNK_WIDTH) << 11 | (i / CHUNK_WIDTH) << 7; int colDataPosition = (i % LevelConstants::CHUNK_WIDTH) << 11 | (i / LevelConstants::CHUNK_WIDTH) << 7;
for (int set = 0; set < 8; set++) for (int set = 0; set < 8; set++)
{ {

View File

@@ -9,17 +9,20 @@ public:
RakNet::RakString clientName; RakNet::RakString clientName;
int clientNetworkVersion; int clientNetworkVersion;
int clientNetworkLowestSupportedVersion; int clientNetworkLowestSupportedVersion;
bool newProto;
LoginPacket() LoginPacket()
: clientNetworkVersion(-1), : clientNetworkVersion(-1),
clientNetworkLowestSupportedVersion(-1) clientNetworkLowestSupportedVersion(-1),
newProto(false)
{ {
} }
LoginPacket(const RakNet::RakString& clientName, int clientVersion) LoginPacket(const RakNet::RakString& clientName, int clientVersion, bool newProto)
: clientName(clientName), : clientName(clientName),
clientNetworkVersion(clientVersion), clientNetworkVersion(clientVersion),
clientNetworkLowestSupportedVersion(clientVersion) clientNetworkLowestSupportedVersion(clientVersion),
newProto(newProto)
{ {
} }
@@ -29,6 +32,7 @@ public:
bitStream->Write(clientName); bitStream->Write(clientName);
bitStream->Write(clientNetworkVersion); bitStream->Write(clientNetworkVersion);
bitStream->Write(clientNetworkLowestSupportedVersion); bitStream->Write(clientNetworkLowestSupportedVersion);
bitStream->Write(newProto);
} }
void read(RakNet::BitStream* bitStream) void read(RakNet::BitStream* bitStream)
@@ -39,6 +43,11 @@ public:
if (bitStream->GetNumberOfUnreadBits() > 0) { if (bitStream->GetNumberOfUnreadBits() > 0) {
bitStream->Read(clientNetworkVersion); bitStream->Read(clientNetworkVersion);
bitStream->Read(clientNetworkLowestSupportedVersion); bitStream->Read(clientNetworkLowestSupportedVersion);
// Checking for new proto
if (bitStream->GetNumberOfUnreadBits() > 0) {
bitStream->Read(newProto);
}
} }
} }

View File

@@ -3,10 +3,13 @@
#include "../Packet.h" #include "../Packet.h"
// wtf why not enum
namespace LoginStatus { namespace LoginStatus {
const int Success = 0; const int Success = 0;
const int Failed_ClientOld = 1; const int Failed_ClientOld = 1;
const int Failed_ServerOld = 2; const int Failed_ServerOld = 2;
const int Failed_TakenNickname = 3;
const int Failed_Banned = 4;
} }
class LoginStatusPacket : public Packet { class LoginStatusPacket : public Packet {

View File

@@ -50,5 +50,7 @@
#include "TileEventPacket.h" #include "TileEventPacket.h"
#include "UpdateBlockPacket.h" #include "UpdateBlockPacket.h"
#include "UseItemPacket.h" #include "UseItemPacket.h"
#include "RemoveItemPacket.h"
#include "WantCreatePacket.h"
#include "TakeItemPacket.h"
#endif /*NET_MINECRAFT_NETWORK_PACKET__PacketInclude_H__*/ #endif /*NET_MINECRAFT_NETWORK_PACKET__PacketInclude_H__*/

View File

@@ -9,15 +9,19 @@ public:
int entityId; int entityId;
unsigned short itemId; unsigned short itemId;
unsigned short itemAuxValue; unsigned short itemAuxValue;
unsigned char selectedSlot;
unsigned char inventorySlot;
PlayerEquipmentPacket() PlayerEquipmentPacket()
{ {
} }
PlayerEquipmentPacket(int entityId, int itemId, int data) PlayerEquipmentPacket(int entityId, int itemId, int data, int selSlot, int invSlot)
: entityId(entityId), : entityId(entityId),
itemId(itemId), itemId(itemId),
itemAuxValue(data) itemAuxValue(data),
selectedSlot(selSlot),
inventorySlot(invSlot)
{ {
} }
@@ -28,6 +32,8 @@ public:
bitStream->Write(entityId); bitStream->Write(entityId);
bitStream->Write(itemId); bitStream->Write(itemId);
bitStream->Write(itemAuxValue); bitStream->Write(itemAuxValue);
bitStream->Write(selectedSlot);
bitStream->Write(inventorySlot);
} }
void read(RakNet::BitStream* bitStream) void read(RakNet::BitStream* bitStream)
@@ -35,6 +41,8 @@ public:
bitStream->Read(entityId); bitStream->Read(entityId);
bitStream->Read(itemId); bitStream->Read(itemId);
bitStream->Read(itemAuxValue); bitStream->Read(itemAuxValue);
bitStream->Read(selectedSlot);
bitStream->Read(inventorySlot);
} }
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)

View File

@@ -0,0 +1,54 @@
#ifndef NET_MINECRAFT_NETWORK_PACKET__RemoveItemPacket_H__
#define NET_MINECRAFT_NETWORK_PACKET__RemoveItemPacket_H__
//package net.minecraft.network.packet;
#include "../Packet.h"
class RemoveItemPacket: public Packet
{
public:
RemoveItemPacket() {
}
RemoveItemPacket(int playerId, int count, int auxValue, int itemId)
:
playerId(playerId),
count(count),
auxValue(auxValue),
itemId(itemId)
{
}
void write(RakNet::BitStream* bitStream)
{
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_REMOVEITEM));
bitStream->Write(itemId);
bitStream->Write(count);
bitStream->Write(auxValue);
bitStream->Write(playerId);
}
void read(RakNet::BitStream* bitStream)
{
bitStream->Read(itemId);
bitStream->Read(count);
bitStream->Read(auxValue);
bitStream->Read(playerId);
}
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
{
callback->handle(source, (RemoveItemPacket*)this);
}
int playerId;
int itemId;
int count;
int auxValue;
};
#endif /*NET_MINECRAFT_NETWORK_PACKET__RemoveItemPacket_H__*/

View File

@@ -2,13 +2,14 @@
#define NET_MINECRAFT_NETWORK_PACKET__SendInventoryPacket_H__ #define NET_MINECRAFT_NETWORK_PACKET__SendInventoryPacket_H__
#include "../Packet.h" #include "../Packet.h"
#include "world/entity/player/Inventory.h"
#include "world/inventory/FillingContainer.h"
#include <array>
class SendInventoryPacket: public Packet class SendInventoryPacket: public Packet
{ {
public: public:
SendInventoryPacket() SendInventoryPacket() {}
{
}
SendInventoryPacket(Player* player, bool dropItems) SendInventoryPacket(Player* player, bool dropItems)
: entityId(player->entityId), : entityId(player->entityId),
@@ -21,10 +22,15 @@ public:
ItemInstance* item = inv->getItem(i); ItemInstance* item = inv->getItem(i);
items.push_back(item? *item : ItemInstance()); items.push_back(item? *item : ItemInstance());
} }
for (int i = 0; i < NumArmorItems; ++i) { for (int i = 0; i < NumArmorItems; ++i) {
ItemInstance* item = player->getArmor(i); ItemInstance* item = player->getArmor(i);
items.push_back(item? *item : ItemInstance()); items.push_back(item? *item : ItemInstance());
} }
for (int i = 0; i < inv->numLinkedSlots; ++i) {
linkedSlot[i] = inv->linkedSlots[i];
}
} }
void write(RakNet::BitStream* bitStream) void write(RakNet::BitStream* bitStream)
@@ -39,6 +45,13 @@ public:
// Armor // Armor
for (int i = 0; i < NumArmorItems; ++i) for (int i = 0; i < NumArmorItems; ++i)
PacketUtil::writeItemInstance(items[i + numItems], bitStream); PacketUtil::writeItemInstance(items[i + numItems], bitStream);
int lSlots = Inventory::MAX_SELECTION_SIZE;
// Linked slots
bitStream->Write(lSlots);
for (int i = 0; i < lSlots; ++i)
bitStream->Write(linkedSlot[i]);
} }
void read(RakNet::BitStream* bitStream) void read(RakNet::BitStream* bitStream)
@@ -50,6 +63,12 @@ public:
// Inventory, Armor // Inventory, Armor
for (int i = 0; i < numItems + NumArmorItems; ++i) for (int i = 0; i < numItems + NumArmorItems; ++i)
items.push_back(PacketUtil::readItemInstance(bitStream)); items.push_back(PacketUtil::readItemInstance(bitStream));
// Linked slots
int lSlots = 0;
bitStream->Read(lSlots);
for (int i = 0; i < lSlots; ++i)
bitStream->Read(linkedSlot[i]);
} }
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
@@ -62,6 +81,8 @@ public:
short numItems; short numItems;
unsigned char extra; unsigned char extra;
std::array<FillingContainer::LinkedSlot, Inventory::MAX_SELECTION_SIZE> linkedSlot;
static const int ExtraDrop = 1; static const int ExtraDrop = 1;
static const int NumArmorItems = 4; static const int NumArmorItems = 4;
}; };

View File

@@ -2,6 +2,7 @@
#define NET_MINECRAFT_NETWORK_PACKET__StartGamePacket_H__ #define NET_MINECRAFT_NETWORK_PACKET__StartGamePacket_H__
#include "../Packet.h" #include "../Packet.h"
#include "world/level/LevelConstants.h"
#include <cstdint> #include <cstdint>
class StartGamePacket : public Packet class StartGamePacket : public Packet
@@ -14,18 +15,20 @@ public:
int entityId; int entityId;
float x, y, z; float x, y, z;
int chunkCacheWidth = 0;
StartGamePacket() StartGamePacket()
{ {
} }
StartGamePacket(long seed, int levelGeneratorVersion, int gameType, int entityId, float x, float y, float z) StartGamePacket(long seed, int levelGeneratorVersion, int gameType, int entityId, float x, float y, float z, int chunkCacheWidth)
: levelSeed((int32_t)seed), : levelSeed((int32_t)seed),
levelGeneratorVersion(levelGeneratorVersion), levelGeneratorVersion(levelGeneratorVersion),
gameType(gameType), gameType(gameType),
entityId(entityId), entityId(entityId),
x(x), x(x),
y(y), y(y),
z(z) z(z),
chunkCacheWidth(chunkCacheWidth)
{ {
} }
@@ -40,6 +43,7 @@ public:
bitStream->Write(x); bitStream->Write(x);
bitStream->Write(y); bitStream->Write(y);
bitStream->Write(z); bitStream->Write(z);
bitStream->Write(LevelConstants::CHUNK_CACHE_WIDTH);
} }
void read(RakNet::BitStream* bitStream) void read(RakNet::BitStream* bitStream)
@@ -51,6 +55,10 @@ public:
bitStream->Read(x); bitStream->Read(x);
bitStream->Read(y); bitStream->Read(y);
bitStream->Read(z); bitStream->Read(z);
if (bitStream->GetNumberOfUnreadBits() > 0) {
bitStream->Read(chunkCacheWidth);
}
} }
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)

View File

@@ -0,0 +1,54 @@
#ifndef NET_MINECRAFT_NETWORK_PACKET__TakeItemPacket_H__
#define NET_MINECRAFT_NETWORK_PACKET__TakeItemPacket_H__
//package net.minecraft.network.packet;
#include "../Packet.h"
class TakeItemPacket: public Packet
{
public:
TakeItemPacket() {
}
TakeItemPacket(int playerId, int count, int auxValue, int itemId)
:
playerId(playerId),
count(count),
auxValue(auxValue),
itemId(itemId)
{
}
void write(RakNet::BitStream* bitStream)
{
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_TAKEITEM));
bitStream->Write(itemId);
bitStream->Write(count);
bitStream->Write(auxValue);
bitStream->Write(playerId);
}
void read(RakNet::BitStream* bitStream)
{
bitStream->Read(itemId);
bitStream->Read(count);
bitStream->Read(auxValue);
bitStream->Read(playerId);
}
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
{
callback->handle(source, (TakeItemPacket*)this);
}
int playerId;
int itemId;
int count;
int auxValue;
};
#endif /*NET_MINECRAFT_NETWORK_PACKET__TakeItemPacket_H__*/

View File

@@ -16,10 +16,14 @@ public:
short itemId; short itemId;
unsigned char itemData; unsigned char itemData;
ItemInstance item; ItemInstance item;
float playerX, playerY, playerZ;
float playerX0, playerY0, playerZ0;
float playerX1, playerY1, playerZ1;
UseItemPacket() {} UseItemPacket() {}
UseItemPacket(int x, int y, int z, int face, const ItemInstance* item, int entityId, float clickX, float clickY, float clickZ) UseItemPacket(int x, int y, int z, int face, const ItemInstance* item, int entityId, float clickX, float clickY, float clickZ,
float plrX, float plrY, float plrZ, float plrX0, float plrY0, float plrZ0, float plrX1, float plrY1, float plrZ1)
: x(x), : x(x),
y(y), y(y),
z(z), z(z),
@@ -29,17 +33,36 @@ public:
entityId(entityId), entityId(entityId),
clickX(clickX), clickX(clickX),
clickY(clickY), clickY(clickY),
clickZ(clickZ) clickZ(clickZ),
playerX(plrX),
playerY(plrY),
playerZ(plrZ),
playerX0(plrX0),
playerY0(plrY0),
playerZ0(plrZ0),
playerX1(plrX1),
playerY1(plrY1),
playerZ1(plrZ1)
{} {}
UseItemPacket(const ItemInstance* item, int entityId, const Vec3& aim) UseItemPacket(const ItemInstance* item, int entityId, const Vec3& aim, float plrX, float plrY, float plrZ,
float plrX0, float plrY0, float plrZ0, float plrX1, float plrY1, float plrZ1)
: face(255), : face(255),
itemId(item? item->id : 0), itemId(item? item->id : 0),
itemData(item? item->getAuxValue() : 0), itemData(item? item->getAuxValue() : 0),
entityId(entityId), entityId(entityId),
x((int)(aim.x * 32768.0f)), x((int)(aim.x * 32768.0f)),
y((int)(aim.y * 32768.0f)), y((int)(aim.y * 32768.0f)),
z((int)(aim.z * 32768.0f)) z((int)(aim.z * 32768.0f)),
playerX(plrX),
playerY(plrY),
playerZ(plrZ),
playerX0(plrX0),
playerY0(plrY0),
playerZ0(plrZ0),
playerX1(plrX1),
playerY1(plrY1),
playerZ1(plrZ1)
{ {
} }
@@ -57,6 +80,15 @@ public:
bitStream->Write(clickX); bitStream->Write(clickX);
bitStream->Write(clickY); bitStream->Write(clickY);
bitStream->Write(clickZ); bitStream->Write(clickZ);
bitStream->Write(playerX);
bitStream->Write(playerY);
bitStream->Write(playerZ);
bitStream->Write(playerX0);
bitStream->Write(playerY0);
bitStream->Write(playerZ0);
bitStream->Write(playerX1);
bitStream->Write(playerY1);
bitStream->Write(playerZ1);
} }
void read(RakNet::BitStream* bitStream) void read(RakNet::BitStream* bitStream)
@@ -74,7 +106,15 @@ public:
item.id = itemId; item.id = itemId;
item.setAuxValue(itemData); item.setAuxValue(itemData);
item.count = (itemId == 0 && itemData == 0)? 0 : 1; item.count = (itemId == 0 && itemData == 0)? 0 : 1;
bitStream->Read(playerX);
bitStream->Read(playerY);
bitStream->Read(playerZ);
bitStream->Read(playerX0);
bitStream->Read(playerY0);
bitStream->Read(playerZ0);
bitStream->Read(playerX1);
bitStream->Read(playerY1);
bitStream->Read(playerZ1);
} }
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)

View File

@@ -0,0 +1,54 @@
#ifndef NET_MINECRAFT_NETWORK_PACKET__WantCreatePacket_H__
#define NET_MINECRAFT_NETWORK_PACKET__WantCreatePacket_H__
//package net.minecraft.network.packet;
#include "../Packet.h"
class WantCreatePacket: public Packet
{
public:
WantCreatePacket() {
}
WantCreatePacket(int playerId, int count, int auxValue, int itemId)
:
playerId(playerId),
count(count),
auxValue(auxValue),
itemId(itemId)
{
}
void write(RakNet::BitStream* bitStream)
{
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_WANTCREATEITEM));
bitStream->Write(itemId);
bitStream->Write(count);
bitStream->Write(auxValue);
bitStream->Write(playerId);
}
void read(RakNet::BitStream* bitStream)
{
bitStream->Read(itemId);
bitStream->Read(count);
bitStream->Read(auxValue);
bitStream->Read(playerId);
}
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
{
callback->handle(source, (WantCreatePacket*)this);
}
int playerId;
int itemId;
int count;
int auxValue;
};
#endif /*NET_MINECRAFT_NETWORK_PACKET__WantCreatePacket_H__*/

View File

@@ -31,13 +31,6 @@
pthread_attr_init(&m_attributes); pthread_attr_init(&m_attributes);
pthread_attr_setdetachstate( &m_attributes, PTHREAD_CREATE_DETACHED ); pthread_attr_setdetachstate( &m_attributes, PTHREAD_CREATE_DETACHED );
/*int error =*/ pthread_create(&m_thread, &m_attributes, mp_threadFunc, threadParam); /*int error =*/ pthread_create(&m_thread, &m_attributes, mp_threadFunc, threadParam);
#endif
#if defined(__HAIKU__)
mp_threadFunc = (thread_func)threadFunc;
m_thread = spawn_thread(mp_threadFunc, "CThread", 10, threadParam);
int res = resume_thread(m_thread);
#endif #endif
#ifdef MACOSX #ifdef MACOSX
mp_threadFunc = (TaskProc) threadFunc; mp_threadFunc = (TaskProc) threadFunc;
@@ -63,9 +56,6 @@
#if defined(LINUX) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX) #if defined(LINUX) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX)
usleep(millis * 1000); usleep(millis * 1000);
#endif #endif
#if defined(__HAIKU__)
snooze((bigtime_t)(millis * 1000));
#endif
} }
CThread::~CThread() CThread::~CThread()
@@ -78,9 +68,6 @@
// and causes SIGABRT when the pthread_t is no longer valid. // and causes SIGABRT when the pthread_t is no longer valid.
pthread_attr_destroy(&m_attributes); pthread_attr_destroy(&m_attributes);
#endif #endif
#if defined(__HAIKU__)
kill_thread(m_thread);
#endif
} }

Some files were not shown because too many files have changed in this diff Show More