summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTiger Wang <ziwei.tiger@hotmail.co.uk>2014-04-24 19:57:25 +0200
committerTiger Wang <ziwei.tiger@hotmail.co.uk>2014-04-24 19:57:25 +0200
commit48904ae201a38c4b6e018567976c00c40c2829c9 (patch)
treedfba8600b7f48e09c3c1d752b1cce1b4a45c8ea8
parentSome change to Entity.cpp (diff)
parentThe new leaves don't decay anymore. (diff)
downloadcuberite-48904ae201a38c4b6e018567976c00c40c2829c9.tar
cuberite-48904ae201a38c4b6e018567976c00c40c2829c9.tar.gz
cuberite-48904ae201a38c4b6e018567976c00c40c2829c9.tar.bz2
cuberite-48904ae201a38c4b6e018567976c00c40c2829c9.tar.lz
cuberite-48904ae201a38c4b6e018567976c00c40c2829c9.tar.xz
cuberite-48904ae201a38c4b6e018567976c00c40c2829c9.tar.zst
cuberite-48904ae201a38c4b6e018567976c00c40c2829c9.zip
-rw-r--r--MCServer/Plugins/APIDump/APIDesc.lua7
-rw-r--r--MCServer/Plugins/APIDump/UsingChunkStays.html167
-rw-r--r--MCServer/Plugins/APIDump/WebWorldThreads.html48
-rw-r--r--MCServer/monsters.ini9
-rw-r--r--MakeLuaAPI.cmd2
-rw-r--r--SetFlags.cmake8
-rw-r--r--src/BlockEntities/BeaconEntity.cpp116
-rw-r--r--src/BlockEntities/BeaconEntity.h44
-rw-r--r--src/BlockEntities/BlockEntity.cpp2
-rw-r--r--src/BlockEntities/DispenserEntity.cpp9
-rw-r--r--src/BlockEntities/FurnaceEntity.cpp7
-rw-r--r--src/BlockEntities/HopperEntity.cpp11
-rw-r--r--src/Blocks/BlockChest.h1
-rw-r--r--src/Blocks/BlockEnchantmentTable.h37
-rw-r--r--src/Blocks/BlockHandler.cpp2
-rw-r--r--src/Blocks/BlockLeaves.h1
-rw-r--r--src/Blocks/BlockRail.h2
-rw-r--r--src/BoundingBox.cpp2
-rw-r--r--src/Chunk.cpp6
-rw-r--r--src/Chunk.h4
-rw-r--r--src/ChunkMap.cpp40
-rw-r--r--src/ClientHandle.cpp37
-rw-r--r--src/ClientHandle.h5
-rw-r--r--src/CraftingRecipes.cpp12
-rw-r--r--src/Crypto.cpp2
-rw-r--r--src/DeadlockDetect.cpp13
-rw-r--r--src/Enchantments.cpp787
-rw-r--r--src/Enchantments.h78
-rw-r--r--src/Entities/Entity.cpp26
-rw-r--r--src/Entities/Entity.h8
-rw-r--r--src/Entities/Minecart.cpp2
-rw-r--r--src/Entities/Player.cpp11
-rw-r--r--src/Entities/Player.h2
-rw-r--r--src/FastRandom.cpp10
-rw-r--r--src/FastRandom.h3
-rw-r--r--src/FurnaceRecipe.cpp1
-rw-r--r--src/Generating/Caves.cpp36
-rw-r--r--src/Generating/Prefab.cpp9
-rw-r--r--src/Generating/Prefab.h6
-rw-r--r--src/Generating/Prefabs/NetherFortPrefabs.cpp1183
-rw-r--r--src/Generating/Ravines.cpp15
-rw-r--r--src/Group.cpp4
-rw-r--r--src/Group.h8
-rw-r--r--src/Item.cpp156
-rw-r--r--src/Item.h7
-rw-r--r--src/Items/ItemHandler.cpp1
-rw-r--r--src/Items/ItemHandler.h4
-rw-r--r--src/MobProximityCounter.cpp4
-rw-r--r--src/MobSpawner.cpp4
-rw-r--r--src/Mobs/Sheep.cpp7
-rw-r--r--src/Mobs/Wolf.h2
-rw-r--r--src/MonsterConfig.cpp3
-rw-r--r--src/Noise.cpp22
-rw-r--r--src/Protocol/Authenticator.cpp7
-rw-r--r--src/Protocol/Protocol125.cpp48
-rw-r--r--src/Protocol/Protocol125.h1
-rw-r--r--src/Protocol/Protocol132.cpp18
-rw-r--r--src/Protocol/Protocol14x.cpp12
-rw-r--r--src/Protocol/Protocol16x.cpp36
-rw-r--r--src/Protocol/Protocol16x.h1
-rw-r--r--src/Protocol/Protocol17x.cpp98
-rw-r--r--src/Protocol/Protocol17x.h1
-rw-r--r--src/Protocol/ProtocolRecognizer.cpp13
-rw-r--r--src/Server.cpp4
-rw-r--r--src/Server.h4
-rw-r--r--src/Simulator/FireSimulator.cpp2
-rw-r--r--src/Simulator/FluidSimulator.cpp2
-rw-r--r--src/StackWalker.cpp3
-rw-r--r--src/UI/SlotArea.cpp316
-rw-r--r--src/UI/SlotArea.h32
-rw-r--r--src/UI/Window.cpp60
-rw-r--r--src/UI/Window.h34
-rw-r--r--src/WebAdmin.cpp6
-rw-r--r--src/World.cpp10
-rw-r--r--src/World.h2
-rw-r--r--src/WorldStorage/FastNBT.cpp4
-rw-r--r--src/WorldStorage/WSSCompact.cpp2
-rw-r--r--src/WorldStorage/WSSCompact.h2
78 files changed, 3146 insertions, 565 deletions
diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua
index 233bdbc46..45e8d9677 100644
--- a/MCServer/Plugins/APIDump/APIDesc.lua
+++ b/MCServer/Plugins/APIDump/APIDesc.lua
@@ -2929,9 +2929,10 @@ end
{
-- No sorting is provided for these, they will be output in the same order as defined here
{ FileName = "Writing-a-MCServer-plugin.html", Title = "Writing a MCServer plugin" },
- { FileName = "SettingUpDecoda.html", Title = "Setting up the Decoda Lua IDE" },
- { FileName = "SettingUpZeroBrane.html", Title = "Setting up the ZeroBrane Studio Lua IDE" },
- { FileName = "WebWorldThreads.html", Title = "Webserver vs World threads" },
+ { FileName = "SettingUpDecoda.html", Title = "Setting up the Decoda Lua IDE" },
+ { FileName = "SettingUpZeroBrane.html", Title = "Setting up the ZeroBrane Studio Lua IDE" },
+ { FileName = "UsingChunkStays.html", Title = "Using ChunkStays" },
+ { FileName = "WebWorldThreads.html", Title = "Webserver vs World threads" },
}
} ;
diff --git a/MCServer/Plugins/APIDump/UsingChunkStays.html b/MCServer/Plugins/APIDump/UsingChunkStays.html
new file mode 100644
index 000000000..d3ecc6674
--- /dev/null
+++ b/MCServer/Plugins/APIDump/UsingChunkStays.html
@@ -0,0 +1,167 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>MCServer - Using ChunkStays</title>
+ <link rel="stylesheet" type="text/css" href="main.css" />
+ <link rel="stylesheet" type="text/css" href="prettify.css" />
+ <script src="prettify.js"></script>
+ <script src="lang-lua.js"></script>
+ <meta charset="UTF-8">
+ </head>
+ <body>
+ <div id="content">
+ <h1>Using ChunkStays</h1>
+ <p>
+ A plugin may need to manipulate data in arbitrary chunks, and it needs a way to make the server
+ guarantee that the chunks are available in memory.</p>
+
+ <h2>The problem</h2>
+ <p>
+ Usually when plugins want to manipulate larger areas of world data, they need to make sure that the
+ server has the appropriate chunks loaded in the memory. When the data being manipulated can be further
+ away from the connected players, or the data is being manipulated from a console handler, there is a
+ real chance that the chunks are not loaded.</p>
+ <p>
+ This gets even more important when using the <a href="cBlockArea.html">cBlockArea</a> class for reading
+ and writing. Those functions will fail when any of the required chunks aren't valid. This means that
+ either the block area has incomplete data (Read() failed) or incomplete data has been written to the
+ world (Write() failed). Recovery from this is near impossible - you can't simply read or write again
+ later, because the world may have changed in the meantime.</p>
+
+ <h2>The solution</h2>
+ <p>
+ The naive solution would be to monitor chunk loads and unloads, and postpone the operations until all
+ the chunks are available. This would be quite ineffective and also very soon it would become very
+ difficult to maintain, if there were multiple code paths requiring this handling.</p>
+ <p>
+ An alternate approach has been implemented, accessible through a single (somewhat hidden) function
+ call: <a href="cWorld.html">cWorld:ChunkStay()</a>. All that this call basically does is, it tells the
+ server "Load these chunks for me, and call this callback function once you have them all." And the
+ server does exactly that - it remembers the callback and asks the world loader / generator to provide
+ the chunks. Once the chunks become available, it calls the callback function for the plugin.</p>
+ <p>
+ There are a few gotcha-s, though. If the code that was requesting the read or write had access to some
+ of the volatile objects, such as <a href="cPlayer.html">cPlayer</a> or
+ <a href="cEntity.html">cEntity</a> objects, those cannot be accessed by the callback anymore, because
+ they may have become invalid in the meantime - the player may have disconnected, the entity may have
+ despawned. So the callback must use the longer way to access such objects, such as calling
+ <a href="cWorld.html">cWorld:DoWithEntityByID()</a> or
+ <a href="cWorld.html">cWorld:DoWithPlayer()</a>.</p>
+
+ <h2>The example</h2>
+ <p>
+ As a simple example, consider a theoretical plugin that allows a player to save the immediate
+ surroundings of the spawn into a schematic file. The player issues a command to initiate the save, and
+ the plugin reads a 50 x 50 x 50 block area around the spawn into a cBlockArea and saves it on the disk
+ as "<PlayerName>_spawn.schematic". When it's done with the saving, it wants to send a message to the
+ player to let them know the command has succeeded.</p>
+ <p>
+ The first attempt shows the naive approach. It simply reads the block area and saves it, then sends the
+ message. I'll repeat once more, this code is <b>the wrong way</b> to do it!</p>
+<pre class="prettyprint lang-lua">
+function HandleCommandSaveSpawn(a_Split, a_Player)
+ -- Get the coords for the spawn:
+ local SpawnX = a_Player:GetWorld():GetSpawnX()
+ local SpawnY = a_Player:GetWorld():GetSpawnY()
+ local SpawnZ = a_Player:GetWorld():GetSpawnZ()
+ local Bounds = cCuboid(SpawnX - 25, SpawnY - 25, SpawnZ - 25, SpawnX + 25, SpawnY + 25, SpawnZ + 25)
+ Bounds:ClampY(0, 255)
+
+ -- Read the area around spawn into a cBlockArea, save to file:
+ local Area = cBlockArea()
+ local FileName = a_Player:GetName() .. "_spawn.schematic"
+ Area:Read(a_Player:GetWorld(), Bounds, cBlockArea.baTypes + cBlockArea.baMetas)
+ Area:SaveToSchematicFile(FileName)
+
+ -- Notify the player:
+ a_Player:SendMessage(cCompositeChat("The spawn has been saved", mtInfo))
+ return true
+end
+</pre>
+ <p>
+ Now if the player goes exploring far and uses the command to save their spawn, the chunks aren't
+ loaded, so the BlockArea reading fails, the BlockArea contains bad data. Note that the plugin fails to
+ do any error checking and if the area isn't read from the world, it happily saves the incomplete data
+ and says "hey, everything's right", althought it has just trashed any previous backup of the spawn
+ schematic with nonsense data.</p>
+ <hr/>
+ <p>
+ The following script uses the ChunkStay method to alleviate chunk-related problems. This is <b>the
+ right way</b> of doing it:</p>
+<pre class="prettyprint lang-lua">
+function HandleCommandSaveSpawn(a_Split, a_Player)
+ -- Get the coords for the spawn:
+ local SpawnX = a_Player:GetWorld():GetSpawnX()
+ local SpawnY = a_Player:GetWorld():GetSpawnY()
+ local SpawnZ = a_Player:GetWorld():GetSpawnZ()
+ local Bounds = cCuboid(SpawnX - 25, SpawnY - 25, SpawnZ - 25, SpawnX + 25, SpawnY + 25, SpawnZ + 25)
+ Bounds:ClampY(0, 255)
+
+ -- Get a list of chunks that we need loaded:
+ local MinChunkX = math.floor((SpawnX - 25) / 16)
+ local MaxChunkX = math.ceil ((SpawnX + 25) / 16)
+ local MinChunkZ = math.floor((SpawnZ - 25) / 16)
+ local MaxChunkZ = math.ceil ((SpawnZ + 25) / 16)
+ local Chunks = {}
+ for x = MinChunkX, MaxChunkX do
+ for z = MinChunkZ, MaxChunkZ do
+ table.insert(Chunks, {x, z})
+ end
+ end -- for x
+
+ -- Store the player's name and world to use in the callback, because the a_Player object may no longer be valid:
+ local PlayerName = a_Player:GetName()
+ local World = a_Player:GetWorld()
+
+ -- This is the callback that is executed once all the chunks are loaded:
+ local OnAllChunksAvailable = function()
+ -- Read the area around spawn into a cBlockArea, save to file:
+ local Area = cBlockArea()
+ local FileName = PlayerName .. "_spawn.schematic"
+ if (Area:Read(World, Bounds, cBlockArea.baTypes + cBlockArea.baMetas)) then
+ Area:SaveToSchematicFile(FileName)
+ Msg = cCompositeChat("The spawn has been saved", mtInfo)
+ else
+ Msg = cCompositeChat("Cannot save the spawn", mtFailure)
+ end
+
+ -- Notify the player:
+ -- Note that we cannot use a_Player here, because it may no longer be valid (if the player disconnected before the command completes)
+ World:DoWithPlayer(PlayerName,
+ function (a_CBPlayer)
+ a_CBPlayer:SendMessage(Msg)
+ end
+ )
+ end
+
+ -- Ask the server to load our chunks and notify us once it's done:
+ World:ChunkStay(Chunks, nil, OnAllChunksAvailable)
+
+ -- Note that code here may get executed before the callback is called!
+ -- The ChunkStay says "once you have the chunks", not "wait until you have the chunks"
+ -- So you can't notify the player here, because the saving needn't have occurred yet.
+
+ return true
+end
+</pre>
+ <p>
+ Note that this code does its error checking of the Area:Read() function, and it will not overwrite the
+ previous file unless it actually has the correct data. If you're wondering how the reading could fail
+ when we've got the chunks loaded, there's still the issue of free RAM - if the memory for the area
+ cannot be allocated, it cannot be read even with all the chunks present. So we still do need that
+ check.</p>
+
+ <h2>The conclusion</h2>
+ <p>
+ Although it makes the code a little bit longer and is a bit more difficult to grasp at first, the
+ ChunkStay is a useful technique to add to your repertoire. It is to be used whenever you need access to
+ chunks that may potentially be inaccessible, and you really need the data.</p>
+ <p>Possibly the biggest hurdle in using the ChunkStay is the fact that it does its work in the
+ background, thus invalidating all cPlayer and cEntity objects your function may hold, so you need to
+ re-acquire them from their IDs and names. This is the penalty for using multi-threaded code.</p>
+ <script>
+ prettyPrint();
+ </script>
+ </div>
+ </body>
+</html>
diff --git a/MCServer/Plugins/APIDump/WebWorldThreads.html b/MCServer/Plugins/APIDump/WebWorldThreads.html
index fc80a6178..ee0b172e6 100644
--- a/MCServer/Plugins/APIDump/WebWorldThreads.html
+++ b/MCServer/Plugins/APIDump/WebWorldThreads.html
@@ -39,31 +39,31 @@
<h2>Example</h2>
The Core has the facility to kick players using the web interface. It used the following code for the kicking (inside the webadmin handler):
- <pre class="prettyprint lang-lua">
- local KickPlayerName = Request.Params["players-kick"]
- local FoundPlayerCallback = function(Player)
- if (Player:GetName() == KickPlayerName) then
- Player:GetClientHandle():Kick("You were kicked from the game!")
- end
+<pre class="prettyprint lang-lua">
+local KickPlayerName = Request.Params["players-kick"]
+local FoundPlayerCallback = function(Player)
+ if (Player:GetName() == KickPlayerName) then
+ Player:GetClientHandle():Kick("You were kicked from the game!")
+ end
+end
+cRoot:Get():FindAndDoWithPlayer(KickPlayerName, FoundPlayerCallback)
+</pre>
+The cRoot:FindAndDoWithPlayer() is unsafe and could have caused a deadlock. The new solution is queue a task; but since we don't know in which world the player is, we need to queue the task to all worlds:
+<pre class="prettyprint lang-lua">
+cRoot:Get():ForEachWorld( -- For each world...
+ function(World)
+ World:QueueTask( -- ... queue a task...
+ function(a_World)
+ a_World:DoWithPlayer(KickPlayerName, -- ... to walk the playerlist...
+ function (a_Player)
+ a_Player:GetClientHandle():Kick("You were kicked from the game!") -- ... and kick the player
end
- cRoot:Get():FindAndDoWithPlayer(KickPlayerName, FoundPlayerCallback)
- </pre>
- The cRoot:FindAndDoWithPlayer() is unsafe and could have caused a deadlock. The new solution is queue a task; but since we don't know in which world the player is, we need to queue the task to all worlds:
- <pre class="prettyprint lang-lua">
- cRoot:Get():ForEachWorld( -- For each world...
- function(World)
- World:QueueTask( -- ... queue a task...
- function(a_World)
- a_World:DoWithPlayer(KickPlayerName, -- ... to walk the playerlist...
- function (a_Player)
- a_Player:GetClientHandle():Kick("You were kicked from the game!") -- ... and kick the player
- end
- )
- end
- )
- end
- )
- </pre>
+ )
+ end
+ )
+ end
+)
+</pre>
<script>
prettyPrint();
</script>
diff --git a/MCServer/monsters.ini b/MCServer/monsters.ini
index 8cd956157..fa376bfff 100644
--- a/MCServer/monsters.ini
+++ b/MCServer/monsters.ini
@@ -47,12 +47,13 @@ AttackDamage=4.0
SightDistance=25.0
MaxHealth=40
-[Zombiepigman]
+[ZombiePigman]
AttackRange=2.0
AttackRate=1
AttackDamage=7.0
SightDistance=25.0
MaxHealth=20
+IsFireproof=1
[Cavespider]
AttackRange=2.0
@@ -74,6 +75,7 @@ AttackRate=1
AttackDamage=0.0
SightDistance=50.0
MaxHealth=10
+IsFireproof=1
[Silverfish]
AttackRange=2.0
@@ -115,6 +117,7 @@ AttackRate=1
AttackDamage=6.0
SightDistance=25.0
MaxHealth=20
+IsFireproof=1
[Villager]
AttackRange=2.0
@@ -122,6 +125,7 @@ AttackRate=1
AttackDamage=0.0
SightDistance=25.0
MaxHealth=20
+IsFireproof=0
[Witch]
AttackRange=2.0
@@ -145,12 +149,13 @@ AttackDamage=0.0
SightDistance=25.0
MaxHealth=10
-[Magmacube]
+[MagmaCube]
AttackRange=2.0
AttackRate=1
AttackDamage=6.0
SightDistance=25.0
MaxHealth=16
+IsFireproof=1
[Horse]
AttackRange=2.0
diff --git a/MakeLuaAPI.cmd b/MakeLuaAPI.cmd
index 7054977a0..90b8cf53e 100644
--- a/MakeLuaAPI.cmd
+++ b/MakeLuaAPI.cmd
@@ -30,7 +30,7 @@ if "a%ftpsite%" == "a" (
cd MCServer
copy /Y settings_apidump.ini settings.ini
-echo stop | MCServer
+echo api | MCServer
cd ..
diff --git a/SetFlags.cmake b/SetFlags.cmake
index 6c974ea94..c5a3a0697 100644
--- a/SetFlags.cmake
+++ b/SetFlags.cmake
@@ -46,10 +46,6 @@ macro(set_flags)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
else()
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++0x")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++0x")
-
add_flags_cxx("-pthread")
endif()
@@ -60,10 +56,6 @@ macro(set_flags)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
- else()
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++0x")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++0x")
endif()
# We use a signed char (fixes #640 on RasPi)
diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp
new file mode 100644
index 000000000..0914353eb
--- /dev/null
+++ b/src/BlockEntities/BeaconEntity.cpp
@@ -0,0 +1,116 @@
+
+#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
+
+#include "BeaconEntity.h"
+#include "../BlockArea.h"
+
+
+
+
+
+cBeaconEntity::cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
+ super(E_BLOCK_BEACON, a_BlockX, a_BlockY, a_BlockZ, a_World)
+{
+}
+
+
+
+
+
+int cBeaconEntity::GetPyramidLevel(void)
+{
+ cBlockArea Area;
+ int MinY = GetPosY() - 4;
+ if (MinY < 0)
+ {
+ MinY = 0;
+ }
+ int MaxY = GetPosY() - 1;
+ if (MaxY < 0)
+ {
+ MaxY = 0;
+ }
+
+ Area.Read(
+ m_World,
+ GetPosX() - 4, GetPosX() + 4,
+ MinY, MaxY,
+ GetPosZ() - 4, GetPosZ() + 4,
+ cBlockArea::baTypes
+ );
+
+ int Layer = 1;
+ int MiddleXZ = 4;
+
+ for (int Y = Area.GetSizeY() - 1; Y > 0; Y--)
+ {
+ for (int X = MiddleXZ - Layer; X <= (MiddleXZ + Layer); X++)
+ {
+ for (int Z = MiddleXZ - Layer; Z <= (MiddleXZ + Layer); Z++)
+ {
+ if (!IsMineralBlock(Area.GetRelBlockType(X, Y, Z)))
+ {
+ return Layer - 1;
+ }
+ }
+ }
+ Layer++;
+ }
+
+ return Layer - 1;
+}
+
+
+
+
+
+bool cBeaconEntity::IsMineralBlock(BLOCKTYPE a_BlockType)
+{
+ switch(a_BlockType)
+ {
+ case E_BLOCK_DIAMOND_BLOCK:
+ case E_BLOCK_GOLD_BLOCK:
+ case E_BLOCK_IRON_BLOCK:
+ case E_BLOCK_EMERALD_BLOCK:
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+
+
+bool cBeaconEntity::Tick(float a_Dt, cChunk & a_Chunk)
+{
+ return false;
+}
+
+
+
+
+
+void cBeaconEntity::SaveToJson(Json::Value& a_Value)
+{
+}
+
+
+
+
+void cBeaconEntity::SendTo(cClientHandle & a_Client)
+{
+}
+
+
+
+
+
+void cBeaconEntity::UsedBy(cPlayer * a_Player)
+{
+}
+
+
+
+
diff --git a/src/BlockEntities/BeaconEntity.h b/src/BlockEntities/BeaconEntity.h
new file mode 100644
index 000000000..b1df68bc4
--- /dev/null
+++ b/src/BlockEntities/BeaconEntity.h
@@ -0,0 +1,44 @@
+
+#pragma once
+
+#include "BlockEntity.h"
+
+
+
+
+
+namespace Json
+{
+ class Value;
+}
+
+
+
+
+
+class cBeaconEntity :
+ public cBlockEntity
+{
+ typedef cBlockEntity super;
+
+public:
+
+ /** The initial constructor */
+ cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
+
+ /** Returns the amount of layers the pyramid below the beacon has. */
+ int GetPyramidLevel(void);
+
+ /** Returns true if the block is a diamond block, a golden block, an iron block or an emerald block. */
+ static bool IsMineralBlock(BLOCKTYPE a_BlockType);
+
+ // cBlockEntity overrides:
+ virtual void SaveToJson(Json::Value& a_Value ) override;
+ virtual void SendTo(cClientHandle & a_Client) override;
+ virtual void UsedBy(cPlayer * a_Player) override;
+ virtual bool Tick(float a_Dt, cChunk & /* a_Chunk */) override;
+} ;
+
+
+
+
diff --git a/src/BlockEntities/BlockEntity.cpp b/src/BlockEntities/BlockEntity.cpp
index b42318c2f..430f04551 100644
--- a/src/BlockEntities/BlockEntity.cpp
+++ b/src/BlockEntities/BlockEntity.cpp
@@ -4,6 +4,7 @@
// Implements the cBlockEntity class that is the common ancestor for all block entities
#include "Globals.h"
+#include "BeaconEntity.h"
#include "BlockEntity.h"
#include "ChestEntity.h"
#include "CommandBlockEntity.h"
@@ -26,6 +27,7 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE
{
switch (a_BlockType)
{
+ case E_BLOCK_BEACON: return new cBeaconEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
case E_BLOCK_CHEST: return new cChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
case E_BLOCK_COMMAND_BLOCK: return new cCommandBlockEntity(a_BlockX, a_BlockY, a_BlockZ, a_World);
case E_BLOCK_DISPENSER: return new cDispenserEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp
index e03bf776d..2a32f69d9 100644
--- a/src/BlockEntities/DispenserEntity.cpp
+++ b/src/BlockEntities/DispenserEntity.cpp
@@ -128,10 +128,11 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
if (DispChunk->GetBlock(DispX, DispY, DispZ) == E_BLOCK_AIR)
{
DispChunk->SetBlock(DispX, DispY, DispZ, E_BLOCK_FIRE, 0);
- m_Contents.SetSlot(a_SlotNum, m_Contents.GetSlot(a_SlotNum).m_ItemType, m_Contents.GetSlot(a_SlotNum).m_ItemCount, m_Contents.GetSlot(a_SlotNum).m_ItemDamage + 1);
- // If the durability has run out destroy the item.
- if (m_Contents.GetSlot(a_SlotNum).m_ItemDamage > 64)
- {
+
+ bool ItemBroke = m_Contents.DamageItem(a_SlotNum, 1);
+
+ if (ItemBroke)
+ {
m_Contents.ChangeSlotCount(a_SlotNum, -1);
}
}
diff --git a/src/BlockEntities/FurnaceEntity.cpp b/src/BlockEntities/FurnaceEntity.cpp
index 7d6d1f89e..1b1741713 100644
--- a/src/BlockEntities/FurnaceEntity.cpp
+++ b/src/BlockEntities/FurnaceEntity.cpp
@@ -413,19 +413,20 @@ bool cFurnaceEntity::CanCookInputToOutput(void) const
return false;
}
- if (m_Contents.GetSlot(fsOutput).IsEmpty())
+ const cItem & Slot = m_Contents.GetSlot(fsOutput);
+ if (Slot.IsEmpty())
{
// The output is empty, can cook
return true;
}
- if (!m_Contents.GetSlot(fsOutput).IsEqual(*m_CurrentRecipe->Out))
+ if (!Slot.IsEqual(*m_CurrentRecipe->Out))
{
// The output slot is blocked with something that cannot be stacked with the recipe's output
return false;
}
- if (m_Contents.GetSlot(fsOutput).IsFullStack())
+ if (Slot.IsFullStack())
{
// Cannot add any more items to the output slot
return false;
diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp
index 41fb9f811..7f001c739 100644
--- a/src/BlockEntities/HopperEntity.cpp
+++ b/src/BlockEntities/HopperEntity.cpp
@@ -234,24 +234,27 @@ bool cHopperEntity::MovePickupsIn(cChunk & a_Chunk, Int64 a_CurrentTick)
bool TrySuckPickupIn(cPickup * a_Pickup)
{
+ cItem & Item = a_Pickup->GetItem();
+
for (int i = 0; i < ContentsWidth * ContentsHeight; i++)
{
if (m_Contents.IsSlotEmpty(i))
{
m_bFoundPickupsAbove = true;
- m_Contents.SetSlot(i, a_Pickup->GetItem());
+ m_Contents.SetSlot(i, Item);
a_Pickup->Destroy(); // Kill pickup
return true;
}
- else if (m_Contents.GetSlot(i).IsEqual(a_Pickup->GetItem()) && !m_Contents.GetSlot(i).IsFullStack())
+ else if (m_Contents.GetSlot(i).IsEqual(Item) && !m_Contents.GetSlot(i).IsFullStack())
{
m_bFoundPickupsAbove = true;
int PreviousCount = m_Contents.GetSlot(i).m_ItemCount;
- a_Pickup->GetItem().m_ItemCount -= m_Contents.ChangeSlotCount(i, a_Pickup->GetItem().m_ItemCount) - PreviousCount; // Set count to however many items were added
- if (a_Pickup->GetItem().IsEmpty())
+ Item.m_ItemCount -= m_Contents.ChangeSlotCount(i, Item.m_ItemCount) - PreviousCount; // Set count to however many items were added
+
+ if (Item.IsEmpty())
{
a_Pickup->Destroy(); // Kill pickup if all items were added
}
diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h
index a1ded4c26..c9a769c75 100644
--- a/src/Blocks/BlockChest.h
+++ b/src/Blocks/BlockChest.h
@@ -56,6 +56,7 @@ public:
(Area.GetRelBlockType(2, 0, 1) == E_BLOCK_CHEST)
)
{
+ // FIXME: This is unreachable, as the condition is the same as the above one
a_BlockMeta = (yaw < 0) ? 4 : 5;
return true;
}
diff --git a/src/Blocks/BlockEnchantmentTable.h b/src/Blocks/BlockEnchantmentTable.h
new file mode 100644
index 000000000..81d2cb9a0
--- /dev/null
+++ b/src/Blocks/BlockEnchantmentTable.h
@@ -0,0 +1,37 @@
+
+#pragma once
+
+#include "BlockHandler.h"
+#include "../UI/Window.h"
+#include "../Entities/Player.h"
+
+
+
+
+
+class cBlockEnchantmentTableHandler :
+ public cBlockHandler
+{
+public:
+ cBlockEnchantmentTableHandler(BLOCKTYPE a_BlockType)
+ : cBlockHandler(a_BlockType)
+ {
+ }
+
+
+ virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
+ {
+ cWindow * Window = new cEnchantingWindow(a_BlockX, a_BlockY, a_BlockZ);
+ a_Player->OpenWindow(Window);
+ }
+
+
+ virtual bool IsUseable(void) override
+ {
+ return true;
+ }
+};
+
+
+
+
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index 4a29ff628..a764c6f44 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -25,6 +25,7 @@
#include "BlockDirt.h"
#include "BlockDoor.h"
#include "BlockDropSpenser.h"
+#include "BlockEnchantmentTable.h"
#include "BlockEnderchest.h"
#include "BlockEntity.h"
#include "BlockFarmland.h"
@@ -119,6 +120,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_DOUBLE_WOODEN_SLAB: return new cBlockDoubleSlabHandler (a_BlockType);
case E_BLOCK_DROPPER: return new cBlockDropSpenserHandler (a_BlockType);
case E_BLOCK_EMERALD_ORE: return new cBlockOreHandler (a_BlockType);
+ case E_BLOCK_ENCHANTMENT_TABLE: return new cBlockEnchantmentTableHandler(a_BlockType);
case E_BLOCK_ENDER_CHEST: return new cBlockEnderchestHandler (a_BlockType);
case E_BLOCK_FARMLAND: return new cBlockFarmlandHandler ( );
case E_BLOCK_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType);
diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h
index 8af14686e..d21227b07 100644
--- a/src/Blocks/BlockLeaves.h
+++ b/src/Blocks/BlockLeaves.h
@@ -16,6 +16,7 @@
{ \
case E_BLOCK_LEAVES: a_Area.SetBlockType(x, y, z, (BLOCKTYPE)(E_BLOCK_SPONGE + i + 1)); break; \
case E_BLOCK_LOG: return true; \
+ case E_BLOCK_NEW_LEAVES: a_Area.SetBlockType(x, y, z, (BLOCKTYPE)(E_BLOCK_SPONGE + i + 1)); break; \
case E_BLOCK_NEW_LOG: return true; \
}
diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h
index ad78d290a..358b5ca11 100644
--- a/src/Blocks/BlockRail.h
+++ b/src/Blocks/BlockRail.h
@@ -141,7 +141,7 @@ public:
NIBBLETYPE Meta = 0;
char RailsCnt = 0;
bool Neighbors[8]; // 0 - EAST, 1 - WEST, 2 - NORTH, 3 - SOUTH, 4 - EAST UP, 5 - WEST UP, 6 - NORTH UP, 7 - SOUTH UP
- memset(Neighbors, false, sizeof(Neighbors));
+ memset(Neighbors, 0, sizeof(Neighbors));
Neighbors[0] = (IsUnstable(a_ChunkInterface, a_BlockX + 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST, E_PURE_DOWN));
Neighbors[1] = (IsUnstable(a_ChunkInterface, a_BlockX - 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST, E_PURE_DOWN));
Neighbors[2] = (IsUnstable(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ - 1) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_DOWN));
diff --git a/src/BoundingBox.cpp b/src/BoundingBox.cpp
index 482f9923f..ce831c200 100644
--- a/src/BoundingBox.cpp
+++ b/src/BoundingBox.cpp
@@ -288,7 +288,7 @@ bool cBoundingBox::CalcLineIntersection(const Vector3d & a_Min, const Vector3d &
Coeff = c;
}
c = a_Line1.LineCoeffToXZPlane(a_Line2, a_Max.y);
- if ((c >= 0) && (c >= 0) && (c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c))
+ if ((c >= 0) && (c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c))
{
Face = (a_Line1.y > a_Line2.y) ? BLOCK_FACE_YP : BLOCK_FACE_YM;
Coeff = c;
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index fe9cd9b31..8bd0985e9 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -452,7 +452,7 @@ void cChunk::CollectMobCensus(cMobCensus& toFill)
{
cMonster& Monster = (cMonster&)(**itr);
currentPosition = Monster.GetPosition();
- for (std::list<const Vector3d*>::const_iterator itr2 = playerPositions.begin(); itr2 != playerPositions.end(); itr2 ++)
+ for (std::list<const Vector3d*>::const_iterator itr2 = playerPositions.begin(); itr2 != playerPositions.end(); ++itr2)
{
toFill.CollectMob(Monster,*this,(currentPosition-**itr2).SqrLength());
}
@@ -600,7 +600,7 @@ void cChunk::Tick(float a_Dt)
delete ToDelete;
continue;
}
- itr++;
+ ++itr;
} // for itr - m_Entitites[]
// If any entity moved out of the chunk, move it to the neighbor:
@@ -1299,6 +1299,7 @@ void cChunk::CreateBlockEntities(void)
BLOCKTYPE BlockType = cChunkDef::GetBlock(m_BlockTypes, x, y, z);
switch (BlockType)
{
+ case E_BLOCK_BEACON:
case E_BLOCK_CHEST:
case E_BLOCK_COMMAND_BLOCK:
case E_BLOCK_DISPENSER:
@@ -1429,6 +1430,7 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType,
// If the new block is a block entity, create the entity object:
switch (a_BlockType)
{
+ case E_BLOCK_BEACON:
case E_BLOCK_CHEST:
case E_BLOCK_COMMAND_BLOCK:
case E_BLOCK_DISPENSER:
diff --git a/src/Chunk.h b/src/Chunk.h
index b3fa563cc..f20134e66 100644
--- a/src/Chunk.h
+++ b/src/Chunk.h
@@ -382,14 +382,14 @@ private:
struct sSetBlockQueueItem
{
+ Int64 m_Tick;
int m_RelX, m_RelY, m_RelZ;
BLOCKTYPE m_BlockType;
NIBBLETYPE m_BlockMeta;
- Int64 m_Tick;
BLOCKTYPE m_PreviousType;
sSetBlockQueueItem(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Int64 a_Tick, BLOCKTYPE a_PreviousBlockType) :
- m_RelX(a_RelX), m_RelY(a_RelY), m_RelZ(a_RelZ), m_BlockType(a_BlockType), m_BlockMeta(a_BlockMeta), m_Tick(a_Tick), m_PreviousType(a_PreviousBlockType)
+ m_Tick(a_Tick), m_RelX(a_RelX), m_RelY(a_RelY), m_RelZ(a_RelZ), m_BlockType(a_BlockType), m_BlockMeta(a_BlockMeta), m_PreviousType(a_PreviousBlockType)
{
}
} ;
diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp
index 83eae2665..ed9103174 100644
--- a/src/ChunkMap.cpp
+++ b/src/ChunkMap.cpp
@@ -1656,7 +1656,7 @@ void cChunkMap::AddEntity(cEntity * a_Entity)
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(a_Entity->GetChunkX(), ZERO_CHUNK_Y, a_Entity->GetChunkZ());
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
LOGWARNING("Entity at %p (%s, ID %d) spawning in a non-existent chunk, the entity is lost.",
a_Entity, a_Entity->GetClass(), a_Entity->GetUniqueID()
@@ -1691,7 +1691,7 @@ void cChunkMap::RemoveEntity(cEntity * a_Entity)
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(a_Entity->GetChunkX(), ZERO_CHUNK_Y, a_Entity->GetChunkZ());
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return;
}
@@ -1723,7 +1723,7 @@ bool cChunkMap::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -1973,7 +1973,7 @@ bool cChunkMap::ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEnti
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -1988,7 +1988,7 @@ bool cChunkMap::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback &
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -2003,7 +2003,7 @@ bool cChunkMap::ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCa
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -2018,7 +2018,7 @@ bool cChunkMap::ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallba
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -2033,7 +2033,7 @@ bool cChunkMap::ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpens
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -2048,7 +2048,7 @@ bool cChunkMap::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallba
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -2066,7 +2066,7 @@ bool cChunkMap::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cB
cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -2084,7 +2084,7 @@ bool cChunkMap::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCa
cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -2102,7 +2102,7 @@ bool cChunkMap::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDis
cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -2120,7 +2120,7 @@ bool cChunkMap::DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropp
cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -2138,7 +2138,7 @@ bool cChunkMap::DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cD
cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -2156,7 +2156,7 @@ bool cChunkMap::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurna
cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -2173,7 +2173,7 @@ bool cChunkMap::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNot
cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -2190,7 +2190,7 @@ bool cChunkMap::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, c
cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -2208,7 +2208,7 @@ bool cChunkMap::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHe
cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -2226,7 +2226,7 @@ bool cChunkMap::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlo
cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
@@ -2244,7 +2244,7 @@ bool cChunkMap::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString &
cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
+ if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
}
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index 07e91f59a..0f26d41e7 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -453,14 +453,16 @@ void cClientHandle::HandlePing(void)
{
// Somebody tries to retrieve information about the server
AString Reply;
+ const cServer & Server = *cRoot::Get()->GetServer();
+
Printf(Reply, "%s%s%i%s%i",
- cRoot::Get()->GetServer()->GetDescription().c_str(),
+ Server.GetDescription().c_str(),
cChatColor::Delimiter.c_str(),
- cRoot::Get()->GetServer()->GetNumPlayers(),
+ Server.GetNumPlayers(),
cChatColor::Delimiter.c_str(),
- cRoot::Get()->GetServer()->GetMaxPlayers()
+ Server.GetMaxPlayers()
);
- Kick(Reply.c_str());
+ Kick(Reply);
}
@@ -1216,8 +1218,8 @@ void cClientHandle::HandleChat(const AString & a_Message)
Color = AString("@") + Color[2];
}
else
- {
- Color.empty();
+ {
+ Color.clear();
}
Msg.AddTextPart(AString("<") + m_Player->GetName() + "> ", Color);
Msg.ParseText(a_Message);
@@ -2729,4 +2731,27 @@ void cClientHandle::SocketClosed(void)
+void cClientHandle::HandleEnchantItem(Byte & WindowID, Byte & Enchantment)
+{
+ cEnchantingWindow * Window = (cEnchantingWindow*)m_Player->GetWindow();
+ cItem Item = *Window->m_SlotArea->GetSlot(0, *m_Player);
+ int BaseEnchantmentLevel = Window->GetPropertyValue(Enchantment);
+
+ if (Item.EnchantByXPLevels(BaseEnchantmentLevel))
+ {
+ if (m_Player->IsGameModeCreative() || m_Player->DeltaExperience(-m_Player->XpForLevel(BaseEnchantmentLevel)) >= 0)
+ {
+ Window->m_SlotArea->SetSlot(0, *m_Player, Item);
+ Window->SendSlot(*m_Player, Window->m_SlotArea, 0);
+ Window->BroadcastWholeWindow();
+
+ Window->SetProperty(0, 0, *m_Player);
+ Window->SetProperty(1, 0, *m_Player);
+ Window->SetProperty(2, 0, *m_Player);
+ }
+ }
+}
+
+
+
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index 12e0256de..3d01d8034 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -18,6 +18,8 @@
#include "ByteBuffer.h"
#include "Scoreboard.h"
#include "Map.h"
+#include "Enchantments.h"
+#include "UI/SlotArea.h"
@@ -244,6 +246,9 @@ public:
/** Called when the player moves into a different world; queues sreaming the new chunks */
void MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket);
+ /** Called when the player will enchant a Item */
+ void HandleEnchantItem(Byte & WindowID, Byte & Enchantment);
+
private:
/** Handles the block placing packet when it is a real block placement (not block-using, item-using or eating) */
diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp
index 157d634cd..53a638ee5 100644
--- a/src/CraftingRecipes.cpp
+++ b/src/CraftingRecipes.cpp
@@ -661,14 +661,16 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti
ASSERT(itrS->x + a_OffsetX < a_GridWidth);
ASSERT(itrS->y + a_OffsetY < a_GridHeight);
int GridID = (itrS->x + a_OffsetX) + a_GridStride * (itrS->y + a_OffsetY);
+
+ const cItem & Item = itrS->m_Item;
if (
(itrS->x >= a_GridWidth) ||
(itrS->y >= a_GridHeight) ||
- (itrS->m_Item.m_ItemType != a_CraftingGrid[GridID].m_ItemType) || // same item type?
- (itrS->m_Item.m_ItemCount > a_CraftingGrid[GridID].m_ItemCount) || // not enough items
+ (Item.m_ItemType != a_CraftingGrid[GridID].m_ItemType) || // same item type?
+ (Item.m_ItemCount > a_CraftingGrid[GridID].m_ItemCount) || // not enough items
(
- (itrS->m_Item.m_ItemDamage > 0) && // should compare damage values?
- (itrS->m_Item.m_ItemDamage != a_CraftingGrid[GridID].m_ItemDamage)
+ (Item.m_ItemDamage > 0) && // should compare damage values?
+ (Item.m_ItemDamage != a_CraftingGrid[GridID].m_ItemDamage)
)
)
{
@@ -824,7 +826,7 @@ void cCraftingRecipes::HandleFireworks(const cItem * a_CraftingGrid, cCraftingRe
case E_ITEM_DYE:
{
int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY);
- DyeColours.push_back(cFireworkItem::GetVanillaColourCodeFromDye(a_CraftingGrid[GridID].m_ItemDamage));
+ DyeColours.push_back(cFireworkItem::GetVanillaColourCodeFromDye((NIBBLETYPE)(a_CraftingGrid[GridID].m_ItemDamage & 0x0f)));
break;
}
case E_ITEM_GUNPOWDER: break;
diff --git a/src/Crypto.cpp b/src/Crypto.cpp
index 26500f263..16be5ec35 100644
--- a/src/Crypto.cpp
+++ b/src/Crypto.cpp
@@ -206,7 +206,7 @@ int cRSAPrivateKey::Encrypt(const Byte * a_PlainData, size_t a_PlainLength, Byte
ASSERT(!"Invalid a_DecryptedMaxLength!");
return -1;
}
- if (a_EncryptedMaxLength < m_Rsa.len)
+ if (a_PlainLength < m_Rsa.len)
{
LOGD("%s: Invalid a_PlainLength: got %u, exp at least %u",
__FUNCTION__, (unsigned)a_PlainLength, (unsigned)(m_Rsa.len)
diff --git a/src/DeadlockDetect.cpp b/src/DeadlockDetect.cpp
index 322084dc4..38a3c369e 100644
--- a/src/DeadlockDetect.cpp
+++ b/src/DeadlockDetect.cpp
@@ -112,18 +112,21 @@ void cDeadlockDetect::CheckWorldAge(const AString & a_WorldName, Int64 a_Age)
ASSERT(!"Unknown world in cDeadlockDetect");
return;
}
- if (itr->second.m_Age == a_Age)
+
+ cDeadlockDetect::sWorldAge & WorldAge = itr->second;
+
+ if (WorldAge.m_Age == a_Age)
{
- itr->second.m_NumCyclesSame += 1;
- if (itr->second.m_NumCyclesSame > (1000 * m_IntervalSec) / CYCLE_MILLISECONDS)
+ WorldAge.m_NumCyclesSame += 1;
+ if (WorldAge.m_NumCyclesSame > (1000 * m_IntervalSec) / CYCLE_MILLISECONDS)
{
DeadlockDetected();
}
}
else
{
- itr->second.m_Age = a_Age;
- itr->second.m_NumCyclesSame = 0;
+ WorldAge.m_Age = a_Age;
+ WorldAge.m_NumCyclesSame = 0;
}
}
diff --git a/src/Enchantments.cpp b/src/Enchantments.cpp
index 9d4e23e0a..64f89815b 100644
--- a/src/Enchantments.cpp
+++ b/src/Enchantments.cpp
@@ -5,6 +5,7 @@
#include "Globals.h"
#include "Enchantments.h"
#include "WorldStorage/FastNBT.h"
+#include "FastRandom.h"
@@ -28,6 +29,18 @@ cEnchantments::cEnchantments(const AString & a_StringSpec)
+void cEnchantments::Add(const cEnchantments & a_Other)
+{
+ for (cEnchantments::cMap::const_iterator itr = a_Other.m_Enchantments.begin(), end = a_Other.m_Enchantments.end(); itr != end; ++itr)
+ {
+ SetLevel(itr->first, itr->second);
+ } // for itr - a_Other.m_Enchantments[]
+}
+
+
+
+
+
void cEnchantments::AddFromString(const AString & a_StringSpec)
{
// Add enchantments in the stringspec; if a specified enchantment already exists, overwrites it
@@ -218,7 +231,781 @@ bool cEnchantments::operator !=(const cEnchantments & a_Other) const
+void cEnchantments::AddItemEnchantmentWeights(cWeightedEnchantments & a_Enchantments, short a_ItemType, int a_EnchantmentLevel)
+{
+ if (ItemCategory::IsSword(a_ItemType))
+ {
+ // Sharpness
+ if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 54))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 4);
+ }
+ else if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 43))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 3);
+ }
+ else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 32))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 2);
+ }
+ else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 21))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 1);
+ }
+
+ // Smite
+ if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 49))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 4);
+ }
+ else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 41))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 3);
+ }
+ else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 33))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 2);
+ }
+ else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 25))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 1);
+ }
+
+ // Bane of Arthropods
+ if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 49))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 4);
+ }
+ else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 41))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 3);
+ }
+ else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 33))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 2);
+ }
+ else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 25))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 1);
+ }
+
+ // Knockback
+ if ((a_EnchantmentLevel >= 25) && (a_EnchantmentLevel <= 75))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchKnockback, 2);
+ }
+ else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 55))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchKnockback, 1);
+ }
+
+ // Fire Aspect
+ if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 80))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchFireAspect, 2);
+ }
+ else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 60))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchFireAspect, 1);
+ }
+
+ // Looting
+ if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 3);
+ }
+ else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 2);
+ }
+ else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 1);
+ }
+ }
+
+ else if (ItemCategory::IsTool(a_ItemType))
+ {
+ // Efficiency
+ if ((a_EnchantmentLevel >= 31) && (a_EnchantmentLevel <= 81))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 4);
+ }
+ else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 71))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 3);
+ }
+ else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 61))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 2);
+ }
+ else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 51))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 1);
+ }
+
+ // Silk Touch
+ if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchSilkTouch, 1);
+ }
+
+ // Fortune
+ if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 3);
+ }
+ else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 2);
+ }
+ else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 1);
+ }
+ }
+
+ else if (ItemCategory::IsArmor(a_ItemType))
+ {
+ // Protection
+ if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 54))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 4);
+ }
+ else if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 43))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 3);
+ }
+ else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 32))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 2);
+ }
+ else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 21))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 1);
+ }
+
+ // Fire Protection
+ if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 46))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 4);
+ }
+ else if ((a_EnchantmentLevel >= 26) && (a_EnchantmentLevel <= 38))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 3);
+ }
+ else if ((a_EnchantmentLevel >= 18) && (a_EnchantmentLevel <= 30))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 2);
+ }
+ else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 22))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 1);
+ }
+
+ // Blast Protection
+ if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 41))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 4);
+ }
+ else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 33))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 3);
+ }
+ else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 25))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 2);
+ }
+ else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 17))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 1);
+ }
+
+ // Projectile Protection
+ if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 36))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchProjectileProtection, 4);
+ }
+ else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 30))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchProjectileProtection, 3);
+ }
+ else if ((a_EnchantmentLevel >= 9) && (a_EnchantmentLevel <= 24))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchProjectileProtection, 2);
+ }
+ else if ((a_EnchantmentLevel >= 3) && (a_EnchantmentLevel <= 18))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchProjectileProtection, 1);
+ }
+
+ // Thorns
+ if ((a_EnchantmentLevel >= 50) && (a_EnchantmentLevel <= 100))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 3);
+ }
+ else if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 80))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 2);
+ }
+ else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 60))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 1);
+ }
+
+
+ if (ItemCategory::IsHelmet(a_ItemType))
+ {
+ // Respiration
+ if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 60))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 3);
+ }
+ else if ((a_EnchantmentLevel >= 20) && (a_EnchantmentLevel <= 50))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 2);
+ }
+ else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 40))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 1);
+ }
+
+ // Aqua Affinity
+ if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 41))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchAquaAffinity, 1);
+ }
+ }
+
+ else if (ItemCategory::IsBoots(a_ItemType))
+ {
+ // Feather Fall
+ if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 33))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 4);
+ }
+ else if ((a_EnchantmentLevel >= 17) && (a_EnchantmentLevel <= 27))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 3);
+ }
+ else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 21))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 2);
+ }
+ else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 15))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 1);
+ }
+ }
+ }
+
+ else if (a_ItemType == E_ITEM_BOW)
+ {
+ // Power
+ if ((a_EnchantmentLevel >= 31) && (a_EnchantmentLevel <= 46))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 4);
+ }
+ else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 36))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 3);
+ }
+ else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 26))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 2);
+ }
+ else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 16))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 1);
+ }
+
+ // Punch
+ if ((a_EnchantmentLevel >= 32) && (a_EnchantmentLevel <= 57))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchPunch, 2);
+ }
+ else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 37))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchPunch, 1);
+ }
+
+ // Flame and Infinity
+ if ((a_EnchantmentLevel >= 20) && (a_EnchantmentLevel <= 50))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchFlame, 1);
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchInfinity, 1);
+ }
+ }
+
+ else if (a_ItemType == E_ITEM_FISHING_ROD)
+ {
+ // Luck of the Sea and Lure
+ if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 3);
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 3);
+ }
+ else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 2);
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 2);
+ }
+ else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 1);
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 1);
+ }
+ }
+
+ else if (a_ItemType == E_ITEM_BOOK)
+ {
+ // All Enchantments
+
+ // Sharpness
+ if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 54))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 4);
+ }
+ else if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 43))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 3);
+ }
+ else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 32))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 2);
+ }
+ else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 21))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 1);
+ }
+
+ // Smite
+ if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 49))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 4);
+ }
+ else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 41))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 3);
+ }
+ else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 33))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 2);
+ }
+ else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 25))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 1);
+ }
+
+ // Bane of Arthropods
+ if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 49))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 4);
+ }
+ else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 41))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 3);
+ }
+ else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 33))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 2);
+ }
+ else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 25))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 1);
+ }
+
+ // Knockback
+ if ((a_EnchantmentLevel >= 25) && (a_EnchantmentLevel <= 75))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchKnockback, 2);
+ }
+ else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 55))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchKnockback, 1);
+ }
+
+ // Fire Aspect
+ if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 80))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchFireAspect, 2);
+ }
+ else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 60))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchFireAspect, 1);
+ }
+
+ // Looting
+ if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 3);
+ }
+ else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 2);
+ }
+ else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 1);
+ }
+
+ // Efficiency
+ if ((a_EnchantmentLevel >= 31) && (a_EnchantmentLevel <= 81))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 4);
+ }
+ else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 71))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 3);
+ }
+ else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 61))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 2);
+ }
+ else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 51))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 1);
+ }
+
+ // Silk Touch
+ if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchSilkTouch, 1);
+ }
+
+ // Fortune
+ if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 3);
+ }
+ else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 2);
+ }
+ else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 1);
+ }
+
+ // Protection
+ if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 54))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 4);
+ }
+ else if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 43))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 3);
+ }
+ else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 32))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 2);
+ }
+ else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 21))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 1);
+ }
+
+ // Fire Protection
+ if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 46))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 4);
+ }
+ else if ((a_EnchantmentLevel >= 26) && (a_EnchantmentLevel <= 38))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 3);
+ }
+ else if ((a_EnchantmentLevel >= 18) && (a_EnchantmentLevel <= 30))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 2);
+ }
+ else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 22))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 1);
+ }
+
+ // Blast Protection
+ if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 41))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 4);
+ }
+ else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 33))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 3);
+ }
+ else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 25))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 2);
+ }
+ else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 17))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 1);
+ }
+
+ // Projectile Protection
+ if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 36))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchProjectileProtection, 4);
+ }
+ else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 30))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchProjectileProtection, 3);
+ }
+ else if ((a_EnchantmentLevel >= 9) && (a_EnchantmentLevel <= 24))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchProjectileProtection, 2);
+ }
+ else if ((a_EnchantmentLevel >= 3) && (a_EnchantmentLevel <= 18))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchProjectileProtection, 1);
+ }
+
+ // Thorns
+ if ((a_EnchantmentLevel >= 50) && (a_EnchantmentLevel <= 100))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 3);
+ }
+ else if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 80))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 2);
+ }
+ else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 60))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 1);
+ }
+
+ // Respiration
+ if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 60))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 3);
+ }
+ else if ((a_EnchantmentLevel >= 20) && (a_EnchantmentLevel <= 50))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 2);
+ }
+ else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 40))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 1);
+ }
+
+ // Aqua Affinity
+ if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 41))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchAquaAffinity, 1);
+ }
+
+ // Feather Fall
+ if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 33))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 4);
+ }
+ else if ((a_EnchantmentLevel >= 17) && (a_EnchantmentLevel <= 27))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 3);
+ }
+ else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 21))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 2);
+ }
+ else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 15))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 1);
+ }
+
+ // Power
+ if ((a_EnchantmentLevel >= 31) && (a_EnchantmentLevel <= 46))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 4);
+ }
+ else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 36))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 3);
+ }
+ else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 26))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 2);
+ }
+ else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 16))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 1);
+ }
+
+ // Punch
+ if ((a_EnchantmentLevel >= 32) && (a_EnchantmentLevel <= 57))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchPunch, 2);
+ }
+ else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 37))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchPunch, 1);
+ }
+
+ // Flame and Infinity
+ if ((a_EnchantmentLevel >= 20) && (a_EnchantmentLevel <= 50))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 2, enchFlame, 1);
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchInfinity, 1);
+ }
+
+ // Luck of the Sea and Lure
+ if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 3);
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 3);
+ }
+ else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 2);
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 2);
+ }
+ else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 1);
+ AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 1);
+ }
+ }
+
+ // Unbreaking
+ if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 71))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchUnbreaking, 3);
+ }
+ else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 63))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchUnbreaking, 2);
+ }
+ else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 55))
+ {
+ AddEnchantmentWeightToVector(a_Enchantments, 5, enchUnbreaking, 1);
+ }
+}
+
+
+
+
+
+void cEnchantments::AddEnchantmentWeightToVector(cWeightedEnchantments & a_Enchantments, int a_Weight, int a_EnchantmentID, int a_EnchantmentLevel)
+{
+ cWeightedEnchantment weightedenchantment;
+ weightedenchantment.m_Weight = a_Weight;
+ cEnchantments enchantment;
+ enchantment.SetLevel(a_EnchantmentID, a_EnchantmentLevel);
+ weightedenchantment.m_Enchantments = enchantment;
+ a_Enchantments.push_back(weightedenchantment);
+}
+
+
+
+
+
+void cEnchantments::RemoveEnchantmentWeightFromVector(cWeightedEnchantments & a_Enchantments, int a_EnchantmentID)
+{
+ for (cWeightedEnchantments::iterator it = a_Enchantments.begin(); it != a_Enchantments.end(); ++it)
+ {
+ if ((*it).m_Enchantments.GetLevel(a_EnchantmentID) > 0)
+ {
+ a_Enchantments.erase(it);
+ break;
+ }
+ }
+}
+
+
+
+
+
+void cEnchantments::RemoveEnchantmentWeightFromVector(cWeightedEnchantments & a_Enchantments, const cEnchantments & a_Enchantment)
+{
+ for (cWeightedEnchantments::iterator it = a_Enchantments.begin(); it != a_Enchantments.end(); ++it)
+ {
+ if ((*it).m_Enchantments == a_Enchantment)
+ {
+ a_Enchantments.erase(it);
+ break;
+ }
+ }
+}
+
+
+
+
+
+void cEnchantments::CheckEnchantmentConflictsFromVector(cWeightedEnchantments & a_Enchantments, cEnchantments a_FirstEnchantment)
+{
+ if (a_FirstEnchantment.GetLevel(cEnchantments::enchProtection) > 0)
+ {
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchFireProtection);
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchBlastProtection);
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchProjectileProtection);
+ }
+ else if (a_FirstEnchantment.GetLevel(cEnchantments::enchFireProtection) > 0)
+ {
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchProtection);
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchBlastProtection);
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchProjectileProtection);
+ }
+ else if (a_FirstEnchantment.GetLevel(cEnchantments::enchBlastProtection) > 0)
+ {
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchProtection);
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchFireProtection);
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchProjectileProtection);
+ }
+ else if (a_FirstEnchantment.GetLevel(cEnchantments::enchProjectileProtection) > 0)
+ {
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchProtection);
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchFireProtection);
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchBlastProtection);
+ }
+
+ else if (a_FirstEnchantment.GetLevel(cEnchantments::enchSharpness) > 0)
+ {
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchSmite);
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchBaneOfArthropods);
+ }
+ else if (a_FirstEnchantment.GetLevel(cEnchantments::enchSmite) > 0)
+ {
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchSharpness);
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchBaneOfArthropods);
+ }
+ else if (a_FirstEnchantment.GetLevel(cEnchantments::enchBaneOfArthropods) > 0)
+ {
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchSharpness);
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchSmite);
+ }
+ else if (a_FirstEnchantment.GetLevel(cEnchantments::enchSilkTouch) > 0)
+ {
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchFortune);
+ }
+ else if (a_FirstEnchantment.GetLevel(cEnchantments::enchFortune) > 0)
+ {
+ RemoveEnchantmentWeightFromVector(a_Enchantments, cEnchantments::enchSilkTouch);
+ }
+}
+
+
+
+
+
+cEnchantments cEnchantments::GetRandomEnchantmentFromVector(cWeightedEnchantments & a_Enchantments)
+{
+ cFastRandom Random;
+
+ int AllWeights = 0;
+ for (cWeightedEnchantments::iterator it = a_Enchantments.begin(); it != a_Enchantments.end(); ++it)
+ {
+ AllWeights += (*it).m_Weight;
+ }
+ int RandomNumber = Random.GenerateRandomInteger(0, AllWeights - 1);
+ for (cWeightedEnchantments::iterator it = a_Enchantments.begin(); it != a_Enchantments.end(); ++it)
+ {
+ RandomNumber -= (*it).m_Weight;
+ if (RandomNumber < 0)
+ {
+ return (*it).m_Enchantments;
+ }
+ }
+ return cEnchantments();
+}
diff --git a/src/Enchantments.h b/src/Enchantments.h
index f77b535d8..dc5502702 100644
--- a/src/Enchantments.h
+++ b/src/Enchantments.h
@@ -8,6 +8,7 @@
#pragma once
+#include "Defines.h"
#include "WorldStorage/EnchantmentSerializer.h"
@@ -18,6 +19,11 @@ class cFastNBTWriter;
class cParsedNBT;
+// fwd:
+struct cWeightedEnchantment;
+
+typedef std::vector<cWeightedEnchantment> cWeightedEnchantments;
+
@@ -28,11 +34,14 @@ mapping each enchantment's id onto its level. ID may be either a number or the e
Level value of 0 means no such enchantment, and it will not be stored in the m_Enchantments.
Serialization will never put zero-level enchantments into the stringspec and will always use numeric IDs.
*/
+
+
// tolua_begin
class cEnchantments
{
public:
- /// Individual enchantment IDs, corresponding to their NBT IDs ( http://www.minecraftwiki.net/wiki/Data_Values#Enchantment_IDs )
+ /** Individual enchantment IDs, corresponding to their NBT IDs ( http://www.minecraftwiki.net/wiki/Data_Values#Enchantment_IDs )
+ */
enum
{
@@ -61,56 +70,87 @@ public:
enchLuckOfTheSea = 61,
enchLure = 62,
} ;
-
- /// Creates an empty enchantments container
+
+ /** Creates an empty enchantments container */
cEnchantments(void);
- /// Creates an enchantments container filled with enchantments parsed from stringspec
+ /** Creates an enchantments container filled with enchantments parsed from stringspec */
cEnchantments(const AString & a_StringSpec);
- /// Adds enchantments in the stringspec; if a specified enchantment already exists, overwrites it
+ /** Adds the enchantments contained in a_Other into this object.
+ Existing enchantments are preserved, unless a_Other specifies a different level, in which case the level is changed. */
+ void Add(const cEnchantments & a_Other);
+
+ /** Adds enchantments in the stringspec; if a specified enchantment already exists, overwrites it */
void AddFromString(const AString & a_StringSpec);
- /// Serializes all the enchantments into a string
+ /** Serializes all the enchantments into a string */
AString ToString(void) const;
- /// Returns the level for the specified enchantment; 0 if not stored
+ /** Returns the level for the specified enchantment; 0 if not stored */
int GetLevel(int a_EnchantmentID) const;
- /// Sets the level for the specified enchantment, adding it if not stored before or removing it if level <= 0
+ /** Sets the level for the specified enchantment, adding it if not stored before or removing it if level <= 0 */
void SetLevel(int a_EnchantmentID, int a_Level);
- /// Removes all enchantments
+ /** Removes all enchantments */
void Clear(void);
- /// Returns true if there are no enchantments
+ /** Returns true if there are no enchantments */
bool IsEmpty(void) const;
- /// Converts enchantment name to the numeric representation; returns -1 if enchantment name not found; case insensitive
+ /** Converts enchantment name to the numeric representation; returns -1 if enchantment name not found; case insensitive */
static int StringToEnchantmentID(const AString & a_EnchantmentName);
- /// Returns true if a_Other contains exactly the same enchantments and levels
+ /** Returns true if a_Other contains exactly the same enchantments and levels */
bool operator ==(const cEnchantments & a_Other) const;
-
+
// tolua_end
+
+ /** Add enchantment weights from item to the vector */
+ static void AddItemEnchantmentWeights(cWeightedEnchantments & a_Enchantments, short a_ItemType, int a_EnchantmentLevel);
+
+ /** Add a enchantment with weight to the vector */
+ static void AddEnchantmentWeightToVector(cWeightedEnchantments & a_Enchantments, int a_Weight, int a_EnchantmentID, int a_EnchantmentLevel);
- /// Returns true if a_Other doesn't contain exactly the same enchantments and levels
+ /** Remove the entire enchantment (with weight) from the vector */
+ static void RemoveEnchantmentWeightFromVector(cWeightedEnchantments & a_Enchantments, int a_EnchantmentID);
+
+ /** Remove the entire enchantment (with weight) from the vector */
+ static void RemoveEnchantmentWeightFromVector(cWeightedEnchantments & a_Enchantments, const cEnchantments & a_Enchantment);
+
+ /** Check enchantment conflicts from enchantments from the vector */
+ static void CheckEnchantmentConflictsFromVector(cWeightedEnchantments & a_Enchantments, cEnchantments a_FirstEnchantment);
+
+ /** Gets random enchantment from Vector and returns it */
+ static cEnchantments GetRandomEnchantmentFromVector(cWeightedEnchantments & a_Enchantments);
+
+ /** Returns true if a_Other doesn't contain exactly the same enchantments and levels */
bool operator !=(const cEnchantments & a_Other) const;
- /// Writes the enchantments into the specified NBT writer; begins with the LIST tag of the specified name ("ench" or "StoredEnchantments")
+ /** Writes the enchantments into the specified NBT writer; begins with the LIST tag of the specified name ("ench" or "StoredEnchantments") */
friend void EnchantmentSerializer::WriteToNBTCompound(cEnchantments const& a_Enchantments, cFastNBTWriter & a_Writer, const AString & a_ListTagName);
- /// Reads the enchantments from the specified NBT list tag (ench or StoredEnchantments)
+ /** Reads the enchantments from the specified NBT list tag (ench or StoredEnchantments) */
friend void EnchantmentSerializer::ParseFromNBT(cEnchantments& a_Enchantments, const cParsedNBT & a_NBT, int a_EnchListTagIdx);
-
+
protected:
- /// Maps enchantment ID -> enchantment level
+ /** Maps enchantment ID -> enchantment level */
typedef std::map<int, int> cMap;
- /// Currently stored enchantments
+ /** Currently stored enchantments */
cMap m_Enchantments;
} ; // tolua_export
+// Define the cWeightedEnchantment struct for the Enchanting System to store the EnchantmentWeights:
+struct cWeightedEnchantment
+{
+ int m_Weight;
+ cEnchantments m_Enchantments;
+};
+
+
+
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 25ae4c7d8..5c7c9c95a 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -38,6 +38,7 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d
, m_IsInitialized(false)
, m_EntityType(a_EntityType)
, m_World(NULL)
+ , m_IsFireproof(false)
, m_TicksSinceLastBurnDamage(0)
, m_TicksSinceLastLavaDamage(0)
, m_TicksSinceLastFireDamage(0)
@@ -796,7 +797,10 @@ void cEntity::TickBurning(cChunk & a_Chunk)
m_TicksSinceLastBurnDamage++;
if (m_TicksSinceLastBurnDamage >= BURN_TICKS_PER_DAMAGE)
{
- TakeDamage(dtOnFire, NULL, BURN_DAMAGE, 0);
+ if (!m_IsFireproof)
+ {
+ TakeDamage(dtOnFire, NULL, BURN_DAMAGE, 0);
+ }
m_TicksSinceLastBurnDamage = 0;
}
m_TicksLeftBurning--;
@@ -864,7 +868,10 @@ void cEntity::TickBurning(cChunk & a_Chunk)
m_TicksSinceLastLavaDamage++;
if (m_TicksSinceLastLavaDamage >= LAVA_TICKS_PER_DAMAGE)
{
- TakeDamage(dtLavaContact, NULL, LAVA_DAMAGE, 0);
+ if (!m_IsFireproof)
+ {
+ TakeDamage(dtLavaContact, NULL, LAVA_DAMAGE, 0);
+ }
m_TicksSinceLastLavaDamage = 0;
}
}
@@ -882,7 +889,10 @@ void cEntity::TickBurning(cChunk & a_Chunk)
m_TicksSinceLastFireDamage++;
if (m_TicksSinceLastFireDamage >= FIRE_TICKS_PER_DAMAGE)
{
- TakeDamage(dtFireContact, NULL, FIRE_DAMAGE, 0);
+ if (!m_IsFireproof)
+ {
+ TakeDamage(dtFireContact, NULL, FIRE_DAMAGE, 0);
+ }
m_TicksSinceLastFireDamage = 0;
}
}
@@ -1041,6 +1051,16 @@ void cEntity::SetMaxHealth(int a_MaxHealth)
+/// Sets whether the entity is fireproof
+void cEntity::SetIsFireproof(bool a_IsFireproof)
+{
+ m_IsFireproof = a_IsFireproof;
+}
+
+
+
+
+
/// Puts the entity on fire for the specified amount of ticks
void cEntity::StartBurning(int a_TicksLeftBurning)
{
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index 354e324c9..0785b5609 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -329,6 +329,11 @@ public:
int GetMaxHealth(void) const { return m_MaxHealth; }
+ /// Sets whether the entity is fireproof
+ void SetIsFireproof(bool a_IsFireproof);
+
+ bool IsFireproof(void) const { return m_IsFireproof; }
+
/// Puts the entity on fire for the specified amount of ticks
void StartBurning(int a_TicksLeftBurning);
@@ -432,6 +437,9 @@ protected:
cWorld * m_World;
+ /// Whether the entity is capable of taking fire or lava damage.
+ bool m_IsFireproof;
+
/// Time, in ticks, since the last damage dealt by being on fire. Valid only if on fire (IsOnFire())
int m_TicksSinceLastBurnDamage;
diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp
index 6db13231d..db55eb058 100644
--- a/src/Entities/Minecart.cpp
+++ b/src/Entities/Minecart.cpp
@@ -795,7 +795,7 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta)
{
BLOCKTYPE BlockXM = m_World->GetBlock(POSX_TOINT - 1, POSY_TOINT, POSZ_TOINT);
BLOCKTYPE BlockXP = m_World->GetBlock(POSX_TOINT + 1, POSY_TOINT, POSZ_TOINT);
- BLOCKTYPE BlockZM = m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT + 1);
+ BLOCKTYPE BlockZM = m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT - 1);
BLOCKTYPE BlockZP = m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT + 1);
if (
(!IsBlockRail(BlockXM) && cBlockInfo::IsSolid(BlockXM)) ||
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index ba4353478..a7b1dd74e 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -82,9 +82,10 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
if (!LoadFromDisk())
{
m_Inventory.Clear();
- SetPosX(cRoot::Get()->GetDefaultWorld()->GetSpawnX());
- SetPosY(cRoot::Get()->GetDefaultWorld()->GetSpawnY());
- SetPosZ(cRoot::Get()->GetDefaultWorld()->GetSpawnZ());
+ cWorld * DefaultWorld = cRoot::Get()->GetDefaultWorld();
+ SetPosX(DefaultWorld->GetSpawnX());
+ SetPosY(DefaultWorld->GetSpawnY());
+ SetPosZ(DefaultWorld->GetSpawnZ());
LOGD("Player \"%s\" is connecting for the first time, spawning at default world spawn {%.2f, %.2f, %.2f}",
a_PlayerName.c_str(), GetPosX(), GetPosY(), GetPosZ()
@@ -1159,9 +1160,9 @@ Vector3d cPlayer::GetThrowSpeed(double a_SpeedCoeff) const
-void cPlayer::ForceSetSpeed(Vector3d a_Direction)
+void cPlayer::ForceSetSpeed(const Vector3d & a_Speed)
{
- SetSpeed(a_Direction);
+ SetSpeed(a_Speed);
m_ClientHandle->SendEntityVelocity(*this);
}
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index 7a6b46ae9..aa329b97c 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -181,7 +181,7 @@ public:
void LoginSetGameMode(eGameMode a_GameMode);
/** Forces the player to move in the given direction. */
- void ForceSetSpeed(Vector3d a_Direction); // tolua_export
+ void ForceSetSpeed(const Vector3d & a_Speed); // tolua_export
/** Tries to move to a new position, with attachment-related checks (y == -999) */
void MoveTo(const Vector3d & a_NewPos); // tolua_export
diff --git a/src/FastRandom.cpp b/src/FastRandom.cpp
index e6634bb0d..c45261947 100644
--- a/src/FastRandom.cpp
+++ b/src/FastRandom.cpp
@@ -172,3 +172,13 @@ float cFastRandom::NextFloat(float a_Range, int a_Salt)
+
+int cFastRandom::GenerateRandomInteger(int a_Begin, int a_End)
+{
+ cFastRandom Random;
+ return Random.NextInt(a_End - a_Begin + 1) + a_Begin;
+}
+
+
+
+
diff --git a/src/FastRandom.h b/src/FastRandom.h
index bf70822cf..567198a31 100644
--- a/src/FastRandom.h
+++ b/src/FastRandom.h
@@ -43,6 +43,9 @@ public:
/// Returns a random float in the range [0 .. a_Range]; a_Range must be less than 1M; a_Salt is additional source of randomness
float NextFloat(float a_Range, int a_Salt);
+
+ /** Returns a random int in the range [a_Begin .. a_End] */
+ int GenerateRandomInteger(int a_Begin, int a_End);
protected:
int m_Seed;
diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp
index 1810d7c49..bd7fd8079 100644
--- a/src/FurnaceRecipe.cpp
+++ b/src/FurnaceRecipe.cpp
@@ -56,7 +56,6 @@ void cFurnaceRecipe::ReloadRecipes(void)
std::ifstream f;
char a_File[] = "furnace.txt";
f.open(a_File, std::ios::in);
- std::string input;
if (!f.good())
{
diff --git a/src/Generating/Caves.cpp b/src/Generating/Caves.cpp
index 98b7c8681..5cad11d2a 100644
--- a/src/Generating/Caves.cpp
+++ b/src/Generating/Caves.cpp
@@ -200,13 +200,14 @@ void cCaveTunnel::Randomize(cNoise & a_Noise)
for (int i = 0; i < 4; i++)
{
// For each already present point, insert a point in between it and its predecessor, shifted randomly.
- int PrevX = m_Points.front().m_BlockX;
- int PrevY = m_Points.front().m_BlockY;
- int PrevZ = m_Points.front().m_BlockZ;
- int PrevR = m_Points.front().m_Radius;
+ cCaveDefPoint & Point = m_Points.front();
+ int PrevX = Point.m_BlockX;
+ int PrevY = Point.m_BlockY;
+ int PrevZ = Point.m_BlockZ;
+ int PrevR = Point.m_Radius;
cCaveDefPoints Pts;
Pts.reserve(m_Points.size() * 2 + 1);
- Pts.push_back(m_Points.front());
+ Pts.push_back(Point);
for (cCaveDefPoints::const_iterator itr = m_Points.begin() + 1, end = m_Points.end(); itr != end; ++itr)
{
int Random = a_Noise.IntNoise3DInt(PrevX, PrevY, PrevZ + i) / 11;
@@ -244,11 +245,12 @@ bool cCaveTunnel::RefineDefPoints(const cCaveDefPoints & a_Src, cCaveDefPoints &
a_Dst.clear();
a_Dst.reserve(Num * 2 + 2);
cCaveDefPoints::const_iterator itr = a_Src.begin() + 1;
- a_Dst.push_back(a_Src.front());
- int PrevX = a_Src.front().m_BlockX;
- int PrevY = a_Src.front().m_BlockY;
- int PrevZ = a_Src.front().m_BlockZ;
- int PrevR = a_Src.front().m_Radius;
+ const cCaveDefPoint & Source = a_Src.front();
+ a_Dst.push_back(Source);
+ int PrevX = Source.m_BlockX;
+ int PrevY = Source.m_BlockY;
+ int PrevZ = Source.m_BlockZ;
+ int PrevR = Source.m_Radius;
for (int i = 0; i <= Num; ++i, ++itr)
{
int dx = itr->m_BlockX - PrevX;
@@ -310,9 +312,10 @@ void cCaveTunnel::FinishLinear(void)
std::swap(Pts, m_Points);
m_Points.reserve(Pts.size() * 3);
- int PrevX = Pts.front().m_BlockX;
- int PrevY = Pts.front().m_BlockY;
- int PrevZ = Pts.front().m_BlockZ;
+ cCaveDefPoint & PrevPoint = Pts.front();
+ int PrevX = PrevPoint.m_BlockX;
+ int PrevY = PrevPoint.m_BlockY;
+ int PrevZ = PrevPoint.m_BlockZ;
for (cCaveDefPoints::const_iterator itr = Pts.begin() + 1, end = Pts.end(); itr != end; ++itr)
{
int x1 = itr->m_BlockX;
@@ -433,9 +436,10 @@ void cCaveTunnel::FinishLinear(void)
void cCaveTunnel::CalcBoundingBox(void)
{
- m_MinBlockX = m_MaxBlockX = m_Points.front().m_BlockX;
- m_MinBlockY = m_MaxBlockY = m_Points.front().m_BlockY;
- m_MinBlockZ = m_MaxBlockZ = m_Points.front().m_BlockZ;
+ cCaveDefPoint & Point = m_Points.front();
+ m_MinBlockX = m_MaxBlockX = Point.m_BlockX;
+ m_MinBlockY = m_MaxBlockY = Point.m_BlockY;
+ m_MinBlockZ = m_MaxBlockZ = Point.m_BlockZ;
for (cCaveDefPoints::const_iterator itr = m_Points.begin() + 1, end = m_Points.end(); itr != end; ++itr)
{
m_MinBlockX = std::min(m_MinBlockX, itr->m_BlockX - itr->m_Radius);
diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp
index 7d1762036..c0c9e8a13 100644
--- a/src/Generating/Prefab.cpp
+++ b/src/Generating/Prefab.cpp
@@ -23,6 +23,10 @@ static const cPrefab::sDef g_TestPrefabDef =
// Size:
7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 5, 6, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* 0 */
"a:112: 0\n" /* netherbrick */
@@ -115,7 +119,10 @@ static cPrefab g_TestPrefab(g_TestPrefabDef);
cPrefab::cPrefab(const cPrefab::sDef & a_Def) :
m_Size(a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ),
- m_HitBox(0, 0, 0, a_Def.m_SizeX - 1, a_Def.m_SizeY - 1, a_Def.m_SizeZ - 1),
+ 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
+ ),
m_AllowedRotations(a_Def.m_AllowedRotations),
m_MergeStrategy(a_Def.m_MergeStrategy),
m_ShouldExtendFloor(a_Def.m_ShouldExtendFloor),
diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h
index dbf882e21..37db2ff16 100644
--- a/src/Generating/Prefab.h
+++ b/src/Generating/Prefab.h
@@ -38,6 +38,10 @@ public:
int m_SizeY;
int m_SizeZ;
+ /** The hitbox used for collision-checking between prefabs. Relative to the bounds. */
+ int m_HitboxMinX, m_HitboxMinY, m_HitboxMinZ;
+ int m_HitboxMaxX, m_HitboxMaxY, m_HitboxMaxZ;
+
/** The mapping between characters in m_Image and the blocktype / blockmeta.
Format: "Char: BlockType: BlockMeta \n Char: BlockType : BlockMeta \n ..." */
const char * m_CharMap;
@@ -114,7 +118,7 @@ protected:
/** The size of the prefab */
Vector3i m_Size;
- /** The hitbox of the prefab. In first version is the same as the m_BlockArea dimensions */
+ /** The hitbox used for collision-checking between prefabs. */
cCuboid m_HitBox;
/** The connectors through which the piece connects to other pieces */
diff --git a/src/Generating/Prefabs/NetherFortPrefabs.cpp b/src/Generating/Prefabs/NetherFortPrefabs.cpp
index 7a46df5d8..20cee576c 100644
--- a/src/Generating/Prefabs/NetherFortPrefabs.cpp
+++ b/src/Generating/Prefabs/NetherFortPrefabs.cpp
@@ -22,6 +22,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
13, 7, 9, // SizeX = 13, SizeY = 7, SizeZ = 9
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 12, 6, 8, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -160,6 +164,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
13, 7, 11, // SizeX = 13, SizeY = 7, SizeZ = 11
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 12, 6, 10, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -313,6 +321,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
10, 7, 7, // SizeX = 10, SizeY = 7, SizeZ = 7
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 9, 6, 6, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -414,7 +426,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
100,
// DepthWeight:
- "",
+ "1:0|2:0|3:0|4:0|5:0",
// AddWeightIfSame:
0,
@@ -429,6 +441,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
14, 9, 7, // SizeX = 14, SizeY = 9, SizeZ = 7
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 13, 18, 6, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -558,7 +574,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
100,
// DepthWeight:
- "",
+ "1:0|2:0|3:0|4:0|5:0",
// AddWeightIfSame:
0,
@@ -573,6 +589,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
15, 8, 15, // SizeX = 15, SizeY = 8, SizeZ = 15
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 14, 17, 14, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -757,7 +777,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
"",
// AddWeightIfSame:
- 0,
+ -1000,
}, // BridgeCircleCrossing
@@ -769,6 +789,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
15, 8, 15, // SizeX = 15, SizeY = 8, SizeZ = 15
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 14, 17, 14, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -966,6 +990,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
9, 6, 5, // SizeX = 9, SizeY = 6, SizeZ = 5
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 8, 15, 4, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -1041,7 +1069,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
100,
// DepthWeight:
- "1:0",
+ "1:0|2:0|3:0|4:0|5:0",
// AddWeightIfSame:
0,
@@ -1056,6 +1084,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
13, 6, 5, // SizeX = 13, SizeY = 6, SizeZ = 5
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 12, 15, 4, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -1137,7 +1169,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
100,
// DepthWeight:
- "1:0",
+ "1:0|2:0|3:0|4:0|5:0",
// AddWeightIfSame:
0,
@@ -1152,6 +1184,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
5, 7, 16, // SizeX = 5, SizeY = 7, SizeZ = 16
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 4, 6, 15, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -1327,6 +1363,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
15, 12, 12, // SizeX = 15, SizeY = 12, SizeZ = 12
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 14, 21, 11, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -1558,304 +1598,311 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// BridgeLevelCrossing:
- // The data has been exported from the gallery Nether, area index 45, ID 304, created by Aloe_vera
+ // The data has been exported from the gallery Nether, area index 61, ID 321, created by Aloe_vera
{
// Size:
- 15, 14, 16, // SizeX = 15, SizeY = 14, SizeZ = 16
+ 16, 14, 16, // SizeX = 16, SizeY = 14, SizeZ = 16
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 15, 23, 15, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
- "b:114: 6\n" /* netherbrickstairs */
+ "b:114: 5\n" /* netherbrickstairs */
"c:114: 4\n" /* netherbrickstairs */
- "d:114: 5\n" /* netherbrickstairs */
- "e: 44:14\n" /* step */
+ "d: 44:14\n" /* step */
+ "e:114: 6\n" /* netherbrickstairs */
"f:114: 7\n" /* netherbrickstairs */
"m: 19: 0\n" /* sponge */,
// Block data:
// Level 0
- /* z\x* 11111 */
- /* * 012345678901234 */
- /* 0 */ "...........aaa."
- /* 1 */ "aa.........aaaa"
- /* 2 */ "aa...........aa"
- /* 3 */ "aa...........aa"
- /* 4 */ "..............."
- /* 5 */ "..............."
- /* 6 */ "..............."
- /* 7 */ "..............."
- /* 8 */ "..............."
- /* 9 */ "..............."
- /* 10 */ "..............."
- /* 11 */ "..............."
- /* 12 */ "..............."
- /* 13 */ "..............."
- /* 14 */ "...........aaa."
- /* 15 */ "...........aaa."
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmmmmm"
+ /* 1 */ "aammmmmmmmmmmmaa"
+ /* 2 */ "aammmmmmmmmmmmaa"
+ /* 3 */ "aammmmmmmmmmmmaa"
+ /* 4 */ "mmmmmmmmmmmmmmmm"
+ /* 5 */ "mmmmmmmmmmmmmmmm"
+ /* 6 */ "mmmmmmmmmmmmmmmm"
+ /* 7 */ "mmmmmmmmmmmmmmmm"
+ /* 8 */ "mmmmmmmmmmmmmmmm"
+ /* 9 */ "mmmmmmmmmmmmmmmm"
+ /* 10 */ "mmmmmmmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmmmm"
+ /* 12 */ "maaammmmmmmmmmmm"
+ /* 13 */ "maaammmmmmmmmmmm"
+ /* 14 */ "maaammmmmmmmaaam"
+ /* 15 */ "mmmmmmmmmmmmaaam"
// Level 1
- /* z\x* 11111 */
- /* * 012345678901234 */
- /* 0 */ "...........aaa."
- /* 1 */ "aa.........aaaa"
- /* 2 */ "aa...........aa"
- /* 3 */ "aa...........aa"
- /* 4 */ "..............."
- /* 5 */ "..............."
- /* 6 */ "..............."
- /* 7 */ "..............."
- /* 8 */ "..............."
- /* 9 */ "..............."
- /* 10 */ "..............."
- /* 11 */ "..............."
- /* 12 */ "..............."
- /* 13 */ "..............."
- /* 14 */ "...........aaa."
- /* 15 */ "...........aaa."
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmmmmm"
+ /* 1 */ "aabmmmmmmmmmmcaa"
+ /* 2 */ "aabmmmmmmmmmmcaa"
+ /* 3 */ "aabmmmmmmmmmmcaa"
+ /* 4 */ "mmmmmmmmmmmmmmmm"
+ /* 5 */ "mmmmmmmmmmmmmmmm"
+ /* 6 */ "mmmmmmmmmmmmmmmm"
+ /* 7 */ "mmmmmmmmmmmmmmmm"
+ /* 8 */ "mmmmmmmmmmmmmmmm"
+ /* 9 */ "mmmmmmmmmmmmmmmm"
+ /* 10 */ "mmmmmmmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmmmm"
+ /* 12 */ "maaammmmmmmmmmmm"
+ /* 13 */ "maaammmmmmmmmmmm"
+ /* 14 */ "maaammmmmmmmaaam"
+ /* 15 */ "mmmmmmmmmmmmaaam"
// Level 2
- /* z\x* 11111 */
- /* * 012345678901234 */
- /* 0 */ "...........aaa."
- /* 1 */ "aa.........aaaa"
- /* 2 */ "aa...........aa"
- /* 3 */ "aa...........aa"
- /* 4 */ "..............."
- /* 5 */ "..............."
- /* 6 */ "..............."
- /* 7 */ "..............."
- /* 8 */ "..............."
- /* 9 */ "..............."
- /* 10 */ "..............."
- /* 11 */ "..............."
- /* 12 */ "..............."
- /* 13 */ "...........bbb."
- /* 14 */ "...........aaa."
- /* 15 */ "...........aaa."
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmmmmm"
+ /* 1 */ "aaabdmmmmmmdcaaa"
+ /* 2 */ "aaabdmmmmmmdcaaa"
+ /* 3 */ "aaabdmmmmmmdcaaa"
+ /* 4 */ "mmmmmmmmmmmmmmmm"
+ /* 5 */ "mmmmmmmmmmmmmmmm"
+ /* 6 */ "mmmmmmmmmmmmmmmm"
+ /* 7 */ "mmmmmmmmmmmmmmmm"
+ /* 8 */ "mmmmmmmmmmmmmmmm"
+ /* 9 */ "mmmmmmmmmmmmmmmm"
+ /* 10 */ "mmmmmmmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmmmm"
+ /* 12 */ "maaammmmmmmmmmmm"
+ /* 13 */ "maaammmmmmmmmmmm"
+ /* 14 */ "maaammmmmmmmaaam"
+ /* 15 */ "mmmmmmmmmmmmaaam"
// Level 3
- /* z\x* 11111 */
- /* * 012345678901234 */
- /* 0 */ "..........caaad"
- /* 1 */ "aa........caaaa"
- /* 2 */ "aa........caaaa"
- /* 3 */ "aa........caaaa"
- /* 4 */ "...........aaad"
- /* 5 */ "...........aaad"
- /* 6 */ "...........aaad"
- /* 7 */ "...........aaad"
- /* 8 */ "...........aaad"
- /* 9 */ "..........caaad"
- /* 10 */ "..........caaad"
- /* 11 */ "..........caaad"
- /* 12 */ "..........caaad"
- /* 13 */ "..........caaad"
- /* 14 */ "..........caaad"
- /* 15 */ "..........caaad"
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "eeeeeeeeeeeeeeee"
+ /* 1 */ "aaaaaaaaaaaaaaaa"
+ /* 2 */ "aaaaaaaaaaaaaaaa"
+ /* 3 */ "aaaaaaaaaaaaaaaa"
+ /* 4 */ "ffffffffffffffff"
+ /* 5 */ "mmmmmmmmmmmmmmmm"
+ /* 6 */ "mmmmmmmmmmmmmmmm"
+ /* 7 */ "mmmmmmmmmmmmmmmm"
+ /* 8 */ "mmmmmmmmmmmmmmmm"
+ /* 9 */ "mmmmmmmmmmmmmmmm"
+ /* 10 */ "mmmmmmmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmmmm"
+ /* 12 */ "maaammmmmmmmmmmm"
+ /* 13 */ "maaammmmmmmmmmmm"
+ /* 14 */ "maaammmmmmmmaaam"
+ /* 15 */ "mmmmmmmmmmmmaaam"
// Level 4
- /* z\x* 11111 */
- /* * 012345678901234 */
- /* 0 */ "..........aaaaa"
- /* 1 */ "aa........aaaaa"
- /* 2 */ "aa........aaaaa"
- /* 3 */ "aa........aaaaa"
- /* 4 */ "..........aaaaa"
- /* 5 */ "..........aaaaa"
- /* 6 */ "..........aaaaa"
- /* 7 */ "..........aaaaa"
- /* 8 */ "..........aaaaa"
- /* 9 */ "..........aaaaa"
- /* 10 */ "..........aaaaa"
- /* 11 */ "..........aaaaa"
- /* 12 */ "..........aaaaa"
- /* 13 */ "..........aaaaa"
- /* 14 */ "..........aaaaa"
- /* 15 */ "..........aaaaa"
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "aaaaaaaaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaaaaaaaa"
+ /* 2 */ "aaaaaaaaaaaaaaaa"
+ /* 3 */ "aaaaaaaaaaaaaaaa"
+ /* 4 */ "aaaaaaaaaaaaaaaa"
+ /* 5 */ "faaabmmmmmmmmmmm"
+ /* 6 */ "caaabmmmmmmmmmmm"
+ /* 7 */ "caaabmmmmmmmmmmm"
+ /* 8 */ "mmmmmmmmmmmmmmmm"
+ /* 9 */ "mmmmmmmmmmmmmmmm"
+ /* 10 */ "mmmmmmmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmmmm"
+ /* 12 */ "maaammmmmmmmmmmm"
+ /* 13 */ "maaammmmmmmmmmmm"
+ /* 14 */ "maaammmmmmmmaaam"
+ /* 15 */ "mmmmmmmmmmmmaaam"
// Level 5
- /* z\x* 11111 */
- /* * 012345678901234 */
- /* 0 */ "..........a...a"
- /* 1 */ "aa........a...a"
- /* 2 */ "aa........a...a"
- /* 3 */ "aa........a...a"
- /* 4 */ "..........a...a"
- /* 5 */ "..........a...a"
- /* 6 */ "........aaa...a"
- /* 7 */ "........aa....a"
- /* 8 */ "........aa....a"
- /* 9 */ "........aa....a"
- /* 10 */ "........aaa...a"
- /* 11 */ "..........a...a"
- /* 12 */ "..........a...a"
- /* 13 */ "..........a...a"
- /* 14 */ "..........a...a"
- /* 15 */ "..........a...a"
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "aaaaaaaaaaaaaaaa"
+ /* 1 */ "................"
+ /* 2 */ "................"
+ /* 3 */ "................"
+ /* 4 */ "a...aaaaaaaaaaaa"
+ /* 5 */ "a...ammmmmmmmmmm"
+ /* 6 */ "aaaaammmmmmmmmmm"
+ /* 7 */ "aaaaammmmmmmmmmm"
+ /* 8 */ "caaabmmmmmmmmmmm"
+ /* 9 */ "caaabmmmmmmmmmmm"
+ /* 10 */ "mmmmmmmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmmmm"
+ /* 12 */ "maaammmmmmmmmmmm"
+ /* 13 */ "maaammmmmmmmmmmm"
+ /* 14 */ "maaammmmmmmmaaam"
+ /* 15 */ "mmmmmmmmmmmmaaam"
// Level 6
- /* z\x* 11111 */
- /* * 012345678901234 */
- /* 0 */ "..............."
- /* 1 */ "aa........a...a"
- /* 2 */ "aa........a...a"
- /* 3 */ "aa........a...a"
- /* 4 */ "..............."
- /* 5 */ "..............."
- /* 6 */ "........aaa...."
- /* 7 */ "....aaaaa......"
- /* 8 */ "....aaaaa......"
- /* 9 */ "....aaaaa......"
- /* 10 */ "....aaaaaaa...."
- /* 11 */ "..............."
- /* 12 */ "..............."
- /* 13 */ "..............."
- /* 14 */ "..............."
- /* 15 */ "..............."
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmaaam"
+ /* 1 */ "................"
+ /* 2 */ "................"
+ /* 3 */ "................"
+ /* 4 */ "m...mmmmmmmmaaam"
+ /* 5 */ "a...ammmmmmmmmmm"
+ /* 6 */ "a...ammmmmmmmmmm"
+ /* 7 */ "a...ammmmmmmmmmm"
+ /* 8 */ "aaaaammmmmmmmmmm"
+ /* 9 */ "aaaaammmmmmmmmmm"
+ /* 10 */ "caaabmmmmmmmmmmm"
+ /* 11 */ "caaabmmmmmmmmmmm"
+ /* 12 */ "maaabmmmmmmmmmmm"
+ /* 13 */ "maaabmmmmmmmmmmm"
+ /* 14 */ "maaafmmmmmmmaaam"
+ /* 15 */ "mmmmmmmmmmmmaaam"
// Level 7
- /* z\x* 11111 */
- /* * 012345678901234 */
- /* 0 */ "..............."
- /* 1 */ "aad.......a...a"
- /* 2 */ "aad.......a...a"
- /* 3 */ "aad.......a...a"
- /* 4 */ "..............."
- /* 5 */ "..............."
- /* 6 */ "....aaaaaa....."
- /* 7 */ "....aaaa......."
- /* 8 */ "....aaaa......."
- /* 9 */ "....aaaa......."
- /* 10 */ "....aaaaaa....."
- /* 11 */ "..............."
- /* 12 */ "..............."
- /* 13 */ "..............."
- /* 14 */ "..............."
- /* 15 */ "..............."
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmaaam"
+ /* 1 */ "................"
+ /* 2 */ "................"
+ /* 3 */ "................"
+ /* 4 */ "m...mmmmmmmmaaam"
+ /* 5 */ "m...mmmmmmmmmmmm"
+ /* 6 */ "m...mmmmmmmmmmmm"
+ /* 7 */ "a...ammmmmmmmmmm"
+ /* 8 */ "a...ammmmmmmmmmm"
+ /* 9 */ "a...ammmmmmmmmmm"
+ /* 10 */ "aaaaammmmmmmmmmm"
+ /* 11 */ "aaaaaeemmmmmmmmm"
+ /* 12 */ "caaaaaammmmmmmmm"
+ /* 13 */ "caaaaaammmmmmmmm"
+ /* 14 */ "caaaaaammmmmaaam"
+ /* 15 */ "fffffffmmmmmaaam"
// Level 8
- /* z\x* 11111 */
- /* * 012345678901234 */
- /* 0 */ "..............."
- /* 1 */ "aaade.....a...a"
- /* 2 */ "aaade.....a...a"
- /* 3 */ "aaade.....a...a"
- /* 4 */ "..............."
- /* 5 */ "..............."
- /* 6 */ "....aaaaa......"
- /* 7 */ "....a.........."
- /* 8 */ "....a.........."
- /* 9 */ "....a.........."
- /* 10 */ "....aaaa......."
- /* 11 */ "..............."
- /* 12 */ "..............."
- /* 13 */ "..............."
- /* 14 */ "..............."
- /* 15 */ "..............."
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmaaam"
+ /* 1 */ "mmmmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmmmmmmm"
+ /* 4 */ "m...mmmmmmmmaaam"
+ /* 5 */ "m...mmmmmmmmmmmm"
+ /* 6 */ "m...mmmmmmmmmmmm"
+ /* 7 */ "m...mmmmmmmmmmmm"
+ /* 8 */ "m...mmmmmmmmmmmm"
+ /* 9 */ "a...ammmmmmmmmmm"
+ /* 10 */ "a...ammmmmmmmmmm"
+ /* 11 */ "a...aaaeemmmmmmm"
+ /* 12 */ "a.....aaammmmmmm"
+ /* 13 */ "a.....aaammmmmmm"
+ /* 14 */ "a.....aaammmaaam"
+ /* 15 */ "aaaaaaaffmmmaaam"
// Level 9
- /* z\x* 11111 */
- /* * 012345678901234 */
- /* 0 */ "bbbbbbbbbbbbbbb"
- /* 1 */ "aaaaaaaaaaaaaaa"
- /* 2 */ "aaaaaaaaaaaaaaa"
- /* 3 */ "aaaaaaaaaaaaaaa"
- /* 4 */ "ffffffaaaffffff"
- /* 5 */ "....aaaaa......"
- /* 6 */ "....a...a......"
- /* 7 */ "....a.........."
- /* 8 */ "..............."
- /* 9 */ "..............."
- /* 10 */ "..............."
- /* 11 */ "..............."
- /* 12 */ "..............."
- /* 13 */ "..............."
- /* 14 */ "..............."
- /* 15 */ "..............."
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmcaaab"
+ /* 1 */ "mmmmmmmmmmmcaaab"
+ /* 2 */ "mmmmmmmmmmmcaaab"
+ /* 3 */ "mmmmmmmmmmmcaaab"
+ /* 4 */ "mmmmmmmmmmmcaaab"
+ /* 5 */ "mmmmmmmmmmmcaaab"
+ /* 6 */ "m...mmmmmmmcaaab"
+ /* 7 */ "m...mmmmmmmcaaab"
+ /* 8 */ "m...mmmmmmmcaaab"
+ /* 9 */ "m...mmmmmmmcaaab"
+ /* 10 */ "m...mmmmmmmcaaab"
+ /* 11 */ "m...maaaaeecaaab"
+ /* 12 */ "m.......aaaaaaab"
+ /* 13 */ "m.......aaaaaaab"
+ /* 14 */ "m.......aaaaaaab"
+ /* 15 */ "mmmmmaaaafffaaab"
// Level 10
- /* z\x* 11111 */
- /* * 012345678901234 */
- /* 0 */ "aaaaaaaaaaaaaaa"
- /* 1 */ "aaaaaaaaaaaaaaa"
- /* 2 */ "aaaaaaaaaaaaaaa"
- /* 3 */ "aaaaaaaaaaaaaaa"
- /* 4 */ "aaaaaaaaaaaaaaa"
- /* 5 */ "....a...a......"
- /* 6 */ "....a...a......"
- /* 7 */ "..............."
- /* 8 */ "..............."
- /* 9 */ "..............."
- /* 10 */ "..............."
- /* 11 */ "..............."
- /* 12 */ "..............."
- /* 13 */ "..............."
- /* 14 */ "..............."
- /* 15 */ "..............."
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmaaaaa"
+ /* 1 */ "mmmmmmmmmmmaaaaa"
+ /* 2 */ "mmmmmmmmmmmaaaaa"
+ /* 3 */ "mmmmmmmmmmmaaaaa"
+ /* 4 */ "mmmmmmmmmmmaaaaa"
+ /* 5 */ "mmmmmmmmmmmaaaaa"
+ /* 6 */ "mmmmmmmmmmmaaaaa"
+ /* 7 */ "mmmmmmmmmmmaaaaa"
+ /* 8 */ "m...mmmmmmmaaaaa"
+ /* 9 */ "m...mmmmmmmaaaaa"
+ /* 10 */ "m...mmmmmmmaaaaa"
+ /* 11 */ "m...mmmaaaaaaaaa"
+ /* 12 */ "m.........aaaaaa"
+ /* 13 */ "m.........aaaaaa"
+ /* 14 */ "m.........aaaaaa"
+ /* 15 */ "mmmmmmmaaaaaaaaa"
// Level 11
- /* z\x* 11111 */
- /* * 012345678901234 */
- /* 0 */ "aaaaaaaaaaaaaaa"
- /* 1 */ "..............."
- /* 2 */ "..............."
- /* 3 */ "..............."
- /* 4 */ "aaaaa...aaaaaaa"
- /* 5 */ "....a...a......"
- /* 6 */ "..............."
- /* 7 */ "..............."
- /* 8 */ "..............."
- /* 9 */ "..............."
- /* 10 */ "..............."
- /* 11 */ "..............."
- /* 12 */ "..............."
- /* 13 */ "..............."
- /* 14 */ "..............."
- /* 15 */ "..............."
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmma...a"
+ /* 1 */ "mmmmmmmmmmma...a"
+ /* 2 */ "mmmmmmmmmmma...a"
+ /* 3 */ "mmmmmmmmmmma...a"
+ /* 4 */ "mmmmmmmmmmma...a"
+ /* 5 */ "mmmmmmmmmmma...a"
+ /* 6 */ "mmmmmmmmmmma...a"
+ /* 7 */ "mmmmmmmmmmma...a"
+ /* 8 */ "mmmmmmmmmmma...a"
+ /* 9 */ "mmmmmmmmmmma...a"
+ /* 10 */ "mmmmmmmmmmma...a"
+ /* 11 */ "mmmmmmmmmaaa...a"
+ /* 12 */ "mmmm...........a"
+ /* 13 */ "mmmm...........a"
+ /* 14 */ "mmmm...........a"
+ /* 15 */ "mmmmmmmmmaaa...a"
// Level 12
- /* z\x* 11111 */
- /* * 012345678901234 */
- /* 0 */ "..............."
- /* 1 */ "..............."
- /* 2 */ "..............."
- /* 3 */ "..............."
- /* 4 */ "..............."
- /* 5 */ "..............."
- /* 6 */ "..............."
- /* 7 */ "..............."
- /* 8 */ "..............."
- /* 9 */ "..............."
- /* 10 */ "..............."
- /* 11 */ "..............."
- /* 12 */ "..............."
- /* 13 */ "..............."
- /* 14 */ "..............."
- /* 15 */ "..............."
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmm...m"
+ /* 1 */ "mmmmmmmmmmmm...m"
+ /* 2 */ "mmmmmmmmmmmm...m"
+ /* 3 */ "mmmmmmmmmmmm...m"
+ /* 4 */ "mmmmmmmmmmmm...m"
+ /* 5 */ "mmmmmmmmmmmm...m"
+ /* 6 */ "mmmmmmmmmmmm...m"
+ /* 7 */ "mmmmmmmmmmmm...m"
+ /* 8 */ "mmmmmmmmmmmm...m"
+ /* 9 */ "mmmmmmmmmmmm...m"
+ /* 10 */ "mmmmmmmmmmmm...m"
+ /* 11 */ "mmmmmmmmmmmm...m"
+ /* 12 */ "mmmmmm.........m"
+ /* 13 */ "mmmmmm.........m"
+ /* 14 */ "mmmmmm.........m"
+ /* 15 */ "mmmmmmmmmmmm...m"
// Level 13
- /* z\x* 11111 */
- /* * 012345678901234 */
- /* 0 */ "..............."
- /* 1 */ "..............."
- /* 2 */ "..............."
- /* 3 */ "..............."
- /* 4 */ "..............."
- /* 5 */ "..............."
- /* 6 */ "..............."
- /* 7 */ "..............."
- /* 8 */ "..............."
- /* 9 */ "..............."
- /* 10 */ "..............."
- /* 11 */ "..............."
- /* 12 */ "..............."
- /* 13 */ "..............."
- /* 14 */ "..............."
- /* 15 */ "...............",
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmm...m"
+ /* 1 */ "mmmmmmmmmmmm...m"
+ /* 2 */ "mmmmmmmmmmmm...m"
+ /* 3 */ "mmmmmmmmmmmm...m"
+ /* 4 */ "mmmmmmmmmmmm...m"
+ /* 5 */ "mmmmmmmmmmmm...m"
+ /* 6 */ "mmmmmmmmmmmm...m"
+ /* 7 */ "mmmmmmmmmmmm...m"
+ /* 8 */ "mmmmmmmmmmmm...m"
+ /* 9 */ "mmmmmmmmmmmm...m"
+ /* 10 */ "mmmmmmmmmmmm...m"
+ /* 11 */ "mmmmmmmmmmmm...m"
+ /* 12 */ "mmmmmmmm.......m"
+ /* 13 */ "mmmmmmmm.......m"
+ /* 14 */ "mmmmmmmm.......m"
+ /* 15 */ "mmmmmmmmmmmm...m",
// Connectors:
- "",
+ "0: 0, 5, 2: 4\n" /* Type 0, direction X- */
+ "0: 15, 5, 2: 5\n" /* Type 0, direction X+ */
+ "0: 13, 11, 0: 2\n" /* Type 0, direction Z- */
+ "0: 13, 11, 15: 3\n" /* Type 0, direction Z+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1867,7 +1914,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
false,
// DefaultWeight:
- 100,
+ 20,
// DepthWeight:
"",
@@ -1885,6 +1932,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
15, 8, 5, // SizeX = 15, SizeY = 8, SizeZ = 5
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 14, 17, 4, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -1985,7 +2036,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
500,
// DepthWeight:
- "",
+ "4:-3000|8:-3000|12:-3000|16:-3000|20:-3000",
// AddWeightIfSame:
1000,
@@ -2000,6 +2051,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
15, 8, 10, // SizeX = 15, SizeY = 8, SizeZ = 10
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 14, 17, 9, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -2156,6 +2211,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
11, 6, 5, // SizeX = 11, SizeY = 6, SizeZ = 5
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 10, 5, 4, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -2233,7 +2292,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
false,
// DefaultWeight:
- 200,
+ 300,
// DepthWeight:
"",
@@ -2251,6 +2310,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
13, 6, 5, // SizeX = 13, SizeY = 6, SizeZ = 5
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 12, 5, 4, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -2328,7 +2391,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
false,
// DefaultWeight:
- 200,
+ 300,
// DepthWeight:
"",
@@ -2340,12 +2403,109 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Corridor5:
+ // The data has been exported from the gallery Nether, area index 65, ID 330, created by xoft
+ {
+ // Size:
+ 5, 6, 5, // SizeX = 5, SizeY = 6, SizeZ = 5
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 4, 5, 4, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:112: 0\n" /* netherbrick */
+ "b:113: 0\n" /* netherbrickfence */
+ "c:114: 2\n" /* netherbrickstairs */
+ "d:114: 3\n" /* netherbrickstairs */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "aaaaa"
+ /* 2 */ "aaaaa"
+ /* 3 */ "aaaaa"
+ /* 4 */ "aaaaa"
+
+ // Level 1
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "....."
+ /* 2 */ "....."
+ /* 3 */ "....."
+ /* 4 */ "aaaaa"
+
+ // Level 2
+ /* z\x* 01234 */
+ /* 0 */ "ababa"
+ /* 1 */ "....."
+ /* 2 */ "....."
+ /* 3 */ "....."
+ /* 4 */ "ababa"
+
+ // Level 3
+ /* z\x* 01234 */
+ /* 0 */ "ababa"
+ /* 1 */ "....."
+ /* 2 */ "....."
+ /* 3 */ "....."
+ /* 4 */ "ababa"
+
+ // Level 4
+ /* z\x* 01234 */
+ /* 0 */ "ababa"
+ /* 1 */ "....."
+ /* 2 */ "....."
+ /* 3 */ "....."
+ /* 4 */ "ababa"
+
+ // Level 5
+ /* z\x* 01234 */
+ /* 0 */ "ccccc"
+ /* 1 */ "aaaaa"
+ /* 2 */ "aaaaa"
+ /* 3 */ "aaaaa"
+ /* 4 */ "ddddd",
+
+ // Connectors:
+ "1: 4, 1, 2: 5\n" /* Type 1, direction X+ */
+ "1: 0, 1, 2: 4\n" /* Type 1, direction X- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 500,
+
+ // DepthWeight:
+ "6:0|12:0|18:0",
+
+ // AddWeightIfSame:
+ 500,
+ }, // Corridor5
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CorridorCorner5:
// The data has been exported from the gallery Nether, area index 10, ID 40, created by xoft
{
// Size:
11, 6, 11, // SizeX = 11, SizeY = 6, SizeZ = 11
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 10, 5, 10, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -2479,6 +2639,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
11, 6, 11, // SizeX = 11, SizeY = 6, SizeZ = 11
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 10, 5, 10, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -2607,12 +2771,137 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CorridorCrossing:
+ // The data has been exported from the gallery Nether, area index 63, ID 328, created by xoft
+ {
+ // Size:
+ 9, 6, 9, // SizeX = 9, SizeY = 6, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 8, 5, 8, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:112: 0\n" /* netherbrick */
+ "b:113: 0\n" /* netherbrickfence */
+ "c:114: 0\n" /* netherbrickstairs */
+ "d:114: 1\n" /* netherbrickstairs */
+ "e:114: 2\n" /* netherbrickstairs */
+ "f:114: 3\n" /* netherbrickstairs */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 012345678 */
+ /* 0 */ "mmaaaaamm"
+ /* 1 */ "mmaaaaamm"
+ /* 2 */ "aaaaaaaaa"
+ /* 3 */ "aaaaaaaaa"
+ /* 4 */ "aaaaaaaaa"
+ /* 5 */ "aaaaaaaaa"
+ /* 6 */ "aaaaaaaaa"
+ /* 7 */ "mmaaaaamm"
+ /* 8 */ "mmaaaaamm"
+
+ // Level 1
+ /* z\x* 012345678 */
+ /* 0 */ "mma...amm"
+ /* 1 */ "mma...amm"
+ /* 2 */ "aaa...aaa"
+ /* 3 */ "........."
+ /* 4 */ "........."
+ /* 5 */ "........."
+ /* 6 */ "aaa...aaa"
+ /* 7 */ "mma...amm"
+ /* 8 */ "mma...amm"
+
+ // Level 2
+ /* z\x* 012345678 */
+ /* 0 */ "mma...amm"
+ /* 1 */ "mmb...bmm"
+ /* 2 */ "aba...aba"
+ /* 3 */ "........."
+ /* 4 */ "........."
+ /* 5 */ "........."
+ /* 6 */ "aba...aba"
+ /* 7 */ "mmb...bmm"
+ /* 8 */ "mma...amm"
+
+ // Level 3
+ /* z\x* 012345678 */
+ /* 0 */ "mma...amm"
+ /* 1 */ "mmb...bmm"
+ /* 2 */ "aba...aba"
+ /* 3 */ "........."
+ /* 4 */ "........."
+ /* 5 */ "........."
+ /* 6 */ "aba...aba"
+ /* 7 */ "mmb...bmm"
+ /* 8 */ "mma...amm"
+
+ // Level 4
+ /* z\x* 012345678 */
+ /* 0 */ "mma...amm"
+ /* 1 */ "mmb...bmm"
+ /* 2 */ "aba...aba"
+ /* 3 */ "........."
+ /* 4 */ "........."
+ /* 5 */ "........."
+ /* 6 */ "aba...aba"
+ /* 7 */ "mmb...bmm"
+ /* 8 */ "mma...amm"
+
+ // Level 5
+ /* z\x* 012345678 */
+ /* 0 */ "mmcaaadmm"
+ /* 1 */ "mmcaaadmm"
+ /* 2 */ "eeeaaaeee"
+ /* 3 */ "aaaaaaaaa"
+ /* 4 */ "aaaaaaaaa"
+ /* 5 */ "aaaaaaaaa"
+ /* 6 */ "ffcaaadff"
+ /* 7 */ "mmcaaadmm"
+ /* 8 */ "mmcaaadmm",
+
+ // Connectors:
+ "1: 8, 1, 4: 5\n" /* Type 1, direction X+ */
+ "1: 4, 1, 0: 2\n" /* Type 1, direction Z- */
+ "1: 4, 1, 8: 3\n" /* Type 1, direction Z+ */
+ "1: 0, 1, 4: 4\n" /* Type 1, direction X- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ -50,
+ }, // CorridorCrossing
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CorridorStairs:
// The data has been exported from the gallery Nether, area index 12, ID 42, created by xoft
{
// Size:
9, 13, 5, // SizeX = 9, SizeY = 13, SizeZ = 5
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 8, 12, 4, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -2741,10 +3030,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
false,
// DefaultWeight:
- 100,
+ 250,
// DepthWeight:
- "",
+ "0:0|2:0|4:0|6:0|8:0|10:0|12:0|14:0|16:0|18:0",
// AddWeightIfSame:
0,
@@ -2759,6 +3048,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
14, 6, 5, // SizeX = 14, SizeY = 6, SizeZ = 5
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 13, 5, 4, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -2854,6 +3147,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
15, 11, 15, // SizeX = 15, SizeY = 11, SizeZ = 15
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 14, 10, 14, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -3086,7 +3383,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
false,
// DefaultWeight:
- 100,
+ 10,
// DepthWeight:
"",
@@ -3104,6 +3401,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
12, 15, 15, // SizeX = 12, SizeY = 15, SizeZ = 15
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 11, 14, 14, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -3411,13 +3712,13 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
false,
// DefaultWeight:
- 100,
+ 10,
// DepthWeight:
"",
// AddWeightIfSame:
- 0,
+ -1000,
}, // LavaStaircaseBig
@@ -3429,6 +3730,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
16, 12, 15, // SizeX = 16, SizeY = 12, SizeZ = 15
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 15, 11, 14, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -3685,7 +3990,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
false,
// DefaultWeight:
- 100,
+ 10,
// DepthWeight:
"",
@@ -3703,6 +4008,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
13, 8, 13, // SizeX = 13, SizeY = 8, SizeZ = 13
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 12, 7, 12, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -3873,7 +4182,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
"",
// AddWeightIfSame:
- 0,
+ -1000,
}, // MidStaircase
@@ -3885,6 +4194,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
7, 10, 7, // SizeX = 7, SizeY = 10, SizeZ = 7
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 19, 6, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -4009,7 +4322,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
100,
// DepthWeight:
- "",
+ "1:0|3:0|5:0|7:0|9:0|11:0|13:0|15:0",
// AddWeightIfSame:
0,
@@ -4024,6 +4337,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
7, 10, 7, // SizeX = 7, SizeY = 10, SizeZ = 7
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 19, 6, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -4148,7 +4465,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
100,
// DepthWeight:
- "",
+ "1:0|3:0|5:0|7:0|9:0|11:0|13:0|15:0",
// AddWeightIfSame:
0,
@@ -4163,6 +4480,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
13, 6, 7, // SizeX = 13, SizeY = 6, SizeZ = 7
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 12, 5, 6, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -4273,6 +4594,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Size:
13, 6, 9, // SizeX = 13, SizeY = 6, SizeZ = 9
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 12, 5, 8, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
@@ -4389,11 +4714,299 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TinyCorridorCorner:
+ // The data has been exported from the gallery Nether, area index 66, ID 331, created by xoft
+ {
+ // Size:
+ 5, 6, 5, // SizeX = 5, SizeY = 6, SizeZ = 5
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 4, 5, 4, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:112: 0\n" /* netherbrick */
+ "b:113: 0\n" /* netherbrickfence */
+ "c:114: 2\n" /* netherbrickstairs */
+ "d:114: 1\n" /* netherbrickstairs */
+ "e:114: 0\n" /* netherbrickstairs */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "aaaaa"
+ /* 2 */ "aaaaa"
+ /* 3 */ "aaaaa"
+ /* 4 */ "aaaaa"
+
+ // Level 1
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "....a"
+ /* 2 */ "....a"
+ /* 3 */ "....a"
+ /* 4 */ "a...a"
+
+ // Level 2
+ /* z\x* 01234 */
+ /* 0 */ "ababa"
+ /* 1 */ "....b"
+ /* 2 */ "....a"
+ /* 3 */ "....b"
+ /* 4 */ "a...a"
+
+ // Level 3
+ /* z\x* 01234 */
+ /* 0 */ "ababa"
+ /* 1 */ "....b"
+ /* 2 */ "....a"
+ /* 3 */ "....b"
+ /* 4 */ "a...a"
+
+ // Level 4
+ /* z\x* 01234 */
+ /* 0 */ "ababa"
+ /* 1 */ "....b"
+ /* 2 */ "....a"
+ /* 3 */ "....b"
+ /* 4 */ "a...a"
+
+ // Level 5
+ /* z\x* 01234 */
+ /* 0 */ "ccccc"
+ /* 1 */ "aaaad"
+ /* 2 */ "aaaad"
+ /* 3 */ "aaaad"
+ /* 4 */ "eaaad",
+
+ // Connectors:
+ "1: 2, 1, 4: 3\n" /* Type 1, direction Z+ */
+ "1: 0, 1, 2: 4\n" /* Type 1, direction X- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ -50,
+ }, // TinyCorridorCorner
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TinyCorridorCornerChest:
+ // The data has been exported from the gallery Nether, area index 67, ID 332, created by Aloe_vera
+ {
+ // Size:
+ 5, 6, 5, // SizeX = 5, SizeY = 6, SizeZ = 5
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 4, 5, 4, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:112: 0\n" /* netherbrick */
+ "b: 54: 4\n" /* chest */
+ "c:113: 0\n" /* netherbrickfence */
+ "d:114: 2\n" /* netherbrickstairs */
+ "e:114: 1\n" /* netherbrickstairs */
+ "f:114: 0\n" /* netherbrickstairs */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "aaaaa"
+ /* 2 */ "aaaaa"
+ /* 3 */ "aaaaa"
+ /* 4 */ "aaaaa"
+
+ // Level 1
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "....a"
+ /* 2 */ "...ba"
+ /* 3 */ "....a"
+ /* 4 */ "a...a"
+
+ // Level 2
+ /* z\x* 01234 */
+ /* 0 */ "acaca"
+ /* 1 */ "....c"
+ /* 2 */ "....a"
+ /* 3 */ "....c"
+ /* 4 */ "a...a"
+
+ // Level 3
+ /* z\x* 01234 */
+ /* 0 */ "acaca"
+ /* 1 */ "....c"
+ /* 2 */ "....a"
+ /* 3 */ "....c"
+ /* 4 */ "a...a"
+
+ // Level 4
+ /* z\x* 01234 */
+ /* 0 */ "acaca"
+ /* 1 */ "....c"
+ /* 2 */ "....a"
+ /* 3 */ "....c"
+ /* 4 */ "a...a"
+
+ // Level 5
+ /* z\x* 01234 */
+ /* 0 */ "ddddd"
+ /* 1 */ "aaaae"
+ /* 2 */ "aaaae"
+ /* 3 */ "aaaae"
+ /* 4 */ "faaae",
+
+ // Connectors:
+ "1: 2, 1, 4: 3\n" /* Type 1, direction Z+ */
+ "1: 0, 1, 2: 4\n" /* Type 1, direction X- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+ }, // TinyCorridorCornerChest
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TinyCorridorCrossing:
+ // The data has been exported from the gallery Nether, area index 64, ID 329, created by xoft
+ {
+ // Size:
+ 5, 6, 5, // SizeX = 5, SizeY = 6, SizeZ = 5
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 4, 5, 4, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:112: 0\n" /* netherbrick */
+ "b:114: 2\n" /* netherbrickstairs */
+ "c:114: 0\n" /* netherbrickstairs */
+ "d:114: 1\n" /* netherbrickstairs */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "aaaaa"
+ /* 2 */ "aaaaa"
+ /* 3 */ "aaaaa"
+ /* 4 */ "aaaaa"
+
+ // Level 1
+ /* z\x* 01234 */
+ /* 0 */ "a...a"
+ /* 1 */ "....."
+ /* 2 */ "....."
+ /* 3 */ "....."
+ /* 4 */ "a...a"
+
+ // Level 2
+ /* z\x* 01234 */
+ /* 0 */ "a...a"
+ /* 1 */ "....."
+ /* 2 */ "....."
+ /* 3 */ "....."
+ /* 4 */ "a...a"
+
+ // Level 3
+ /* z\x* 01234 */
+ /* 0 */ "a...a"
+ /* 1 */ "....."
+ /* 2 */ "....."
+ /* 3 */ "....."
+ /* 4 */ "a...a"
+
+ // Level 4
+ /* z\x* 01234 */
+ /* 0 */ "a...a"
+ /* 1 */ "....."
+ /* 2 */ "....."
+ /* 3 */ "....."
+ /* 4 */ "a...a"
+
+ // Level 5
+ /* z\x* 01234 */
+ /* 0 */ "baaab"
+ /* 1 */ "aaaaa"
+ /* 2 */ "aaaaa"
+ /* 3 */ "aaaaa"
+ /* 4 */ "caaad",
+
+ // Connectors:
+ "1: 4, 1, 2: 5\n" /* Type 1, direction X+ */
+ "1: 2, 1, 4: 3\n" /* Type 1, direction Z+ */
+ "1: 0, 1, 2: 4\n" /* Type 1, direction X- */
+ "1: 2, 1, 0: 2\n" /* Type 1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "1:200|2:400|3:0|4:500",
+
+ // AddWeightIfSame:
+ -50,
+ }, // TinyCorridorCrossing
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Turret:
// The data has been exported from the gallery Nether, area index 7, ID 34, created by xoft
{
// Size:
- 7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7
+ 7, 7, 7, // SizeX = 7, SizeY = 7, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 16, 6, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
@@ -4460,7 +5073,17 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
/* 3 */ "a.....a"
/* 4 */ "a.....a"
/* 5 */ "a.....a"
- /* 6 */ "aaaaaaa",
+ /* 6 */ "aaaaaaa"
+
+ // Level 6
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "......."
+ /* 2 */ "......."
+ /* 3 */ "......."
+ /* 4 */ "......."
+ /* 5 */ "......."
+ /* 6 */ ".......",
// Connectors:
"0: 0, 1, 3: 4\n" /* Type 0, direction X- */
@@ -4502,6 +5125,10 @@ const cPrefab::sDef g_NetherFortStartingPrefabs[] =
// Size:
13, 9, 13, // SizeX = 13, SizeY = 9, SizeZ = 13
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 12, 8, 12, // MaxX, MaxY, MaxZ
+
// Block definitions:
".: 0: 0\n" /* air */
"a:112: 0\n" /* netherbrick */
diff --git a/src/Generating/Ravines.cpp b/src/Generating/Ravines.cpp
index e64f55214..267dcbbf9 100644
--- a/src/Generating/Ravines.cpp
+++ b/src/Generating/Ravines.cpp
@@ -269,7 +269,7 @@ void cStructGenRavines::cRavine::GenerateBaseDefPoints(int a_BlockX, int a_Block
int CenterZ = a_BlockZ + OffsetZ;
// Get the base angle in which the ravine "axis" goes:
- float Angle = (float)(((float)((a_Noise.IntNoise3DInt(20 * a_BlockX, 70 * a_BlockZ, 6000) / 9) % 16384)) / 16384.0 * 3.141592653);
+ float Angle = (float)(((float)((a_Noise.IntNoise3DInt(20 * a_BlockX, 70 * a_BlockZ, 6000) / 9) % 16384)) / 16384.0 * M_PI);
float xc = sin(Angle);
float zc = cos(Angle);
@@ -311,12 +311,13 @@ void cStructGenRavines::cRavine::RefineDefPoints(const cRavDefPoints & a_Src, cR
a_Dst.clear();
a_Dst.reserve(Num * 2 + 2);
cRavDefPoints::const_iterator itr = a_Src.begin() + 1;
- a_Dst.push_back(a_Src.front());
- int PrevX = a_Src.front().m_BlockX;
- int PrevZ = a_Src.front().m_BlockZ;
- int PrevR = a_Src.front().m_Radius;
- int PrevT = a_Src.front().m_Top;
- int PrevB = a_Src.front().m_Bottom;
+ const cRavDefPoint & Source = a_Src.front();
+ a_Dst.push_back(Source);
+ int PrevX = Source.m_BlockX;
+ int PrevZ = Source.m_BlockZ;
+ int PrevR = Source.m_Radius;
+ int PrevT = Source.m_Top;
+ int PrevB = Source.m_Bottom;
for (int i = 0; i <= Num; ++i, ++itr)
{
int dx = itr->m_BlockX - PrevX;
diff --git a/src/Group.cpp b/src/Group.cpp
index 9c2467144..725740905 100644
--- a/src/Group.cpp
+++ b/src/Group.cpp
@@ -7,7 +7,7 @@
-void cGroup::AddCommand( AString a_Command )
+void cGroup::AddCommand( const AString & a_Command )
{
m_Commands[ a_Command ] = true;
}
@@ -16,7 +16,7 @@ void cGroup::AddCommand( AString a_Command )
-void cGroup::AddPermission( AString a_Permission )
+void cGroup::AddPermission( const AString & a_Permission )
{
m_Permissions[ a_Permission ] = true;
}
diff --git a/src/Group.h b/src/Group.h
index 8bee6f7ed..47088d50d 100644
--- a/src/Group.h
+++ b/src/Group.h
@@ -11,11 +11,11 @@ public: // tolua_export
cGroup() {}
~cGroup() {}
- void SetName( AString a_Name ) { m_Name = a_Name; } // tolua_export
+ void SetName( const AString & a_Name ) { m_Name = a_Name; } // tolua_export
const AString & GetName() const { return m_Name; } // tolua_export
- void SetColor( AString a_Color ) { m_Color = a_Color; } // tolua_export
- void AddCommand( AString a_Command ); // tolua_export
- void AddPermission( AString a_Permission ); // tolua_export
+ void SetColor( const AString & a_Color ) { m_Color = a_Color; } // tolua_export
+ void AddCommand( const AString & a_Command ); // tolua_export
+ void AddPermission( const AString & a_Permission ); // tolua_export
void InheritFrom( cGroup* a_Group ); // tolua_export
typedef std::map< AString, bool > PermissionMap;
diff --git a/src/Item.cpp b/src/Item.cpp
index 856b68be6..7e472f6d8 100644
--- a/src/Item.cpp
+++ b/src/Item.cpp
@@ -5,6 +5,8 @@
#include "json/json.h"
#include "Items/ItemHandler.h"
+#include "FastRandom.h"
+
@@ -196,9 +198,6 @@ bool cItem::IsEnchantable(short item)
return true;
if ((item >= 298) && (item <= 317))
return true;
- if ((item >= 290) && (item <= 294))
- return true;
-
if ((item == 346) || (item == 359) || (item == 261))
return true;
@@ -209,6 +208,157 @@ bool cItem::IsEnchantable(short item)
+int cItem::GetEnchantability()
+{
+ int Enchantability = 0;
+
+ switch (m_ItemType)
+ {
+ case E_ITEM_WOODEN_SWORD: Enchantability = 15; break;
+ case E_ITEM_WOODEN_PICKAXE: Enchantability = 15; break;
+ case E_ITEM_WOODEN_SHOVEL: Enchantability = 15; break;
+ case E_ITEM_WOODEN_AXE: Enchantability = 15; break;
+ case E_ITEM_WOODEN_HOE: Enchantability = 15; break;
+
+ case E_ITEM_LEATHER_CAP: Enchantability = 15; break;
+ case E_ITEM_LEATHER_TUNIC: Enchantability = 15; break;
+ case E_ITEM_LEATHER_PANTS: Enchantability = 15; break;
+ case E_ITEM_LEATHER_BOOTS: Enchantability = 15; break;
+
+ case E_ITEM_STONE_SWORD: Enchantability = 5; break;
+ case E_ITEM_STONE_PICKAXE: Enchantability = 5; break;
+ case E_ITEM_STONE_SHOVEL: Enchantability = 5; break;
+ case E_ITEM_STONE_AXE: Enchantability = 5; break;
+ case E_ITEM_STONE_HOE: Enchantability = 5; break;
+
+ case E_ITEM_IRON_HELMET: Enchantability = 9; break;
+ case E_ITEM_IRON_CHESTPLATE: Enchantability = 9; break;
+ case E_ITEM_IRON_LEGGINGS: Enchantability = 9; break;
+ case E_ITEM_IRON_BOOTS: Enchantability = 9; break;
+
+ case E_ITEM_IRON_SWORD: Enchantability = 14; break;
+ case E_ITEM_IRON_PICKAXE: Enchantability = 14; break;
+ case E_ITEM_IRON_SHOVEL: Enchantability = 14; break;
+ case E_ITEM_IRON_AXE: Enchantability = 14; break;
+ case E_ITEM_IRON_HOE: Enchantability = 14; break;
+
+ case E_ITEM_CHAIN_HELMET: Enchantability = 12; break;
+ case E_ITEM_CHAIN_CHESTPLATE: Enchantability = 12; break;
+ case E_ITEM_CHAIN_LEGGINGS: Enchantability = 12; break;
+ case E_ITEM_CHAIN_BOOTS: Enchantability = 12; break;
+
+ case E_ITEM_DIAMOND_HELMET: Enchantability = 10; break;
+ case E_ITEM_DIAMOND_CHESTPLATE: Enchantability = 10; break;
+ case E_ITEM_DIAMOND_LEGGINGS: Enchantability = 10; break;
+ case E_ITEM_DIAMOND_BOOTS: Enchantability = 10; break;
+
+ case E_ITEM_DIAMOND_SWORD: Enchantability = 10; break;
+ case E_ITEM_DIAMOND_PICKAXE: Enchantability = 10; break;
+ case E_ITEM_DIAMOND_SHOVEL: Enchantability = 10; break;
+ case E_ITEM_DIAMOND_AXE: Enchantability = 10; break;
+ case E_ITEM_DIAMOND_HOE: Enchantability = 10; break;
+
+ case E_ITEM_GOLD_HELMET: Enchantability = 25; break;
+ case E_ITEM_GOLD_CHESTPLATE: Enchantability = 25; break;
+ case E_ITEM_GOLD_LEGGINGS: Enchantability = 25; break;
+ case E_ITEM_GOLD_BOOTS: Enchantability = 25; break;
+
+ case E_ITEM_GOLD_SWORD: Enchantability = 22; break;
+ case E_ITEM_GOLD_PICKAXE: Enchantability = 22; break;
+ case E_ITEM_GOLD_SHOVEL: Enchantability = 22; break;
+ case E_ITEM_GOLD_AXE: Enchantability = 22; break;
+ case E_ITEM_GOLD_HOE: Enchantability = 22; break;
+
+ case E_ITEM_FISHING_ROD: Enchantability = 1; break;
+ case E_ITEM_BOW: Enchantability = 1; break;
+ case E_ITEM_BOOK: Enchantability = 1; break;
+ }
+
+ return Enchantability;
+}
+
+
+
+
+
+bool cItem::EnchantByXPLevels(int a_NumXPLevels)
+{
+ if (!cItem::IsEnchantable(m_ItemType) && (m_ItemType != E_ITEM_BOOK))
+ {
+ return false;
+ }
+
+ int Enchantability = GetEnchantability();
+
+ cFastRandom Random;
+ int ModifiedEnchantmentLevel = a_NumXPLevels + (int)Random.NextFloat((float)Enchantability / 4) + (int)Random.NextFloat((float)Enchantability / 4) + 1;
+ float RandomBonus = 1.0F + (Random.NextFloat(1) + Random.NextFloat(1) - 1.0F) * 0.15F;
+ int FinalEnchantmentLevel = (int)(ModifiedEnchantmentLevel * RandomBonus + 0.5F);
+
+ cWeightedEnchantments enchantments;
+ cEnchantments::AddItemEnchantmentWeights(enchantments, m_ItemType, FinalEnchantmentLevel);
+
+ if (m_ItemType == E_ITEM_BOOK)
+ {
+ m_ItemType = E_ITEM_ENCHANTED_BOOK;
+ }
+
+ cEnchantments Enchantment1 = cEnchantments::GetRandomEnchantmentFromVector(enchantments);
+ m_Enchantments.AddFromString(Enchantment1.ToString());
+ cEnchantments::RemoveEnchantmentWeightFromVector(enchantments, Enchantment1);
+
+ // Checking for conflicting enchantments
+ cEnchantments::CheckEnchantmentConflictsFromVector(enchantments, Enchantment1);
+
+ float NewEnchantmentLevel = (float)a_NumXPLevels;
+
+ // Next Enchantment (Second)
+ NewEnchantmentLevel = NewEnchantmentLevel / 2;
+ float SecondEnchantmentChance = (NewEnchantmentLevel + 1) / 50 * 100;
+ if (enchantments.empty() || (Random.NextFloat(100) > SecondEnchantmentChance))
+ {
+ return true;
+ }
+
+ cEnchantments Enchantment2 = cEnchantments::GetRandomEnchantmentFromVector(enchantments);
+ m_Enchantments.AddFromString(Enchantment2.ToString());
+ cEnchantments::RemoveEnchantmentWeightFromVector(enchantments, Enchantment2);
+
+ // Checking for conflicting enchantments
+ cEnchantments::CheckEnchantmentConflictsFromVector(enchantments, Enchantment2);
+
+ // Next Enchantment (Third)
+ NewEnchantmentLevel = NewEnchantmentLevel / 2;
+ float ThirdEnchantmentChance = (NewEnchantmentLevel + 1) / 50 * 100;
+ if (enchantments.empty() || (Random.NextFloat(100) > ThirdEnchantmentChance))
+ {
+ return true;
+ }
+
+ cEnchantments Enchantment3 = cEnchantments::GetRandomEnchantmentFromVector(enchantments);
+ m_Enchantments.AddFromString(Enchantment3.ToString());
+ cEnchantments::RemoveEnchantmentWeightFromVector(enchantments, Enchantment3);
+
+ // Checking for conflicting enchantments
+ cEnchantments::CheckEnchantmentConflictsFromVector(enchantments, Enchantment3);
+
+ // Next Enchantment (Fourth)
+ NewEnchantmentLevel = NewEnchantmentLevel / 2;
+ float FourthEnchantmentChance = (NewEnchantmentLevel + 1) / 50 * 100;
+ if (enchantments.empty() || (Random.NextFloat(100) > FourthEnchantmentChance))
+ {
+ return true;
+ }
+ cEnchantments Enchantment4 = cEnchantments::GetRandomEnchantmentFromVector(enchantments);
+ m_Enchantments.AddFromString(Enchantment4.ToString());
+
+ return true;
+}
+
+
+
+
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cItems:
diff --git a/src/Item.h b/src/Item.h
index 910ecb382..00316c188 100644
--- a/src/Item.h
+++ b/src/Item.h
@@ -175,6 +175,13 @@ public:
/** Returns true if the specified item type is enchantable (as per 1.2.5 protocol requirements) */
static bool IsEnchantable(short a_ItemType); // tolua_export
+ /** Returns the enchantability of the item. When the item hasn't a enchantability, it will returns 0 */
+ int GetEnchantability(); // tolua_export
+
+ /** Enchants the item using the specified number of XP levels.
+ Returns true if item enchanted, false if not. */
+ bool EnchantByXPLevels(int a_NumXPLevels); // tolua_export
+
// tolua_begin
short m_ItemType;
diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp
index 1e77717e3..5151eac38 100644
--- a/src/Items/ItemHandler.cpp
+++ b/src/Items/ItemHandler.cpp
@@ -431,7 +431,6 @@ bool cItemHandler::IsTool()
|| (m_ItemType >= 267 && m_ItemType <= 279)
|| (m_ItemType >= 283 && m_ItemType <= 286)
|| (m_ItemType >= 290 && m_ItemType <= 294)
- || (m_ItemType >= 256 && m_ItemType <= 259)
|| (m_ItemType == 325)
|| (m_ItemType == 346);
}
diff --git a/src/Items/ItemHandler.h b/src/Items/ItemHandler.h
index 5b6c239cc..f3d78335e 100644
--- a/src/Items/ItemHandler.h
+++ b/src/Items/ItemHandler.h
@@ -58,13 +58,13 @@ public:
struct FoodInfo
{
- int FoodLevel;
double Saturation;
+ int FoodLevel;
int PoisonChance; // 0 - 100, in percent. 0 = no chance of poisoning, 100 = sure poisoning
FoodInfo(int a_FoodLevel, double a_Saturation, int a_PoisonChance = 0) :
- FoodLevel(a_FoodLevel),
Saturation(a_Saturation),
+ FoodLevel(a_FoodLevel),
PoisonChance(a_PoisonChance)
{
}
diff --git a/src/MobProximityCounter.cpp b/src/MobProximityCounter.cpp
index 6c44ea458..519757c2c 100644
--- a/src/MobProximityCounter.cpp
+++ b/src/MobProximityCounter.cpp
@@ -34,7 +34,7 @@ void cMobProximityCounter::CollectMob(cEntity& a_Monster, cChunk& a_Chunk, doubl
void cMobProximityCounter::convertMaps()
{
- for(tMonsterToDistance::const_iterator itr = m_MonsterToDistance.begin(); itr != m_MonsterToDistance.end(); itr++)
+ for(tMonsterToDistance::const_iterator itr = m_MonsterToDistance.begin(); itr != m_MonsterToDistance.end(); ++itr)
{
m_DistanceToMonster.insert(tDistanceToMonster::value_type(itr->second.m_Distance,sMonsterAndChunk(*itr->first,itr->second.m_Chunk)));
}
@@ -55,7 +55,7 @@ cMobProximityCounter::sIterablePair cMobProximityCounter::getMobWithinThosesDist
convertMaps();
}
- for(tDistanceToMonster::const_iterator itr = m_DistanceToMonster.begin(); itr != m_DistanceToMonster.end(); itr++)
+ for(tDistanceToMonster::const_iterator itr = m_DistanceToMonster.begin(); itr != m_DistanceToMonster.end(); ++itr)
{
if (toReturn.m_Begin == m_DistanceToMonster.end())
{
diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp
index 05da5d01c..ce8e06777 100644
--- a/src/MobSpawner.cpp
+++ b/src/MobSpawner.cpp
@@ -13,7 +13,7 @@ cMobSpawner::cMobSpawner(cMonster::eFamily a_MonsterFamily,const std::set<cMonst
m_NewPack(true),
m_MobType(cMonster::mtInvalidType)
{
- for (std::set<cMonster::eType>::const_iterator itr = a_AllowedTypes.begin(); itr != a_AllowedTypes.end(); itr++)
+ for (std::set<cMonster::eType>::const_iterator itr = a_AllowedTypes.begin(); itr != a_AllowedTypes.end(); ++itr)
{
if (cMonster::FamilyFromType(*itr) == a_MonsterFamily)
{
@@ -112,7 +112,7 @@ cMonster::eType cMobSpawner::ChooseMobType(EMCSBiome a_Biome)
for(int i = 0; i < iRandom; i++)
{
- itr++;
+ ++itr;
}
return *itr;
diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp
index d599a4cef..5a6b760af 100644
--- a/src/Mobs/Sheep.cpp
+++ b/src/Mobs/Sheep.cpp
@@ -36,7 +36,8 @@ void cSheep::GetDrops(cItems & a_Drops, cEntity * a_Killer)
void cSheep::OnRightClicked(cPlayer & a_Player)
{
- if ((a_Player.GetEquippedItem().m_ItemType == E_ITEM_SHEARS) && (!m_IsSheared))
+ const cItem & EquippedItem = a_Player.GetEquippedItem();
+ if ((EquippedItem.m_ItemType == E_ITEM_SHEARS) && (!m_IsSheared))
{
m_IsSheared = true;
m_World->BroadcastEntityMetadata(*this);
@@ -51,9 +52,9 @@ void cSheep::OnRightClicked(cPlayer & a_Player)
Drops.push_back(cItem(E_BLOCK_WOOL, NumDrops, m_WoolColor));
m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10);
}
- if ((a_Player.GetEquippedItem().m_ItemType == E_ITEM_DYE) && (m_WoolColor != 15 - a_Player.GetEquippedItem().m_ItemDamage))
+ else if ((EquippedItem.m_ItemType == E_ITEM_DYE) && (m_WoolColor != 15 - EquippedItem.m_ItemDamage))
{
- m_WoolColor = 15 - a_Player.GetEquippedItem().m_ItemDamage;
+ m_WoolColor = 15 - EquippedItem.m_ItemDamage;
if (!a_Player.IsGameModeCreative())
{
a_Player.GetInventory().RemoveOneEquippedItem();
diff --git a/src/Mobs/Wolf.h b/src/Mobs/Wolf.h
index 9e5ad03c7..5925373e1 100644
--- a/src/Mobs/Wolf.h
+++ b/src/Mobs/Wolf.h
@@ -37,7 +37,7 @@ public:
void SetIsTame (bool a_IsTame) { m_IsTame = a_IsTame; }
void SetIsBegging (bool a_IsBegging) { m_IsBegging = a_IsBegging; }
void SetIsAngry (bool a_IsAngry) { m_IsAngry = a_IsAngry; }
- void SetOwner (AString a_NewOwner) { m_OwnerName = a_NewOwner; }
+ void SetOwner (const AString & a_NewOwner) { m_OwnerName = a_NewOwner; }
void SetCollarColor(int a_CollarColor) { m_CollarColor = a_CollarColor; }
protected:
diff --git a/src/MonsterConfig.cpp b/src/MonsterConfig.cpp
index c06bd6b6f..72a3a3245 100644
--- a/src/MonsterConfig.cpp
+++ b/src/MonsterConfig.cpp
@@ -17,6 +17,7 @@ struct cMonsterConfig::sAttributesStruct
int m_AttackRange;
double m_AttackRate;
int m_MaxHealth;
+ bool m_IsFireproof;
};
@@ -72,6 +73,7 @@ void cMonsterConfig::Initialize()
Attributes.m_SightDistance = MonstersIniFile.GetValueI(Name, "SightDistance", 0);
Attributes.m_AttackRate = MonstersIniFile.GetValueF(Name, "AttackRate", 0);
Attributes.m_MaxHealth = MonstersIniFile.GetValueI(Name, "MaxHealth", 1);
+ Attributes.m_IsFireproof = MonstersIniFile.GetValueB(Name, "IsFireproof", false);
m_pState->AttributesList.push_front(Attributes);
} // for i - SplitList[]
}
@@ -92,6 +94,7 @@ void cMonsterConfig::AssignAttributes(cMonster * a_Monster, const AString & a_Na
a_Monster->SetSightDistance(itr->m_SightDistance);
a_Monster->SetAttackRate ((float)itr->m_AttackRate);
a_Monster->SetMaxHealth (itr->m_MaxHealth);
+ a_Monster->SetIsFireproof (itr->m_IsFireproof);
return;
}
} // for itr - m_pState->AttributesList[]
diff --git a/src/Noise.cpp b/src/Noise.cpp
index 32922c8f3..efbb128c3 100644
--- a/src/Noise.cpp
+++ b/src/Noise.cpp
@@ -840,12 +840,14 @@ void cPerlinNoise::Generate2D(
}
// Generate the first octave directly into array:
- m_Octaves.front().m_Noise.Generate2D(
+ const cOctave & FirstOctave = m_Octaves.front();
+
+ FirstOctave.m_Noise.Generate2D(
a_Workspace, a_SizeX, a_SizeY,
- a_StartX * m_Octaves.front().m_Frequency, a_EndX * m_Octaves.front().m_Frequency,
- a_StartY * m_Octaves.front().m_Frequency, a_EndY * m_Octaves.front().m_Frequency
+ a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency,
+ a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency
);
- NOISE_DATATYPE Amplitude = m_Octaves.front().m_Amplitude;
+ NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude;
for (int i = 0; i < ArrayCount; i++)
{
a_Array[i] *= Amplitude;
@@ -902,13 +904,15 @@ void cPerlinNoise::Generate3D(
}
// Generate the first octave directly into array:
- m_Octaves.front().m_Noise.Generate3D(
+ const cOctave & FirstOctave = m_Octaves.front();
+
+ FirstOctave.m_Noise.Generate3D(
a_Workspace, a_SizeX, a_SizeY, a_SizeZ,
- a_StartX * m_Octaves.front().m_Frequency, a_EndX * m_Octaves.front().m_Frequency,
- a_StartY * m_Octaves.front().m_Frequency, a_EndY * m_Octaves.front().m_Frequency,
- a_StartZ * m_Octaves.front().m_Frequency, a_EndZ * m_Octaves.front().m_Frequency
+ a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency,
+ a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency,
+ a_StartZ * FirstOctave.m_Frequency, a_EndZ * FirstOctave.m_Frequency
);
- NOISE_DATATYPE Amplitude = m_Octaves.front().m_Amplitude;
+ NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude;
for (int i = 0; i < ArrayCount; i++)
{
a_Array[i] = a_Workspace[i] * Amplitude;
diff --git a/src/Protocol/Authenticator.cpp b/src/Protocol/Authenticator.cpp
index a30131b36..e0fcc0007 100644
--- a/src/Protocol/Authenticator.cpp
+++ b/src/Protocol/Authenticator.cpp
@@ -119,9 +119,10 @@ void cAuthenticator::Execute(void)
}
ASSERT(!m_Queue.empty());
- int ClientID = m_Queue.front().m_ClientID;
- AString UserName = m_Queue.front().m_Name;
- AString ServerID = m_Queue.front().m_ServerID;
+ cAuthenticator::cUser & User = m_Queue.front();
+ int ClientID = User.m_ClientID;
+ AString UserName = User.m_Name;
+ AString ServerID = User.m_ServerID;
m_Queue.pop_front();
Lock.Unlock();
diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp
index af1b1c604..3282a827f 100644
--- a/src/Protocol/Protocol125.cpp
+++ b/src/Protocol/Protocol125.cpp
@@ -96,6 +96,7 @@ enum
PACKET_INVENTORY_WHOLE = 0x68,
PACKET_WINDOW_PROPERTY = 0x69,
PACKET_CREATIVE_INVENTORY_ACTION = 0x6B,
+ PACKET_ENCHANT_ITEM = 0x6C,
PACKET_UPDATE_SIGN = 0x82,
PACKET_ITEM_DATA = 0x83,
PACKET_PLAYER_LIST_ITEM = 0xC9,
@@ -537,9 +538,10 @@ void cProtocol125::SendHealth(void)
{
cCSLock Lock(m_CSPacket);
WriteByte (PACKET_UPDATE_HEALTH);
- WriteShort((short)m_Client->GetPlayer()->GetHealth());
- WriteShort((short)m_Client->GetPlayer()->GetFoodLevel());
- WriteFloat((float)m_Client->GetPlayer()->GetFoodSaturationLevel());
+ cPlayer * Player = m_Client->GetPlayer();
+ WriteShort((short)Player->GetHealth());
+ WriteShort((short)Player->GetFoodLevel());
+ WriteFloat((float)Player->GetFoodSaturationLevel());
Flush();
}
@@ -667,13 +669,14 @@ void cProtocol125::SendPickupSpawn(const cPickup & a_Pickup)
cCSLock Lock(m_CSPacket);
WriteByte (PACKET_PICKUP_SPAWN);
WriteInt (a_Pickup.GetUniqueID());
- WriteShort (a_Pickup.GetItem().m_ItemType);
- WriteChar (a_Pickup.GetItem().m_ItemCount);
- WriteShort (a_Pickup.GetItem().m_ItemDamage);
+ const cItem & Item = a_Pickup.GetItem();
+ WriteShort (Item.m_ItemType);
+ WriteChar (Item.m_ItemCount);
+ WriteShort (Item.m_ItemDamage);
WriteVectorI((Vector3i)(a_Pickup.GetPosition() * 32));
- WriteByte ((char)(a_Pickup.GetSpeed().x * 8));
- WriteByte ((char)(a_Pickup.GetSpeed().y * 8));
- WriteByte ((char)(a_Pickup.GetSpeed().z * 8));
+ WriteByte ((char)(a_Pickup.GetSpeedX() * 8));
+ WriteByte ((char)(a_Pickup.GetSpeedY() * 8));
+ WriteByte ((char)(a_Pickup.GetSpeedZ() * 8));
Flush();
}
@@ -830,10 +833,11 @@ void cProtocol125::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effect
void cProtocol125::SendRespawn(void)
{
cCSLock Lock(m_CSPacket);
+ cPlayer * Player = m_Client->GetPlayer();
WriteByte (PACKET_RESPAWN);
- WriteInt ((int)(m_Client->GetPlayer()->GetWorld()->GetDimension()));
+ WriteInt ((int)(Player->GetWorld()->GetDimension()));
WriteByte (2); // TODO: Difficulty; 2 = Normal
- WriteChar ((char)m_Client->GetPlayer()->GetGameMode());
+ WriteChar ((char)Player->GetGameMode());
WriteShort (256); // Current world height
WriteString("default");
}
@@ -845,10 +849,11 @@ void cProtocol125::SendRespawn(void)
void cProtocol125::SendExperience(void)
{
cCSLock Lock(m_CSPacket);
+ cPlayer * Player = m_Client->GetPlayer();
WriteByte (PACKET_EXPERIENCE);
- WriteFloat (m_Client->GetPlayer()->GetXpPercentage());
- WriteShort (m_Client->GetPlayer()->GetXpLevel());
- WriteShort (m_Client->GetPlayer()->GetCurrentXp());
+ WriteFloat (Player->GetXpPercentage());
+ WriteShort (Player->GetXpLevel());
+ WriteShort (Player->GetCurrentXp());
Flush();
}
@@ -1278,6 +1283,7 @@ int cProtocol125::ParsePacket(unsigned char a_PacketType)
case PACKET_SLOT_SELECTED: return ParseSlotSelected();
case PACKET_UPDATE_SIGN: return ParseUpdateSign();
case PACKET_USE_ENTITY: return ParseUseEntity();
+ case PACKET_ENCHANT_ITEM: return ParseEnchantItem();
case PACKET_WINDOW_CLICK: return ParseWindowClick();
case PACKET_WINDOW_CLOSE: return ParseWindowClose();
}
@@ -1639,6 +1645,20 @@ int cProtocol125::ParseUseEntity(void)
+int cProtocol125::ParseEnchantItem(void)
+{
+ HANDLE_PACKET_READ(ReadByte, Byte, WindowID);
+ HANDLE_PACKET_READ(ReadByte, Byte, Enchantment);
+
+ m_Client->HandleEnchantItem(WindowID, Enchantment);
+
+ return PARSE_OK;
+}
+
+
+
+
+
int cProtocol125::ParseWindowClick(void)
{
HANDLE_PACKET_READ(ReadChar, char, WindowID);
diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h
index 16f31bd0e..89e64f386 100644
--- a/src/Protocol/Protocol125.h
+++ b/src/Protocol/Protocol125.h
@@ -143,6 +143,7 @@ protected:
virtual int ParseSlotSelected (void);
virtual int ParseUpdateSign (void);
virtual int ParseUseEntity (void);
+ virtual int ParseEnchantItem (void);
virtual int ParseWindowClick (void);
virtual int ParseWindowClose (void);
diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp
index ce5942a5c..53d8c1561 100644
--- a/src/Protocol/Protocol132.cpp
+++ b/src/Protocol/Protocol132.cpp
@@ -408,7 +408,8 @@ void cProtocol132::SendWholeInventory(const cWindow & a_Window)
super::SendWholeInventory(a_Window);
// Send the player inventory and hotbar:
- const cInventory & Inventory = m_Client->GetPlayer()->GetInventory();
+ cPlayer * Player = m_Client->GetPlayer();
+ const cInventory & Inventory = Player->GetInventory();
int BaseOffset = a_Window.GetNumSlots() - (cInventory::invNumSlots - cInventory::invInventoryOffset); // Number of non-inventory slots
char WindowID = a_Window.GetWindowID();
for (short i = 0; i < cInventory::invInventoryCount; i++)
@@ -422,7 +423,7 @@ void cProtocol132::SendWholeInventory(const cWindow & a_Window)
} // for i - Hotbar[]
// Send even the item being dragged:
- SendInventorySlot(-1, -1, m_Client->GetPlayer()->GetDraggingItem());
+ SendInventorySlot(-1, -1, Player->GetDraggingItem());
}
@@ -800,10 +801,12 @@ void cProtocol132::SendCompass(const cWorld & a_World)
void cProtocol132::SendEncryptionKeyRequest(void)
{
cCSLock Lock(m_CSPacket);
+ cServer * Server = cRoot::Get()->GetServer();
WriteByte(0xfd);
- WriteString(cRoot::Get()->GetServer()->GetServerID());
- WriteShort((short)(cRoot::Get()->GetServer()->GetPublicKeyDER().size()));
- SendData(cRoot::Get()->GetServer()->GetPublicKeyDER().data(), cRoot::Get()->GetServer()->GetPublicKeyDER().size());
+ WriteString(Server->GetServerID());
+ const AString & PublicKeyDER = Server->GetPublicKeyDER();
+ WriteShort((short)(PublicKeyDER.size()));
+ SendData(PublicKeyDER.data(), PublicKeyDER.size());
WriteShort(4);
WriteInt((int)(intptr_t)this); // Using 'this' as the cryptographic nonce, so that we don't have to generate one each time :)
Flush();
@@ -874,10 +877,11 @@ void cProtocol132::StartEncryption(const Byte * a_Key)
// Prepare the m_AuthServerID:
cSHA1Checksum Checksum;
- AString ServerID = cRoot::Get()->GetServer()->GetServerID();
+ cServer * Server = cRoot::Get()->GetServer();
+ AString ServerID = Server->GetServerID();
Checksum.Update((const Byte *)ServerID.c_str(), ServerID.length());
Checksum.Update(a_Key, 16);
- Checksum.Update((const Byte *)cRoot::Get()->GetServer()->GetPublicKeyDER().data(), cRoot::Get()->GetServer()->GetPublicKeyDER().size());
+ Checksum.Update((const Byte *)Server->GetPublicKeyDER().data(), Server->GetPublicKeyDER().size());
Byte Digest[20];
Checksum.Finalize(Digest);
cSHA1Checksum::DigestToJava(Digest, m_AuthServerID);
diff --git a/src/Protocol/Protocol14x.cpp b/src/Protocol/Protocol14x.cpp
index f694af1eb..f60e756fd 100644
--- a/src/Protocol/Protocol14x.cpp
+++ b/src/Protocol/Protocol14x.cpp
@@ -103,9 +103,9 @@ void cProtocol142::SendPickupSpawn(const cPickup & a_Pickup)
WriteInt (a_Pickup.GetUniqueID());
WriteItem (a_Pickup.GetItem());
WriteVectorI((Vector3i)(a_Pickup.GetPosition() * 32));
- WriteChar ((char)(a_Pickup.GetSpeed().x * 8));
- WriteChar ((char)(a_Pickup.GetSpeed().y * 8));
- WriteChar ((char)(a_Pickup.GetSpeed().z * 8));
+ WriteChar((char)(a_Pickup.GetSpeedX() * 8));
+ WriteChar((char)(a_Pickup.GetSpeedY() * 8));
+ WriteChar((char)(a_Pickup.GetSpeedZ() * 8));
Flush();
}
@@ -170,9 +170,9 @@ void cProtocol146::SendPickupSpawn(const cPickup & a_Pickup)
WriteInt ((int)(a_Pickup.GetPosY() * 32));
WriteInt ((int)(a_Pickup.GetPosZ() * 32));
WriteInt (1);
- WriteShort((short)(a_Pickup.GetSpeed().x * 32));
- WriteShort((short)(a_Pickup.GetSpeed().y * 32));
- WriteShort((short)(a_Pickup.GetSpeed().z * 32));
+ WriteShort((short)(a_Pickup.GetSpeedX() * 32));
+ WriteShort((short)(a_Pickup.GetSpeedY() * 32));
+ WriteShort((short)(a_Pickup.GetSpeedZ() * 32));
WriteByte(0);
WriteByte(0);
diff --git a/src/Protocol/Protocol16x.cpp b/src/Protocol/Protocol16x.cpp
index 3da23a1dc..714bf5e46 100644
--- a/src/Protocol/Protocol16x.cpp
+++ b/src/Protocol/Protocol16x.cpp
@@ -131,9 +131,10 @@ void cProtocol161::SendHealth(void)
{
cCSLock Lock(m_CSPacket);
WriteByte (PACKET_UPDATE_HEALTH);
- WriteFloat((float)m_Client->GetPlayer()->GetHealth());
- WriteShort((short)m_Client->GetPlayer()->GetFoodLevel());
- WriteFloat((float)m_Client->GetPlayer()->GetFoodSaturationLevel());
+ cPlayer * Player = m_Client->GetPlayer();
+ WriteFloat((float)Player->GetHealth());
+ WriteShort((short)Player->GetFoodLevel());
+ WriteFloat((float)Player->GetFoodSaturationLevel());
Flush();
}
@@ -144,11 +145,12 @@ void cProtocol161::SendHealth(void)
void cProtocol161::SendPlayerMaxSpeed(void)
{
cCSLock Lock(m_CSPacket);
+ cPlayer * Player = m_Client->GetPlayer();
WriteByte(PACKET_ENTITY_PROPERTIES);
- WriteInt(m_Client->GetPlayer()->GetUniqueID());
+ WriteInt(Player->GetUniqueID());
WriteInt(1);
WriteString("generic.movementSpeed");
- WriteDouble(0.1 * m_Client->GetPlayer()->GetMaxSpeed());
+ WriteDouble(0.1 * Player->GetMaxSpeed());
Flush();
}
@@ -214,6 +216,25 @@ int cProtocol161::ParseEntityAction(void)
+int cProtocol161::ParseLogin(void)
+{
+ // The login packet is sent by Forge clients only
+ // Only parse the packet, do no extra processing
+ // Note that the types and the names have been only guessed and are not verified at all!
+ HANDLE_PACKET_READ(ReadBEInt, int, Int1);
+ HANDLE_PACKET_READ(ReadBEUTF16String16, AString, String1);
+ HANDLE_PACKET_READ(ReadChar, char, Char1);
+ HANDLE_PACKET_READ(ReadChar, char, Char2);
+ HANDLE_PACKET_READ(ReadChar, char, Char3);
+ HANDLE_PACKET_READ(ReadByte, Byte, Byte1);
+ HANDLE_PACKET_READ(ReadByte, Byte, Byte2);
+ return PARSE_OK;
+}
+
+
+
+
+
int cProtocol161::ParsePlayerAbilities(void)
{
HANDLE_PACKET_READ(ReadByte, Byte, Flags);
@@ -276,11 +297,12 @@ cProtocol162::cProtocol162(cClientHandle * a_Client) :
void cProtocol162::SendPlayerMaxSpeed(void)
{
cCSLock Lock(m_CSPacket);
+ cPlayer * Player = m_Client->GetPlayer();
WriteByte(PACKET_ENTITY_PROPERTIES);
- WriteInt(m_Client->GetPlayer()->GetUniqueID());
+ WriteInt(Player->GetUniqueID());
WriteInt(1);
WriteString("generic.movementSpeed");
- WriteDouble(0.1 * m_Client->GetPlayer()->GetMaxSpeed());
+ WriteDouble(0.1 * Player->GetMaxSpeed());
WriteShort(0);
Flush();
}
diff --git a/src/Protocol/Protocol16x.h b/src/Protocol/Protocol16x.h
index ae1388649..8eedce8d5 100644
--- a/src/Protocol/Protocol16x.h
+++ b/src/Protocol/Protocol16x.h
@@ -46,6 +46,7 @@ protected:
virtual void SendWindowOpen (const cWindow & a_Window) override;
virtual int ParseEntityAction (void) override;
+ virtual int ParseLogin (void) override;
virtual int ParsePlayerAbilities(void) override;
// New packets:
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index 403046760..e57b551cb 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -563,9 +563,10 @@ void cProtocol172::SendHealth(void)
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x06); // Update Health packet
- Pkt.WriteFloat((float)m_Client->GetPlayer()->GetHealth());
- Pkt.WriteShort(m_Client->GetPlayer()->GetFoodLevel());
- Pkt.WriteFloat((float)m_Client->GetPlayer()->GetFoodSaturationLevel());
+ cPlayer * Player = m_Client->GetPlayer();
+ Pkt.WriteFloat((float)Player->GetHealth());
+ Pkt.WriteShort(Player->GetFoodLevel());
+ Pkt.WriteFloat((float)Player->GetFoodSaturationLevel());
}
@@ -607,12 +608,13 @@ void cProtocol172::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
{
// Send the Join Game packet:
{
+ cServer * Server = cRoot::Get()->GetServer();
cPacketizer Pkt(*this, 0x01); // Join Game packet
Pkt.WriteInt(a_Player.GetUniqueID());
- Pkt.WriteByte((Byte)a_Player.GetEffectiveGameMode() | (cRoot::Get()->GetServer()->IsHardcore() ? 0x08 : 0)); // Hardcore flag bit 4
+ Pkt.WriteByte((Byte)a_Player.GetEffectiveGameMode() | (Server->IsHardcore() ? 0x08 : 0)); // Hardcore flag bit 4
Pkt.WriteChar((char)a_World.GetDimension());
Pkt.WriteByte(2); // TODO: Difficulty (set to Normal)
- Pkt.WriteByte(std::min(cRoot::Get()->GetServer()->GetMaxPlayers(), 60));
+ Pkt.WriteByte(std::min(Server->GetMaxPlayers(), 60));
Pkt.WriteString("default"); // Level type - wtf?
}
@@ -758,22 +760,23 @@ void cProtocol172::SendPlayerAbilities(void)
cPacketizer Pkt(*this, 0x39); // Player Abilities packet
Byte Flags = 0;
- if (m_Client->GetPlayer()->IsGameModeCreative())
+ cPlayer * Player = m_Client->GetPlayer();
+ if (Player->IsGameModeCreative())
{
Flags |= 0x01;
Flags |= 0x08; // Godmode, used for creative
}
- if (m_Client->GetPlayer()->IsFlying())
+ if (Player->IsFlying())
{
Flags |= 0x02;
}
- if (m_Client->GetPlayer()->CanFly())
+ if (Player->CanFly())
{
Flags |= 0x04;
}
Pkt.WriteByte(Flags);
- Pkt.WriteFloat((float)(0.05 * m_Client->GetPlayer()->GetFlyingMaxSpeed()));
- Pkt.WriteFloat((float)(0.1 * m_Client->GetPlayer()->GetMaxSpeed()));
+ Pkt.WriteFloat((float)(0.05 * Player->GetFlyingMaxSpeed()));
+ Pkt.WriteFloat((float)(0.1 * Player->GetMaxSpeed()));
}
@@ -832,17 +835,18 @@ void cProtocol172::SendPlayerMaxSpeed(void)
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x20); // Entity Properties
- Pkt.WriteInt(m_Client->GetPlayer()->GetUniqueID());
+ cPlayer * Player = m_Client->GetPlayer();
+ Pkt.WriteInt(Player->GetUniqueID());
Pkt.WriteInt(1); // Count
Pkt.WriteString("generic.movementSpeed");
// The default game speed is 0.1, multiply that value by the relative speed:
- Pkt.WriteDouble(0.1 * m_Client->GetPlayer()->GetNormalMaxSpeed());
- if (m_Client->GetPlayer()->IsSprinting())
+ Pkt.WriteDouble(0.1 * Player->GetNormalMaxSpeed());
+ if (Player->IsSprinting())
{
Pkt.WriteShort(1); // Modifier count
Pkt.WriteInt64(0x662a6b8dda3e4c1c);
Pkt.WriteInt64(0x881396ea6097278d); // UUID of the modifier
- Pkt.WriteDouble(m_Client->GetPlayer()->GetSprintingMaxSpeed() - m_Client->GetPlayer()->GetNormalMaxSpeed());
+ Pkt.WriteDouble(Player->GetSprintingMaxSpeed() - Player->GetNormalMaxSpeed());
Pkt.WriteByte(2);
}
else
@@ -860,16 +864,17 @@ void cProtocol172::SendPlayerMoveLook(void)
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x08); // Player Position And Look packet
- Pkt.WriteDouble(m_Client->GetPlayer()->GetPosX());
+ cPlayer * Player = m_Client->GetPlayer();
+ Pkt.WriteDouble(Player->GetPosX());
// Protocol docs say this is PosY, but #323 says this is eye-pos
// Moreover, the "+ 0.001" is there because otherwise the player falls through the block they were standing on.
- Pkt.WriteDouble(m_Client->GetPlayer()->GetStance() + 0.001);
+ Pkt.WriteDouble(Player->GetStance() + 0.001);
- Pkt.WriteDouble(m_Client->GetPlayer()->GetPosZ());
- Pkt.WriteFloat((float)m_Client->GetPlayer()->GetYaw());
- Pkt.WriteFloat((float)m_Client->GetPlayer()->GetPitch());
- Pkt.WriteBool(m_Client->GetPlayer()->IsOnGround());
+ Pkt.WriteDouble(Player->GetPosZ());
+ Pkt.WriteFloat((float)Player->GetYaw());
+ Pkt.WriteFloat((float)Player->GetPitch());
+ Pkt.WriteBool(Player->IsOnGround());
}
@@ -941,9 +946,10 @@ void cProtocol172::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effect
void cProtocol172::SendRespawn(void)
{
cPacketizer Pkt(*this, 0x07); // Respawn packet
- Pkt.WriteInt(m_Client->GetPlayer()->GetWorld()->GetDimension());
+ cPlayer * Player = m_Client->GetPlayer();
+ Pkt.WriteInt(Player->GetWorld()->GetDimension());
Pkt.WriteByte(2); // TODO: Difficulty (set to Normal)
- Pkt.WriteByte((Byte)m_Client->GetPlayer()->GetEffectiveGameMode());
+ Pkt.WriteByte((Byte)Player->GetEffectiveGameMode());
Pkt.WriteString("default");
}
@@ -956,9 +962,10 @@ void cProtocol172::SendExperience (void)
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x1f); // Experience Packet
- Pkt.WriteFloat(m_Client->GetPlayer()->GetXpPercentage());
- Pkt.WriteShort(m_Client->GetPlayer()->GetXpLevel());
- Pkt.WriteShort(m_Client->GetPlayer()->GetCurrentXp());
+ cPlayer * Player = m_Client->GetPlayer();
+ Pkt.WriteFloat(Player->GetXpPercentage());
+ Pkt.WriteShort(Player->GetXpLevel());
+ Pkt.WriteShort(Player->GetCurrentXp());
}
@@ -1580,6 +1587,7 @@ bool cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
case 0x0e: HandlePacketWindowClick (a_ByteBuffer); return true;
case 0x0f: // Confirm transaction - not used in MCS
case 0x10: HandlePacketCreativeInventoryAction(a_ByteBuffer); return true;
+ case 0x11: HandlePacketEnchantItem (a_ByteBuffer); return true;
case 0x12: HandlePacketUpdateSign (a_ByteBuffer); return true;
case 0x13: HandlePacketPlayerAbilities (a_ByteBuffer); return true;
case 0x14: HandlePacketTabComplete (a_ByteBuffer); return true;
@@ -1634,15 +1642,16 @@ void cProtocol172::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer)
{
// Send the response:
AString Response = "{\"version\":{\"name\":\"1.7.2\",\"protocol\":4},\"players\":{";
+ cServer * Server = cRoot::Get()->GetServer();
AppendPrintf(Response, "\"max\":%u,\"online\":%u,\"sample\":[]},",
- cRoot::Get()->GetServer()->GetMaxPlayers(),
- cRoot::Get()->GetServer()->GetNumPlayers()
+ Server->GetMaxPlayers(),
+ Server->GetNumPlayers()
);
AppendPrintf(Response, "\"description\":{\"text\":\"%s\"},",
- cRoot::Get()->GetServer()->GetDescription().c_str()
+ Server->GetDescription().c_str()
);
AppendPrintf(Response, "\"favicon\":\"data:image/png;base64,%s\"",
- cRoot::Get()->GetServer()->GetFaviconData().c_str()
+ Server->GetFaviconData().c_str()
);
Response.append("}");
@@ -1722,12 +1731,13 @@ void cProtocol172::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer)
return;
}
+ cServer * Server = cRoot::Get()->GetServer();
// If auth is required, then send the encryption request:
- if (cRoot::Get()->GetServer()->ShouldAuthenticate())
+ if (Server->ShouldAuthenticate())
{
cPacketizer Pkt(*this, 0x01);
- Pkt.WriteString(cRoot::Get()->GetServer()->GetServerID());
- const AString & PubKeyDer = cRoot::Get()->GetServer()->GetPublicKeyDER();
+ Pkt.WriteString(Server->GetServerID());
+ const AString & PubKeyDer = Server->GetPublicKeyDER();
Pkt.WriteShort(PubKeyDer.size());
Pkt.WriteBuf(PubKeyDer.data(), PubKeyDer.size());
Pkt.WriteShort(4);
@@ -2044,6 +2054,18 @@ void cProtocol172::HandlePacketUseEntity(cByteBuffer & a_ByteBuffer)
+void cProtocol172::HandlePacketEnchantItem(cByteBuffer & a_ByteBuffer)
+{
+ HANDLE_READ(a_ByteBuffer, ReadByte, Byte, WindowID);
+ HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Enchantment);
+
+ m_Client->HandleEnchantItem(WindowID, Enchantment);
+}
+
+
+
+
+
void cProtocol172::HandlePacketWindowClick(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadChar, char, WindowID);
@@ -2268,10 +2290,11 @@ void cProtocol172::StartEncryption(const Byte * a_Key)
// Prepare the m_AuthServerID:
cSHA1Checksum Checksum;
- const AString & ServerID = cRoot::Get()->GetServer()->GetServerID();
+ cServer * Server = cRoot::Get()->GetServer();
+ const AString & ServerID = Server->GetServerID();
Checksum.Update((const Byte *)ServerID.c_str(), ServerID.length());
Checksum.Update(a_Key, 16);
- Checksum.Update((const Byte *)cRoot::Get()->GetServer()->GetPublicKeyDER().data(), cRoot::Get()->GetServer()->GetPublicKeyDER().size());
+ Checksum.Update((const Byte *)Server->GetPublicKeyDER().data(), Server->GetPublicKeyDER().size());
Byte Digest[20];
Checksum.Finalize(Digest);
cSHA1Checksum::DigestToJava(Digest, m_AuthServerID);
@@ -2613,11 +2636,12 @@ void cProtocol172::cPacketizer::WriteEntityMetadata(const cEntity & a_Entity)
if (((cMinecart &)a_Entity).GetPayload() == cMinecart::mpNone)
{
cRideableMinecart & RideableMinecart = ((cRideableMinecart &)a_Entity);
- if (!RideableMinecart.GetContent().IsEmpty())
+ const cItem & MinecartContent = RideableMinecart.GetContent();
+ if (!MinecartContent.IsEmpty())
{
WriteByte(0x54);
- int Content = RideableMinecart.GetContent().m_ItemType;
- Content |= RideableMinecart.GetContent().m_ItemDamage << 8;
+ int Content = MinecartContent.m_ItemType;
+ Content |= MinecartContent.m_ItemDamage << 8;
WriteInt(Content);
WriteByte(0x55);
WriteInt(RideableMinecart.GetBlockHeight());
diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h
index 5cafc4722..6a3e81eff 100644
--- a/src/Protocol/Protocol17x.h
+++ b/src/Protocol/Protocol17x.h
@@ -280,6 +280,7 @@ protected:
void HandlePacketTabComplete (cByteBuffer & a_ByteBuffer);
void HandlePacketUpdateSign (cByteBuffer & a_ByteBuffer);
void HandlePacketUseEntity (cByteBuffer & a_ByteBuffer);
+ void HandlePacketEnchantItem (cByteBuffer & a_ByteBuffer);
void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer);
void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer);
diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp
index 8a97b9713..2ccb9f197 100644
--- a/src/Protocol/ProtocolRecognizer.cpp
+++ b/src/Protocol/ProtocolRecognizer.cpp
@@ -1003,6 +1003,7 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema
void cProtocolRecognizer::SendLengthlessServerPing(void)
{
AString Reply;
+ cServer * Server = cRoot::Get()->GetServer();
switch (cRoot::Get()->GetPrimaryServerVersion())
{
case PROTO_VERSION_1_2_5:
@@ -1010,11 +1011,11 @@ void cProtocolRecognizer::SendLengthlessServerPing(void)
{
// http://wiki.vg/wiki/index.php?title=Protocol&oldid=3099#Server_List_Ping_.280xFE.29
Printf(Reply, "%s%s%i%s%i",
- cRoot::Get()->GetServer()->GetDescription().c_str(),
+ Server->GetDescription().c_str(),
cChatColor::Delimiter.c_str(),
- cRoot::Get()->GetServer()->GetNumPlayers(),
+ Server->GetNumPlayers(),
cChatColor::Delimiter.c_str(),
- cRoot::Get()->GetServer()->GetMaxPlayers()
+ Server->GetMaxPlayers()
);
break;
}
@@ -1044,9 +1045,9 @@ void cProtocolRecognizer::SendLengthlessServerPing(void)
// http://wiki.vg/wiki/index.php?title=Server_List_Ping&oldid=3100
AString NumPlayers;
- Printf(NumPlayers, "%d", cRoot::Get()->GetServer()->GetNumPlayers());
+ Printf(NumPlayers, "%d", Server->GetNumPlayers());
AString MaxPlayers;
- Printf(MaxPlayers, "%d", cRoot::Get()->GetServer()->GetMaxPlayers());
+ Printf(MaxPlayers, "%d", Server->GetMaxPlayers());
AString ProtocolVersionNum;
Printf(ProtocolVersionNum, "%d", cRoot::Get()->GetPrimaryServerVersion());
@@ -1060,7 +1061,7 @@ void cProtocolRecognizer::SendLengthlessServerPing(void)
Reply.push_back(0);
Reply.append(ProtocolVersionTxt);
Reply.push_back(0);
- Reply.append(cRoot::Get()->GetServer()->GetDescription());
+ Reply.append(Server->GetDescription());
Reply.push_back(0);
Reply.append(NumPlayers);
Reply.push_back(0);
diff --git a/src/Server.cpp b/src/Server.cpp
index e0feaf0d8..bfb1b1cbb 100644
--- a/src/Server.cpp
+++ b/src/Server.cpp
@@ -190,7 +190,7 @@ void cServer::PlayerDestroying(const cPlayer * a_Player)
bool cServer::InitServer(cIniFile & a_SettingsIni)
{
- m_Description = a_SettingsIni.GetValueSet("Server", "Description", "MCServer - in C++!").c_str();
+ m_Description = a_SettingsIni.GetValueSet("Server", "Description", "MCServer - in C++!");
m_MaxPlayers = a_SettingsIni.GetValueSetI("Server", "MaxPlayers", 100);
m_bIsHardcore = a_SettingsIni.GetValueSetB("Server", "HardcoreEnabled", false);
m_PlayerCount = 0;
@@ -275,7 +275,7 @@ bool cServer::InitServer(cIniFile & a_SettingsIni)
-int cServer::GetNumPlayers(void)
+int cServer::GetNumPlayers(void) const
{
cCSLock Lock(m_CSPlayerCount);
return m_PlayerCount;
diff --git a/src/Server.h b/src/Server.h
index b5c384a44..51c450ebd 100644
--- a/src/Server.h
+++ b/src/Server.h
@@ -59,7 +59,7 @@ public: // tolua_export
// Player counts:
int GetMaxPlayers(void) const {return m_MaxPlayers; }
- int GetNumPlayers(void);
+ int GetNumPlayers(void) const;
void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; }
// Hardcore mode or not:
@@ -168,7 +168,7 @@ private:
cClientHandleList m_Clients; ///< Clients that are connected to the server and not yet assigned to a cWorld
cClientHandleList m_ClientsToRemove; ///< Clients that have just been moved into a world and are to be removed from m_Clients in the next Tick()
- cCriticalSection m_CSPlayerCount; ///< Locks the m_PlayerCount
+ mutable cCriticalSection m_CSPlayerCount; ///< Locks the m_PlayerCount
int m_PlayerCount; ///< Number of players currently playing in the server
cCriticalSection m_CSPlayerCountDiff; ///< Locks the m_PlayerCountDiff
int m_PlayerCountDiff; ///< Adjustment to m_PlayerCount to be applied in the Tick thread
diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp
index 470dfc791..4fbfffd43 100644
--- a/src/Simulator/FireSimulator.cpp
+++ b/src/Simulator/FireSimulator.cpp
@@ -350,7 +350,7 @@ void cFireSimulator::RemoveFuelNeighbors(cChunk * a_Chunk, int a_RelX, int a_Rel
{
continue;
}
- BlockType = Neighbour->GetBlock(X, a_RelY + gCrossCoords[i].y, Z);
+ BlockType = Neighbour->GetBlock(X, a_RelY + gNeighborCoords[i].y, Z);
if (!IsFuel(BlockType))
{
diff --git a/src/Simulator/FluidSimulator.cpp b/src/Simulator/FluidSimulator.cpp
index 7779573d7..4a84084d2 100644
--- a/src/Simulator/FluidSimulator.cpp
+++ b/src/Simulator/FluidSimulator.cpp
@@ -155,7 +155,7 @@ Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a
Points.push_back(new Vector3i(a_X, a_Y, a_Z + 1));
Points.push_back(new Vector3i(a_X, a_Y, a_Z - 1));
- for (std::vector<Vector3i *>::iterator it = Points.begin(); it < Points.end(); it++)
+ for (std::vector<Vector3i *>::iterator it = Points.begin(); it < Points.end(); ++it)
{
Vector3i *Pos = (*it);
char BlockID = m_World.GetBlock(Pos->x, Pos->y, Pos->z);
diff --git a/src/StackWalker.cpp b/src/StackWalker.cpp
index b4f8ed8c7..b608d69e6 100644
--- a/src/StackWalker.cpp
+++ b/src/StackWalker.cpp
@@ -935,7 +935,8 @@ BOOL StackWalker::LoadModules()
break;
}
} // for (search for path separator...)
- if (strlen(szTemp) > 0)
+
+ if (szTemp[0] != '\0') // If szTemp is not empty (Note: This is more efficient than using strlen)
{
strcat_s(szSymPath, nSymPathLen, szTemp);
strcat_s(szSymPath, nSymPathLen, ";");
diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp
index 88977e005..2d58388b1 100644
--- a/src/UI/SlotArea.cpp
+++ b/src/UI/SlotArea.cpp
@@ -13,6 +13,8 @@
#include "Window.h"
#include "../CraftingRecipes.h"
#include "../Root.h"
+#include "../FastRandom.h"
+#include "../BlockArea.h"
@@ -145,6 +147,7 @@ void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickA
FreeSlots = 0;
}
int Filling = (FreeSlots > DraggingItem.m_ItemCount) ? DraggingItem.m_ItemCount : FreeSlots;
+
Slot.m_ItemCount += (char)Filling;
DraggingItem.m_ItemCount -= (char)Filling;
if (DraggingItem.m_ItemCount <= 0)
@@ -167,7 +170,6 @@ void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickA
{
m_ParentWindow.BroadcastWholeWindow();
}
-
}
@@ -483,6 +485,7 @@ void cSlotAreaCrafting::ClickedResult(cPlayer & a_Player)
// Get the current recipe:
cCraftingRecipe & Recipe = GetRecipeForPlayer(a_Player);
+ const cItem & Result = Recipe.GetResult();
cItem * PlayerSlots = GetPlayerSlots(a_Player) + 1;
cCraftingGrid Grid(PlayerSlots, m_GridSize, m_GridSize);
@@ -490,16 +493,16 @@ void cSlotAreaCrafting::ClickedResult(cPlayer & a_Player)
// If possible, craft:
if (DraggingItem.IsEmpty())
{
- DraggingItem = Recipe.GetResult();
+ DraggingItem = Result;
Recipe.ConsumeIngredients(Grid);
Grid.CopyToItems(PlayerSlots);
}
- else if (DraggingItem.IsEqual(Recipe.GetResult()))
+ else if (DraggingItem.IsEqual(Result))
{
- cItemHandler * Handler = ItemHandler(Recipe.GetResult().m_ItemType);
- if (DraggingItem.m_ItemCount + Recipe.GetResult().m_ItemCount <= Handler->GetMaxStackSize())
+ cItemHandler * Handler = ItemHandler(Result.m_ItemType);
+ if (DraggingItem.m_ItemCount + Result.m_ItemCount <= Handler->GetMaxStackSize())
{
- DraggingItem.m_ItemCount += Recipe.GetResult().m_ItemCount;
+ DraggingItem.m_ItemCount += Result.m_ItemCount;
Recipe.ConsumeIngredients(Grid);
Grid.CopyToItems(PlayerSlots);
}
@@ -593,6 +596,307 @@ cCraftingRecipe & cSlotAreaCrafting::GetRecipeForPlayer(cPlayer & a_Player)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cSlotAreaEnchanting:
+
+cSlotAreaEnchanting::cSlotAreaEnchanting(cEnchantingWindow & a_ParentWindow) :
+ cSlotAreaTemporary(1, a_ParentWindow)
+{
+ a_ParentWindow.m_SlotArea = this;
+}
+
+
+
+
+
+void cSlotAreaEnchanting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem)
+{
+ ASSERT((a_SlotNum >= 0) && (a_SlotNum < GetNumSlots()));
+
+ bool bAsync = false;
+ if (GetSlot(a_SlotNum, a_Player) == NULL)
+ {
+ LOGWARNING("GetSlot(%d) returned NULL! Ignoring click", a_SlotNum);
+ return;
+ }
+
+ switch (a_ClickAction)
+ {
+ case caShiftLeftClick:
+ case caShiftRightClick:
+ {
+ ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
+ return;
+ }
+
+ case caDblClick:
+ {
+ DblClicked(a_Player, a_SlotNum);
+ return;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ cItem Slot(*GetSlot(a_SlotNum, a_Player));
+ if (!Slot.IsSameType(a_ClickedItem))
+ {
+ LOGWARNING("*** Window lost sync at item %d in SlotArea with %d items ***", a_SlotNum, m_NumSlots);
+ LOGWARNING("My item: %s", ItemToFullString(Slot).c_str());
+ LOGWARNING("Their item: %s", ItemToFullString(a_ClickedItem).c_str());
+ bAsync = true;
+ }
+ cItem & DraggingItem = a_Player.GetDraggingItem();
+ switch (a_ClickAction)
+ {
+ case caRightClick:
+ {
+ // Right-clicked
+ if (DraggingItem.IsEmpty())
+ {
+ DraggingItem = Slot.CopyOne();
+ Slot.Empty();
+ break;
+ }
+
+ if (Slot.IsEmpty())
+ {
+ Slot = DraggingItem.CopyOne();
+ DraggingItem.m_ItemCount -= 1;
+ if (DraggingItem.m_ItemCount <= 0)
+ {
+ DraggingItem.Empty();
+ }
+ }
+ else if ((!DraggingItem.IsEqual(Slot)) && (DraggingItem.m_ItemCount == 1))
+ {
+ // Swap contents
+ cItem tmp(DraggingItem);
+ DraggingItem = Slot;
+ Slot = tmp;
+ }
+ break;
+ }
+
+ case caLeftClick:
+ {
+ // Left-clicked
+ if (DraggingItem.IsEmpty())
+ {
+ DraggingItem = Slot.CopyOne();
+ Slot.Empty();
+ break;
+ }
+
+ if (DraggingItem.IsEqual(Slot))
+ {
+ // Do nothing
+ break;
+ }
+
+ if (!Slot.IsEmpty())
+ {
+ if (DraggingItem.m_ItemCount == 1)
+ {
+ // Swap contents
+ cItem tmp(DraggingItem);
+ DraggingItem = Slot;
+ Slot = tmp;
+ }
+ }
+ else
+ {
+ Slot = DraggingItem.CopyOne();
+ DraggingItem.m_ItemCount -= 1;
+ if (DraggingItem.m_ItemCount <= 0)
+ {
+ DraggingItem.Empty();
+ }
+ }
+ break;
+ }
+ default:
+ {
+ LOGWARNING("SlotArea: Unhandled click action: %d (%s)", a_ClickAction, ClickActionToString(a_ClickAction));
+ m_ParentWindow.BroadcastWholeWindow();
+ return;
+ }
+ } // switch (a_ClickAction
+
+ SetSlot(a_SlotNum, a_Player, Slot);
+ if (bAsync)
+ {
+ m_ParentWindow.BroadcastWholeWindow();
+ }
+ UpdateResult(a_Player);
+}
+
+
+
+
+
+void cSlotAreaEnchanting::DblClicked(cPlayer & a_Player, int a_SlotNum)
+{
+ cItem & Dragging = a_Player.GetDraggingItem();
+ if ((!Dragging.IsEmpty()) || (a_SlotNum != 0))
+ {
+ return;
+ }
+
+ cItem Item = *GetSlot(0, a_Player);
+ if (!m_ParentWindow.CollectItemsToHand(Item, *this, a_Player, false))
+ {
+ m_ParentWindow.CollectItemsToHand(Item, *this, a_Player, true);
+ }
+}
+
+
+
+
+
+void cSlotAreaEnchanting::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_Apply, bool a_KeepEmptySlots)
+{
+ const cItem * Slot = GetSlot(0, a_Player);
+ if (!Slot->IsEmpty())
+ {
+ return;
+ }
+
+ if (a_Apply)
+ {
+ SetSlot(0, a_Player, a_ItemStack.CopyOne());
+ }
+ a_ItemStack.m_ItemCount -= 1;
+ if (a_ItemStack.m_ItemCount <= 0)
+ {
+ a_ItemStack.Empty();
+ }
+
+ UpdateResult(a_Player);
+}
+
+
+
+
+
+void cSlotAreaEnchanting::OnPlayerRemoved(cPlayer & a_Player)
+{
+ // Toss the item in the enchanting slot
+ TossItems(a_Player, 0, 1);
+
+ super::OnPlayerRemoved(a_Player);
+}
+
+
+
+
+
+void cSlotAreaEnchanting::UpdateResult(cPlayer & a_Player)
+{
+ cItem Item = *GetSlot(0, a_Player);
+
+ if (Item.IsEmpty() || !Item.m_Enchantments.IsEmpty())
+ {
+ m_ParentWindow.SetProperty(0, 0, a_Player);
+ m_ParentWindow.SetProperty(1, 0, a_Player);
+ m_ParentWindow.SetProperty(2, 0, a_Player);
+ }
+ else if (cItem::IsEnchantable(Item.m_ItemType) || Item.m_ItemType == E_ITEM_BOOK)
+ {
+ int Bookshelves = std::min(GetBookshelvesCount(a_Player.GetWorld()), 15);
+
+ cFastRandom Random;
+ int base = (Random.GenerateRandomInteger(1, 8) + (int)floor((float)Bookshelves / 2) + Random.GenerateRandomInteger(0, Bookshelves));
+ int topSlot = std::max(base / 3, 1);
+ int middleSlot = (base * 2) / 3 + 1;
+ int bottomSlot = std::max(base, Bookshelves * 2);
+
+ m_ParentWindow.SetProperty(0, topSlot, a_Player);
+ m_ParentWindow.SetProperty(1, middleSlot, a_Player);
+ m_ParentWindow.SetProperty(2, bottomSlot, a_Player);
+ }
+ else
+ {
+ m_ParentWindow.SetProperty(0, 0, a_Player);
+ m_ParentWindow.SetProperty(1, 0, a_Player);
+ m_ParentWindow.SetProperty(2, 0, a_Player);
+ }
+}
+
+
+
+
+
+int cSlotAreaEnchanting::GetBookshelvesCount(cWorld * a_World)
+{
+ int PosX, PosY, PosZ;
+ ((cEnchantingWindow*)&m_ParentWindow)->GetBlockPos(PosX, PosY, PosZ);
+
+ int Bookshelves = 0;
+ cBlockArea Area;
+ Area.Read(a_World, PosX - 2, PosX + 2, PosY, PosY + 1, PosZ - 2, PosZ + 2);
+
+ static const struct
+ {
+ int m_BookX, m_BookY, m_BookZ; // Coords to check for bookcases
+ int m_AirX, m_AirY, m_AirZ; // Coords to check for air; if not air, the bookcase won't be counted
+ } CheckCoords[] =
+ {
+ { 0, 0, 0, 1, 0, 1 }, // Bookcase at {0, 0, 0}, air at {1, 0, 1}
+ { 0, 0, 1, 1, 0, 1 }, // Bookcase at {0, 0, 1}, air at {1, 0, 1}
+ { 0, 0, 2, 1, 0, 2 }, // Bookcase at {0, 0, 2}, air at {1, 0, 2}
+ { 0, 0, 3, 1, 0, 3 }, // Bookcase at {0, 0, 3}, air at {1, 0, 3}
+ { 0, 0, 4, 1, 0, 3 }, // Bookcase at {0, 0, 4}, air at {1, 0, 3}
+ { 1, 0, 4, 1, 0, 3 }, // Bookcase at {1, 0, 4}, air at {1, 0, 3}
+ { 2, 0, 4, 2, 0, 3 }, // Bookcase at {2, 0, 4}, air at {2, 0, 3}
+ { 3, 0, 4, 3, 0, 3 }, // Bookcase at {3, 0, 4}, air at {3, 0, 3}
+ { 4, 0, 4, 3, 0, 3 }, // Bookcase at {4, 0, 4}, air at {3, 0, 3}
+ { 4, 0, 3, 3, 0, 3 }, // Bookcase at {4, 0, 3}, air at {3, 0, 3}
+ { 4, 0, 2, 3, 0, 2 }, // Bookcase at {4, 0, 2}, air at {3, 0, 2}
+ { 4, 0, 1, 3, 0, 1 }, // Bookcase at {4, 0, 1}, air at {3, 0, 1}
+ { 4, 0, 0, 3, 0, 1 }, // Bookcase at {4, 0, 0}, air at {3, 0, 1}
+ { 3, 0, 0, 3, 0, 1 }, // Bookcase at {3, 0, 0}, air at {3, 0, 1}
+ { 2, 0, 0, 2, 0, 1 }, // Bookcase at {2, 0, 0}, air at {2, 0, 1}
+ { 1, 0, 0, 1, 0, 1 }, // Bookcase at {1, 0, 0}, air at {1, 0, 1}
+
+ { 0, 1, 0, 1, 1, 1 }, // Bookcase at {0, 1, 0}, air at {1, 1, 1}
+ { 0, 1, 1, 1, 1, 1 }, // Bookcase at {0, 1, 1}, air at {1, 1, 1}
+ { 0, 1, 2, 1, 1, 2 }, // Bookcase at {0, 1, 2}, air at {1, 1, 2}
+ { 0, 1, 3, 1, 1, 3 }, // Bookcase at {0, 1, 3}, air at {1, 1, 3}
+ { 0, 1, 4, 1, 1, 3 }, // Bookcase at {0, 1, 4}, air at {1, 1, 3}
+ { 1, 1, 4, 1, 1, 3 }, // Bookcase at {1, 1, 4}, air at {1, 1, 3}
+ { 2, 1, 4, 2, 1, 3 }, // Bookcase at {2, 1, 4}, air at {2, 1, 3}
+ { 3, 1, 4, 3, 1, 3 }, // Bookcase at {3, 1, 4}, air at {3, 1, 3}
+ { 4, 1, 4, 3, 1, 3 }, // Bookcase at {4, 1, 4}, air at {3, 1, 3}
+ { 4, 1, 3, 3, 1, 3 }, // Bookcase at {4, 1, 3}, air at {3, 1, 3}
+ { 4, 1, 2, 3, 1, 2 }, // Bookcase at {4, 1, 2}, air at {3, 1, 2}
+ { 4, 1, 1, 3, 1, 1 }, // Bookcase at {4, 1, 1}, air at {3, 1, 1}
+ { 4, 1, 0, 3, 1, 1 }, // Bookcase at {4, 1, 0}, air at {3, 1, 1}
+ { 3, 1, 0, 3, 1, 1 }, // Bookcase at {3, 1, 0}, air at {3, 1, 1}
+ { 2, 1, 0, 2, 1, 1 }, // Bookcase at {2, 1, 0}, air at {2, 1, 1}
+ { 1, 1, 0, 1, 1, 1 }, // Bookcase at {1, 1, 0}, air at {1, 1, 1}
+ };
+
+ for (size_t i = 0; i < ARRAYCOUNT(CheckCoords); i++)
+ {
+ if (
+ (Area.GetRelBlockType(CheckCoords[i].m_AirX, CheckCoords[i].m_AirY, CheckCoords[i].m_AirZ) == E_BLOCK_AIR) && // There's air in the checkspot
+ (Area.GetRelBlockType(CheckCoords[i].m_BookX, CheckCoords[i].m_BookY, CheckCoords[i].m_BookZ) == E_BLOCK_BOOKCASE) // There's bookcase in the wanted place
+ )
+ {
+ Bookshelves++;
+ }
+ } // for i - CheckCoords
+
+ return Bookshelves;
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cSlotAreaEnderChest:
cSlotAreaEnderChest::cSlotAreaEnderChest(cEnderChestEntity * a_EnderChest, cWindow & a_ParentWindow) :
diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h
index 25b367cff..bab1098bb 100644
--- a/src/UI/SlotArea.h
+++ b/src/UI/SlotArea.h
@@ -19,6 +19,8 @@ class cDropSpenserEntity;
class cEnderChestEntity;
class cFurnaceEntity;
class cCraftingRecipe;
+class cEnchantingWindow;
+class cWorld;
@@ -66,7 +68,7 @@ public:
/// If a_CollectFullStacks is false, slots with full stacks are skipped while collecting.
/// Returns true if full stack has been collected in a_Dragging, false if there's space remaining to fill.
virtual bool CollectItemsToHand(cItem & a_Dragging, cPlayer & a_Player, bool a_CollectFullStacks);
-
+
protected:
int m_NumSlots;
cWindow & m_ParentWindow;
@@ -252,6 +254,34 @@ protected:
+class cSlotAreaEnchanting :
+ public cSlotAreaTemporary
+{
+ typedef cSlotAreaTemporary super;
+
+public:
+ cSlotAreaEnchanting(cEnchantingWindow & a_ParentWindow);
+
+ // cSlotArea overrides:
+ virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
+ virtual void DblClicked(cPlayer & a_Player, int a_SlotNum) override;
+ virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) override;
+
+ // cSlotAreaTemporary overrides:
+ virtual void OnPlayerRemoved(cPlayer & a_Player) override;
+
+ /* Get the count of bookshelves who stand in the near of the enchanting table */
+ int GetBookshelvesCount(cWorld * a_World);
+
+protected:
+ /** Handles a click in the item slot. */
+ void UpdateResult(cPlayer & a_Player);
+};
+
+
+
+
+
class cSlotAreaChest :
public cSlotArea
{
diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp
index aae7b99a3..0a78578fc 100644
--- a/src/UI/Window.cpp
+++ b/src/UI/Window.cpp
@@ -805,6 +805,66 @@ cCraftingWindow::cCraftingWindow(int a_BlockX, int a_BlockY, int a_BlockZ) :
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cEnchantingWindow:
+
+cEnchantingWindow::cEnchantingWindow(int a_BlockX, int a_BlockY, int a_BlockZ) :
+ cWindow(wtEnchantment, "Enchant"),
+ m_BlockX(a_BlockX),
+ m_BlockY(a_BlockY),
+ m_BlockZ(a_BlockZ)
+{
+ m_SlotAreas.push_back(new cSlotAreaEnchanting(*this));
+ m_SlotAreas.push_back(new cSlotAreaInventory(*this));
+ m_SlotAreas.push_back(new cSlotAreaHotBar(*this));
+}
+
+
+
+
+
+void cEnchantingWindow::SetProperty(int a_Property, int a_Value)
+{
+ m_PropertyValue[a_Property] = a_Value;
+
+ super::SetProperty(a_Property, a_Value);
+}
+
+
+
+
+
+void cEnchantingWindow::SetProperty(int a_Property, int a_Value, cPlayer & a_Player)
+{
+ m_PropertyValue[a_Property] = a_Value;
+
+ super::SetProperty(a_Property, a_Value, a_Player);
+}
+
+
+
+
+
+int cEnchantingWindow::GetPropertyValue(int a_Property)
+{
+ return m_PropertyValue[a_Property];
+}
+
+
+
+
+
+void cEnchantingWindow::GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ)
+{
+ a_PosX = m_BlockX;
+ a_PosY = m_BlockY;
+ a_PosZ = m_BlockZ;
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cChestWindow:
cChestWindow::cChestWindow(cChestEntity * a_Chest) :
diff --git a/src/UI/Window.h b/src/UI/Window.h
index 030182888..1ca67bfd8 100644
--- a/src/UI/Window.h
+++ b/src/UI/Window.h
@@ -136,11 +136,11 @@ public:
void SetWindowTitle(const AString & a_WindowTitle ) { m_WindowTitle = a_WindowTitle; }
/// Sends the UpdateWindowProperty (0x69) packet to all clients of the window
- void SetProperty(int a_Property, int a_Value);
+ virtual void SetProperty(int a_Property, int a_Value);
/// Sends the UpdateWindowPropert(0x69) packet to the specified player
- void SetProperty(int a_Property, int a_Value, cPlayer & a_Player);
-
+ virtual void SetProperty(int a_Property, int a_Value, cPlayer & a_Player);
+
// tolua_end
void OwnerDestroyed(void);
@@ -165,7 +165,7 @@ public:
/// Used by cSlotAreas to send individual slots to clients, a_RelativeSlotNum is the slot number relative to a_SlotArea
void SendSlot(cPlayer & a_Player, cSlotArea * a_SlotArea, int a_RelativeSlotNum);
-
+
protected:
cSlotAreas m_SlotAreas;
@@ -231,6 +231,32 @@ public:
+class cEnchantingWindow :
+ public cWindow
+{
+ typedef cWindow super;
+public:
+ cEnchantingWindow(int a_BlockX, int a_BlockY, int a_BlockZ);
+ virtual void SetProperty(int a_Property, int a_Value, cPlayer & a_Player) override;
+ virtual void SetProperty(int a_Property, int a_Value) override;
+
+ /** Return the Value of a Property */
+ int GetPropertyValue(int a_Property);
+
+ /** Set the Position Values to the Position of the Enchantment Table */
+ void GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ);
+
+ cSlotArea * m_SlotArea;
+
+protected:
+ int m_PropertyValue[3];
+ int m_BlockX, m_BlockY, m_BlockZ;
+};
+
+
+
+
+
class cFurnaceWindow :
public cWindow
{
diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp
index cd141f7eb..a3b3cc5be 100644
--- a/src/WebAdmin.cpp
+++ b/src/WebAdmin.cpp
@@ -229,10 +229,11 @@ void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPReque
} // for itr - Data->m_Form[]
// Parse the URL into individual params:
- size_t idxQM = a_Request.GetURL().find('?');
+ const AString & URL = a_Request.GetURL();
+ size_t idxQM = URL.find('?');
if (idxQM != AString::npos)
{
- cHTTPFormParser URLParams(cHTTPFormParser::fpkURL, a_Request.GetURL().c_str() + idxQM + 1, a_Request.GetURL().length() - idxQM - 1, *Data);
+ cHTTPFormParser URLParams(cHTTPFormParser::fpkURL, URL.c_str() + idxQM + 1, URL.length() - idxQM - 1, *Data);
URLParams.Finish();
for (cHTTPFormParser::const_iterator itr = URLParams.begin(), end = URLParams.end(); itr != end; ++itr)
{
@@ -388,7 +389,6 @@ AString cWebAdmin::GetDefaultPage(void)
{
continue;
}
- AString VersionNum;
AppendPrintf(Content, "<li>%s V.%i</li>", itr->second->GetName().c_str(), itr->second->GetVersion());
}
Content += "</ul>";
diff --git a/src/World.cpp b/src/World.cpp
index 800bdde0e..25ac9b021 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -860,7 +860,7 @@ void cWorld::TickMobs(float a_Dt)
{
m_ChunkMap->SpawnMobs(Spawner);
// do the spawn
- for (cMobSpawner::tSpawnedContainer::const_iterator itr2 = Spawner.getSpawned().begin(); itr2 != Spawner.getSpawned().end(); itr2++)
+ for (cMobSpawner::tSpawnedContainer::const_iterator itr2 = Spawner.getSpawned().begin(); itr2 != Spawner.getSpawned().end(); ++itr2)
{
SpawnMobFinalize(*itr2);
}
@@ -870,14 +870,14 @@ void cWorld::TickMobs(float a_Dt)
// move close mobs
cMobProximityCounter::sIterablePair allCloseEnoughToMoveMobs = MobCensus.GetProximityCounter().getMobWithinThosesDistances(-1, 64 * 16);// MG TODO : deal with this magic number (the 16 is the size of a block)
- for(cMobProximityCounter::tDistanceToMonster::const_iterator itr = allCloseEnoughToMoveMobs.m_Begin; itr != allCloseEnoughToMoveMobs.m_End; itr++)
+ for(cMobProximityCounter::tDistanceToMonster::const_iterator itr = allCloseEnoughToMoveMobs.m_Begin; itr != allCloseEnoughToMoveMobs.m_End; ++itr)
{
itr->second.m_Monster.Tick(a_Dt, itr->second.m_Chunk);
}
// remove too far mobs
cMobProximityCounter::sIterablePair allTooFarMobs = MobCensus.GetProximityCounter().getMobWithinThosesDistances(128 * 16, -1);// MG TODO : deal with this magic number (the 16 is the size of a block)
- for(cMobProximityCounter::tDistanceToMonster::const_iterator itr = allTooFarMobs.m_Begin; itr != allTooFarMobs.m_End; itr++)
+ for(cMobProximityCounter::tDistanceToMonster::const_iterator itr = allTooFarMobs.m_Begin; itr != allTooFarMobs.m_End; ++itr)
{
itr->second.m_Monster.Destroy(true);
}
@@ -2894,7 +2894,7 @@ void cWorld::TickQueuedBlocks(void)
m_BlockTickQueueCopy.clear();
m_BlockTickQueue.swap(m_BlockTickQueueCopy);
- for (std::vector<BlockTickQueueItem *>::iterator itr = m_BlockTickQueueCopy.begin(); itr != m_BlockTickQueueCopy.end(); itr++)
+ for (std::vector<BlockTickQueueItem *>::iterator itr = m_BlockTickQueueCopy.begin(); itr != m_BlockTickQueueCopy.end(); ++itr)
{
BlockTickQueueItem * Block = (*itr);
Block->TicksToWait -= 1;
@@ -2985,7 +2985,7 @@ int cWorld::SpawnMobFinalize(cMonster * a_Monster)
-int cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem a_Item, const Vector3d * a_Speed)
+int cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem & a_Item, const Vector3d * a_Speed)
{
cProjectileEntity * Projectile = cProjectileEntity::Create(a_Kind, a_Creator, a_PosX, a_PosY, a_PosZ, a_Item, a_Speed);
if (Projectile == NULL)
diff --git a/src/World.h b/src/World.h
index 61733bca0..ef2971846 100644
--- a/src/World.h
+++ b/src/World.h
@@ -713,7 +713,7 @@ public:
/** Creates a projectile of the specified type. Returns the projectile's EntityID if successful, <0 otherwise
Item parameter used currently for Fireworks to correctly set entity metadata based on item metadata
*/
- int CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem a_Item, const Vector3d * a_Speed = NULL); // tolua_export
+ int CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem & a_Item, const Vector3d * a_Speed = NULL); // tolua_export
/** Returns a random number from the m_TickRand in range [0 .. a_Range]. To be used only in the tick thread! */
int GetTickRandomNumber(unsigned a_Range) { return (int)(m_TickRand.randInt(a_Range)); }
diff --git a/src/WorldStorage/FastNBT.cpp b/src/WorldStorage/FastNBT.cpp
index be25fd1a4..ac9a21205 100644
--- a/src/WorldStorage/FastNBT.cpp
+++ b/src/WorldStorage/FastNBT.cpp
@@ -345,7 +345,7 @@ cFastNBTWriter::cFastNBTWriter(const AString & a_RootTagName) :
void cFastNBTWriter::BeginCompound(const AString & a_Name)
{
- if (m_CurrentStack >= MAX_STACK)
+ if (m_CurrentStack >= MAX_STACK - 1)
{
ASSERT(!"Stack overflow");
return;
@@ -376,7 +376,7 @@ void cFastNBTWriter::EndCompound(void)
void cFastNBTWriter::BeginList(const AString & a_Name, eTagType a_ChildrenType)
{
- if (m_CurrentStack >= MAX_STACK)
+ if (m_CurrentStack >= MAX_STACK - 1)
{
ASSERT(!"Stack overflow");
return;
diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp
index bb9d4b9e6..5435e6d5a 100644
--- a/src/WorldStorage/WSSCompact.cpp
+++ b/src/WorldStorage/WSSCompact.cpp
@@ -839,7 +839,7 @@ void cWSSCompact::cPAKFile::UpdateChunk2To3()
-bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, const AString & a_Data, cWorld * a_World)
+bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data, cWorld * a_World)
{
// Crude data integrity check:
if (a_UncompressedSize < cChunkDef::BlockDataSize)
diff --git a/src/WorldStorage/WSSCompact.h b/src/WorldStorage/WSSCompact.h
index 4df146ec3..97e3b82f9 100644
--- a/src/WorldStorage/WSSCompact.h
+++ b/src/WorldStorage/WSSCompact.h
@@ -135,7 +135,7 @@ protected:
bool EraseChunkData(const cChunkCoords & a_Chunk);
/// Loads the chunk from the data (no locking needed)
- bool LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, const AString & a_Data, cWorld * a_World);
+ bool LoadChunkFromData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data, cWorld * a_World);
void LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World);