diff options
-rw-r--r-- | CONTRIBUTING.md | 6 | ||||
-rw-r--r-- | CONTRIBUTORS | 11 | ||||
-rw-r--r-- | LICENSE | 9 | ||||
-rw-r--r-- | README.md | 18 | ||||
-rw-r--r-- | Server/Plugins/APIDump/APIDesc.lua | 44 | ||||
-rw-r--r-- | Server/Plugins/APIDump/Classes/Plugins.lua | 4 | ||||
-rw-r--r-- | Server/Plugins/APIDump/Classes/World.lua | 88 | ||||
-rw-r--r-- | Server/Plugins/APIDump/Hooks/OnPlayerOpeningWindow.lua | 20 | ||||
-rw-r--r-- | Server/Plugins/APIDump/InfoFile.html | 28 | ||||
-rw-r--r-- | Server/Plugins/APIDump/main_APIDump.lua | 2 | ||||
-rw-r--r-- | Server/Plugins/InfoDump.lua | 8 | ||||
-rw-r--r-- | Server/Plugins/TestLuaRocks/TestLuaRocks.lua | 24 | ||||
-rw-r--r-- | dev-docs/.gitignore (renamed from docs/.gitignore) | 0 | ||||
-rw-r--r-- | dev-docs/API class inheritance - blockentities.gv (renamed from docs/API class inheritance - blockentities.gv) | 0 | ||||
-rw-r--r-- | dev-docs/API class inheritance - entities.gv (renamed from docs/API class inheritance - entities.gv) | 0 | ||||
-rw-r--r-- | dev-docs/Cubeset file format.html (renamed from docs/Cubeset file format.html) | 0 | ||||
-rw-r--r-- | dev-docs/Generator.html (renamed from docs/Generator.html) | 0 | ||||
-rw-r--r-- | dev-docs/Login sequence.txt (renamed from docs/Login sequence.txt) | 0 | ||||
-rw-r--r-- | dev-docs/NBT Examples/single chunk NBT data.txt (renamed from docs/NBT Examples/single chunk NBT data.txt) | 0 | ||||
-rw-r--r-- | dev-docs/NBT Examples/tile entities.txt (renamed from docs/NBT Examples/tile entities.txt) | 0 | ||||
-rw-r--r-- | dev-docs/Object ownership.gv (renamed from docs/Object ownership.gv) | 0 | ||||
-rw-r--r-- | dev-docs/Plugin API.md | 3 | ||||
-rw-r--r-- | dev-docs/SocketThreads states.gv (renamed from docs/SocketThreads states.gv) | 0 | ||||
-rw-r--r-- | dev-docs/Springs.ods (renamed from docs/Springs.ods) | bin | 27173 -> 27173 bytes | |||
-rw-r--r-- | dev-docs/_files.txt (renamed from docs/_files.txt) | 0 | ||||
-rw-r--r-- | dev-docs/img/biomalheights.jpg (renamed from docs/img/biomalheights.jpg) | bin | 77747 -> 77747 bytes | |||
-rw-r--r-- | dev-docs/img/biomeheights.jpg (renamed from docs/img/biomeheights.jpg) | bin | 16432 -> 16432 bytes | |||
-rw-r--r-- | dev-docs/img/biomeheightsavg.jpg (renamed from docs/img/biomeheightsavg.jpg) | bin | 14946 -> 14946 bytes | |||
-rw-r--r-- | dev-docs/img/biomes.jpg (renamed from docs/img/biomes.jpg) | bin | 12833 -> 12833 bytes | |||
-rw-r--r-- | dev-docs/img/densitymap.jpg (renamed from docs/img/densitymap.jpg) | bin | 29301 -> 29301 bytes | |||
-rw-r--r-- | dev-docs/img/distortedvoronoibiomes.png (renamed from docs/img/distortedvoronoibiomes.png) | bin | 6012 -> 6012 bytes | |||
-rw-r--r-- | dev-docs/img/finishers.jpg (renamed from docs/img/finishers.jpg) | bin | 14701 -> 14701 bytes | |||
-rw-r--r-- | dev-docs/img/gaussprobability.jpg (renamed from docs/img/gaussprobability.jpg) | bin | 12994 -> 12994 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_add_islands.png (renamed from docs/img/grownexample_add_islands.png) | bin | 1707 -> 1707 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_alt_biomes.png (renamed from docs/img/grownexample_alt_biomes.png) | bin | 1760 -> 1760 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_beaches.png (renamed from docs/img/grownexample_beaches.png) | bin | 1615 -> 1615 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_biome_edges.png (renamed from docs/img/grownexample_biome_edges.png) | bin | 1497 -> 1497 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_biomes.png (renamed from docs/img/grownexample_biomes.png) | bin | 1703 -> 1703 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_grp_edges.png (renamed from docs/img/grownexample_grp_edges.png) | bin | 1457 -> 1457 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_in1.png (renamed from docs/img/grownexample_in1.png) | bin | 1477 -> 1477 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_in2.png (renamed from docs/img/grownexample_in2.png) | bin | 1274 -> 1274 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_in3.png (renamed from docs/img/grownexample_in3.png) | bin | 1532 -> 1532 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_in_alt.png (renamed from docs/img/grownexample_in_alt.png) | bin | 1476 -> 1476 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_in_river.png (renamed from docs/img/grownexample_in_river.png) | bin | 1169 -> 1169 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_m_biomes.png (renamed from docs/img/grownexample_m_biomes.png) | bin | 1842 -> 1842 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_mix_river.png (renamed from docs/img/grownexample_mix_river.png) | bin | 1586 -> 1586 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_river.png (renamed from docs/img/grownexample_river.png) | bin | 1202 -> 1202 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_set_rnd.png (renamed from docs/img/grownexample_set_rnd.png) | bin | 1616 -> 1616 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_smooth.png (renamed from docs/img/grownexample_smooth.png) | bin | 1449 -> 1449 bytes | |||
-rw-r--r-- | dev-docs/img/grownexample_zoom.png (renamed from docs/img/grownexample_zoom.png) | bin | 2167 -> 2167 bytes | |||
-rw-r--r-- | dev-docs/img/heightmap.jpg (renamed from docs/img/heightmap.jpg) | bin | 27951 -> 27951 bytes | |||
-rw-r--r-- | dev-docs/img/jittergrid.jpg (renamed from docs/img/jittergrid.jpg) | bin | 18522 -> 18522 bytes | |||
-rw-r--r-- | dev-docs/img/jittergridlocality.jpg (renamed from docs/img/jittergridlocality.jpg) | bin | 15026 -> 15026 bytes | |||
-rw-r--r-- | dev-docs/img/multistepmapbiomes.png (renamed from docs/img/multistepmapbiomes.png) | bin | 11103 -> 11103 bytes | |||
-rw-r--r-- | dev-docs/img/multistepmapdistance.jpg (renamed from docs/img/multistepmapdistance.jpg) | bin | 16536 -> 16536 bytes | |||
-rw-r--r-- | dev-docs/img/multistepmapgrid.jpg (renamed from docs/img/multistepmapgrid.jpg) | bin | 22910 -> 22910 bytes | |||
-rw-r--r-- | dev-docs/img/perlin.jpg (renamed from docs/img/perlin.jpg) | bin | 24105 -> 24105 bytes | |||
-rw-r--r-- | dev-docs/img/perlincompositor1.jpg (renamed from docs/img/perlincompositor1.jpg) | bin | 15457 -> 15457 bytes | |||
-rw-r--r-- | dev-docs/img/perlincompositor2.jpg (renamed from docs/img/perlincompositor2.jpg) | bin | 29005 -> 29005 bytes | |||
-rw-r--r-- | dev-docs/img/perlincompositor3.jpg (renamed from docs/img/perlincompositor3.jpg) | bin | 21119 -> 21119 bytes | |||
-rw-r--r-- | dev-docs/img/perlinheightmap.jpg (renamed from docs/img/perlinheightmap.jpg) | bin | 53543 -> 53543 bytes | |||
-rw-r--r-- | dev-docs/img/perlinrivers1.jpg (renamed from docs/img/perlinrivers1.jpg) | bin | 20688 -> 20688 bytes | |||
-rw-r--r-- | dev-docs/img/perlinrivers2.jpg (renamed from docs/img/perlinrivers2.jpg) | bin | 28926 -> 28926 bytes | |||
-rw-r--r-- | dev-docs/img/perlinrivers3.jpg (renamed from docs/img/perlinrivers3.jpg) | bin | 28791 -> 28791 bytes | |||
-rw-r--r-- | dev-docs/img/roofprobability.jpg (renamed from docs/img/roofprobability.jpg) | bin | 16679 -> 16679 bytes | |||
-rw-r--r-- | dev-docs/img/smallfoliageclumps.jpg (renamed from docs/img/smallfoliageclumps.jpg) | bin | 15867 -> 15867 bytes | |||
-rw-r--r-- | dev-docs/img/smoothedgrown_1.png (renamed from docs/img/smoothedgrown_1.png) | bin | 2082 -> 2082 bytes | |||
-rw-r--r-- | dev-docs/img/smoothedgrown_2.png (renamed from docs/img/smoothedgrown_2.png) | bin | 1815 -> 1815 bytes | |||
-rw-r--r-- | dev-docs/img/smoothedgrown_3.png (renamed from docs/img/smoothedgrown_3.png) | bin | 1701 -> 1701 bytes | |||
-rw-r--r-- | dev-docs/img/smoothedgrown_4.png (renamed from docs/img/smoothedgrown_4.png) | bin | 1571 -> 1571 bytes | |||
-rw-r--r-- | dev-docs/img/smoothedgrown_5.png (renamed from docs/img/smoothedgrown_5.png) | bin | 1537 -> 1537 bytes | |||
-rw-r--r-- | dev-docs/img/smoothedgrown_6.png (renamed from docs/img/smoothedgrown_6.png) | bin | 1546 -> 1546 bytes | |||
-rw-r--r-- | dev-docs/img/smoothedgrown_7.png (renamed from docs/img/smoothedgrown_7.png) | bin | 1363 -> 1363 bytes | |||
-rw-r--r-- | dev-docs/img/temperaturehumiditydecisionhills.jpg (renamed from docs/img/temperaturehumiditydecisionhills.jpg) | bin | 32979 -> 32979 bytes | |||
-rw-r--r-- | dev-docs/img/temperaturehumiditydecisionsimple.jpg (renamed from docs/img/temperaturehumiditydecisionsimple.jpg) | bin | 18201 -> 18201 bytes | |||
-rw-r--r-- | dev-docs/img/terraincomposition.jpg (renamed from docs/img/terraincomposition.jpg) | bin | 15748 -> 15748 bytes | |||
-rw-r--r-- | dev-docs/img/terrainheight.jpg (renamed from docs/img/terrainheight.jpg) | bin | 11009 -> 11009 bytes | |||
-rw-r--r-- | dev-docs/img/twolevelbiomes.png (renamed from docs/img/twolevelbiomes.png) | bin | 33816 -> 33816 bytes | |||
-rw-r--r-- | dev-docs/img/twolevellargeareas.jpg (renamed from docs/img/twolevellargeareas.jpg) | bin | 17419 -> 17419 bytes | |||
-rw-r--r-- | dev-docs/img/twolevelsmallareas.jpg (renamed from docs/img/twolevelsmallareas.jpg) | bin | 23550 -> 23550 bytes | |||
-rw-r--r-- | dev-docs/img/twolevelsmallgrid.jpg (renamed from docs/img/twolevelsmallgrid.jpg) | bin | 39141 -> 39141 bytes | |||
-rw-r--r-- | dev-docs/img/vanilla_springs_huge.png (renamed from docs/img/vanilla_springs_huge.png) | bin | 29827 -> 29827 bytes | |||
-rw-r--r-- | dev-docs/img/voronoi.png (renamed from docs/img/voronoi.png) | bin | 19306 -> 19306 bytes | |||
-rw-r--r-- | dev-docs/img/voronoijitterbiomes.png (renamed from docs/img/voronoijitterbiomes.png) | bin | 4268 -> 4268 bytes | |||
-rw-r--r-- | dev-docs/img/zoomedgrown_1.png (renamed from docs/img/zoomedgrown_1.png) | bin | 817 -> 817 bytes | |||
-rw-r--r-- | dev-docs/img/zoomedgrown_2.png (renamed from docs/img/zoomedgrown_2.png) | bin | 880 -> 880 bytes | |||
-rw-r--r-- | dev-docs/img/zoomedgrown_3.png (renamed from docs/img/zoomedgrown_3.png) | bin | 955 -> 955 bytes | |||
-rw-r--r-- | dev-docs/img/zoomedgrown_4.png (renamed from docs/img/zoomedgrown_4.png) | bin | 1116 -> 1116 bytes | |||
-rw-r--r-- | dev-docs/img/zoomedgrown_5.png (renamed from docs/img/zoomedgrown_5.png) | bin | 1516 -> 1516 bytes | |||
-rw-r--r-- | dev-docs/img/zoomedgrown_6.png (renamed from docs/img/zoomedgrown_6.png) | bin | 2033 -> 2033 bytes | |||
-rw-r--r-- | dev-docs/img/zoomedgrown_7.png (renamed from docs/img/zoomedgrown_7.png) | bin | 2978 -> 2978 bytes | |||
-rw-r--r-- | dev-docs/js/ValueMap.js (renamed from docs/js/ValueMap.js) | 0 | ||||
-rw-r--r-- | dev-docs/js/grown.js (renamed from docs/js/grown.js) | 0 | ||||
-rw-r--r-- | dev-docs/style.css (renamed from docs/style.css) | 0 | ||||
-rw-r--r-- | src/Bindings/DeprecatedBindings.cpp | 61 | ||||
-rw-r--r-- | src/Bindings/DiffAPIDesc.lua | 11 | ||||
-rw-r--r-- | src/Bindings/LuaState.cpp | 11 | ||||
-rw-r--r-- | src/Bindings/LuaState.h | 1 | ||||
-rw-r--r-- | src/Bindings/LuaWindow.cpp | 36 | ||||
-rw-r--r-- | src/Bindings/LuaWindow.h | 12 | ||||
-rw-r--r-- | src/Bindings/ManualBindings.cpp | 1 | ||||
-rw-r--r-- | src/Bindings/Plugin.h | 1 | ||||
-rw-r--r-- | src/Bindings/PluginLua.cpp | 10 | ||||
-rw-r--r-- | src/Bindings/PluginLua.h | 1 | ||||
-rw-r--r-- | src/Bindings/PluginManager.cpp | 19 | ||||
-rw-r--r-- | src/Bindings/PluginManager.h | 3 | ||||
-rw-r--r-- | src/BlockArea.cpp | 4 | ||||
-rw-r--r-- | src/BlockEntities/ChestEntity.cpp | 26 | ||||
-rw-r--r-- | src/BlockEntities/EnderChestEntity.cpp | 10 | ||||
-rw-r--r-- | src/BlockInServerPluginInterface.h | 3 | ||||
-rw-r--r-- | src/BlockInfo.h | 5 | ||||
-rw-r--r-- | src/Blocks/BlockBed.h | 2 | ||||
-rw-r--r-- | src/Blocks/BlockButton.h | 4 | ||||
-rw-r--r-- | src/Blocks/BlockHandler.cpp | 2 | ||||
-rw-r--r-- | src/Blocks/BlockLever.h | 2 | ||||
-rw-r--r-- | src/Blocks/BlockVine.h | 2 | ||||
-rw-r--r-- | src/Blocks/WorldInterface.h | 10 | ||||
-rw-r--r-- | src/BoundingBox.cpp | 20 | ||||
-rw-r--r-- | src/BoundingBox.h | 24 | ||||
-rw-r--r-- | src/Chunk.cpp | 11 | ||||
-rw-r--r-- | src/ChunkDef.h | 64 | ||||
-rw-r--r-- | src/ChunkMap.cpp | 22 | ||||
-rw-r--r-- | src/ChunkMap.h | 17 | ||||
-rw-r--r-- | src/ClientHandle.h | 2 | ||||
-rw-r--r-- | src/Cuboid.cpp | 40 | ||||
-rw-r--r-- | src/Cuboid.h | 42 | ||||
-rw-r--r-- | src/Entities/ArrowEntity.cpp | 18 | ||||
-rw-r--r-- | src/Entities/Entity.cpp | 32 | ||||
-rw-r--r-- | src/Entities/Player.cpp | 6 | ||||
-rw-r--r-- | src/Entities/SplashPotionEntity.h | 4 | ||||
-rw-r--r-- | src/Generating/Prefab.cpp | 4 | ||||
-rw-r--r-- | src/Generating/VillageGen.cpp | 5 | ||||
-rw-r--r-- | src/Items/ItemHandler.h | 2 | ||||
-rw-r--r-- | src/MobSpawner.h | 6 | ||||
-rw-r--r-- | src/Mobs/Monster.h | 2 | ||||
-rw-r--r-- | src/Mobs/Ocelot.cpp | 28 | ||||
-rw-r--r-- | src/Mobs/Ocelot.h | 3 | ||||
-rw-r--r-- | src/Mobs/Wolf.h | 2 | ||||
-rw-r--r-- | src/Protocol/Packetizer.h | 5 | ||||
-rw-r--r-- | src/Protocol/Protocol.h | 2 | ||||
-rw-r--r-- | src/Protocol/ProtocolRecognizer.cpp | 6 | ||||
-rw-r--r-- | src/Protocol/ProtocolRecognizer.h | 7 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_12.cpp | 759 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_12.h | 59 | ||||
-rw-r--r-- | src/Simulator/DelayedFluidSimulator.cpp | 12 | ||||
-rw-r--r-- | src/Simulator/DelayedFluidSimulator.h | 2 | ||||
-rw-r--r-- | src/Simulator/FireSimulator.cpp | 14 | ||||
-rw-r--r-- | src/Simulator/FireSimulator.h | 2 | ||||
-rw-r--r-- | src/Simulator/FloodyFluidSimulator.cpp | 2 | ||||
-rw-r--r-- | src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h | 4 | ||||
-rw-r--r-- | src/Simulator/NoopFluidSimulator.h | 6 | ||||
-rw-r--r-- | src/Simulator/NoopRedstoneSimulator.h | 6 | ||||
-rw-r--r-- | src/Simulator/RedstoneSimulator.h | 2 | ||||
-rw-r--r-- | src/Simulator/SandSimulator.cpp | 12 | ||||
-rw-r--r-- | src/Simulator/SandSimulator.h | 2 | ||||
-rw-r--r-- | src/Simulator/Simulator.cpp | 31 | ||||
-rw-r--r-- | src/Simulator/Simulator.h | 4 | ||||
-rw-r--r-- | src/Simulator/SimulatorManager.cpp | 4 | ||||
-rw-r--r-- | src/Simulator/SimulatorManager.h | 2 | ||||
-rw-r--r-- | src/Simulator/VaporizeFluidSimulator.cpp | 16 | ||||
-rw-r--r-- | src/Simulator/VaporizeFluidSimulator.h | 2 | ||||
-rw-r--r-- | src/UI/ChestWindow.cpp | 8 | ||||
-rw-r--r-- | src/UI/SlotArea.h | 3 | ||||
-rw-r--r-- | src/UI/Window.h | 2 | ||||
-rw-r--r-- | src/World.cpp | 18 | ||||
-rw-r--r-- | src/World.h | 26 | ||||
-rwxr-xr-x | src/WorldStorage/WSSAnvil.h | 3 |
167 files changed, 1496 insertions, 381 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4cd96afdd..ad10f1e69 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,6 +21,12 @@ Here are the conventions: - `ThisIsAProperFunction()` `This_is_bad()` `this_is_bad()` `GoodVariableName` `badVariableName`. * All member variables start with `m_`, all function parameters start with `a_`, all class names start with `c`. - `class cMonster { int m_Health; int DecreaseHealth(int a_Amount); }` + * Function parameters that are coordinates should be passed using an appropriate storage container, and not as three separate arguments. + - e.g. for a block position, Vector3i. For an entity position, Vector3d. For a chunk coordinate, cChunkCoords. + - For a 3-dimensional box of blocks, use cCuboid. For an axis-aligned bounding box, use cBoundingBox. + * Parameters smaller than 4 elements (e.g. Vector3, cChunkCoords) should be passed by value. All other parameters should be passed by const reference, where applicable. + - `Foo(Vector3d a_Param1, const cCuboid & a_Param2)` + - See the discussion in issue #3853 * Put spaces after commas. `Vector3d(1, 2, 3)` instead of `Vector3d(1,2,3)` * Put spaces before and after every operator. - `a = b + c;` diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 0cf95af2a..2b3c877d9 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1,4 +1,9 @@ -Many people have contributed to Cuberite, and this list attempts to broadcast at least some of them. +This file contains all known copyright holders of this software, as far as is +practically possible to ascertain. + +If you contribute to this software you must add yourself to this file, to +indicate your agreement to license your contributions according to the license +as provided in the LICENSE file. Altenius BasedDoge (Donated AlchemistVillage prefabs) @@ -50,9 +55,7 @@ tonibm19 UltraCoderRU Warmist WebFreak001 +williamhatcher (Helped with API documentation updates and bug fixes) worktycho xoft (Mattes Dolak/madmaxoft on GH) Yeeeeezus (Donated AlchemistVillage prefabs) - -Please add yourself to this list if you contribute to the official Cuberite project -and license your work under the Apache License 2.0 @@ -1,7 +1,10 @@ Cuberite: A lightweight, fast and extensible game server for Minecraft -www: https://github.com/cuberite/cuberite - -Copyright 2011-2016 Cuberite Team +www: https://cuberite.org + +Copyright 2011-2017 Cuberite Contributors + +A full list of known copyright holders can be found in the CONTRIBUTORS file +to be distributed with all copies of this software. ------ @@ -5,7 +5,7 @@ Cuberite is a Minecraft-compatible multiplayer game server that is written in C+ Cuberite can run on Windows, *nix and Android operating systems. This includes Android phones and tablets as well as Raspberry Pis. -We currently support Release 1.8 - 1.12 Minecraft protocol versions. +We currently support Release 1.8 - 1.12.1 Minecraft protocol versions. Subscribe to [the newsletter](https://cuberite.org/news/#subscribe) for important updates and project news. @@ -15,18 +15,21 @@ Installation There are several ways to obtain Cuberite. #### Binaries - - The easiest method is downloading for Windows or Linux from the [Project site](https://cuberite.org/). - - You can use the EasyInstall script for Linux and macOS, which automatically downloads the correct binary. The script is described below. - - You can also obtain a binary from the [buildserver archive](https://builds.cuberite.org/). + +- The easiest method is downloading for Windows or Linux from the [Project site](https://cuberite.org/). +- You can use the EasyInstall script for Linux and macOS, which automatically downloads the correct binary. The script is described below. +- You can also obtain a binary from the [buildserver archive](https://builds.cuberite.org/). ##### The EasyInstall script + This script will download the correct binary from the project site. curl -sSfL https://download.cuberite.org | sh #### Compiling - - You can compile automatically for Linux / *nix with the `compile.sh` script. The script is described below. - - You can also compile manually. See [COMPILING.md](https://github.com/cuberite/cuberite/blob/master/COMPILING.md). + +- You can compile automatically for Linux / *nix with the `compile.sh` script. The script is described below. +- You can also compile manually. See [COMPILING.md](https://github.com/cuberite/cuberite/blob/master/COMPILING.md). Compiling may provide better performance (1.5-3x as fast) and it supports more operating systems. @@ -36,7 +39,8 @@ This script downloads the source code and compiles it. The script is smart enoug sh -c "$(wget -O - https://compile.cuberite.org)" #### Hosted services - - Hosted Cuberite is available via [Gamocosm](https://gamocosm.com/). + +- Hosted Cuberite is available via [Gamocosm](https://gamocosm.com/). Contributing ------------ diff --git a/Server/Plugins/APIDump/APIDesc.lua b/Server/Plugins/APIDump/APIDesc.lua index 9e920d429..38340d0f3 100644 --- a/Server/Plugins/APIDump/APIDesc.lua +++ b/Server/Plugins/APIDump/APIDesc.lua @@ -202,7 +202,7 @@ return Type = "string", }, }, - Notes = "Returns the name of the sound that is played when placing the block of this type.", + Notes = "(<b>DEPRECATED</b>) Not used by cuberite internally and always returns an empty string.", }, GetSpreadLightFalloff = { @@ -378,16 +378,6 @@ return Type = "bool", Notes = "Can a piston break this block?", }, - m_PlaceSound = - { - Type = "string", - Notes = "The name of the sound that is placed when a block is placed.", - }, - m_RequiresSpecialTool = - { - Type = "bool", - Notes = "Does this block require a tool to drop?", - }, m_SpreadLightFalloff = { Type = "number", @@ -8039,6 +8029,17 @@ This class is used by plugins wishing to display a custom window to the player, }, Notes = "Returns the cItemGrid object representing the internal storage in this window", }, + SetOnClicked = + { + Params = + { + { + Name = "OnClickedCallback", + Type = "function", + }, + }, + Notes = "Sets the function that the window will call when it is about to process a click from a player. See {{#additionalinfo_1|below}} for the signature of the callback function.", + }, SetOnClosing = { Params = @@ -8071,6 +8072,17 @@ This class is used by plugins wishing to display a custom window to the player, ]], }, { + Header = "OnClicked Callback", + Contents = [[ + This callback, settable via the SetOnClicked() function, will be called when the player clicks a slot in the window. The callback can cancel the click.</p> +<pre class="prettyprint lang-lua"> +function OnWindowClicked(a_Window, a_Player, a_SlotNum, a_ClickAction, a_ClickedItem) +</pre> + <p> + The a_Window parameter is the cLuaWindow object representing the window, a_Player is the player who made the click, a_SlotNum is the slot the player clicked, a_ClickAction is the type of click the player made, and a_ClickedItem is the item the player clicked on, if applicable. If the function returns true, the click is cancelled (internally, the server resends the window slots to the player to keep the player in sync). + ]], + }, + { Header = "OnClosing Callback", Contents = [[ This callback, settable via the SetOnClosing() function, will be called when the player tries to close the window, or the window is closed for any other reason (such as a player disconnecting).</p> @@ -8096,7 +8108,7 @@ function OnWindowSlotChanged(a_Window, a_SlotNum) { Header = "Example", Contents = [[ - This example is taken from the Debuggers plugin, used to test the API functionality. It opens a window and refuse to close it 3 times. It also logs slot changes to the server console. + This example is taken from the Debuggers plugin, used to test the API functionality. It opens a window and refuse to close it 3 times. It also logs slot changes to the server console and prevents shift-clicking in the window. <pre class="prettyprint lang-lua"> -- Callback that refuses to close the window twice, then allows: local Attempt = 1; @@ -8111,10 +8123,18 @@ local OnSlotChanged = function(Window, SlotNum) LOG("Window \"" .. Window:GetWindowTitle() .. "\" slot " .. SlotNum .. " changed."); end +-- Prevent shift-clicking: +local OnClicked = function(Window, ClickingPlayer, SlotNum, ClickAction, ClickedItem) + if ClickAction == caShiftLeftClick then + return true + end +end + -- Set window contents: -- a_Player is a cPlayer object received from the outside of this code fragment local Window = cLuaWindow(cWindow.wtHopper, 3, 3, "TestWnd"); Window:SetSlot(a_Player, 0, cItem(E_ITEM_DIAMOND, 64)); +Window:SetOnClicked(OnClicked); Window:SetOnClosing(OnClosing); Window:SetOnSlotChanged(OnSlotChanged); diff --git a/Server/Plugins/APIDump/Classes/Plugins.lua b/Server/Plugins/APIDump/Classes/Plugins.lua index c00735412..e22f4e3a0 100644 --- a/Server/Plugins/APIDump/Classes/Plugins.lua +++ b/Server/Plugins/APIDump/Classes/Plugins.lua @@ -840,6 +840,10 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage); { Notes = "Called when the player has moved and the movement is now being applied.", }, + HOOK_PLAYER_OPENING_WINDOW = + { + Notes = "Called when the player is about to open a window. The plugin can return true to cancel the window opening.", + }, HOOK_PLAYER_PLACED_BLOCK = { Notes = "Called when the player has just placed a block", diff --git a/Server/Plugins/APIDump/Classes/World.lua b/Server/Plugins/APIDump/Classes/World.lua index e452db2ff..62d71828f 100644 --- a/Server/Plugins/APIDump/Classes/World.lua +++ b/Server/Plugins/APIDump/Classes/World.lua @@ -3353,53 +3353,77 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i }, WakeUpSimulators = { - Params = { + Params = { - Name = "BlockX", - Type = "number", - }, - { - Name = "BlockY", - Type = "number", + { + Name = "Block", + Type = "Vector3i", + }, }, + Notes = "Wakes up the simulators for the specified block.", + }, + { + Params = { - Name = "BlockZ", - Type = "number", + { + Name = "BlockX", + Type = "number", + }, + { + Name = "BlockY", + Type = "number", + }, + { + Name = "BlockZ", + Type = "number", + }, }, + Notes = "Wakes up the simulators for the specified block. (DEPRECATED, use vector-parametered version)", }, - Notes = "Wakes up the simulators for the specified block.", }, WakeUpSimulatorsInArea = { - Params = { + Params = { - Name = "MinBlockX", - Type = "number", - }, - { - Name = "MaxBlockX", - Type = "number", - }, - { - Name = "MinBlockY", - Type = "number", - }, - { - Name = "MaxBlockY", - Type = "number", - }, - { - Name = "MinBlockZ", - Type = "number", + { + Name = "Area", + Type = "cCuboid", + }, }, + Notes = "Wakes up the simulators for all the blocks in the specified area (edges inclusive).", + }, + { + Params = { - Name = "MaxBlockZ", - Type = "number", + { + Name = "MinBlockX", + Type = "number", + }, + { + Name = "MaxBlockX", + Type = "number", + }, + { + Name = "MinBlockY", + Type = "number", + }, + { + Name = "MaxBlockY", + Type = "number", + }, + { + Name = "MinBlockZ", + Type = "number", + }, + { + Name = "MaxBlockZ", + Type = "number", + }, }, + Notes = "Wakes up the simulators for all the blocks in the specified area (edges inclusive). (DEPRECATED, use vector-parametered version)", }, - Notes = "Wakes up the simulators for all the blocks in the specified area (edges inclusive).", }, }, AdditionalInfo = diff --git a/Server/Plugins/APIDump/Hooks/OnPlayerOpeningWindow.lua b/Server/Plugins/APIDump/Hooks/OnPlayerOpeningWindow.lua new file mode 100644 index 000000000..04563df89 --- /dev/null +++ b/Server/Plugins/APIDump/Hooks/OnPlayerOpeningWindow.lua @@ -0,0 +1,20 @@ +return +{ + HOOK_PLAYER_OPENING_WINDOW = + { + CalledWhen = "Called when a player is about to open a window", + DefaultFnName = "OnPlayerOpeningWindow", -- also used as pagename + Desc = [[ + This hook is called when a player is about to open a window, e.g. when they click on a chest or a furnace. + ]], + Params = + { + { Name = "Player", Type = "{{cPlayer}}", Notes = "The player who is opening the window" }, + { Name = "Window", Type = "{{cWindow}}", Notes = "The window that is being opened" }, + }, + Returns = [[ + If the function returns false or no value, the next plugin's callback is called, and finally + Cuberite will process the opening window. If the function returns true, no other callback is called for this event. + ]], + }, -- HOOK_PLAYER_OPENING_WINDOW +} diff --git a/Server/Plugins/APIDump/InfoFile.html b/Server/Plugins/APIDump/InfoFile.html index e293931f2..4b35a41be 100644 --- a/Server/Plugins/APIDump/InfoFile.html +++ b/Server/Plugins/APIDump/InfoFile.html @@ -20,6 +20,7 @@ <li><a href="#Commands">Commands table</a></li> <li><a href="#ConsoleCommands">ConsoleCommands table</a></li> <li><a href="#Permissions">Permissions table</a></li> + <li><a href="#Categories">Categories table</a></li> <li><a href="#Using">Using the file in code</a></li> <li><a href="#Examples">Examples</a></li> </ul> @@ -34,7 +35,10 @@ <p>Last, but not least, we want to make a plugin repository on the web in the future, a repository that would store plugins, their descriptions, comments. It makes sense that the centralized information can be parsed by the repository automatically, so that advanced things, such as searching for a plugin based on a command, or determining whether two plugins collide command-wise, are possible.</p> - <p>After this file format has been devised, a tool has been written that allows for an easy generation of the documentation for the plugin in various formats. It outputs the documentation in a format that is perfect for pasting into the forum. It generates documentation in a Markup format to use in README.md on GitHub and similar sites. The clever thing is that you don't need to keep all those formats in sync manually - you edit the Info.lua file and this tool will re-generate the documentation for you.</p> + <p>A tool has been written that allows for an easy generation of the documentation for the plugin in various formats. It outputs the documentation in a format that is perfect for pasting into the forum. It generates documentation in a Markup format to use in README.md on GitHub and similar sites. The clever thing is that you don't need to keep all those formats in sync manually - you edit the Info.lua file and this tool will re-generate the documentation for you. + <br> + To generate documentation for the plugin, activate the DumpInfo plugin on a cuberite server with your plugin installed, and use the webadmin interface to "Dump" the plugin information. This will create a README.md suitable for uploading to your git repo, and a forum_info.txt, which can be copy-pasted into a forum post. + </p> <p>So to sum up, the Info.lua file contains the plugins' commands, console commands, their permissions and possibly the overall plugin documentation, in a structured manner that can be parsed by a program, yet is human readable and editable.</p> @@ -56,6 +60,7 @@ g_PluginInfo = Commands = {}, ConsoleCommands = {}, Permissions = {}, + Categories = {}, } </pre> <p>As you can see, the structure is pretty straightforward. Note that the order of the elements inside the table is not important (Lua property).</p> @@ -115,6 +120,7 @@ Commands = ["/cmd2"] = { Alias = {"/c2", "//c2" }, + Category = "Something", Subcommands = { sub1 = -- This declares a "/cmd2 sub1" command @@ -150,6 +156,8 @@ Commands = <p>The permission element specifies that the command is only available with the specified permission. Note that the permission for subcommand's parent isn't checked when the subcommand is called. This means that specifying the permission for a command that has subcommands has no effect whatsoever, but is discouraged because we may add processing for that in the future.</p> + <p>The optional Categories table provides descriptions for command categories in the generated documentation. The documentation generator will group the commands by their specified Category ("General" by default) and each category will have the specified description written to it.</p> + <p>The ParameterCombinations table is used only for generating the documentation, it lists the various combinations of parameters that the command supports. It's worth specifying even if the command supports only one combination, because that combination will get documented this way.</p> <p>The Alias member specifies any possible aliases for the command. Each alias is registered separately and if there is a subcommand table, it is applied to all aliases, just as one would expect. You can specify either a single string as the value (if there's only one alias), or a table of strings for multiple aliases. Commands with no aliases do not need to specify this member at all.</p> @@ -217,6 +225,24 @@ Permissions = <hr /> + <a name="Categories"><h2>Categories</h2></a> + + <p>The optional Categories table provides descriptions for categories in the generated documentation. Commands can have categories with or without category descriptions in this table. The documentation generator will output a table of listed categories along with their description.</p> +<pre class="prettyprint lang-lua"> +Categories = +{ + General = + { + Description = "A general, yet somehow vague description of the default category." + }, + Something = + { + Description = "Some descriptive words which form sentences pertaining to this set of commands use and goals." + }, +}, +</pre> + + <hr /> <a name="Using"><h2>Using the file in code</h2></a> <p>Just writing the Info.lua file and saving it to the plugin folder is not enough for it to actually be used. Your plugin needs to include the following boilerplate code, preferably in its Initialize() function:</p> diff --git a/Server/Plugins/APIDump/main_APIDump.lua b/Server/Plugins/APIDump/main_APIDump.lua index 0f1476ef7..fd243b25f 100644 --- a/Server/Plugins/APIDump/main_APIDump.lua +++ b/Server/Plugins/APIDump/main_APIDump.lua @@ -168,7 +168,7 @@ end --- Returns the timestamp in HTML format -- The timestamp will be inserted to all generated HTML files local function GetHtmlTimestamp() - return string.format("<div id='timestamp'>Generated on %s, Build ID %s, Commit %s</div>", + return string.format("<div id='timestamp'>Generated by <a href='https://github.com/cuberite/cuberite/tree/master/Server/Plugins/APIDump'>APIDump</a> on %s, Build ID %s, Commit %s</div>", os.date("%Y-%m-%d %H:%M:%S"), cRoot:GetBuildID(), cRoot:GetBuildCommitID() ) diff --git a/Server/Plugins/InfoDump.lua b/Server/Plugins/InfoDump.lua index 4dde35978..494ddd85f 100644 --- a/Server/Plugins/InfoDump.lua +++ b/Server/Plugins/InfoDump.lua @@ -306,7 +306,7 @@ local function WriteCommandsCategoryForum(a_Category, f) if (CategoryName == "") then CategoryName = "General" end - f:write("\n[size=Large]", ForumizeString(a_Category.DisplayName or CategoryName), "[/size]\n") + f:write("\n[size=large]", ForumizeString(a_Category.DisplayName or CategoryName), "[/size]\n") -- Write description: if (a_Category.Description ~= "") then @@ -377,7 +377,7 @@ local function DumpCommandsForum(a_PluginInfo, f) return end - f:write("\n[size=X-Large]Commands[/size]\n") + f:write("\n[size=x-large]Commands[/size]\n") -- Dump per-category commands: for idx, cat in ipairs(Categories) do @@ -425,7 +425,7 @@ local function DumpAdditionalInfoForum(a_PluginInfo, f) for idx, info in ipairs(a_PluginInfo.AdditionalInfo) do if ((info.Title ~= nil) and (info.Contents ~= nil)) then - f:write("\n[size=X-Large]", ForumizeString(info.Title), "[/size]\n") + f:write("\n[size=x-large]", ForumizeString(info.Title), "[/size]\n") f:write(ForumizeString(info.Contents), "\n") end end @@ -530,7 +530,7 @@ local function DumpPermissionsForum(a_PluginInfo, f) end -- Dump the permissions: - f:write("\n[size=X-Large]Permissions[/size]\n[list]\n") + f:write("\n[size=x-large]Permissions[/size]\n[list]\n") for idx, perm in ipairs(Permissions) do f:write(" - [color=red]", perm.Name, "[/color] - ") f:write(ForumizeString(perm.Info.Description or "")) diff --git a/Server/Plugins/TestLuaRocks/TestLuaRocks.lua b/Server/Plugins/TestLuaRocks/TestLuaRocks.lua index a4c2be6f8..44a545032 100644 --- a/Server/Plugins/TestLuaRocks/TestLuaRocks.lua +++ b/Server/Plugins/TestLuaRocks/TestLuaRocks.lua @@ -20,14 +20,14 @@ local http = require("socket.http"); -LOGINFO("Trying to download a webpage..."); -local body, code, headers = http.request('https://forum.cuberite.org/'); -LOG("code: " .. tostring(code)); -LOG("headers: "); +LOGINFO("Trying to download a webpage...") +local body, code, headers = http.request('https://forum.cuberite.org/') +LOG("code: " .. tostring(code)) +LOG("headers: ") for k, v in pairs(headers or {}) do - LOG(" " .. k .. ": " .. v); + LOG(" " .. k .. ": " .. v) end -LOG("body length: " .. string.len(body)); +LOG("body length: " .. string.len(body)) @@ -35,15 +35,15 @@ LOG("body length: " .. string.len(body)); function Initialize(a_Plugin) if (socket == nil) then - LOG("LuaSocket not found"); + LOGWARNING("LuaSocket not found") else - LOG("LuaSocket loaded"); + LOG("LuaSocket loaded") end if (log30 == nil) then - LOG("30log not found"); + LOGWARNING("30log not found") else - LOG("30log loaded"); + LOG("30log loaded") end - LOGINFO("Preventing plugin load so that it may be requested again from the webadmin."); - return false; + LOGINFO("Reload plugin from console or webadmin to rerun tests.") + return false end diff --git a/docs/.gitignore b/dev-docs/.gitignore index f6caf1c11..f6caf1c11 100644 --- a/docs/.gitignore +++ b/dev-docs/.gitignore diff --git a/docs/API class inheritance - blockentities.gv b/dev-docs/API class inheritance - blockentities.gv index 966588c5f..966588c5f 100644 --- a/docs/API class inheritance - blockentities.gv +++ b/dev-docs/API class inheritance - blockentities.gv diff --git a/docs/API class inheritance - entities.gv b/dev-docs/API class inheritance - entities.gv index 4e167e1d3..4e167e1d3 100644 --- a/docs/API class inheritance - entities.gv +++ b/dev-docs/API class inheritance - entities.gv diff --git a/docs/Cubeset file format.html b/dev-docs/Cubeset file format.html index 6ead2e700..6ead2e700 100644 --- a/docs/Cubeset file format.html +++ b/dev-docs/Cubeset file format.html diff --git a/docs/Generator.html b/dev-docs/Generator.html index 4d17826c1..4d17826c1 100644 --- a/docs/Generator.html +++ b/dev-docs/Generator.html diff --git a/docs/Login sequence.txt b/dev-docs/Login sequence.txt index df9d386c6..df9d386c6 100644 --- a/docs/Login sequence.txt +++ b/dev-docs/Login sequence.txt diff --git a/docs/NBT Examples/single chunk NBT data.txt b/dev-docs/NBT Examples/single chunk NBT data.txt index 905d6465c..905d6465c 100644 --- a/docs/NBT Examples/single chunk NBT data.txt +++ b/dev-docs/NBT Examples/single chunk NBT data.txt diff --git a/docs/NBT Examples/tile entities.txt b/dev-docs/NBT Examples/tile entities.txt index e16ae45a7..e16ae45a7 100644 --- a/docs/NBT Examples/tile entities.txt +++ b/dev-docs/NBT Examples/tile entities.txt diff --git a/docs/Object ownership.gv b/dev-docs/Object ownership.gv index 29e0407a6..29e0407a6 100644 --- a/docs/Object ownership.gv +++ b/dev-docs/Object ownership.gv diff --git a/dev-docs/Plugin API.md b/dev-docs/Plugin API.md new file mode 100644 index 000000000..6a0fd9a0e --- /dev/null +++ b/dev-docs/Plugin API.md @@ -0,0 +1,3 @@ +# Looking for the API documentation for Lua plugins? + +See the [cuberite website](api.cuberite.org) or browse the [source](https://github.com/cuberite/cuberite/tree/master/Server/Plugins/APIDump). diff --git a/docs/SocketThreads states.gv b/dev-docs/SocketThreads states.gv index 5afaa5370..5afaa5370 100644 --- a/docs/SocketThreads states.gv +++ b/dev-docs/SocketThreads states.gv diff --git a/docs/Springs.ods b/dev-docs/Springs.ods Binary files differindex 4b3559f1d..4b3559f1d 100644 --- a/docs/Springs.ods +++ b/dev-docs/Springs.ods diff --git a/docs/_files.txt b/dev-docs/_files.txt index 85a4253c1..85a4253c1 100644 --- a/docs/_files.txt +++ b/dev-docs/_files.txt diff --git a/docs/img/biomalheights.jpg b/dev-docs/img/biomalheights.jpg Binary files differindex a01faef87..a01faef87 100644 --- a/docs/img/biomalheights.jpg +++ b/dev-docs/img/biomalheights.jpg diff --git a/docs/img/biomeheights.jpg b/dev-docs/img/biomeheights.jpg Binary files differindex 9dda27b0e..9dda27b0e 100644 --- a/docs/img/biomeheights.jpg +++ b/dev-docs/img/biomeheights.jpg diff --git a/docs/img/biomeheightsavg.jpg b/dev-docs/img/biomeheightsavg.jpg Binary files differindex c8217cafc..c8217cafc 100644 --- a/docs/img/biomeheightsavg.jpg +++ b/dev-docs/img/biomeheightsavg.jpg diff --git a/docs/img/biomes.jpg b/dev-docs/img/biomes.jpg Binary files differindex 59c23b870..59c23b870 100644 --- a/docs/img/biomes.jpg +++ b/dev-docs/img/biomes.jpg diff --git a/docs/img/densitymap.jpg b/dev-docs/img/densitymap.jpg Binary files differindex a7a7b3f36..a7a7b3f36 100644 --- a/docs/img/densitymap.jpg +++ b/dev-docs/img/densitymap.jpg diff --git a/docs/img/distortedvoronoibiomes.png b/dev-docs/img/distortedvoronoibiomes.png Binary files differindex d56dff347..d56dff347 100644 --- a/docs/img/distortedvoronoibiomes.png +++ b/dev-docs/img/distortedvoronoibiomes.png diff --git a/docs/img/finishers.jpg b/dev-docs/img/finishers.jpg Binary files differindex 06f7485c3..06f7485c3 100644 --- a/docs/img/finishers.jpg +++ b/dev-docs/img/finishers.jpg diff --git a/docs/img/gaussprobability.jpg b/dev-docs/img/gaussprobability.jpg Binary files differindex 77da24748..77da24748 100644 --- a/docs/img/gaussprobability.jpg +++ b/dev-docs/img/gaussprobability.jpg diff --git a/docs/img/grownexample_add_islands.png b/dev-docs/img/grownexample_add_islands.png Binary files differindex f69faaaf1..f69faaaf1 100644 --- a/docs/img/grownexample_add_islands.png +++ b/dev-docs/img/grownexample_add_islands.png diff --git a/docs/img/grownexample_alt_biomes.png b/dev-docs/img/grownexample_alt_biomes.png Binary files differindex 866d774e2..866d774e2 100644 --- a/docs/img/grownexample_alt_biomes.png +++ b/dev-docs/img/grownexample_alt_biomes.png diff --git a/docs/img/grownexample_beaches.png b/dev-docs/img/grownexample_beaches.png Binary files differindex a84fb0eff..a84fb0eff 100644 --- a/docs/img/grownexample_beaches.png +++ b/dev-docs/img/grownexample_beaches.png diff --git a/docs/img/grownexample_biome_edges.png b/dev-docs/img/grownexample_biome_edges.png Binary files differindex 58de63aef..58de63aef 100644 --- a/docs/img/grownexample_biome_edges.png +++ b/dev-docs/img/grownexample_biome_edges.png diff --git a/docs/img/grownexample_biomes.png b/dev-docs/img/grownexample_biomes.png Binary files differindex ecd8af29b..ecd8af29b 100644 --- a/docs/img/grownexample_biomes.png +++ b/dev-docs/img/grownexample_biomes.png diff --git a/docs/img/grownexample_grp_edges.png b/dev-docs/img/grownexample_grp_edges.png Binary files differindex 2ac32b9a6..2ac32b9a6 100644 --- a/docs/img/grownexample_grp_edges.png +++ b/dev-docs/img/grownexample_grp_edges.png diff --git a/docs/img/grownexample_in1.png b/dev-docs/img/grownexample_in1.png Binary files differindex 2238886ab..2238886ab 100644 --- a/docs/img/grownexample_in1.png +++ b/dev-docs/img/grownexample_in1.png diff --git a/docs/img/grownexample_in2.png b/dev-docs/img/grownexample_in2.png Binary files differindex 9ef9f6ae2..9ef9f6ae2 100644 --- a/docs/img/grownexample_in2.png +++ b/dev-docs/img/grownexample_in2.png diff --git a/docs/img/grownexample_in3.png b/dev-docs/img/grownexample_in3.png Binary files differindex 95d6608b5..95d6608b5 100644 --- a/docs/img/grownexample_in3.png +++ b/dev-docs/img/grownexample_in3.png diff --git a/docs/img/grownexample_in_alt.png b/dev-docs/img/grownexample_in_alt.png Binary files differindex 59979ed62..59979ed62 100644 --- a/docs/img/grownexample_in_alt.png +++ b/dev-docs/img/grownexample_in_alt.png diff --git a/docs/img/grownexample_in_river.png b/dev-docs/img/grownexample_in_river.png Binary files differindex 58556369d..58556369d 100644 --- a/docs/img/grownexample_in_river.png +++ b/dev-docs/img/grownexample_in_river.png diff --git a/docs/img/grownexample_m_biomes.png b/dev-docs/img/grownexample_m_biomes.png Binary files differindex c3d7079ae..c3d7079ae 100644 --- a/docs/img/grownexample_m_biomes.png +++ b/dev-docs/img/grownexample_m_biomes.png diff --git a/docs/img/grownexample_mix_river.png b/dev-docs/img/grownexample_mix_river.png Binary files differindex 81899a8c7..81899a8c7 100644 --- a/docs/img/grownexample_mix_river.png +++ b/dev-docs/img/grownexample_mix_river.png diff --git a/docs/img/grownexample_river.png b/dev-docs/img/grownexample_river.png Binary files differindex cb07f44dd..cb07f44dd 100644 --- a/docs/img/grownexample_river.png +++ b/dev-docs/img/grownexample_river.png diff --git a/docs/img/grownexample_set_rnd.png b/dev-docs/img/grownexample_set_rnd.png Binary files differindex 5b7a2d254..5b7a2d254 100644 --- a/docs/img/grownexample_set_rnd.png +++ b/dev-docs/img/grownexample_set_rnd.png diff --git a/docs/img/grownexample_smooth.png b/dev-docs/img/grownexample_smooth.png Binary files differindex bfd43f6ef..bfd43f6ef 100644 --- a/docs/img/grownexample_smooth.png +++ b/dev-docs/img/grownexample_smooth.png diff --git a/docs/img/grownexample_zoom.png b/dev-docs/img/grownexample_zoom.png Binary files differindex 7afffe50b..7afffe50b 100644 --- a/docs/img/grownexample_zoom.png +++ b/dev-docs/img/grownexample_zoom.png diff --git a/docs/img/heightmap.jpg b/dev-docs/img/heightmap.jpg Binary files differindex c7eb5c865..c7eb5c865 100644 --- a/docs/img/heightmap.jpg +++ b/dev-docs/img/heightmap.jpg diff --git a/docs/img/jittergrid.jpg b/dev-docs/img/jittergrid.jpg Binary files differindex f8066aa72..f8066aa72 100644 --- a/docs/img/jittergrid.jpg +++ b/dev-docs/img/jittergrid.jpg diff --git a/docs/img/jittergridlocality.jpg b/dev-docs/img/jittergridlocality.jpg Binary files differindex 64414c878..64414c878 100644 --- a/docs/img/jittergridlocality.jpg +++ b/dev-docs/img/jittergridlocality.jpg diff --git a/docs/img/multistepmapbiomes.png b/dev-docs/img/multistepmapbiomes.png Binary files differindex d32ac3d8e..d32ac3d8e 100644 --- a/docs/img/multistepmapbiomes.png +++ b/dev-docs/img/multistepmapbiomes.png diff --git a/docs/img/multistepmapdistance.jpg b/dev-docs/img/multistepmapdistance.jpg Binary files differindex 9f7cfd11b..9f7cfd11b 100644 --- a/docs/img/multistepmapdistance.jpg +++ b/dev-docs/img/multistepmapdistance.jpg diff --git a/docs/img/multistepmapgrid.jpg b/dev-docs/img/multistepmapgrid.jpg Binary files differindex 51dd81c46..51dd81c46 100644 --- a/docs/img/multistepmapgrid.jpg +++ b/dev-docs/img/multistepmapgrid.jpg diff --git a/docs/img/perlin.jpg b/dev-docs/img/perlin.jpg Binary files differindex 499fcdeae..499fcdeae 100644 --- a/docs/img/perlin.jpg +++ b/dev-docs/img/perlin.jpg diff --git a/docs/img/perlincompositor1.jpg b/dev-docs/img/perlincompositor1.jpg Binary files differindex 0d8f93cd9..0d8f93cd9 100644 --- a/docs/img/perlincompositor1.jpg +++ b/dev-docs/img/perlincompositor1.jpg diff --git a/docs/img/perlincompositor2.jpg b/dev-docs/img/perlincompositor2.jpg Binary files differindex 11fc5b51d..11fc5b51d 100644 --- a/docs/img/perlincompositor2.jpg +++ b/dev-docs/img/perlincompositor2.jpg diff --git a/docs/img/perlincompositor3.jpg b/dev-docs/img/perlincompositor3.jpg Binary files differindex 46a2583ba..46a2583ba 100644 --- a/docs/img/perlincompositor3.jpg +++ b/dev-docs/img/perlincompositor3.jpg diff --git a/docs/img/perlinheightmap.jpg b/dev-docs/img/perlinheightmap.jpg Binary files differindex d941a2fc6..d941a2fc6 100644 --- a/docs/img/perlinheightmap.jpg +++ b/dev-docs/img/perlinheightmap.jpg diff --git a/docs/img/perlinrivers1.jpg b/dev-docs/img/perlinrivers1.jpg Binary files differindex b11373fa7..b11373fa7 100644 --- a/docs/img/perlinrivers1.jpg +++ b/dev-docs/img/perlinrivers1.jpg diff --git a/docs/img/perlinrivers2.jpg b/dev-docs/img/perlinrivers2.jpg Binary files differindex bbbcaa276..bbbcaa276 100644 --- a/docs/img/perlinrivers2.jpg +++ b/dev-docs/img/perlinrivers2.jpg diff --git a/docs/img/perlinrivers3.jpg b/dev-docs/img/perlinrivers3.jpg Binary files differindex 3cf043e6e..3cf043e6e 100644 --- a/docs/img/perlinrivers3.jpg +++ b/dev-docs/img/perlinrivers3.jpg diff --git a/docs/img/roofprobability.jpg b/dev-docs/img/roofprobability.jpg Binary files differindex e7a155113..e7a155113 100644 --- a/docs/img/roofprobability.jpg +++ b/dev-docs/img/roofprobability.jpg diff --git a/docs/img/smallfoliageclumps.jpg b/dev-docs/img/smallfoliageclumps.jpg Binary files differindex 4cc6cbc00..4cc6cbc00 100644 --- a/docs/img/smallfoliageclumps.jpg +++ b/dev-docs/img/smallfoliageclumps.jpg diff --git a/docs/img/smoothedgrown_1.png b/dev-docs/img/smoothedgrown_1.png Binary files differindex 16e563f96..16e563f96 100644 --- a/docs/img/smoothedgrown_1.png +++ b/dev-docs/img/smoothedgrown_1.png diff --git a/docs/img/smoothedgrown_2.png b/dev-docs/img/smoothedgrown_2.png Binary files differindex 2d97cfb4e..2d97cfb4e 100644 --- a/docs/img/smoothedgrown_2.png +++ b/dev-docs/img/smoothedgrown_2.png diff --git a/docs/img/smoothedgrown_3.png b/dev-docs/img/smoothedgrown_3.png Binary files differindex 2d4d13f49..2d4d13f49 100644 --- a/docs/img/smoothedgrown_3.png +++ b/dev-docs/img/smoothedgrown_3.png diff --git a/docs/img/smoothedgrown_4.png b/dev-docs/img/smoothedgrown_4.png Binary files differindex d52a34bfe..d52a34bfe 100644 --- a/docs/img/smoothedgrown_4.png +++ b/dev-docs/img/smoothedgrown_4.png diff --git a/docs/img/smoothedgrown_5.png b/dev-docs/img/smoothedgrown_5.png Binary files differindex ae14d9847..ae14d9847 100644 --- a/docs/img/smoothedgrown_5.png +++ b/dev-docs/img/smoothedgrown_5.png diff --git a/docs/img/smoothedgrown_6.png b/dev-docs/img/smoothedgrown_6.png Binary files differindex 0a7f17595..0a7f17595 100644 --- a/docs/img/smoothedgrown_6.png +++ b/dev-docs/img/smoothedgrown_6.png diff --git a/docs/img/smoothedgrown_7.png b/dev-docs/img/smoothedgrown_7.png Binary files differindex 4351d6881..4351d6881 100644 --- a/docs/img/smoothedgrown_7.png +++ b/dev-docs/img/smoothedgrown_7.png diff --git a/docs/img/temperaturehumiditydecisionhills.jpg b/dev-docs/img/temperaturehumiditydecisionhills.jpg Binary files differindex c755df158..c755df158 100644 --- a/docs/img/temperaturehumiditydecisionhills.jpg +++ b/dev-docs/img/temperaturehumiditydecisionhills.jpg diff --git a/docs/img/temperaturehumiditydecisionsimple.jpg b/dev-docs/img/temperaturehumiditydecisionsimple.jpg Binary files differindex cbb1271b5..cbb1271b5 100644 --- a/docs/img/temperaturehumiditydecisionsimple.jpg +++ b/dev-docs/img/temperaturehumiditydecisionsimple.jpg diff --git a/docs/img/terraincomposition.jpg b/dev-docs/img/terraincomposition.jpg Binary files differindex 3d03e101d..3d03e101d 100644 --- a/docs/img/terraincomposition.jpg +++ b/dev-docs/img/terraincomposition.jpg diff --git a/docs/img/terrainheight.jpg b/dev-docs/img/terrainheight.jpg Binary files differindex bcbafcfaf..bcbafcfaf 100644 --- a/docs/img/terrainheight.jpg +++ b/dev-docs/img/terrainheight.jpg diff --git a/docs/img/twolevelbiomes.png b/dev-docs/img/twolevelbiomes.png Binary files differindex a3104733f..a3104733f 100644 --- a/docs/img/twolevelbiomes.png +++ b/dev-docs/img/twolevelbiomes.png diff --git a/docs/img/twolevellargeareas.jpg b/dev-docs/img/twolevellargeareas.jpg Binary files differindex 9d5d5ac8a..9d5d5ac8a 100644 --- a/docs/img/twolevellargeareas.jpg +++ b/dev-docs/img/twolevellargeareas.jpg diff --git a/docs/img/twolevelsmallareas.jpg b/dev-docs/img/twolevelsmallareas.jpg Binary files differindex 14afbc42a..14afbc42a 100644 --- a/docs/img/twolevelsmallareas.jpg +++ b/dev-docs/img/twolevelsmallareas.jpg diff --git a/docs/img/twolevelsmallgrid.jpg b/dev-docs/img/twolevelsmallgrid.jpg Binary files differindex 6c75e0b28..6c75e0b28 100644 --- a/docs/img/twolevelsmallgrid.jpg +++ b/dev-docs/img/twolevelsmallgrid.jpg diff --git a/docs/img/vanilla_springs_huge.png b/dev-docs/img/vanilla_springs_huge.png Binary files differindex 694389c85..694389c85 100644 --- a/docs/img/vanilla_springs_huge.png +++ b/dev-docs/img/vanilla_springs_huge.png diff --git a/docs/img/voronoi.png b/dev-docs/img/voronoi.png Binary files differindex e61e183ef..e61e183ef 100644 --- a/docs/img/voronoi.png +++ b/dev-docs/img/voronoi.png diff --git a/docs/img/voronoijitterbiomes.png b/dev-docs/img/voronoijitterbiomes.png Binary files differindex 42f0b7e40..42f0b7e40 100644 --- a/docs/img/voronoijitterbiomes.png +++ b/dev-docs/img/voronoijitterbiomes.png diff --git a/docs/img/zoomedgrown_1.png b/dev-docs/img/zoomedgrown_1.png Binary files differindex c73326b0e..c73326b0e 100644 --- a/docs/img/zoomedgrown_1.png +++ b/dev-docs/img/zoomedgrown_1.png diff --git a/docs/img/zoomedgrown_2.png b/dev-docs/img/zoomedgrown_2.png Binary files differindex 45fa6427f..45fa6427f 100644 --- a/docs/img/zoomedgrown_2.png +++ b/dev-docs/img/zoomedgrown_2.png diff --git a/docs/img/zoomedgrown_3.png b/dev-docs/img/zoomedgrown_3.png Binary files differindex 3c9d89759..3c9d89759 100644 --- a/docs/img/zoomedgrown_3.png +++ b/dev-docs/img/zoomedgrown_3.png diff --git a/docs/img/zoomedgrown_4.png b/dev-docs/img/zoomedgrown_4.png Binary files differindex 221a5fc76..221a5fc76 100644 --- a/docs/img/zoomedgrown_4.png +++ b/dev-docs/img/zoomedgrown_4.png diff --git a/docs/img/zoomedgrown_5.png b/dev-docs/img/zoomedgrown_5.png Binary files differindex 3881532ca..3881532ca 100644 --- a/docs/img/zoomedgrown_5.png +++ b/dev-docs/img/zoomedgrown_5.png diff --git a/docs/img/zoomedgrown_6.png b/dev-docs/img/zoomedgrown_6.png Binary files differindex cc03d2150..cc03d2150 100644 --- a/docs/img/zoomedgrown_6.png +++ b/dev-docs/img/zoomedgrown_6.png diff --git a/docs/img/zoomedgrown_7.png b/dev-docs/img/zoomedgrown_7.png Binary files differindex 7a9f43aac..7a9f43aac 100644 --- a/docs/img/zoomedgrown_7.png +++ b/dev-docs/img/zoomedgrown_7.png diff --git a/docs/js/ValueMap.js b/dev-docs/js/ValueMap.js index 31ddba27e..31ddba27e 100644 --- a/docs/js/ValueMap.js +++ b/dev-docs/js/ValueMap.js diff --git a/docs/js/grown.js b/dev-docs/js/grown.js index 1658ce21c..1658ce21c 100644 --- a/docs/js/grown.js +++ b/dev-docs/js/grown.js diff --git a/docs/style.css b/dev-docs/style.css index 74419d8da..74419d8da 100644 --- a/docs/style.css +++ b/dev-docs/style.css diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index bb59fca7c..e75250604 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -291,6 +291,62 @@ tolua_lerror: +static int tolua_cBlockInfo_GetPlaceSound(lua_State * tolua_S) +{ + cLuaState L(tolua_S); + if ( + !L.CheckParamStaticSelf("cBlockInfo") || + !L.CheckParamNumber(2) + ) + { + return 0; + } + + L.Push(""); + LOGWARNING("cBlockInfo:GetPlaceSound() is deprecated"); + L.LogStackTrace(0); + return 1; +} + + + + + +static int tolua_get_cBlockInfo_m_PlaceSound(lua_State * tolua_S) +{ + cLuaState L(tolua_S); + if (!L.CheckParamSelf("const cBlockInfo")) + { + return 0; + } + + L.Push(""); + LOGWARNING("cBlockInfo.m_PlaceSound is deprecated"); + L.LogStackTrace(0); + return 1; +} + + + + + +static int tolua_set_cBlockInfo_m_PlaceSound(lua_State * tolua_S) +{ + cLuaState L(tolua_S); + if (!L.CheckParamSelf("cBlockInfo")) + { + return 0; + } + + LOGWARNING("cBlockInfo.m_PlaceSound is deprecated"); + L.LogStackTrace(0); + return 0; +} + + + + + /* method: Trace of class cTracer */ static int tolua_cTracer_Trace(lua_State * a_LuaState) { @@ -439,6 +495,11 @@ void DeprecatedBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "StringToMobType", tolua_AllToLua_StringToMobType00); + tolua_beginmodule(tolua_S, "cBlockInfo"); + tolua_function(tolua_S, "GetPlaceSound", tolua_cBlockInfo_GetPlaceSound); + tolua_variable(tolua_S, "m_PlaceSound", tolua_get_cBlockInfo_m_PlaceSound, tolua_set_cBlockInfo_m_PlaceSound); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S, "cTracer"); tolua_function(tolua_S, "Trace", tolua_cTracer_Trace); tolua_endmodule(tolua_S); diff --git a/src/Bindings/DiffAPIDesc.lua b/src/Bindings/DiffAPIDesc.lua index 8b8c340e2..54d379356 100644 --- a/src/Bindings/DiffAPIDesc.lua +++ b/src/Bindings/DiffAPIDesc.lua @@ -129,14 +129,17 @@ end -- a_FunctionDoc is a single documentation item for a function, as loaded from ToLua++'s parser local function functionDescMatchesDocs(a_FunctionDesc, a_FunctionDoc) -- Check the number of parameters: - local numParams + local numParams = 0 local numOptionalParams = 0 if (not(a_FunctionDesc.Params) or (a_FunctionDesc.Params == "")) then numParams = 0 else - _, numParams = string.gsub(a_FunctionDesc.Params, ",", "") - numParams = numParams + 1 - _, numOptionalParams = string.gsub(a_FunctionDesc.Params, "%b[]", "") + for _, Param in pairs(a_FunctionDesc.Params) do + numParams = numParams + 1 + if Param.IsOptional then + numOptionalParams = numOptionalParams + 1 + end + end end local numDocParams = #(a_FunctionDoc.Params) if ((numDocParams > numParams) or (numDocParams < numParams - numOptionalParams)) then diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index e30d0ed5f..07a91f49e 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -875,6 +875,17 @@ void cLuaState::Push(const char * a_Value) +void cLuaState::Push(const cItem & a_Item) +{ + ASSERT(IsValid()); + auto c = new cItem(a_Item); + tolua_pushusertype_and_takeownership(m_LuaState, c, "cItem"); +} + + + + + void cLuaState::Push(const cNil & a_Nil) { ASSERT(IsValid()); diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 3d5b1e645..1d2598813 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -614,6 +614,7 @@ public: void Push(const AStringMap & a_Dictionary); void Push(const AStringVector & a_Vector); void Push(const char * a_Value); + void Push(const cItem & a_Item); void Push(const cNil & a_Nil); void Push(const cRef & a_Ref); void Push(const Vector3d & a_Vector); diff --git a/src/Bindings/LuaWindow.cpp b/src/Bindings/LuaWindow.cpp index fd714390e..2802c69db 100644 --- a/src/Bindings/LuaWindow.cpp +++ b/src/Bindings/LuaWindow.cpp @@ -9,7 +9,7 @@ #include "PluginLua.h" #include "Root.h" #include "lua/src/lauxlib.h" // Needed for LUA_REFNIL - +#include "ClientHandle.h" @@ -86,6 +86,19 @@ cLuaWindow::~cLuaWindow() +void cLuaWindow::SetOnClicked(cLuaState::cCallbackPtr && a_OnClicked) +{ + // Only one Lua state can be a cLuaWindow object callback: + ASSERT(a_OnClicked->IsSameLuaState(*m_LuaState)); + + // Store the new reference, releasing the old one if appropriate: + m_OnClicked = std::move(a_OnClicked); +} + + + + + void cLuaWindow::SetOnClosing(cLuaState::cCallbackPtr && a_OnClosing) { // Only one Lua state can be a cLuaWindow object callback: @@ -206,3 +219,24 @@ void cLuaWindow::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) + +void cLuaWindow::Clicked(cPlayer & a_Player, int a_WindowID, short a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) +{ + if (m_OnClicked != nullptr) + { + // Plugin can stop a click + if (m_OnClicked->Call(this, &a_Player, a_SlotNum, a_ClickAction, a_ClickedItem)) + { + // Tell the client the actual state of the window + a_Player.GetClientHandle()->SendInventorySlot(-1, -1, a_Player.GetDraggingItem()); + BroadcastWholeWindow(); + return; + } + } + + cWindow::Clicked(a_Player, a_WindowID, a_SlotNum, a_ClickAction, a_ClickedItem); +} + + + + diff --git a/src/Bindings/LuaWindow.h b/src/Bindings/LuaWindow.h index fb21c1c4e..8f3349d00 100644 --- a/src/Bindings/LuaWindow.h +++ b/src/Bindings/LuaWindow.h @@ -49,6 +49,10 @@ public: // tolua_end + /** Sets the Lua callback to call when the player clicks on the window. + The window can stop the click from propogating. */ + void SetOnClicked(cLuaState::cCallbackPtr && a_OnClicked); + /** Sets the Lua callback function to call when the window is about to close */ void SetOnClosing(cLuaState::cCallbackPtr && a_OnClosing); @@ -63,6 +67,9 @@ protected: /** The canon Lua state that has opened the window and owns the m_LuaRef */ cLuaState * m_LuaState; + /** The Lua callback to call when the player clicked on a slot */ + cLuaState::cCallbackPtr m_OnClicked; + /** The Lua callback to call when the window is closing for any player */ cLuaState::cCallbackPtr m_OnClosing; @@ -80,6 +87,11 @@ protected: // cWindow overrides: virtual void OpenedByPlayer(cPlayer & a_Player) override; + virtual void Clicked( + cPlayer & a_Player, int a_WindowID, + short a_SlotNum, eClickAction a_ClickAction, + const cItem & a_ClickedItem + ) override; virtual bool ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) override; virtual void Destroy(void) override; virtual void DistributeStack(cItem & a_ItemStack, int a_Slot, cPlayer & a_Player, cSlotArea * a_ClickedArea, bool a_ShouldApply) override; diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index e4410dd14..2251c64b9 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -3816,6 +3816,7 @@ void cManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "new", tolua_cLuaWindow_new); tolua_function(tolua_S, "new_local", tolua_cLuaWindow_new_local); tolua_function(tolua_S, ".call", tolua_cLuaWindow_new_local); + tolua_function(tolua_S, "SetOnClicked", tolua_SetObjectCallback<cLuaWindow, &cLuaWindow::SetOnClicked>); tolua_function(tolua_S, "SetOnClosing", tolua_SetObjectCallback<cLuaWindow, &cLuaWindow::SetOnClosing>); tolua_function(tolua_S, "SetOnSlotChanged", tolua_SetObjectCallback<cLuaWindow, &cLuaWindow::SetOnSlotChanged>); tolua_endmodule(tolua_S); diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 3276fde67..22e8f15e2 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -80,6 +80,7 @@ public: virtual bool OnPlayerJoined (cPlayer & a_Player) = 0; virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) = 0; virtual bool OnPlayerMoving (cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) = 0; + virtual bool OnPlayerOpeningWindow(cPlayer & a_Player, cWindow & a_Window) = 0; virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange) = 0; virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange) = 0; virtual bool OnPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index e3aa63aa1..5af336a95 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -659,6 +659,15 @@ bool cPluginLua::OnEntityTeleport(cEntity & a_Entity, const Vector3d & a_OldPosi +bool cPluginLua::OnPlayerOpeningWindow(cPlayer & a_Player, cWindow & a_Window) +{ + return CallSimpleHooks(cPluginManager::HOOK_PLAYER_OPENING_WINDOW, &a_Player, &a_Window); +} + + + + + bool cPluginLua::OnPlayerPlacedBlock(cPlayer & a_Player, const sSetBlock & a_BlockChange) { return CallSimpleHooks(cPluginManager::HOOK_PLAYER_PLACED_BLOCK, @@ -1056,6 +1065,7 @@ const char * cPluginLua::GetHookFnName(int a_HookType) case cPluginManager::HOOK_PLAYER_JOINED: return "OnPlayerJoined"; case cPluginManager::HOOK_PLAYER_LEFT_CLICK: return "OnPlayerLeftClick"; case cPluginManager::HOOK_PLAYER_MOVING: return "OnPlayerMoving"; + case cPluginManager::HOOK_PLAYER_OPENING_WINDOW: return "OnPlayerOpeningWindow"; case cPluginManager::HOOK_PLAYER_PLACED_BLOCK: return "OnPlayerPlacedBlock"; case cPluginManager::HOOK_PLAYER_PLACING_BLOCK: return "OnPlayerPlacingBlock"; case cPluginManager::HOOK_PLAYER_RIGHT_CLICK: return "OnPlayerRightClick"; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index ff5e8d726..4de5751e7 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -101,6 +101,7 @@ public: virtual bool OnPlayerJoined (cPlayer & a_Player) override; virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) override; virtual bool OnPlayerMoving (cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) override; + virtual bool OnPlayerOpeningWindow(cPlayer & a_Player, cWindow & a_Window) override; virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange) override; virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange) override; virtual bool OnPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 066ccf9d7..1d977fcde 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -999,6 +999,25 @@ bool cPluginManager::CallHookPlayerMoving(cPlayer & a_Player, const Vector3d & a +bool cPluginManager::CallHookPlayerOpeningWindow(cPlayer & a_Player, cWindow & a_Window) +{ + FIND_HOOK(HOOK_PLAYER_OPENING_WINDOW); + VERIFY_HOOK; + + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnPlayerOpeningWindow(a_Player, a_Window)) + { + return true; + } + } + return false; +} + + + + + bool cPluginManager::CallHookPlayerPlacedBlock(cPlayer & a_Player, const sSetBlock & a_BlockChange) { FIND_HOOK(HOOK_PLAYER_PLACED_BLOCK); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index f38ac8fa1..f3fc3551a 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -24,6 +24,7 @@ class cPickup; class cPlayer; class cPlugin; class cProjectileEntity; +class cWindow; class cWorld; class cSettingsRepositoryInterface; class cDeadlockDetect; @@ -111,6 +112,7 @@ public: HOOK_PLAYER_JOINED, HOOK_PLAYER_LEFT_CLICK, HOOK_PLAYER_MOVING, + HOOK_PLAYER_OPENING_WINDOW, HOOK_PLAYER_PLACED_BLOCK, HOOK_PLAYER_PLACING_BLOCK, HOOK_PLAYER_RIGHT_CLICK, @@ -257,6 +259,7 @@ public: bool CallHookPlayerJoined (cPlayer & a_Player); bool CallHookPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status); bool CallHookPlayerMoving (cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition); + bool CallHookPlayerOpeningWindow (cPlayer & a_Player, cWindow & a_Window); bool CallHookPlayerPlacedBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange); bool CallHookPlayerPlacingBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange); bool CallHookPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ); diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 74c4d867f..667a231a4 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -1954,8 +1954,8 @@ void cBlockArea::GetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTY cCuboid cBlockArea::GetBounds(void) const { return cCuboid( - m_Origin.x, m_Origin.y, m_Origin.z, - m_Origin.x + m_Size.x - 1, m_Origin.y + m_Size.y - 1, m_Origin.z + m_Size.z - 1 + m_Origin, + m_Origin + m_Size - Vector3i(1, 1, 1) ); } diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp index 54f6e0dfa..a8f5b7242 100644 --- a/src/BlockEntities/ChestEntity.cpp +++ b/src/BlockEntities/ChestEntity.cpp @@ -7,7 +7,6 @@ #include "../UI/ChestWindow.h" #include "../ClientHandle.h" #include "../Mobs/Ocelot.h" -#include "../BoundingBox.h" @@ -219,32 +218,13 @@ void cChestEntity::DestroyWindow() -class cFindSittingCat : - public cEntityCallback -{ - virtual bool Item(cEntity * a_Entity) override - { - return ( - (a_Entity->GetEntityType() == cEntity::etMonster) && - (static_cast<cMonster *>(a_Entity)->GetMobType() == eMonsterType::mtOcelot) && - (static_cast<cOcelot *>(a_Entity)->IsSitting()) - ); - } -}; - - - - - bool cChestEntity::IsBlocked() { - cFindSittingCat FindSittingCat; return ( - (GetPosY() >= cChunkDef::Height - 1) || - !cBlockInfo::IsTransparent(GetWorld()->GetBlock(GetPosX(), GetPosY() + 1, GetPosZ())) || + (GetPosY() < cChunkDef::Height - 1) && ( - (GetWorld()->GetBlock(GetPosX(), GetPosY() + 1, GetPosZ()) == E_BLOCK_AIR) && - !GetWorld()->ForEachEntityInBox(cBoundingBox(Vector3d(GetPosX(), GetPosY() + 1, GetPosZ()), 1, 1), FindSittingCat) + !cBlockInfo::IsTransparent(GetWorld()->GetBlock(GetPosX(), GetPosY() + 1, GetPosZ())) || + !cOcelot::IsCatSittingOnBlock(GetWorld(), Vector3d(GetPos())) ) ); } diff --git a/src/BlockEntities/EnderChestEntity.cpp b/src/BlockEntities/EnderChestEntity.cpp index 9030a0172..e475d7022 100644 --- a/src/BlockEntities/EnderChestEntity.cpp +++ b/src/BlockEntities/EnderChestEntity.cpp @@ -7,6 +7,7 @@ #include "../Entities/Player.h" #include "../UI/EnderChestWindow.h" #include "../ClientHandle.h" +#include "../Mobs/Ocelot.h" @@ -48,8 +49,13 @@ void cEnderChestEntity::SendTo(cClientHandle & a_Client) bool cEnderChestEntity::UsedBy(cPlayer * a_Player) { - // TODO: cats are an obstruction - if ((GetPosY() < cChunkDef::Height - 1) && !cBlockInfo::IsTransparent(GetWorld()->GetBlock(GetPosX(), GetPosY() + 1, GetPosZ()))) + if ( + (GetPosY() < cChunkDef::Height - 1) && + ( + !cBlockInfo::IsTransparent(GetWorld()->GetBlock(GetPosX(), GetPosY() + 1, GetPosZ())) || + !cOcelot::IsCatSittingOnBlock(GetWorld(), Vector3d(GetPos())) + ) + ) { // Obstruction, don't open return false; diff --git a/src/BlockInServerPluginInterface.h b/src/BlockInServerPluginInterface.h index c6578fe72..b3a71577f 100644 --- a/src/BlockInServerPluginInterface.h +++ b/src/BlockInServerPluginInterface.h @@ -10,11 +10,10 @@ #pragma once #include "Blocks/BlockPluginInterface.h" -#include "World.h" #include "Bindings/PluginManager.h" - +class cWorld; class cBlockInServerPluginInterface : diff --git a/src/BlockInfo.h b/src/BlockInfo.h index 569b537c1..1ba818cb3 100644 --- a/src/BlockInfo.h +++ b/src/BlockInfo.h @@ -55,9 +55,6 @@ public: /** Block height */ float m_BlockHeight; - /** Sound when placing this block */ - AString m_PlaceSound; - /** Block's hardness. The greater the value the longer the player needs to break the block. */ float m_Hardness; @@ -85,7 +82,6 @@ public: inline static bool FullyOccupiesVoxel (BLOCKTYPE a_Type) { return Get(a_Type).m_FullyOccupiesVoxel; } inline static bool CanBeTerraformed (BLOCKTYPE a_Type) { return Get(a_Type).m_CanBeTerraformed; } inline static float GetBlockHeight (BLOCKTYPE a_Type) { return Get(a_Type).m_BlockHeight; } - inline static AString GetPlaceSound (BLOCKTYPE a_Type) { return Get(a_Type).m_PlaceSound; } inline static float GetHardness (BLOCKTYPE a_Type) { return Get(a_Type).m_Hardness; } // tolua_end @@ -105,7 +101,6 @@ public: , m_FullyOccupiesVoxel(false) , m_CanBeTerraformed(false) , m_BlockHeight(1.0) - , m_PlaceSound() , m_Hardness(0.0f) , m_Handler() {} diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h index 634c7dd3a..f2cbfde18 100644 --- a/src/Blocks/BlockBed.h +++ b/src/Blocks/BlockBed.h @@ -6,9 +6,9 @@ #include "BlockEntity.h" #include "MetaRotator.h" #include "ChunkInterface.h" -#include "../Entities/Entity.h" +class cEntity; class cPlayer; class cWorldInterface; diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h index 041a579f7..808c271b3 100644 --- a/src/Blocks/BlockButton.h +++ b/src/Blocks/BlockButton.h @@ -34,7 +34,7 @@ public: Meta |= 0x08; a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta, false); - a_WorldInterface.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ); + a_WorldInterface.WakeUpSimulators({a_BlockX, a_BlockY, a_BlockZ}); a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("block.stone_button.click_on", x, y, z, 0.5f, 0.6f); // Queue a button reset (unpress) @@ -45,7 +45,7 @@ public: { // Block hasn't change in the meantime; set its meta a_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x07, false); - a_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ); + a_World.WakeUpSimulators({a_BlockX, a_BlockY, a_BlockZ}); a_World.BroadcastSoundEffect("block.stone_button.click_off", x, y, z, 0.5f, 0.5f); } } diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 1eae70c42..4c2209383 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -650,7 +650,7 @@ void cBlockHandler::Check(cChunkInterface & a_ChunkInterface, cBlockPluginInterf // Wake up the simulators for this block: int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; - a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp(BlockX, a_RelY, BlockZ, &a_Chunk); + a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp({BlockX, a_RelY, BlockZ}, &a_Chunk); } } diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h index 56a1169e9..7d6a1bc8b 100644 --- a/src/Blocks/BlockLever.h +++ b/src/Blocks/BlockLever.h @@ -23,7 +23,7 @@ public: NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); - a_WorldInterface.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ); + a_WorldInterface.WakeUpSimulators({a_BlockX, a_BlockY, a_BlockZ}); a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("block.lever.click", static_cast<double>(a_BlockX), static_cast<double>(a_BlockY), static_cast<double>(a_BlockZ), 0.5f, (Meta & 0x08) ? 0.6f : 0.5f); return true; } diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 21dba0bed..eae9f7fd5 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -159,7 +159,7 @@ public: // Wake up the simulators for this block: int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; - a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp(BlockX, a_RelY, BlockZ, &a_Chunk); + a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp({BlockX, a_RelY, BlockZ}, &a_Chunk); } } diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index d471df6f1..1300ffe8c 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -1,15 +1,17 @@ #pragma once -#include "BroadcastInterface.h" + #include "../Mobs/MonsterTypes.h" -class cItems; typedef cItemCallback<cBlockEntity> cBlockEntityCallback; +class cBroadcastInterface; +class cItems; +class cPlayer; + -class cPlayer; class cWorldInterface @@ -72,6 +74,6 @@ public: virtual int GetHeight(int a_BlockX, int a_BlockZ) = 0; /** Wakes up the simulators for the specified block */ - virtual void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) = 0; + virtual void WakeUpSimulators(Vector3i a_Block) = 0; }; diff --git a/src/BoundingBox.cpp b/src/BoundingBox.cpp index 5a594a2a4..afb7e025b 100644 --- a/src/BoundingBox.cpp +++ b/src/BoundingBox.cpp @@ -19,7 +19,7 @@ cBoundingBox::cBoundingBox(double a_MinX, double a_MaxX, double a_MinY, double a -cBoundingBox::cBoundingBox(const Vector3d & a_Min, const Vector3d & a_Max) : +cBoundingBox::cBoundingBox(Vector3d a_Min, Vector3d a_Max) : m_Min(a_Min), m_Max(a_Max) { @@ -29,7 +29,7 @@ cBoundingBox::cBoundingBox(const Vector3d & a_Min, const Vector3d & a_Max) : -cBoundingBox::cBoundingBox(const Vector3d & a_Pos, double a_Radius, double a_Height) : +cBoundingBox::cBoundingBox(Vector3d a_Pos, double a_Radius, double a_Height) : m_Min(a_Pos.x - a_Radius, a_Pos.y, a_Pos.z - a_Radius), m_Max(a_Pos.x + a_Radius, a_Pos.y + a_Height, a_Pos.z + a_Radius) { @@ -39,7 +39,7 @@ cBoundingBox::cBoundingBox(const Vector3d & a_Pos, double a_Radius, double a_Hei -cBoundingBox::cBoundingBox(const Vector3d & a_Pos, double a_CubeLength) : +cBoundingBox::cBoundingBox(Vector3d a_Pos, double a_CubeLength) : m_Min(a_Pos.x - a_CubeLength / 2, a_Pos.y - a_CubeLength / 2, a_Pos.z - a_CubeLength / 2), m_Max(a_Pos.x + a_CubeLength / 2, a_Pos.y + a_CubeLength / 2, a_Pos.z + a_CubeLength / 2) { @@ -84,7 +84,7 @@ void cBoundingBox::Move(double a_OffX, double a_OffY, double a_OffZ) -void cBoundingBox::Move(const Vector3d & a_Off) +void cBoundingBox::Move(Vector3d a_Off) { m_Min.x += a_Off.x; m_Min.y += a_Off.y; @@ -141,7 +141,7 @@ cBoundingBox cBoundingBox::Union(const cBoundingBox & a_Other) -bool cBoundingBox::IsInside(const Vector3d & a_Point) +bool cBoundingBox::IsInside(Vector3d a_Point) { return IsInside(m_Min, m_Max, a_Point); } @@ -169,7 +169,7 @@ bool cBoundingBox::IsInside(cBoundingBox & a_Other) -bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max) +bool cBoundingBox::IsInside(Vector3d a_Min, Vector3d a_Max) { // If both coords are inside this, then the entire a_Other is inside return (IsInside(a_Min) && IsInside(a_Max)); @@ -179,7 +179,7 @@ bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max) -bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max, const Vector3d & a_Point) +bool cBoundingBox::IsInside(Vector3d a_Min, Vector3d a_Max, Vector3d a_Point) { return ( ((a_Point.x >= a_Min.x) && (a_Point.x <= a_Max.x)) && @@ -192,7 +192,7 @@ bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max, cons -bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max, double a_X, double a_Y, double a_Z) +bool cBoundingBox::IsInside(Vector3d a_Min, Vector3d a_Max, double a_X, double a_Y, double a_Z) { return ( ((a_X >= a_Min.x) && (a_X <= a_Max.x)) && @@ -205,7 +205,7 @@ bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max, doub -bool cBoundingBox::CalcLineIntersection(const Vector3d & a_Line1, const Vector3d & a_Line2, double & a_LineCoeff, eBlockFace & a_Face) const +bool cBoundingBox::CalcLineIntersection(Vector3d a_Line1, Vector3d a_Line2, double & a_LineCoeff, eBlockFace & a_Face) const { return CalcLineIntersection(m_Min, m_Max, a_Line1, a_Line2, a_LineCoeff, a_Face); } @@ -214,7 +214,7 @@ bool cBoundingBox::CalcLineIntersection(const Vector3d & a_Line1, const Vector3d -bool cBoundingBox::CalcLineIntersection(const Vector3d & a_Min, const Vector3d & a_Max, const Vector3d & a_Line1, const Vector3d & a_Line2, double & a_LineCoeff, eBlockFace & a_Face) +bool cBoundingBox::CalcLineIntersection(Vector3d a_Min, Vector3d a_Max, Vector3d a_Line1, Vector3d a_Line2, double & a_LineCoeff, eBlockFace & a_Face) { if (IsInside(a_Min, a_Max, a_Line1)) { diff --git a/src/BoundingBox.h b/src/BoundingBox.h index 48b9a3d82..809b7fe7c 100644 --- a/src/BoundingBox.h +++ b/src/BoundingBox.h @@ -24,9 +24,9 @@ class cBoundingBox { public: cBoundingBox(double a_MinX, double a_MaxX, double a_MinY, double a_MaxY, double a_MinZ, double a_MaxZ); - cBoundingBox(const Vector3d & a_Min, const Vector3d & a_Max); - cBoundingBox(const Vector3d & a_Pos, double a_Radius, double a_Height); - cBoundingBox(const Vector3d & a_Pos, double a_CubeLength); + cBoundingBox(Vector3d a_Min, Vector3d a_Max); + cBoundingBox(Vector3d a_Pos, double a_Radius, double a_Height); + cBoundingBox(Vector3d a_Pos, double a_CubeLength); cBoundingBox(const cBoundingBox & a_Orig); cBoundingBox & operator=(const cBoundingBox & a_Other); @@ -35,7 +35,7 @@ public: void Move(double a_OffX, double a_OffY, double a_OffZ); /** Moves the entire boundingbox by the specified offset */ - void Move(const Vector3d & a_Off); + void Move(Vector3d a_Off); /** Expands the bounding box by the specified amount in each direction (so the box becomes larger by 2 * Expand in each direction) */ void Expand(double a_ExpandX, double a_ExpandY, double a_ExpandZ); @@ -47,7 +47,7 @@ public: cBoundingBox Union(const cBoundingBox & a_Other); /** Returns true if the point is inside the bounding box */ - bool IsInside(const Vector3d & a_Point); + bool IsInside(Vector3d a_Point); /** Returns true if the point is inside the bounding box */ bool IsInside(double a_X, double a_Y, double a_Z); @@ -56,13 +56,13 @@ public: bool IsInside(cBoundingBox & a_Other); /** Returns true if a boundingbox specified by a_Min and a_Max is inside this bounding box */ - bool IsInside(const Vector3d & a_Min, const Vector3d & a_Max); + bool IsInside(Vector3d a_Min, Vector3d a_Max); /** Returns true if the specified point is inside the bounding box specified by its min / max corners */ - static bool IsInside(const Vector3d & a_Min, const Vector3d & a_Max, const Vector3d & a_Point); + static bool IsInside(Vector3d a_Min, Vector3d a_Max, Vector3d a_Point); /** Returns true if the specified point is inside the bounding box specified by its min / max corners */ - static bool IsInside(const Vector3d & a_Min, const Vector3d & a_Max, double a_X, double a_Y, double a_Z); + static bool IsInside(Vector3d a_Min, Vector3d a_Max, double a_X, double a_Y, double a_Z); // tolua_end @@ -70,13 +70,13 @@ public: Also calculates the distance along the line in which the intersection occurs, and the face hit (BLOCK_FACE_ constants) Only forward collisions (a_LineCoeff >= 0) are returned. Exported to Lua manually, because ToLua++ would generate needless input params (a_LineCoeff, a_Face). */ - bool CalcLineIntersection(const Vector3d & a_LinePoint1, const Vector3d & a_LinePoint2, double & a_LineCoeff, eBlockFace & a_Face) const; + bool CalcLineIntersection(Vector3d a_LinePoint1, Vector3d a_LinePoint2, double & a_LineCoeff, eBlockFace & a_Face) const; /** Returns true if the specified bounding box is intersected by the line specified by its two points Also calculates the distance along the line in which the intersection occurs, and the face hit (BLOCK_FACE_ constants) Only forward collisions (a_LineCoeff >= 0) are returned. Exported to Lua manually, because ToLua++ would generate needless input params (a_LineCoeff, a_Face). */ - static bool CalcLineIntersection(const Vector3d & a_Min, const Vector3d & a_Max, const Vector3d & a_LinePoint1, const Vector3d & a_LinePoint2, double & a_LineCoeff, eBlockFace & a_Face); + static bool CalcLineIntersection(Vector3d a_Min, Vector3d a_Max, Vector3d a_LinePoint1, Vector3d a_LinePoint2, double & a_LineCoeff, eBlockFace & a_Face); /** Calculates the intersection of the two bounding boxes; returns true if nonempty. Exported manually, because ToLua++ would generate needless input params (a_Intersection). */ @@ -92,8 +92,8 @@ public: double GetMaxY(void) const { return m_Max.y; } double GetMaxZ(void) const { return m_Max.z; } - const Vector3d & GetMin(void) const { return m_Min; } - const Vector3d & GetMax(void) const { return m_Max; } + Vector3d GetMin(void) const { return m_Min; } + Vector3d GetMax(void) const { return m_Max; } // tolua_end diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 5c83f9a47..f2b936a3f 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -452,7 +452,10 @@ void cChunk::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlock } // for y // Erase all affected block entities: - cCuboid affectedArea(OffX, a_MinBlockY, OffZ, OffX + SizeX - 1, a_MinBlockY + SizeY - 1, OffZ + SizeZ - 1); + cCuboid affectedArea( + {OffX, a_MinBlockY, OffZ}, + {OffX + SizeX - 1, a_MinBlockY + SizeY - 1, OffZ + SizeZ - 1} + ); for (auto itr = m_BlockEntities.begin(); itr != m_BlockEntities.end();) { if (affectedArea.IsInside(itr->second->GetPos())) @@ -1491,7 +1494,7 @@ void cChunk::WakeUpSimulators(void) // The redstone sim takes multiple blocks, use the inbuilt checker if (RedstoneSimulator->IsAllowedBlock(Block)) { - RedstoneSimulator->AddBlock(BlockX, y, BlockZ, this); + RedstoneSimulator->AddBlock({BlockX, y, BlockZ}, this); continue; } @@ -1499,12 +1502,12 @@ void cChunk::WakeUpSimulators(void) { case E_BLOCK_WATER: { - WaterSimulator->AddBlock(BlockX, y, BlockZ, this); + WaterSimulator->AddBlock({BlockX, y, BlockZ}, this); break; } case E_BLOCK_LAVA: { - LavaSimulator->AddBlock(BlockX, y, BlockZ, this); + LavaSimulator->AddBlock({BlockX, y, BlockZ}, this); break; } default: diff --git a/src/ChunkDef.h b/src/ChunkDef.h index 69eafd18c..f4a0867b5 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -27,6 +27,7 @@ class cBlockEntity; class cEntity; class cClientHandle; class cBlockEntity; +class cChunkCoords; typedef std::unique_ptr<cEntity> OwnedEntity; typedef std::vector<OwnedEntity> cEntityList; @@ -51,6 +52,25 @@ typedef unsigned char HEIGHTTYPE; + +class cChunkCoords +{ +public: + int m_ChunkX; + int m_ChunkZ; + + cChunkCoords(int a_ChunkX, int a_ChunkZ) : m_ChunkX(a_ChunkX), m_ChunkZ(a_ChunkZ) {} + + bool operator == (const cChunkCoords & a_Other) const + { + return ((m_ChunkX == a_Other.m_ChunkX) && (m_ChunkZ == a_Other.m_ChunkZ)); + } +} ; + + + + + /** Constants used throughout the code, useful typedefs and utility functions */ class cChunkDef { @@ -108,9 +128,9 @@ public: } /** Converts relative block coordinates into absolute coordinates with a known chunk location */ - inline static Vector3i RelativeToAbsolute(const Vector3i & a_RelBlockPosition, int a_ChunkX, int a_ChunkZ) + inline static Vector3i RelativeToAbsolute(Vector3i a_RelBlockPosition, int a_ChunkX, int a_ChunkZ) { - return Vector3i(a_RelBlockPosition.x + a_ChunkX * Width, a_RelBlockPosition.y, a_RelBlockPosition.z + a_ChunkZ * Width); + return {a_RelBlockPosition.x + a_ChunkX * Width, a_RelBlockPosition.y, a_RelBlockPosition.z + a_ChunkZ * Width}; } /** Validates a height-coordinate. Returns false if height-coordiante is out of height bounds */ @@ -128,16 +148,26 @@ public: /** Converts absolute block coords to chunk coords: */ inline static void BlockToChunk(int a_X, int a_Z, int & a_ChunkX, int & a_ChunkZ) { - a_ChunkX = a_X / Width; - if ((a_X < 0) && (a_X % Width != 0)) + // This version is deprecated in favor of the vector version + // If you're developing new code, use the other version. + auto ChunkCoords = BlockToChunk({a_X, 0, a_Z}); + a_ChunkX = ChunkCoords.m_ChunkX; + a_ChunkZ = ChunkCoords.m_ChunkZ; + } + + /** The Y coordinate of a_Pos is ignored */ + inline static cChunkCoords BlockToChunk(Vector3i a_Pos) + { + cChunkCoords Chunk(a_Pos.x / Width, a_Pos.z / Width); + if ((a_Pos.x < 0) && (a_Pos.x % Width != 0)) { - a_ChunkX--; + Chunk.m_ChunkX--; } - a_ChunkZ = a_Z / cChunkDef::Width; - if ((a_Z < 0) && (a_Z % Width != 0)) + if ((a_Pos.z < 0) && (a_Pos.z % Width != 0)) { - a_ChunkZ--; + Chunk.m_ChunkZ--; } + return Chunk; } @@ -408,24 +438,6 @@ struct sSetBlock typedef std::list<sSetBlock> sSetBlockList; typedef std::vector<sSetBlock> sSetBlockVector; - - - - -class cChunkCoords -{ -public: - int m_ChunkX; - int m_ChunkZ; - - cChunkCoords(int a_ChunkX, int a_ChunkZ) : m_ChunkX(a_ChunkX), m_ChunkZ(a_ChunkZ) {} - - bool operator == (const cChunkCoords & a_Other) const - { - return ((m_ChunkX == a_Other.m_ChunkX) && (m_ChunkZ == a_Other.m_ChunkZ)); - } -} ; - typedef std::list<cChunkCoords> cChunkCoordsList; typedef std::vector<cChunkCoords> cChunkCoordsVector; diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index e4fdb6ec7..fcd990ad6 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -114,11 +114,11 @@ cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkZ) -cChunkPtr cChunkMap::GetChunkNoGen(int a_ChunkX, int a_ChunkZ) +cChunkPtr cChunkMap::GetChunkNoGen(cChunkCoords a_Chunk) { ASSERT(m_CSChunks.IsLockedByCurrentThread()); // m_CSChunks should already be locked by the operation that called us - auto Chunk = ConstructChunk(a_ChunkX, a_ChunkZ); + auto Chunk = ConstructChunk(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); if (Chunk == nullptr) { return nullptr; @@ -126,7 +126,7 @@ cChunkPtr cChunkMap::GetChunkNoGen(int a_ChunkX, int a_ChunkZ) if (!Chunk->IsValid() && !Chunk->IsQueued()) { Chunk->SetPresence(cChunk::cpQueued); - m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkZ); + m_World->GetStorage().QueueLoadChunk(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); } return Chunk; @@ -739,17 +739,15 @@ bool cChunkMap::DoWithChunkAt(Vector3i a_BlockPos, std::function<bool(cChunk &)> -void cChunkMap::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) +void cChunkMap::WakeUpSimulators(Vector3i a_Block) { cCSLock Lock(m_CSChunks); - int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(cChunkDef::BlockToChunk(a_Block)); if ((Chunk == nullptr) || !Chunk->IsValid()) { return; } - m_World->GetSimulatorManager()->WakeUp(a_BlockX, a_BlockY, a_BlockZ, Chunk); + m_World->GetSimulatorManager()->WakeUp(a_Block, Chunk); } @@ -1139,7 +1137,7 @@ void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_B if ((Chunk != nullptr) && Chunk->IsValid()) { Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta, a_SendToClients); - m_World->GetSimulatorManager()->WakeUp(a_BlockX, a_BlockY, a_BlockZ, Chunk); + m_World->GetSimulatorManager()->WakeUp({a_BlockX, a_BlockY, a_BlockZ}, Chunk); } BlockHandler(a_BlockType)->OnPlaced(ChunkInterface, *m_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); } @@ -1360,7 +1358,7 @@ bool cChunkMap::DigBlock(int a_BlockX, int a_BlockY, int a_BlockZ) } DestChunk->SetBlock(PosX, PosY, PosZ, E_BLOCK_AIR, 0); - m_World->GetSimulatorManager()->WakeUp(a_BlockX, a_BlockY, a_BlockZ, DestChunk); + m_World->GetSimulatorManager()->WakeUp({a_BlockX, a_BlockY, a_BlockZ}, DestChunk); } return true; @@ -1822,8 +1820,8 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ // Wake up all simulators for the area, so that water and lava flows and sand falls into the blasted holes (FS #391): m_World->GetSimulatorManager()->WakeUpArea(cCuboid( - bx - ExplosionSizeInt - 1, MinY, bz - ExplosionSizeInt - 1, - bx + ExplosionSizeInt + 1, MaxY, bz + ExplosionSizeInt + 1 + {bx - ExplosionSizeInt - 1, MinY, bz - ExplosionSizeInt - 1}, + {bx + ExplosionSizeInt + 1, MaxY, bz + ExplosionSizeInt + 1} )); } diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 431ba6c2a..e902be60c 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -110,7 +110,14 @@ public: bool DoWithChunkAt(Vector3i a_BlockPos, std::function<bool(cChunk &)> a_Callback); /** Wakes up simulators for the specified block */ - void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ); + void WakeUpSimulators(Vector3i a_Block); + + // DEPRECATED, use the vector-parametered version instead. + void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) + { + LOGWARNING("cChunkMap::WakeUpSimulators(int, int, int) is deprecated, use cChunkMap::WakeUpSimulators(Vector3i) instead."); + WakeUpSimulators(Vector3i(a_BlockX, a_BlockY, a_BlockZ)); + } void MarkChunkDirty (int a_ChunkX, int a_ChunkZ); void MarkChunkSaving (int a_ChunkX, int a_ChunkZ); @@ -485,7 +492,13 @@ private: cChunkPtr GetChunk(int a_ChunkX, int a_ChunkZ); /** Constructs a chunk and queues the chunk for loading if not valid, returning it; doesn't generate */ - cChunkPtr GetChunkNoGen(int a_ChunkX, int a_ChunkZ); + cChunkPtr GetChunkNoGen(cChunkCoords a_Chunk); + + // Deprecated in favor of the vector version + cChunkPtr GetChunkNoGen(int a_ChunkX, int a_ChunkZ) + { + return GetChunkNoGen(cChunkCoords(a_ChunkX, a_ChunkZ)); + } /** Constructs a chunk, returning it. Doesn't load, doesn't generate */ cChunkPtr GetChunkNoLoad(int a_ChunkX, int a_ChunkZ); diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 617f18c7a..9e1d1a9b5 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -12,7 +12,6 @@ #include "OSSupport/Network.h" #include "Defines.h" #include "Scoreboard.h" -#include "Map.h" #include "UI/SlotArea.h" #include "json/json.h" #include "ChunkSender.h" @@ -34,6 +33,7 @@ class cWindow; class cFallingBlock; class cCompositeChat; class cStatManager; +class cMap; class cClientHandle; typedef std::shared_ptr<cClientHandle> cClientHandlePtr; diff --git a/src/Cuboid.cpp b/src/Cuboid.cpp index 1aa1e92e1..d87a6ef5e 100644 --- a/src/Cuboid.cpp +++ b/src/Cuboid.cpp @@ -7,30 +7,9 @@ -/** Returns true if the two specified intervals have a non-empty union */ -static bool DoIntervalsIntersect(int a_Min1, int a_Max1, int a_Min2, int a_Max2) -{ - return ( - ((a_Min1 >= a_Min2) && (a_Min1 <= a_Max2)) || // Start of first interval is within the second interval - ((a_Max1 >= a_Min2) && (a_Max1 <= a_Max2)) || // End of first interval is within the second interval - ((a_Min2 >= a_Min1) && (a_Min2 <= a_Max1)) // Start of second interval is within the first interval - ); -} - - - - - //////////////////////////////////////////////////////////////////////////////// // cCuboid: -cCuboid & cCuboid::operator =(cCuboid a_Other) -{ - std::swap(p1, a_Other.p1); - std::swap(p2, a_Other.p2); - return *this; -} - @@ -95,23 +74,6 @@ int cCuboid::GetVolume(void) const -bool cCuboid::DoesIntersect(const cCuboid & a_Other) const -{ - ASSERT(IsSorted()); - ASSERT(a_Other.IsSorted()); - - // In order for cuboids to intersect, each of their coord intervals need to intersect - return ( - DoIntervalsIntersect(p1.x, p2.x, a_Other.p1.x, a_Other.p2.x) && - DoIntervalsIntersect(p1.y, p2.y, a_Other.p1.y, a_Other.p2.y) && - DoIntervalsIntersect(p1.z, p2.z, a_Other.p1.z, a_Other.p2.z) - ); -} - - - - - bool cCuboid::IsCompletelyInside(const cCuboid & a_Outer) const { ASSERT(IsSorted()); @@ -229,7 +191,7 @@ bool cCuboid::IsSorted(void) const -void cCuboid::Engulf(const Vector3i & a_Point) +void cCuboid::Engulf(Vector3i a_Point) { if (a_Point.x < p1.x) { diff --git a/src/Cuboid.h b/src/Cuboid.h index 3ade5bc20..b39d3ad4a 100644 --- a/src/Cuboid.h +++ b/src/Cuboid.h @@ -13,16 +13,14 @@ public: Vector3i p1, p2; cCuboid(void) {} - cCuboid(const cCuboid & a_Cuboid) : p1(a_Cuboid.p1), p2(a_Cuboid.p2) {} cCuboid(const Vector3i & a_p1, const Vector3i & a_p2) : p1(a_p1), p2(a_p2) {} cCuboid(int a_X1, int a_Y1, int a_Z1) : p1(a_X1, a_Y1, a_Z1), p2(a_X1, a_Y1, a_Z1) {} - cCuboid(int a_X1, int a_Y1, int a_Z1, int a_X2, int a_Y2, int a_Z2) : p1(a_X1, a_Y1, a_Z1), p2(a_X2, a_Y2, a_Z2) {} - // tolua_end - - cCuboid & operator =(cCuboid a_Other); - - // tolua_begin + // DEPRECATED, use cCuboid(Vector3i, Vector3i) instead + cCuboid(int a_X1, int a_Y1, int a_Z1, int a_X2, int a_Y2, int a_Z2) : p1(a_X1, a_Y1, a_Z1), p2(a_X2, a_Y2, a_Z2) + { + LOGWARNING("cCuboid(int, int, int, int, int, int) constructor is deprecated, use cCuboid(Vector3i, Vector3i) constructor instead."); + } void Assign(int a_X1, int a_Y1, int a_Z1, int a_X2, int a_Y2, int a_Z2); void Assign(const cCuboid & a_SrcCuboid); @@ -40,9 +38,20 @@ public: /** Returns true if the cuboids have at least one voxel in common. Both coords are considered inclusive. Assumes both cuboids are sorted. */ - bool DoesIntersect(const cCuboid & a_Other) const; + inline bool DoesIntersect(const cCuboid & a_Other) const + { + ASSERT(IsSorted()); + ASSERT(a_Other.IsSorted()); + + // In order for cuboids to intersect, each of their coord intervals need to intersect + return ( + DoIntervalsIntersect(p1.x, p2.x, a_Other.p1.x, a_Other.p2.x) && + DoIntervalsIntersect(p1.y, p2.y, a_Other.p1.y, a_Other.p2.y) && + DoIntervalsIntersect(p1.z, p2.z, a_Other.p1.z, a_Other.p2.z) + ); + } - bool IsInside(const Vector3i & v) const + bool IsInside(Vector3i v) const { return ( (v.x >= p1.x) && (v.x <= p2.x) && @@ -60,7 +69,7 @@ public: ); } - bool IsInside( const Vector3d & v) const + bool IsInside(Vector3d v) const { return ( (v.x >= p1.x) && (v.x <= p2.x) && @@ -94,7 +103,18 @@ public: bool IsSorted(void) const; /** If needed, expands the cuboid so that it contains the specified point. Assumes sorted. Doesn't contract. */ - void Engulf(const Vector3i & a_Point); + void Engulf(Vector3i a_Point); + +private: + + /** Returns true if the two specified intervals have a non-empty union */ + inline static bool DoIntervalsIntersect(int a_Min1, int a_Max1, int a_Min2, int a_Max2) + { + ASSERT(a_Min1 <= a_Max1); + ASSERT(a_Min2 <= a_Max2); + return ((a_Min1 <= a_Max2) && (a_Max1 >= a_Min2)); + } + } ; // tolua_end diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index e8430090b..6259098d8 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -119,23 +119,9 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) Damage += ExtraDamage; } - // int KnockbackAmount = 1; unsigned int PunchLevel = m_CreatorData.m_Enchantments.GetLevel(cEnchantments::enchPunch); - if (PunchLevel > 0) - { - Vector3d LookVector = GetLookVector(); - Vector3f FinalSpeed = Vector3f(0, 0, 0); - switch (PunchLevel) - { - case 1: FinalSpeed = LookVector * Vector3d(5, 0.3, 5); break; - case 2: FinalSpeed = LookVector * Vector3d(8, 0.3, 8); break; - default: break; - } - a_EntityHit.SetSpeed(FinalSpeed); - } - - // a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, KnockbackAmount); // TODO fix knockback. - a_EntityHit.TakeDamage(dtRangedAttack, GetCreatorUniqueID(), Damage, 0); // Until knockback is fixed. + double KnockbackAmount = 11 + 10 * PunchLevel; + a_EntityHit.TakeDamage(dtRangedAttack, GetCreatorUniqueID(), Damage, KnockbackAmount); if (IsOnFire() && !a_EntityHit.IsSubmerged() && !a_EntityHit.IsSwimming()) { diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 3167d2917..a38a6552d 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -345,7 +345,7 @@ void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_R Vector3d Heading(0, 0, 0); if (a_Attacker != nullptr) { - Heading = a_Attacker->GetLookVector() * (a_Attacker->IsSprinting() ? 16 : 11); + Heading = a_Attacker->GetLookVector(); } TDI.Knockback = Heading * a_KnockbackAmount; @@ -534,21 +534,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) // Add knockback: if ((IsMob() || IsPlayer()) && (a_TDI.Attacker != nullptr)) { - int KnockbackLevel = static_cast<int>(a_TDI.Attacker->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchKnockback)); // More common enchantment - if (KnockbackLevel < 1) - { - // We support punch on swords and vice versa! :) - KnockbackLevel = static_cast<int>(a_TDI.Attacker->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchPunch)); - } - - Vector3d AdditionalSpeed(0, 0, 0); - switch (KnockbackLevel) - { - case 1: AdditionalSpeed.Set(5, 0.3, 5); break; - case 2: AdditionalSpeed.Set(8, 0.3, 8); break; - default: break; - } - AddSpeed(a_TDI.Knockback + AdditionalSpeed); + AddSpeed(a_TDI.Knockback); } m_World->BroadcastEntityStatus(*this, esGenericHurt); @@ -763,9 +749,19 @@ int cEntity::GetArmorCoverAgainst(const cEntity * a_Attacker, eDamageType a_Dama double cEntity::GetKnockbackAmountAgainst(const cEntity & a_Receiver) { // Returns the knockback amount that the currently equipped items would cause to a_Receiver on a hit + double Knockback = 11; - // TODO: Enchantments - return 1; + // If we're sprinting, bump up the knockback + if (IsSprinting()) + { + Knockback = 16; + } + + // Check for knockback enchantments (punch only applies to shot arrows) + unsigned int KnockbackLevel = GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchKnockback); + Knockback += 10 * KnockbackLevel; + + return Knockback; } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index aaf06fa34..a1b518cbc 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1321,10 +1321,16 @@ cTeam * cPlayer::UpdateTeam(void) void cPlayer::OpenWindow(cWindow & a_Window) { + if (cRoot::Get()->GetPluginManager()->CallHookPlayerOpeningWindow(*this, a_Window)) + { + return; + } + if (&a_Window != m_CurrentWindow) { CloseWindow(false); } + a_Window.OpenedByPlayer(*this); m_CurrentWindow = &a_Window; a_Window.SendWholeWindow(*GetClientHandle()); diff --git a/src/Entities/SplashPotionEntity.h b/src/Entities/SplashPotionEntity.h index 85aa5046f..baa5da725 100644 --- a/src/Entities/SplashPotionEntity.h +++ b/src/Entities/SplashPotionEntity.h @@ -12,10 +12,12 @@ #include "ProjectileEntity.h" #include "EntityEffect.h" #include "../World.h" -#include "Entity.h" +class cEntity; + + // tolua_begin diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index de2f5f95d..818b8254c 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -18,8 +18,8 @@ uses a prefabricate in a cBlockArea for drawing itself. cPrefab::cPrefab(const cPrefab::sDef & a_Def) : m_Size(a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ), m_HitBox( - a_Def.m_HitboxMinX, a_Def.m_HitboxMinY, a_Def.m_HitboxMinZ, - a_Def.m_HitboxMaxX, a_Def.m_HitboxMaxY, a_Def.m_HitboxMaxZ + {a_Def.m_HitboxMinX, a_Def.m_HitboxMinY, a_Def.m_HitboxMinZ}, + {a_Def.m_HitboxMaxX, a_Def.m_HitboxMaxY, a_Def.m_HitboxMaxZ} ), m_AllowedRotations(a_Def.m_AllowedRotations), m_MergeStrategy(a_Def.m_MergeStrategy), diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index bf1fee2e8..5473965d6 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -128,7 +128,10 @@ public: m_Noise(a_Seed), m_MaxSize(a_MaxSize), m_Density(a_Density), - m_Borders(a_OriginX - a_MaxSize, 0, a_OriginZ - a_MaxSize, a_OriginX + a_MaxSize, cChunkDef::Height - 1, a_OriginZ + a_MaxSize), + m_Borders( + {a_OriginX - a_MaxSize, 0, a_OriginZ - a_MaxSize}, + {a_OriginX + a_MaxSize, cChunkDef::Height - 1, a_OriginZ + a_MaxSize} + ), m_Prefabs(a_Prefabs), m_HeightGen(a_HeightGen) { diff --git a/src/Items/ItemHandler.h b/src/Items/ItemHandler.h index 48cf782d8..faee5d008 100644 --- a/src/Items/ItemHandler.h +++ b/src/Items/ItemHandler.h @@ -3,7 +3,6 @@ #include "../Defines.h" #include "../Item.h" -#include "../Blocks/BlockPluginInterface.h" @@ -12,6 +11,7 @@ // fwd: class cWorld; class cPlayer; +class cBlockPluginInterface; diff --git a/src/MobSpawner.h b/src/MobSpawner.h index 2ccc28f0c..14c721ae3 100644 --- a/src/MobSpawner.h +++ b/src/MobSpawner.h @@ -7,12 +7,6 @@ -// fwd: -class cChunk; - - - - /** This class is used to determine which monster can be spawned in which place it is essentially static (eg. Squids spawn in water, Zombies spawn in dark places) diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index 42adfece5..268db6168 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -2,11 +2,11 @@ #pragma once #include "../Entities/Pawn.h" -#include "../Item.h" #include "MonsterTypes.h" #include "PathFinder.h" +class cItem; class cClientHandle; diff --git a/src/Mobs/Ocelot.cpp b/src/Mobs/Ocelot.cpp index 47776670c..e5004a1d1 100644 --- a/src/Mobs/Ocelot.cpp +++ b/src/Mobs/Ocelot.cpp @@ -6,6 +6,7 @@ #include "../Entities/Player.h" #include "../Items/ItemHandler.h" #include "Broadcaster.h" +#include "../BoundingBox.h" @@ -203,3 +204,30 @@ void cOcelot::SpawnOn(cClientHandle & a_ClientHandle) + +class cFindSittingCat : + public cEntityCallback +{ + virtual bool Item(cEntity * a_Entity) override + { + return ( + (a_Entity->GetEntityType() == cEntity::etMonster) && + (static_cast<cMonster *>(a_Entity)->GetMobType() == eMonsterType::mtOcelot) && + (static_cast<cOcelot *>(a_Entity)->IsSitting()) + ); + } +}; + + + + + +bool cOcelot::IsCatSittingOnBlock(cWorld * a_World, Vector3d a_BlockPosition) +{ + cFindSittingCat FindSittingCat; + return a_World->ForEachEntityInBox(cBoundingBox(Vector3d(a_BlockPosition.x, a_BlockPosition.y + 1, a_BlockPosition.z), 1), FindSittingCat); +} + + + + diff --git a/src/Mobs/Ocelot.h b/src/Mobs/Ocelot.h index 5729851fe..59b4f25af 100644 --- a/src/Mobs/Ocelot.h +++ b/src/Mobs/Ocelot.h @@ -54,6 +54,9 @@ public: } void SetCatType (eCatType a_CatType) { m_CatType = a_CatType; } + /** Returns true if there's a cat sitting above the given position */ + static bool IsCatSittingOnBlock(cWorld * a_World, Vector3d a_BlockPosition); + protected: bool m_IsSitting; diff --git a/src/Mobs/Wolf.h b/src/Mobs/Wolf.h index 70e761469..e05fedbf8 100644 --- a/src/Mobs/Wolf.h +++ b/src/Mobs/Wolf.h @@ -2,9 +2,9 @@ #pragma once #include "PassiveAggressiveMonster.h" -#include "../Entities/Entity.h" +class cEntity; diff --git a/src/Protocol/Packetizer.h b/src/Protocol/Packetizer.h index efed9c7a9..26b3a7ec7 100644 --- a/src/Protocol/Packetizer.h +++ b/src/Protocol/Packetizer.h @@ -11,7 +11,10 @@ #pragma once #include "Protocol.h" -#include "../ByteBuffer.h" + + + +class cByteBuffer; diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index 93f25310b..18ede0640 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -12,7 +12,6 @@ #include "../Defines.h" #include "../Scoreboard.h" -#include "../Map.h" #include "../ByteBuffer.h" #include "../EffectID.h" @@ -20,6 +19,7 @@ +class cMap; class cExpOrb; class cPlayer; class cEntity; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 43facde72..a65fb931e 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -59,6 +59,7 @@ AString cProtocolRecognizer::GetVersionTextFromInt(int a_ProtocolVersion) case PROTO_VERSION_1_11_0: return "1.11"; case PROTO_VERSION_1_11_1: return "1.11.1"; case PROTO_VERSION_1_12: return "1.12"; + case PROTO_VERSION_1_12_1: return "1.12.1"; } ASSERT(!"Unknown protocol version"); return Printf("Unknown protocol (%d)", a_ProtocolVersion); @@ -1107,6 +1108,11 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema m_Protocol = new cProtocol_1_12(m_Client, ServerAddress, ServerPort, NextState); return true; } + case PROTO_VERSION_1_12_1: + { + m_Protocol = new cProtocol_1_12_1(m_Client, ServerAddress, ServerPort, NextState); + return true; + } default: { LOGD("Client \"%s\" uses an unsupported protocol (lengthed, version %u (0x%x))", diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 32dcca940..4c338a5b8 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -18,9 +18,9 @@ // Adjust these if a new protocol is added or an old one is removed: -#define MCS_CLIENT_VERSIONS "1.8.x, 1.9.x, 1.10.x, 1.11.x, 1.12" -#define MCS_PROTOCOL_VERSIONS "47, 107, 108, 109, 110, 210, 315, 316, 335" -#define MCS_LATEST_PROTOCOL_VERSION 335 +#define MCS_CLIENT_VERSIONS "1.8.x, 1.9.x, 1.10.x, 1.11.x, 1.12.x" +#define MCS_PROTOCOL_VERSIONS "47, 107, 108, 109, 110, 210, 315, 316, 335, 338" +#define MCS_LATEST_PROTOCOL_VERSION 338 @@ -43,6 +43,7 @@ public: PROTO_VERSION_1_11_0 = 315, PROTO_VERSION_1_11_1 = 316, PROTO_VERSION_1_12 = 335, + PROTO_VERSION_1_12_1 = 338, } ; cProtocolRecognizer(cClientHandle * a_Client); diff --git a/src/Protocol/Protocol_1_12.cpp b/src/Protocol/Protocol_1_12.cpp index 278c063cc..b9eb1801d 100644 --- a/src/Protocol/Protocol_1_12.cpp +++ b/src/Protocol/Protocol_1_12.cpp @@ -1164,7 +1164,7 @@ void cProtocol_1_12::SendExperience(void) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x3f); // Experience Packet + cPacketizer Pkt(*this, 0x3f); // Set Experience Packet cPlayer * Player = m_Client->GetPlayer(); Pkt.WriteBEFloat(Player->GetXpPercentage()); Pkt.WriteVarInt32(static_cast<UInt32>(Player->GetXpLevel())); @@ -1211,7 +1211,7 @@ void cProtocol_1_12::SendScoreboardObjective(const AString & a_Name, const AStri void cProtocol_1_12::SendAttachEntity(const cEntity & a_Entity, const cEntity & a_Vehicle) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x42); // Set passangers packet + cPacketizer Pkt(*this, 0x42); // Set Passengers packet Pkt.WriteVarInt32(a_Vehicle.GetUniqueID()); Pkt.WriteVarInt32(1); // 1 passenger Pkt.WriteVarInt32(a_Entity.GetUniqueID()); @@ -1224,7 +1224,7 @@ void cProtocol_1_12::SendAttachEntity(const cEntity & a_Entity, const cEntity & void cProtocol_1_12::SendDetachEntity(const cEntity & a_Entity, const cEntity & a_PreviousVehicle) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x42); // Set passangers packet + cPacketizer Pkt(*this, 0x42); // Set Passengers packet Pkt.WriteVarInt32(a_PreviousVehicle.GetUniqueID()); Pkt.WriteVarInt32(0); // No passangers } @@ -1600,3 +1600,756 @@ bool cProtocol_1_12::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketTyp m_Client->PacketUnknown(a_PacketType); return false; } + + + + + +cProtocol_1_12_1::cProtocol_1_12_1(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : + super(a_Client, a_ServerAddress, a_ServerPort, a_State) +{ +} + + + + + +void cProtocol_1_12_1::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) +{ + cServer * Server = cRoot::Get()->GetServer(); + AString ServerDescription = Server->GetDescription(); + auto NumPlayers = static_cast<signed>(Server->GetNumPlayers()); + auto MaxPlayers = static_cast<signed>(Server->GetMaxPlayers()); + AString Favicon = Server->GetFaviconData(); + cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon); + + // Version: + Json::Value Version; + Version["name"] = "Cuberite 1.12.1"; + Version["protocol"] = cProtocolRecognizer::PROTO_VERSION_1_12_1; + + // Players: + Json::Value Players; + Players["online"] = NumPlayers; + Players["max"] = MaxPlayers; + // TODO: Add "sample" + + // Description: + Json::Value Description; + Description["text"] = ServerDescription.c_str(); + + // Create the response: + Json::Value ResponseValue; + ResponseValue["version"] = Version; + ResponseValue["players"] = Players; + ResponseValue["description"] = Description; + if (!Favicon.empty()) + { + ResponseValue["favicon"] = Printf("data:image/png;base64,%s", Favicon.c_str()); + } + + // Serialize the response into a packet: + Json::FastWriter Writer; + cPacketizer Pkt(*this, 0x00); // Response packet + Pkt.WriteString(Writer.write(ResponseValue)); +} + + + + + +void cProtocol_1_12_1::SendRespawn(eDimension a_Dimension) +{ + cPacketizer Pkt(*this, 0x35); // Respawn packet + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteBEInt32(static_cast<Int32>(a_Dimension)); + Pkt.WriteBEUInt8(2); // TODO: Difficulty (set to Normal) + Pkt.WriteBEUInt8(static_cast<Byte>(Player->GetEffectiveGameMode())); + Pkt.WriteString("default"); +} + + + + + +void cProtocol_1_12_1::SendPlayerListAddPlayer(const cPlayer & a_Player) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x2e); // Player List Item packet + Pkt.WriteVarInt32(0); + Pkt.WriteVarInt32(1); + Pkt.WriteUUID(a_Player.GetUUID()); + Pkt.WriteString(a_Player.GetPlayerListName()); + + const Json::Value & Properties = a_Player.GetClientHandle()->GetProperties(); + Pkt.WriteVarInt32(Properties.size()); + for (auto & Node : Properties) + { + Pkt.WriteString(Node.get("name", "").asString()); + Pkt.WriteString(Node.get("value", "").asString()); + AString Signature = Node.get("signature", "").asString(); + if (Signature.empty()) + { + Pkt.WriteBool(false); + } + else + { + Pkt.WriteBool(true); + Pkt.WriteString(Signature); + } + } + + Pkt.WriteVarInt32(static_cast<UInt32>(a_Player.GetGameMode())); + Pkt.WriteVarInt32(static_cast<UInt32>(a_Player.GetClientHandle()->GetPing())); + Pkt.WriteBool(false); +} + + + + + +void cProtocol_1_12_1::SendPlayerListRemovePlayer(const cPlayer & a_Player) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x2e); // Player List Item packet + Pkt.WriteVarInt32(4); + Pkt.WriteVarInt32(1); + Pkt.WriteUUID(a_Player.GetUUID()); +} + + + + + +void cProtocol_1_12_1::SendPlayerListUpdateGameMode(const cPlayer & a_Player) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x2e); // Player List Item packet + Pkt.WriteVarInt32(1); + Pkt.WriteVarInt32(1); + Pkt.WriteUUID(a_Player.GetUUID()); + Pkt.WriteVarInt32(static_cast<UInt32>(a_Player.GetGameMode())); +} + + + + + +void cProtocol_1_12_1::SendPlayerListUpdatePing(const cPlayer & a_Player) +{ + ASSERT(m_State == 3); // In game mode? + + auto ClientHandle = a_Player.GetClientHandlePtr(); + if (ClientHandle != nullptr) + { + cPacketizer Pkt(*this, 0x2e); // Player List Item packet + Pkt.WriteVarInt32(2); + Pkt.WriteVarInt32(1); + Pkt.WriteUUID(a_Player.GetUUID()); + Pkt.WriteVarInt32(static_cast<UInt32>(ClientHandle->GetPing())); + } +} + + + + + +void cProtocol_1_12_1::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x2e); // Player List Item packet + Pkt.WriteVarInt32(3); + Pkt.WriteVarInt32(1); + Pkt.WriteUUID(a_Player.GetUUID()); + + if (a_CustomName.empty()) + { + Pkt.WriteBool(false); + } + else + { + Pkt.WriteBool(true); + Pkt.WriteString(Printf("{\"text\":\"%s\"}", a_CustomName.c_str())); + } +} + + + + + +void cProtocol_1_12_1::SendPlayerAbilities(void) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x2c); // Player Abilities packet + Byte Flags = 0; + cPlayer * Player = m_Client->GetPlayer(); + if (Player->IsGameModeCreative()) + { + Flags |= 0x01; + Flags |= 0x08; // Godmode, used for creative + } + if (Player->IsFlying()) + { + Flags |= 0x02; + } + if (Player->CanFly()) + { + Flags |= 0x04; + } + Pkt.WriteBEUInt8(Flags); + Pkt.WriteBEFloat(static_cast<float>(0.05 * Player->GetFlyingMaxSpeed())); + Pkt.WriteBEFloat(static_cast<float>(0.1 * Player->GetNormalMaxSpeed())); +} + + + + + +void cProtocol_1_12_1::SendPlayerMoveLook(void) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x2f); // Player Position And Look packet + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteBEDouble(Player->GetPosX()); + Pkt.WriteBEDouble(Player->GetPosY()); + Pkt.WriteBEDouble(Player->GetPosZ()); + Pkt.WriteBEFloat(static_cast<float>(Player->GetYaw())); + Pkt.WriteBEFloat(static_cast<float>(Player->GetPitch())); + Pkt.WriteBEUInt8(0); + Pkt.WriteVarInt32(++m_OutstandingTeleportId); + + // This teleport ID hasn't been confirmed yet + m_IsTeleportIdConfirmed = false; +} + + + + + +void cProtocol_1_12_1::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x30); // Use bed + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); +} + + + + + +void cProtocol_1_12_1::SendDestroyEntity(const cEntity & a_Entity) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x32); // Destroy Entities packet + Pkt.WriteVarInt32(1); + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); +} + + + + + +void cProtocol_1_12_1::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x33); // Remove entity effect packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEUInt8(static_cast<UInt8>(a_EffectID)); +} + + + + + +void cProtocol_1_12_1::SendEntityHeadLook(const cEntity & a_Entity) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x36); // Entity Head Look packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteByteAngle(a_Entity.GetHeadYaw()); +} + + + + + +void cProtocol_1_12_1::SendCameraSetTo(const cEntity & a_Entity) +{ + cPacketizer Pkt(*this, 0x39); // Camera packet (Attach the camera of a player at another entity in spectator mode) + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); +} + + + + + +void cProtocol_1_12_1::SendDisplayObjective(const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x3b); // Display Scoreboard packet + Pkt.WriteBEUInt8(static_cast<UInt8>(a_Display)); + Pkt.WriteString(a_Objective); +} + + + + + +void cProtocol_1_12_1::SendEntityMetadata(const cEntity & a_Entity) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x3c); // Entity Metadata packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + WriteEntityMetadata(Pkt, a_Entity); + Pkt.WriteBEUInt8(0xff); // The termination byte +} + + + + + +void cProtocol_1_12_1::SendEntityVelocity(const cEntity & a_Entity) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x3e); // Entity Velocity packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + // 400 = 8000 / 20 ... Conversion from our speed in m / s to 8000 m / tick + Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedX() * 400)); + Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400)); + Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedZ() * 400)); +} + + + + + +void cProtocol_1_12_1::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x3f); // Entity Equipment packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + // Needs to be adjusted due to the insertion of offhand at slot 1 + if (a_SlotNum > 0) + { + a_SlotNum++; + } + Pkt.WriteVarInt32(static_cast<UInt32>(a_SlotNum)); + WriteItem(Pkt, a_Item); +} + + + + + +void cProtocol_1_12_1::SendExperience(void) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x40); // Set Experience packet + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteBEFloat(Player->GetXpPercentage()); + Pkt.WriteVarInt32(static_cast<UInt32>(Player->GetXpLevel())); + Pkt.WriteVarInt32(static_cast<UInt32>(Player->GetCurrentXp())); +} + + + + + +void cProtocol_1_12_1::SendHealth(void) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x41); // Update Health packet + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteBEFloat(static_cast<float>(Player->GetHealth())); + Pkt.WriteVarInt32(static_cast<UInt32>(Player->GetFoodLevel())); + Pkt.WriteBEFloat(static_cast<float>(Player->GetFoodSaturationLevel())); +} + + + + + +void cProtocol_1_12_1::SendScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x42); // Scoreboard Objective packet + Pkt.WriteString(a_Name); + Pkt.WriteBEUInt8(a_Mode); + if ((a_Mode == 0) || (a_Mode == 2)) + { + Pkt.WriteString(a_DisplayName); + Pkt.WriteString("integer"); + } +} + + + + + +void cProtocol_1_12_1::SendAttachEntity(const cEntity & a_Entity, const cEntity & a_Vehicle) +{ + ASSERT(m_State == 3); // In game mode? + cPacketizer Pkt(*this, 0x43); // Set Passengers packet + Pkt.WriteVarInt32(a_Vehicle.GetUniqueID()); + Pkt.WriteVarInt32(1); // 1 passenger + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); +} + + + + + +void cProtocol_1_12_1::SendDetachEntity(const cEntity & a_Entity, const cEntity & a_PreviousVehicle) +{ + ASSERT(m_State == 3); // In game mode? + cPacketizer Pkt(*this, 0x43); // Set Passengers packet + Pkt.WriteVarInt32(a_PreviousVehicle.GetUniqueID()); + Pkt.WriteVarInt32(0); // No passangers +} + + + + + +void cProtocol_1_12_1::SendScoreUpdate(const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x45); // Update Score packet + Pkt.WriteString(a_Player); + Pkt.WriteBEUInt8(a_Mode); + Pkt.WriteString(a_Objective); + + if (a_Mode != 1) + { + Pkt.WriteVarInt32(static_cast<UInt32>(a_Score)); + } +} + + + + + +void cProtocol_1_12_1::SendLogin(const cPlayer & a_Player, const cWorld & a_World) +{ + // Send the Join Game packet: + { + cServer * Server = cRoot::Get()->GetServer(); + cPacketizer Pkt(*this, 0x23); // Join Game packet + Pkt.WriteBEUInt32(a_Player.GetUniqueID()); + Pkt.WriteBEUInt8(static_cast<UInt8>(a_Player.GetEffectiveGameMode()) | (Server->IsHardcore() ? 0x08 : 0)); // Hardcore flag bit 4 + Pkt.WriteBEInt32(static_cast<Int32>(a_World.GetDimension())); + Pkt.WriteBEUInt8(2); // TODO: Difficulty (set to Normal) + Pkt.WriteBEUInt8(static_cast<UInt8>(Clamp<size_t>(Server->GetMaxPlayers(), 0, 255))); + Pkt.WriteString("default"); // Level type - wtf? + Pkt.WriteBool(false); // Reduced Debug Info - wtf? + } + + // Send the spawn position: + { + cPacketizer Pkt(*this, 0x46); // Spawn Position packet + Pkt.WritePosition64(FloorC(a_World.GetSpawnX()), FloorC(a_World.GetSpawnY()), FloorC(a_World.GetSpawnZ())); + } + + // Send the server difficulty: + { + cPacketizer Pkt(*this, 0x0d); // Server difficulty packet + Pkt.WriteBEInt8(1); + } + + // Send player abilities: + SendPlayerAbilities(); +} + + + + + +void cProtocol_1_12_1::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) +{ + ASSERT(m_State == 3); // In game mode? + if (!a_DoDaylightCycle) + { + // When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. + a_TimeOfDay = std::min(-a_TimeOfDay, -1LL); + } + + cPacketizer Pkt(*this, 0x47); // Time update packet + Pkt.WriteBEInt64(a_WorldAge); + Pkt.WriteBEInt64(a_TimeOfDay); +} + + + + + +void cProtocol_1_12_1::SendSetRawTitle(const AString & a_Title) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x48); // Title packet + Pkt.WriteVarInt32(0); // Set title + + Pkt.WriteString(a_Title); +} + + + + + +void cProtocol_1_12_1::SendSetRawSubTitle(const AString & a_SubTitle) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x48); // Title packet + Pkt.WriteVarInt32(1); // Set subtitle + + Pkt.WriteString(a_SubTitle); +} + + + + + +void cProtocol_1_12_1::SendTitleTimes(int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x48); // Title packet + Pkt.WriteVarInt32(3); // Set title display times + Pkt.WriteBEInt32(a_FadeInTicks); + Pkt.WriteBEInt32(a_DisplayTicks); + Pkt.WriteBEInt32(a_FadeOutTicks); +} + + + + + +void cProtocol_1_12_1::SendHideTitle(void) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x48); // Title packet + Pkt.WriteVarInt32(4); // Hide title +} + + + + + +void cProtocol_1_12_1::SendResetTitle(void) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x48); // Title packet + Pkt.WriteVarInt32(5); // Reset title +} + + + + + +void cProtocol_1_12_1::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, int a_Count) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x4b); // Collect Item packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteVarInt32(a_Player.GetUniqueID()); + Pkt.WriteVarInt32(static_cast<UInt32>(a_Count)); +} + + + + + +void cProtocol_1_12_1::SendTeleportEntity(const cEntity & a_Entity) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x4c); // Entity teleport packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEDouble(a_Entity.GetPosX()); + Pkt.WriteBEDouble(a_Entity.GetPosY()); + Pkt.WriteBEDouble(a_Entity.GetPosZ()); + Pkt.WriteByteAngle(a_Entity.GetYaw()); + Pkt.WriteByteAngle(a_Entity.GetPitch()); + Pkt.WriteBool(a_Entity.IsOnGround()); +} + + + + + +void cProtocol_1_12_1::SendEntityProperties(const cEntity & a_Entity) +{ + ASSERT(m_State == 3); // In game mode? + + + cPacketizer Pkt(*this, 0x4e); // Entity Properties packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + WriteEntityProperties(Pkt, a_Entity); +} + + + + + +void cProtocol_1_12_1::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x4f); // Entity Effect packet + Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + Pkt.WriteBEUInt8(static_cast<UInt8>(a_EffectID)); + Pkt.WriteBEUInt8(static_cast<UInt8>(a_Amplifier)); + Pkt.WriteVarInt32(static_cast<UInt32>(a_Duration)); + Pkt.WriteBool(false); // Hide particles +} + + + + + +void cProtocol_1_12_1::SendPlayerMaxSpeed(void) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x4e); // Entity Properties + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteVarInt32(Player->GetUniqueID()); + Pkt.WriteBEInt32(1); // Count + Pkt.WriteString("generic.movementSpeed"); + // The default game speed is 0.1, multiply that value by the relative speed: + Pkt.WriteBEDouble(0.1 * Player->GetNormalMaxSpeed()); + if (Player->IsSprinting()) + { + Pkt.WriteVarInt32(1); // Modifier count + Pkt.WriteBEUInt64(0x662a6b8dda3e4c1c); + Pkt.WriteBEUInt64(0x881396ea6097278d); // UUID of the modifier + Pkt.WriteBEDouble(Player->GetSprintingMaxSpeed() - Player->GetNormalMaxSpeed()); + Pkt.WriteBEUInt8(2); + } + else + { + Pkt.WriteVarInt32(0); // Modifier count + } +} + + + + + +bool cProtocol_1_12_1::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) +{ + switch (m_State) + { + case 1: + { + // Status + switch (a_PacketType) + { + case 0x00: HandlePacketStatusRequest(a_ByteBuffer); return true; + case 0x01: HandlePacketStatusPing(a_ByteBuffer); return true; + } + break; + } + + case 2: + { + // Login + switch (a_PacketType) + { + case 0x00: HandlePacketLoginStart(a_ByteBuffer); return true; + case 0x01: HandlePacketLoginEncryptionResponse(a_ByteBuffer); return true; + } + break; + } + + case 3: + { + // Game + switch (a_PacketType) + { + case 0x00: HandleConfirmTeleport(a_ByteBuffer); return true; + case 0x01: HandlePacketTabComplete(a_ByteBuffer); return true; + case 0x02: HandlePacketChatMessage(a_ByteBuffer); return true; + case 0x03: HandlePacketClientStatus(a_ByteBuffer); return true; + case 0x04: HandlePacketClientSettings(a_ByteBuffer); return true; + case 0x05: break; // Confirm transaction - not used in Cuberite + case 0x06: HandlePacketEnchantItem(a_ByteBuffer); return true; + case 0x07: HandlePacketWindowClick(a_ByteBuffer); return true; + case 0x08: HandlePacketWindowClose(a_ByteBuffer); return true; + case 0x09: HandlePacketPluginMessage(a_ByteBuffer); return true; + case 0x0a: HandlePacketUseEntity(a_ByteBuffer); return true; + case 0x0b: HandlePacketKeepAlive(a_ByteBuffer); return true; + case 0x0c: HandlePacketPlayer(a_ByteBuffer); return true; + case 0x0d: HandlePacketPlayerPos(a_ByteBuffer); return true; + case 0x0e: HandlePacketPlayerPosLook(a_ByteBuffer); return true; + case 0x0f: HandlePacketPlayerLook(a_ByteBuffer); return true; + case 0x10: HandlePacketVehicleMove(a_ByteBuffer); return true; + case 0x11: HandlePacketBoatSteer(a_ByteBuffer); return true; + case 0x12: break; // Craft Recipe Request - not yet implemented + case 0x13: HandlePacketPlayerAbilities(a_ByteBuffer); return true; + case 0x14: HandlePacketBlockDig(a_ByteBuffer); return true; + case 0x15: HandlePacketEntityAction(a_ByteBuffer); return true; + case 0x16: HandlePacketSteerVehicle(a_ByteBuffer); return true; + case 0x17: HandlePacketCraftingBookData(a_ByteBuffer); return true; + case 0x18: break; // Resource pack status - not yet implemented + case 0x19: HandlePacketAdvancementTab(a_ByteBuffer); return true; + case 0x1a: HandlePacketSlotSelect(a_ByteBuffer); return true; + case 0x1b: HandlePacketCreativeInventoryAction(a_ByteBuffer); return true; + case 0x1c: HandlePacketUpdateSign(a_ByteBuffer); return true; + case 0x1d: HandlePacketAnimation(a_ByteBuffer); return true; + case 0x1e: HandlePacketSpectate(a_ByteBuffer); return true; + case 0x1f: HandlePacketBlockPlace(a_ByteBuffer); return true; + case 0x20: HandlePacketUseItem(a_ByteBuffer); return true; + } + break; + } + default: + { + // Received a packet in an unknown state, report: + LOGWARNING("Received a packet in an unknown protocol state %d. Ignoring further packets.", m_State); + + // Cannot kick the client - we don't know this state and thus the packet number for the kick packet + + // Switch to a state when all further packets are silently ignored: + m_State = 255; + return false; + } + case 255: + { + // This is the state used for "not processing packets anymore" when we receive a bad packet from a client. + // Do not output anything (the caller will do that for us), just return failure + return false; + } + } // switch (m_State) + + // Unknown packet type, report to the ClientHandle: + m_Client->PacketUnknown(a_PacketType); + return false; +} + + + + diff --git a/src/Protocol/Protocol_1_12.h b/src/Protocol/Protocol_1_12.h index 4d90e2183..53ff05aa6 100644 --- a/src/Protocol/Protocol_1_12.h +++ b/src/Protocol/Protocol_1_12.h @@ -5,6 +5,8 @@ Declares the 1.12 protocol classes: - cProtocol_1_12 - release 1.12 protocol (#335) + - cProtocol_1_12_1 + - release 1.12.1 protocol (#338) (others may be added later in the future for the 1.12 release series) */ @@ -69,3 +71,60 @@ protected: virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) override; virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) override; }; + + + + + +class cProtocol_1_12_1 : + public cProtocol_1_12 +{ + typedef cProtocol_1_12 super; + +public: + cProtocol_1_12_1(cClientHandle * a_Client, const AString &a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State); + + virtual void SendRespawn(eDimension a_Dimension) override; + virtual void SendPlayerListAddPlayer(const cPlayer & a_Player) override; + virtual void SendPlayerListRemovePlayer(const cPlayer & a_Player) override; + virtual void SendPlayerListUpdateGameMode(const cPlayer & a_Player) override; + virtual void SendPlayerListUpdatePing(const cPlayer & a_Player) override; + virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) override; + virtual void SendPlayerAbilities(void) override; + virtual void SendPlayerMoveLook(void) override; + virtual void SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void SendDestroyEntity(const cEntity & a_Entity) override; + virtual void SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) override; + virtual void SendEntityHeadLook(const cEntity & a_Entity) override; + virtual void SendCameraSetTo(const cEntity & a_Entity) override; + virtual void SendDisplayObjective(const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override; + virtual void SendEntityMetadata(const cEntity & a_Entity) override; + virtual void SendEntityVelocity(const cEntity & a_Entity) override; + virtual void SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; + virtual void SendExperience(void) override; + virtual void SendHealth(void) override; + virtual void SendScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; + virtual void SendAttachEntity(const cEntity & a_Entity, const cEntity & a_Vehicle) override; + virtual void SendDetachEntity(const cEntity & a_Entity, const cEntity & a_PreviousVehicle) override; + virtual void SendScoreUpdate(const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override; + virtual void SendLogin(const cPlayer & a_Player, const cWorld & a_World) override; + virtual void SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; + virtual void SendHideTitle(void) override; + virtual void SendResetTitle(void) override; + virtual void SendSetRawSubTitle(const AString & a_SubTitle) override; + virtual void SendSetRawTitle(const AString & a_Title) override; + virtual void SendTitleTimes(int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) override; + virtual void SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, int a_Count) override; + virtual void SendTeleportEntity(const cEntity & a_Entity) override; + virtual void SendEntityProperties(const cEntity & a_Entity) override; + virtual void SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; + virtual void SendPlayerMaxSpeed(void) override; + +protected: + virtual bool HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) override; + virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) override; +}; + + + + diff --git a/src/Simulator/DelayedFluidSimulator.cpp b/src/Simulator/DelayedFluidSimulator.cpp index d21e8dc6d..c3e262dec 100644 --- a/src/Simulator/DelayedFluidSimulator.cpp +++ b/src/Simulator/DelayedFluidSimulator.cpp @@ -78,9 +78,9 @@ cDelayedFluidSimulator::cDelayedFluidSimulator(cWorld & a_World, BLOCKTYPE a_Flu -void cDelayedFluidSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) +void cDelayedFluidSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk) { - if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) + if ((a_Block.y < 0) || (a_Block.y >= cChunkDef::Height)) { // Not inside the world (may happen when rclk with a full bucket - the client sends Y = -1) return; @@ -91,9 +91,9 @@ void cDelayedFluidSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, return; } - int RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; - int RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; - BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_BlockY, RelZ); + int RelX = a_Block.x - a_Chunk->GetPosX() * cChunkDef::Width; + int RelZ = a_Block.z - a_Chunk->GetPosZ() * cChunkDef::Width; + BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_Block.y, RelZ); if (BlockType != m_FluidBlock) { return; @@ -104,7 +104,7 @@ void cDelayedFluidSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cDelayedFluidSimulatorChunkData::cSlot & Slot = ChunkData->m_Slots[m_AddSlotNum]; // Add, if not already present: - if (!Slot.Add(RelX, a_BlockY, RelZ)) + if (!Slot.Add(RelX, a_Block.y, RelZ)) { return; } diff --git a/src/Simulator/DelayedFluidSimulator.h b/src/Simulator/DelayedFluidSimulator.h index 62efb717e..78619a608 100644 --- a/src/Simulator/DelayedFluidSimulator.h +++ b/src/Simulator/DelayedFluidSimulator.h @@ -54,7 +54,7 @@ public: cDelayedFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, int a_TickDelay); // cSimulator overrides: - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override; + virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override; virtual void Simulate(float a_Dt) override; virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override; virtual cFluidSimulatorData * CreateChunkData(void) override { return new cDelayedFluidSimulatorChunkData(m_TickDelay); } diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 55dd7008b..45969bd0a 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -218,16 +218,16 @@ bool cFireSimulator::DoesBurnForever(BLOCKTYPE a_BlockType) -void cFireSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) +void cFireSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk) { if ((a_Chunk == nullptr) || !a_Chunk->IsValid()) { return; } - int RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; - int RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; - BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_BlockY, RelZ); + int RelX = a_Block.x - a_Chunk->GetPosX() * cChunkDef::Width; + int RelZ = a_Block.z - a_Chunk->GetPosZ() * cChunkDef::Width; + BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_Block.y, RelZ); if (!IsAllowedBlock(BlockType)) { return; @@ -237,15 +237,15 @@ void cFireSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * cFireSimulatorChunkData & ChunkData = a_Chunk->GetFireSimulatorData(); for (cCoordWithIntList::iterator itr = ChunkData.begin(), end = ChunkData.end(); itr != end; ++itr) { - if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ)) + if ((itr->x == RelX) && (itr->y == a_Block.y) && (itr->z == RelZ)) { // Already present, skip adding return; } } // for itr - ChunkData[] - FLOG("FS: Adding block {%d, %d, %d}", a_BlockX, a_BlockY, a_BlockZ); - ChunkData.push_back(cCoordWithInt(RelX, a_BlockY, RelZ, 100)); + FLOG("FS: Adding block {%d, %d, %d}", a_Block.x, a_Block.y, a_Block.z); + ChunkData.push_back(cCoordWithInt(RelX, a_Block.y, RelZ, 100)); } diff --git a/src/Simulator/FireSimulator.h b/src/Simulator/FireSimulator.h index 5c926e6ea..bbfeb045e 100644 --- a/src/Simulator/FireSimulator.h +++ b/src/Simulator/FireSimulator.h @@ -43,7 +43,7 @@ protected: int m_ReplaceFuelChance; - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override; + virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override; /** Returns the time [msec] after which the specified fire block is stepped again; based on surrounding fuels */ int GetBurnStepTime(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp index 8d712824f..d24b6aa9b 100644 --- a/src/Simulator/FloodyFluidSimulator.cpp +++ b/src/Simulator/FloodyFluidSimulator.cpp @@ -325,7 +325,7 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i // Spread: FLOG(" Spreading to {%d, %d, %d} with meta %d", BlockX, a_RelY, BlockZ, a_NewMeta); a_NearChunk->SetBlock(a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta); - m_World.GetSimulatorManager()->WakeUp(BlockX, a_RelY, BlockZ, a_NearChunk); + m_World.GetSimulatorManager()->WakeUp({BlockX, a_RelY, BlockZ}, a_NearChunk); HardenBlock(a_NearChunk, a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta); } diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h index a869b3489..e00db39b5 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h +++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h @@ -31,9 +31,9 @@ public: return IsRedstone(a_BlockType); } - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override + virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override { - m_Data.WakeUp({ a_BlockX, a_BlockY, a_BlockZ }); + m_Data.WakeUp(a_Block); } /** Returns if a block is a mechanism (something that accepts power and does something) diff --git a/src/Simulator/NoopFluidSimulator.h b/src/Simulator/NoopFluidSimulator.h index a237e960b..11bbf061d 100644 --- a/src/Simulator/NoopFluidSimulator.h +++ b/src/Simulator/NoopFluidSimulator.h @@ -27,11 +27,9 @@ public: } // cSimulator overrides: - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override + virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override { - UNUSED(a_BlockX); - UNUSED(a_BlockY); - UNUSED(a_BlockZ); + UNUSED(a_Block); UNUSED(a_Chunk); } virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} diff --git a/src/Simulator/NoopRedstoneSimulator.h b/src/Simulator/NoopRedstoneSimulator.h index a5d9e9448..d9e8e00f5 100644 --- a/src/Simulator/NoopRedstoneSimulator.h +++ b/src/Simulator/NoopRedstoneSimulator.h @@ -27,11 +27,9 @@ public: UNUSED(a_Chunk); } virtual bool IsAllowedBlock( BLOCKTYPE a_BlockType) override { return false; } - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override + virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override { - UNUSED(a_BlockX); - UNUSED(a_BlockY); - UNUSED(a_BlockZ); + UNUSED(a_Block); UNUSED(a_Chunk); } diff --git a/src/Simulator/RedstoneSimulator.h b/src/Simulator/RedstoneSimulator.h index cee43db60..2f6b32398 100644 --- a/src/Simulator/RedstoneSimulator.h +++ b/src/Simulator/RedstoneSimulator.h @@ -33,7 +33,7 @@ public: virtual void Simulate(float a_Dt) = 0; virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) = 0; virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) = 0; - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) = 0; + virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) = 0; virtual cRedstoneSimulatorChunkData * CreateChunkData() = 0; diff --git a/src/Simulator/SandSimulator.cpp b/src/Simulator/SandSimulator.cpp index 84e4ba209..01e699b49 100644 --- a/src/Simulator/SandSimulator.cpp +++ b/src/Simulator/SandSimulator.cpp @@ -101,15 +101,15 @@ bool cSandSimulator::IsAllowedBlock(BLOCKTYPE a_BlockType) -void cSandSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) +void cSandSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk) { if ((a_Chunk == nullptr) || !a_Chunk->IsValid()) { return; } - int RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; - int RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; - if (!IsAllowedBlock(a_Chunk->GetBlock(RelX, a_BlockY, RelZ))) + int RelX = a_Block.x - a_Chunk->GetPosX() * cChunkDef::Width; + int RelZ = a_Block.z - a_Chunk->GetPosZ() * cChunkDef::Width; + if (!IsAllowedBlock(a_Chunk->GetBlock(RelX, a_Block.y, RelZ))) { return; } @@ -118,14 +118,14 @@ void cSandSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * cSandSimulatorChunkData & ChunkData = a_Chunk->GetSandSimulatorData(); for (cSandSimulatorChunkData::iterator itr = ChunkData.begin(); itr != ChunkData.end(); ++itr) { - if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ)) + if ((itr->x == RelX) && (itr->y == a_Block.y) && (itr->z == RelZ)) { return; } } m_TotalBlocks += 1; - ChunkData.push_back(cCoordWithInt(RelX, a_BlockY, RelZ)); + ChunkData.push_back(cCoordWithInt(RelX, a_Block.y, RelZ)); } diff --git a/src/Simulator/SandSimulator.h b/src/Simulator/SandSimulator.h index cda26775e..cee0a85e6 100644 --- a/src/Simulator/SandSimulator.h +++ b/src/Simulator/SandSimulator.h @@ -59,7 +59,7 @@ protected: int m_TotalBlocks; // Total number of blocks currently in the queue for simulating - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override; + virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override; /** Performs the instant fall of the block - removes it from top, Finishes it at the bottom */ void DoInstantFall(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); diff --git a/src/Simulator/Simulator.cpp b/src/Simulator/Simulator.cpp index 7d3ce7851..9dbdd6a07 100644 --- a/src/Simulator/Simulator.cpp +++ b/src/Simulator/Simulator.cpp @@ -18,20 +18,20 @@ -void cSimulator::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) +void cSimulator::WakeUp(Vector3i a_Block, cChunk * a_Chunk) { - AddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); - AddBlock(a_BlockX - 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX - 1, a_BlockZ)); - AddBlock(a_BlockX + 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX + 1, a_BlockZ)); - AddBlock(a_BlockX, a_BlockY, a_BlockZ - 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ - 1)); - AddBlock(a_BlockX, a_BlockY, a_BlockZ + 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ + 1)); - if (a_BlockY > 0) + AddBlock(a_Block, a_Chunk); + AddBlock(a_Block + Vector3i(-1, 0, 0), a_Chunk->GetNeighborChunk(a_Block.x - 1, a_Block.z)); + AddBlock(a_Block + Vector3i( 1, 0, 0), a_Chunk->GetNeighborChunk(a_Block.x + 1, a_Block.z)); + AddBlock(a_Block + Vector3i(0, 0, -1), a_Chunk->GetNeighborChunk(a_Block.x, a_Block.z - 1)); + AddBlock(a_Block + Vector3i(0, 0, 1), a_Chunk->GetNeighborChunk(a_Block.x, a_Block.z + 1)); + if (a_Block.y > 0) { - AddBlock(a_BlockX, a_BlockY - 1, a_BlockZ, a_Chunk); + AddBlock(a_Block + Vector3i(0, -1, 0), a_Chunk); } - if (a_BlockY < cChunkDef::Height - 1) + if (a_Block.y < cChunkDef::Height - 1) { - AddBlock(a_BlockX, a_BlockY + 1, a_BlockZ, a_Chunk); + AddBlock(a_Block + Vector3i(0, 1, 0), a_Chunk); } } @@ -47,12 +47,11 @@ void cSimulator::WakeUpArea(const cCuboid & a_Area) area.ClampY(0, cChunkDef::Height - 1); // Add all blocks, in a per-chunk manner: - int chunkStartX, chunkStartZ, chunkEndX, chunkEndZ; - cChunkDef::BlockToChunk(area.p1.x, area.p1.z, chunkStartX, chunkStartZ); - cChunkDef::BlockToChunk(area.p2.x, area.p2.z, chunkEndX, chunkEndZ); - for (int cz = chunkStartZ; cz <= chunkEndZ; ++cz) + cChunkCoords ChunkStart = cChunkDef::BlockToChunk(area.p1); + cChunkCoords ChunkEnd = cChunkDef::BlockToChunk(area.p2); + for (int cz = ChunkStart.m_ChunkZ; cz <= ChunkEnd.m_ChunkZ; ++cz) { - for (int cx = chunkStartX; cx <= chunkEndX; ++cx) + for (int cx = ChunkStart.m_ChunkX; cx <= ChunkEnd.m_ChunkX; ++cx) { m_World.DoWithChunk(cx, cz, [this, &area](cChunk & a_CBChunk) -> bool { @@ -73,7 +72,7 @@ void cSimulator::WakeUpArea(const cCuboid & a_Area) { for (int x = startX; x <= endX; ++x) { - AddBlock(x, y, z, &a_CBChunk); + AddBlock({x, y, z}, &a_CBChunk); } // for x } // for z } // for y diff --git a/src/Simulator/Simulator.h b/src/Simulator/Simulator.h index ef0a3bf68..669680693 100644 --- a/src/Simulator/Simulator.h +++ b/src/Simulator/Simulator.h @@ -39,7 +39,7 @@ public: } /** Called when a block changes */ - void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk); + void WakeUp(Vector3i a_Block, cChunk * a_Chunk); /** Does the same processing as WakeUp, but for all blocks within the specified area. Has better performance than calling WakeUp for each block individually, due to neighbor-checking. @@ -55,7 +55,7 @@ protected: friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up /** Called to simulate a new block */ - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) = 0; + virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) = 0; cWorld & m_World; } ; diff --git a/src/Simulator/SimulatorManager.cpp b/src/Simulator/SimulatorManager.cpp index 78c02fc07..a2740f707 100644 --- a/src/Simulator/SimulatorManager.cpp +++ b/src/Simulator/SimulatorManager.cpp @@ -58,11 +58,11 @@ void cSimulatorManager::SimulateChunk(std::chrono::milliseconds a_Dt, int a_Chun -void cSimulatorManager::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) +void cSimulatorManager::WakeUp(Vector3i a_Block, cChunk * a_Chunk) { for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr) { - itr->first->WakeUp(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); + itr->first->WakeUp(a_Block, a_Chunk); } } diff --git a/src/Simulator/SimulatorManager.h b/src/Simulator/SimulatorManager.h index daa949157..98a60b4ee 100644 --- a/src/Simulator/SimulatorManager.h +++ b/src/Simulator/SimulatorManager.h @@ -36,7 +36,7 @@ public: void SimulateChunk(std::chrono::milliseconds a_DT, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk); /* Called when a single block changes, wakes all simulators up for the block and its face-neighbors. */ - void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk); + void WakeUp(Vector3i a_Block, cChunk * a_Chunk); /** Does the same processing as WakeUp, but for all blocks within the specified area. Has better performance than calling WakeUp for each block individually, due to neighbor-checking. diff --git a/src/Simulator/VaporizeFluidSimulator.cpp b/src/Simulator/VaporizeFluidSimulator.cpp index 1d2db58fb..c023f88c9 100644 --- a/src/Simulator/VaporizeFluidSimulator.cpp +++ b/src/Simulator/VaporizeFluidSimulator.cpp @@ -20,26 +20,26 @@ cVaporizeFluidSimulator::cVaporizeFluidSimulator(cWorld & a_World, BLOCKTYPE a_F -void cVaporizeFluidSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) +void cVaporizeFluidSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk) { if (a_Chunk == nullptr) { return; } - int RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; - int RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; - BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_BlockY, RelZ); + int RelX = a_Block.x - a_Chunk->GetPosX() * cChunkDef::Width; + int RelZ = a_Block.z - a_Chunk->GetPosZ() * cChunkDef::Width; + BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_Block.y, RelZ); if ( (BlockType == m_FluidBlock) || (BlockType == m_StationaryFluidBlock) ) { - a_Chunk->SetBlock(RelX, a_BlockY, RelZ, E_BLOCK_AIR, 0); + a_Chunk->SetBlock(RelX, a_Block.y, RelZ, E_BLOCK_AIR, 0); a_Chunk->BroadcastSoundEffect( "block.fire.extinguish", - static_cast<double>(a_BlockX), - static_cast<double>(a_BlockY), - static_cast<double>(a_BlockZ), + static_cast<double>(a_Block.x), + static_cast<double>(a_Block.y), + static_cast<double>(a_Block.z), 1.0f, 0.6f ); diff --git a/src/Simulator/VaporizeFluidSimulator.h b/src/Simulator/VaporizeFluidSimulator.h index 8076972a8..7a7006309 100644 --- a/src/Simulator/VaporizeFluidSimulator.h +++ b/src/Simulator/VaporizeFluidSimulator.h @@ -25,7 +25,7 @@ public: cVaporizeFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid); // cSimulator overrides: - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override; + virtual void AddBlock(Vector3i a_Block, cChunk * a_Chunk) override; virtual void Simulate(float a_Dt) override; } ; diff --git a/src/UI/ChestWindow.cpp b/src/UI/ChestWindow.cpp index e889f9c44..7b3fe15af 100644 --- a/src/UI/ChestWindow.cpp +++ b/src/UI/ChestWindow.cpp @@ -76,12 +76,12 @@ cChestWindow::~cChestWindow() bool cChestWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) { m_PrimaryChest->SetNumberOfPlayers(m_PrimaryChest->GetNumberOfPlayers() - 1); - m_PrimaryChest->GetWorld()->WakeUpSimulators(m_PrimaryChest->GetPosX(), m_PrimaryChest->GetPosY(), m_PrimaryChest->GetPosZ()); + m_PrimaryChest->GetWorld()->WakeUpSimulators(m_PrimaryChest->GetPos()); if (m_SecondaryChest != nullptr) { m_SecondaryChest->SetNumberOfPlayers(m_SecondaryChest->GetNumberOfPlayers() - 1); - m_SecondaryChest->GetWorld()->WakeUpSimulators(m_SecondaryChest->GetPosX(), m_SecondaryChest->GetPosY(), m_SecondaryChest->GetPosZ()); + m_SecondaryChest->GetWorld()->WakeUpSimulators(m_SecondaryChest->GetPos()); } cWindow::ClosedByPlayer(a_Player, a_CanRefuse); @@ -95,12 +95,12 @@ bool cChestWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) void cChestWindow::OpenedByPlayer(cPlayer & a_Player) { m_PrimaryChest->SetNumberOfPlayers(m_PrimaryChest->GetNumberOfPlayers() + 1); - m_PrimaryChest->GetWorld()->WakeUpSimulators(m_PrimaryChest->GetPosX(), m_PrimaryChest->GetPosY(), m_PrimaryChest->GetPosZ()); + m_PrimaryChest->GetWorld()->WakeUpSimulators(m_PrimaryChest->GetPos()); if (m_SecondaryChest != nullptr) { m_SecondaryChest->SetNumberOfPlayers(m_SecondaryChest->GetNumberOfPlayers() + 1); - m_SecondaryChest->GetWorld()->WakeUpSimulators(m_SecondaryChest->GetPosX(), m_SecondaryChest->GetPosY(), m_SecondaryChest->GetPosZ()); + m_SecondaryChest->GetWorld()->WakeUpSimulators(m_SecondaryChest->GetPos()); } cWindow::OpenedByPlayer(a_Player); diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h index 5a94a26af..be21cdada 100644 --- a/src/UI/SlotArea.h +++ b/src/UI/SlotArea.h @@ -9,7 +9,8 @@ #pragma once #include "../Inventory.h" -#include "Window.h" + + diff --git a/src/UI/Window.h b/src/UI/Window.h index 5bb90a75e..d7a29dc47 100644 --- a/src/UI/Window.h +++ b/src/UI/Window.h @@ -113,7 +113,7 @@ public: void GetSlots(cPlayer & a_Player, cItems & a_Slots) const; /** Handles a click event from a player */ - void Clicked( + virtual void Clicked( cPlayer & a_Player, int a_WindowID, short a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem diff --git a/src/World.cpp b/src/World.cpp index d773a5433..738761aa6 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1289,9 +1289,9 @@ void cWorld::UpdateSkyDarkness(void) -void cWorld::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) +void cWorld::WakeUpSimulators(Vector3i a_Block) { - return m_ChunkMap->WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ); + return m_ChunkMap->WakeUpSimulators(a_Block); } @@ -1300,7 +1300,17 @@ void cWorld::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) void cWorld::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ) { - m_SimulatorManager->WakeUpArea(cCuboid(a_MinBlockX, a_MinBlockY, a_MinBlockZ, a_MaxBlockX, a_MaxBlockY, a_MaxBlockZ)); + LOGWARNING("cWorld::WakeUpSimulatorsInArea(int, int, int) is deprecated, use cWorld::WakeUpSimulatorsInArea(Vector3i) instead."); + WakeUpSimulatorsInArea(cCuboid({a_MinBlockX, a_MinBlockY, a_MinBlockZ}, {a_MaxBlockX, a_MaxBlockY, a_MaxBlockZ})); +} + + + + + +void cWorld::WakeUpSimulatorsInArea(const cCuboid & a_Area) +{ + m_SimulatorManager->WakeUpArea(a_Area); } @@ -3243,7 +3253,7 @@ bool cWorld::DoWithPlayerByUUID(const AString & a_PlayerUUID, cLambdaPlayerCallb -cPlayer * cWorld::FindClosestPlayer(const Vector3d & a_Pos, float a_SightLimit, bool a_CheckLineOfSight) +cPlayer * cWorld::FindClosestPlayer(Vector3d a_Pos, float a_SightLimit, bool a_CheckLineOfSight) { double ClosestDistance = a_SightLimit; cPlayer * ClosestPlayer = nullptr; diff --git a/src/World.h b/src/World.h index 1c0106588..8ff64046d 100644 --- a/src/World.h +++ b/src/World.h @@ -40,13 +40,13 @@ class cChunkGenerator; // The thread responsible for generating chunks class cBeaconEntity; class cBrewingstandEntity; class cChestEntity; +class cCuboid; class cDispenserEntity; class cFlowerPotEntity; class cFurnaceEntity; class cNoteEntity; class cMobHeadEntity; class cCompositeChat; -class cCuboid; class cSetChunkData; class cBroadcaster; class cDeadlockDetect; @@ -282,7 +282,7 @@ public: bool FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << // TODO: This interface is dangerous - rewrite to DoWithClosestPlayer(pos, sight, action) - cPlayer * FindClosestPlayer(const Vector3d & a_Pos, float a_SightLimit, bool a_CheckLineOfSight = true); + cPlayer * FindClosestPlayer(Vector3d a_Pos, float a_SightLimit, bool a_CheckLineOfSight = true); /** Finds the player over his uuid and calls the callback */ bool DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << @@ -417,11 +417,11 @@ public: // tolua_begin // Vector3i variants: - void FastSetBlock(const Vector3i & a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { FastSetBlock( a_Pos.x, a_Pos.y, a_Pos.z, a_BlockType, a_BlockMeta); } - BLOCKTYPE GetBlock (const Vector3i & a_Pos) { return GetBlock( a_Pos.x, a_Pos.y, a_Pos.z); } - NIBBLETYPE GetBlockMeta(const Vector3i & a_Pos) { return GetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z); } - void SetBlockMeta(const Vector3i & a_Pos, NIBBLETYPE a_MetaData) { SetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z, a_MetaData); } - NIBBLETYPE GetBlockBlockLight(const Vector3i & a_Pos) { return GetBlockBlockLight( a_Pos.x, a_Pos.y, a_Pos.z); } + void FastSetBlock(Vector3i a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { FastSetBlock( a_Pos.x, a_Pos.y, a_Pos.z, a_BlockType, a_BlockMeta); } + BLOCKTYPE GetBlock (Vector3i a_Pos) { return GetBlock( a_Pos.x, a_Pos.y, a_Pos.z); } + NIBBLETYPE GetBlockMeta(Vector3i a_Pos) { return GetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z); } + void SetBlockMeta(Vector3i a_Pos, NIBBLETYPE a_MetaData) { SetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z, a_MetaData); } + NIBBLETYPE GetBlockBlockLight(Vector3i a_Pos) { return GetBlockBlockLight( a_Pos.x, a_Pos.y, a_Pos.z); } // tolua_end /** Writes the block area into the specified coords. @@ -489,9 +489,19 @@ public: double GetSpawnZ(void) const { return m_SpawnZ; } /** Wakes up the simulators for the specified block */ - virtual void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void WakeUpSimulators(Vector3i a_Block) override; /** Wakes up the simulators for the specified area of blocks */ + void WakeUpSimulatorsInArea(const cCuboid & a_Area); + + // DEPRECATED, use vector-parametered version instead + void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) + { + LOGWARNING("cWorld::WakeUpSimulators(int, int, int) is deprecated, use cWorld::WakeUpSimulators(Vector3i) instead."); + WakeUpSimulators({a_BlockX, a_BlockY, a_BlockZ}); + } + + // DEPRECATED, use vector-parametered version instead void WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ); // tolua_end diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index 37ccdda4c..454e6f73d 100755 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -10,7 +10,6 @@ #include "WorldStorage.h" #include "FastNBT.h" -#include "../Mobs/Monster.h" @@ -18,7 +17,7 @@ // fwd: ItemGrid.h class cItemGrid; - +class cMonster; class cProjectileEntity; class cHangingEntity; |