summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Server/Plugins/APIDump/APIDesc.lua2
-rw-r--r--Server/Plugins/APIDump/Classes/World.lua22
-rw-r--r--src/Entities/EnderCrystal.cpp12
-rw-r--r--src/Entities/EnderCrystal.h19
-rw-r--r--src/Protocol/Packetizer.h7
-rw-r--r--src/Protocol/Protocol_1_10.cpp17
-rw-r--r--src/Protocol/Protocol_1_11.cpp17
-rw-r--r--src/Protocol/Protocol_1_12.cpp17
-rw-r--r--src/Protocol/Protocol_1_13.cpp15
-rw-r--r--src/Protocol/Protocol_1_9.cpp16
-rw-r--r--src/World.cpp16
-rw-r--r--src/World.h4
-rw-r--r--src/WorldStorage/NBTChunkSerializer.cpp10
-rwxr-xr-xsrc/WorldStorage/WSSAnvil.cpp33
14 files changed, 200 insertions, 7 deletions
diff --git a/Server/Plugins/APIDump/APIDesc.lua b/Server/Plugins/APIDump/APIDesc.lua
index f1346ffee..fb74d8032 100644
--- a/Server/Plugins/APIDump/APIDesc.lua
+++ b/Server/Plugins/APIDump/APIDesc.lua
@@ -4500,7 +4500,7 @@ local Hash = cCryptoHash.sha1HexString("DataToHash")
},
etEnderCrystal =
{
- Notes = "",
+ Notes = "The entity is a {{cEnderCrystal}}",
},
etEntity =
{
diff --git a/Server/Plugins/APIDump/Classes/World.lua b/Server/Plugins/APIDump/Classes/World.lua
index 7f137cf72..0ddd66e60 100644
--- a/Server/Plugins/APIDump/Classes/World.lua
+++ b/Server/Plugins/APIDump/Classes/World.lua
@@ -3306,6 +3306,28 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
Notes = "Spawns a {{cBoat|boat}} at the specific coordinates. Returns the EntityID of the new boat, or {{cEntity#INVALID_ID|cEntity#INVALID_ID}} if no boat was created. (DEPRECATED, use vector-parametered version)",
},
},
+ SpawnEnderCrystal =
+ {
+ Params =
+ {
+ {
+ Name = "Pos",
+ Type = "Vector3i",
+ },
+ {
+ Name = "ShowBottom",
+ Type = "boolean",
+ }
+ },
+ Returns =
+ {
+ {
+ Name = "EntityID",
+ Type = "number",
+ },
+ },
+ Notes = "Spawns an {{cEnderCrystal|ender crystal}} at the specified coords. Returns the EntityID of the new ender crystal, or {{cEntity#INVALID_ID|cEntity#INVALID_ID}} if no ender crystal was created.",
+ },
SpawnExperienceOrb =
{
Params =
diff --git a/src/Entities/EnderCrystal.cpp b/src/Entities/EnderCrystal.cpp
index 4f2bd857f..269714b58 100644
--- a/src/Entities/EnderCrystal.cpp
+++ b/src/Entities/EnderCrystal.cpp
@@ -10,8 +10,9 @@
-cEnderCrystal::cEnderCrystal(Vector3d a_Pos):
- Super(etEnderCrystal, a_Pos, 1.0, 1.0)
+cEnderCrystal::cEnderCrystal(Vector3d a_Pos, bool a_ShowBottom):
+ Super(etEnderCrystal, a_Pos, 1.0, 1.0),
+ m_ShowBottom(a_ShowBottom)
{
SetMaxHealth(5);
}
@@ -33,6 +34,10 @@ void cEnderCrystal::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
UNUSED(a_Dt);
// No further processing (physics e.t.c.) is needed
+ if (m_World->GetDimension() == dimEnd)
+ {
+ m_World->SetBlock(POS_TOINT.addedY(1), E_BLOCK_FIRE, 0);
+ }
}
@@ -47,8 +52,7 @@ void cEnderCrystal::KilledBy(TakeDamageInfo & a_TDI)
Destroy();
- m_World->SetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT, E_BLOCK_BEDROCK, 0);
- m_World->SetBlock(POSX_TOINT, POSY_TOINT + 1, POSZ_TOINT, E_BLOCK_FIRE, 0);
+ m_World->SetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT, E_BLOCK_FIRE, 0);
}
diff --git a/src/Entities/EnderCrystal.h b/src/Entities/EnderCrystal.h
index f29927549..b2a28c517 100644
--- a/src/Entities/EnderCrystal.h
+++ b/src/Entities/EnderCrystal.h
@@ -18,10 +18,27 @@ public:
CLASS_PROTODEF(cEnderCrystal)
- cEnderCrystal(Vector3d a_Pos);
+ cEnderCrystal(Vector3d a_Pos, bool a_ShowBottom);
+
+ // Getters and Setters
+ bool ShowsBottom() const { return m_ShowBottom; }
+ void SetShowBottom(bool a_ShowBottom) { m_ShowBottom = a_ShowBottom; }
+
+ Vector3i GetBeamTarget() const { return m_BeamTarget; }
+ void SetBeamTarget(Vector3i a_BeamTarget) { m_BeamTarget = a_BeamTarget; }
+
+ /** If the EnderCrystal should send it's beam to the client and store to disk. */
+ bool DisplaysBeam() const { return m_DisplayBeam; }
+ void SetDisplayBeam(bool a_DisplayBeam) { m_DisplayBeam = a_DisplayBeam; }
private:
+ // If the bedrock base should be displayed
+ bool m_ShowBottom;
+
+ Vector3i m_BeamTarget;
+ bool m_DisplayBeam;
+
// cEntity overrides:
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
diff --git a/src/Protocol/Packetizer.h b/src/Protocol/Packetizer.h
index 22ef01ed9..b2f2b11f4 100644
--- a/src/Protocol/Packetizer.h
+++ b/src/Protocol/Packetizer.h
@@ -133,6 +133,13 @@ public:
}
/** Writes the specified block position as a single encoded 64-bit BigEndian integer.
+ The three coordinates are written in XYZ order. */
+ inline void WriteXYZPosition64(const Vector3i & a_Pos)
+ {
+ VERIFY(m_Out.WriteXYZPosition64(a_Pos.x, a_Pos.y, a_Pos.z));
+ }
+
+ /** Writes the specified block position as a single encoded 64-bit BigEndian integer.
The three coordinates are written in XZY order, in 1.14+. */
inline void WriteXZYPosition64(int a_BlockX, int a_BlockY, int a_BlockZ)
{
diff --git a/src/Protocol/Protocol_1_10.cpp b/src/Protocol/Protocol_1_10.cpp
index f40bf7b73..d1b48c11a 100644
--- a/src/Protocol/Protocol_1_10.cpp
+++ b/src/Protocol/Protocol_1_10.cpp
@@ -21,6 +21,7 @@ Implements the 1.10 protocol classes:
#include "../WorldStorage/FastNBT.h"
#include "../Entities/Boat.h"
+#include "../Entities/EnderCrystal.h"
#include "../Entities/ExpOrb.h"
#include "../Entities/Minecart.h"
#include "../Entities/FallingBlock.h"
@@ -539,6 +540,22 @@ void cProtocol_1_10_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity &
break;
} // case etItemFrame
+ case cEntity::etEnderCrystal:
+ {
+ const auto & EnderCrystal = static_cast<const cEnderCrystal &>(a_Entity);
+ a_Pkt.WriteBEUInt8(7);
+ a_Pkt.WriteBEUInt8(METADATA_TYPE_OPTIONAL_POSITION);
+ a_Pkt.WriteBool(EnderCrystal.DisplaysBeam());
+ if (EnderCrystal.DisplaysBeam())
+ {
+ a_Pkt.WriteXYZPosition64(EnderCrystal.GetBeamTarget());
+ }
+ a_Pkt.WriteBEUInt8(8);
+ a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
+ a_Pkt.WriteBool(EnderCrystal.ShowsBottom());
+ break;
+ } // case etEnderCrystal
+
default:
{
break;
diff --git a/src/Protocol/Protocol_1_11.cpp b/src/Protocol/Protocol_1_11.cpp
index 1e07419ec..9ea6332b8 100644
--- a/src/Protocol/Protocol_1_11.cpp
+++ b/src/Protocol/Protocol_1_11.cpp
@@ -16,6 +16,7 @@ Implements the 1.11 protocol classes:
#include "../WorldStorage/FastNBT.h"
#include "../Entities/Boat.h"
+#include "../Entities/EnderCrystal.h"
#include "../Entities/ExpOrb.h"
#include "../Entities/Minecart.h"
#include "../Entities/FallingBlock.h"
@@ -805,6 +806,22 @@ void cProtocol_1_11_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity &
break;
} // case etItemFrame
+ case cEntity::etEnderCrystal:
+ {
+ const auto & EnderCrystal = static_cast<const cEnderCrystal &>(a_Entity);
+ a_Pkt.WriteBEUInt8(7);
+ a_Pkt.WriteBEUInt8(METADATA_TYPE_OPTIONAL_POSITION);
+ a_Pkt.WriteBool(EnderCrystal.DisplaysBeam());
+ if (EnderCrystal.DisplaysBeam())
+ {
+ a_Pkt.WriteXYZPosition64(EnderCrystal.GetBeamTarget());
+ }
+ a_Pkt.WriteBEUInt8(8);
+ a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
+ a_Pkt.WriteBool(EnderCrystal.ShowsBottom());
+ break;
+ } // case etEnderCrystal
+
default:
{
break;
diff --git a/src/Protocol/Protocol_1_12.cpp b/src/Protocol/Protocol_1_12.cpp
index 16651bdf6..ee2016ae2 100644
--- a/src/Protocol/Protocol_1_12.cpp
+++ b/src/Protocol/Protocol_1_12.cpp
@@ -13,6 +13,7 @@ Implements the 1.12 protocol classes:
#include "Packetizer.h"
#include "../Entities/Boat.h"
+#include "../Entities/EnderCrystal.h"
#include "../Entities/Minecart.h"
#include "../Entities/Pickup.h"
#include "../Entities/Player.h"
@@ -518,6 +519,22 @@ void cProtocol_1_12::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_
break;
} // case etItemFrame
+ case cEntity::etEnderCrystal:
+ {
+ const auto & EnderCrystal = static_cast<const cEnderCrystal &>(a_Entity);
+ a_Pkt.WriteBEUInt8(7);
+ a_Pkt.WriteBEUInt8(METADATA_TYPE_OPTIONAL_POSITION);
+ a_Pkt.WriteBool(EnderCrystal.DisplaysBeam());
+ if (EnderCrystal.DisplaysBeam())
+ {
+ a_Pkt.WriteXYZPosition64(EnderCrystal.GetBeamTarget());
+ }
+ a_Pkt.WriteBEUInt8(8);
+ a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
+ a_Pkt.WriteBool(EnderCrystal.ShowsBottom());
+ break;
+ } // case etEnderCrystal
+
default:
{
break;
diff --git a/src/Protocol/Protocol_1_13.cpp b/src/Protocol/Protocol_1_13.cpp
index 1b505d58d..efc1e9fc1 100644
--- a/src/Protocol/Protocol_1_13.cpp
+++ b/src/Protocol/Protocol_1_13.cpp
@@ -12,6 +12,7 @@ Implements the 1.13 protocol classes:
#include "Protocol_1_13.h"
#include "../Entities/Boat.h"
+#include "../Entities/EnderCrystal.h"
#include "../Entities/Minecart.h"
#include "../Entities/Pickup.h"
#include "../Entities/Player.h"
@@ -887,6 +888,20 @@ void cProtocol_1_13::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_
break;
} // case etItemFrame
+ case cEntity::etEnderCrystal:
+ {
+ const auto & EnderCrystal = static_cast<const cEnderCrystal &>(a_Entity);
+ WriteEntityMetadata(a_Pkt, EntityMetadata::EnderCrystalBeamTarget, EntityMetadataType::OptPosition);
+ a_Pkt.WriteBool(EnderCrystal.DisplaysBeam());
+ if (EnderCrystal.DisplaysBeam())
+ {
+ a_Pkt.WriteXYZPosition64(EnderCrystal.GetBeamTarget());
+ }
+ WriteEntityMetadata(a_Pkt, EntityMetadata::EnderCrystalShowBottom, EntityMetadataType::Boolean);
+ a_Pkt.WriteBool(EnderCrystal.ShowsBottom());
+ break;
+ } // case etEnderCrystal
+
default:
{
break;
diff --git a/src/Protocol/Protocol_1_9.cpp b/src/Protocol/Protocol_1_9.cpp
index a152a46cb..778d4ca30 100644
--- a/src/Protocol/Protocol_1_9.cpp
+++ b/src/Protocol/Protocol_1_9.cpp
@@ -28,6 +28,7 @@ Implements the 1.9 protocol classes:
#include "../WorldStorage/FastNBT.h"
+#include "../Entities/EnderCrystal.h"
#include "../Entities/ExpOrb.h"
#include "../Entities/Minecart.h"
#include "../Entities/FallingBlock.h"
@@ -1727,6 +1728,21 @@ void cProtocol_1_9_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a
break;
} // case etItemFrame
+ case cEntity::etEnderCrystal:
+ {
+ const auto & EnderCrystal = static_cast<const cEnderCrystal &>(a_Entity);
+ a_Pkt.WriteBEUInt8(7);
+ a_Pkt.WriteBEUInt8(METADATA_TYPE_OPTIONAL_POSITION);
+ a_Pkt.WriteBool(EnderCrystal.DisplaysBeam());
+ if (EnderCrystal.DisplaysBeam())
+ {
+ a_Pkt.WriteXYZPosition64(EnderCrystal.GetBeamTarget());
+ }
+ a_Pkt.WriteBEUInt8(8);
+ a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
+ a_Pkt.WriteBool(EnderCrystal.ShowsBottom());
+ break;
+ } // case etEnderCrystal
default:
{
break;
diff --git a/src/World.cpp b/src/World.cpp
index c3996c8ba..3f9150527 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -20,6 +20,7 @@
#include "WorldStorage/ScoreboardSerializer.h"
// Entities (except mobs):
+#include "Entities/EnderCrystal.h"
#include "Entities/ExpOrb.h"
#include "Entities/FallingBlock.h"
#include "Entities/Minecart.h"
@@ -2164,6 +2165,21 @@ UInt32 cWorld::SpawnPrimedTNT(Vector3d a_Pos, int a_FuseTicks, double a_InitialV
+UInt32 cWorld::SpawnEnderCrystal(Vector3d a_Pos, bool a_ShowBottom)
+{
+ auto EnderCrystal = std::make_unique<cEnderCrystal>(a_Pos, a_ShowBottom);
+ auto EnderCrystalPtr = EnderCrystal.get();
+ if (!EnderCrystalPtr->Initialize(std::move(EnderCrystal), *this))
+ {
+ return cEntity::INVALID_ID;
+ }
+ return EnderCrystalPtr->GetUniqueID();
+}
+
+
+
+
+
void cWorld::PlaceBlock(const Vector3i a_Position, const BLOCKTYPE a_BlockType, const NIBBLETYPE a_BlockMeta)
{
SetBlock(a_Position, a_BlockType, a_BlockMeta);
diff --git a/src/World.h b/src/World.h
index 2ff8fbe29..7460dc624 100644
--- a/src/World.h
+++ b/src/World.h
@@ -652,6 +652,10 @@ public:
Returns the UniqueID of the created entity, or cEntity::INVALID_ID on failure. */
UInt32 SpawnPrimedTNT(Vector3d a_Pos, int a_FuseTimeInSec = 80, double a_InitialVelocityCoeff = 1, bool a_ShouldPlayFuseSound = true);
+ /** Spawns a new ender crystal at the specified block coords.
+ Returns the UniqueID of the created entity, or cEntity::INVALID_ID on failure. */
+ UInt32 SpawnEnderCrystal(Vector3d a_Pos, bool a_ShowBottom = false);
+
// tolua_end
/** Replaces the specified block with another, and calls the OnPlaced block handler.
diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp
index f78f7029f..d159f6e49 100644
--- a/src/WorldStorage/NBTChunkSerializer.cpp
+++ b/src/WorldStorage/NBTChunkSerializer.cpp
@@ -683,6 +683,16 @@ public:
{
mWriter.BeginCompound("");
AddBasicEntity(a_EnderCrystal, "EnderCrystal");
+ mWriter.AddByte("ShowBottom", a_EnderCrystal->ShowsBottom() ? 1 : 0);
+ if (a_EnderCrystal->DisplaysBeam())
+ {
+ mWriter.BeginCompound("BeamTarget");
+ const auto & BeamTarget = a_EnderCrystal->GetBeamTarget();
+ mWriter.AddInt("X", BeamTarget.x);
+ mWriter.AddInt("Y", BeamTarget.y);
+ mWriter.AddInt("Z", BeamTarget.z);
+ mWriter.EndCompound();
+ }
mWriter.EndCompound();
}
diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp
index 03e60bb26..c7b4c7e1f 100755
--- a/src/WorldStorage/WSSAnvil.cpp
+++ b/src/WorldStorage/WSSAnvil.cpp
@@ -1718,11 +1718,42 @@ void cWSSAnvil::LoadBoatFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N
void cWSSAnvil::LoadEnderCrystalFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
{
- auto EnderCrystal = std::make_unique<cEnderCrystal>(Vector3d());
+ auto EnderCrystal = std::make_unique<cEnderCrystal>(Vector3d(), false);
if (!LoadEntityBaseFromNBT(*EnderCrystal.get(), a_NBT, a_TagIdx))
{
return;
}
+
+ int CurrentLine = a_NBT.FindChildByName(a_TagIdx, "BeamTarget");
+ if (CurrentLine > 0)
+ {
+ EnderCrystal->SetDisplayBeam(true);
+ if (a_NBT.GetType(CurrentLine) == TAG_Compound)
+ {
+ Vector3d BeamTarget = {0, 0, 0};
+ int CoordinateLine = a_NBT.FindChildByName(CurrentLine, "X");
+ if (CoordinateLine > 0)
+ {
+ BeamTarget.x = a_NBT.GetInt(CoordinateLine);
+ }
+ CoordinateLine = a_NBT.FindChildByName(CurrentLine, "Y");
+ if (CoordinateLine > 0)
+ {
+ BeamTarget.y = a_NBT.GetInt(CoordinateLine);
+ }
+ CoordinateLine = a_NBT.FindChildByName(CurrentLine, "Z");
+ if (CoordinateLine > 0)
+ {
+ BeamTarget.z = a_NBT.GetInt(CoordinateLine);
+ }
+ }
+ }
+ CurrentLine = a_NBT.FindChildByName(a_TagIdx, "ShowBottom");
+ if (CurrentLine > 0)
+ {
+ EnderCrystal->SetShowBottom(a_NBT.GetByte(CurrentLine) == 1);
+ }
+
a_Entities.emplace_back(std::move(EnderCrystal));
}