Added beacon.
This commit is contained in:
parent
f095e770b8
commit
89b1bbdc5f
|
@ -3,33 +3,31 @@
|
||||||
|
|
||||||
#include "BeaconEntity.h"
|
#include "BeaconEntity.h"
|
||||||
#include "../BlockArea.h"
|
#include "../BlockArea.h"
|
||||||
|
#include "../Entities/Player.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cBeaconEntity::cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
|
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)
|
: super(E_BLOCK_BEACON, a_BlockX, a_BlockY, a_BlockZ, 1, 1, a_World)
|
||||||
|
, m_IsActive(false)
|
||||||
|
, m_BeaconLevel(0)
|
||||||
|
, m_PrimaryPotion(cEntityEffect::effNoEffect)
|
||||||
|
, m_SecondaryPotion(cEntityEffect::effNoEffect)
|
||||||
{
|
{
|
||||||
|
UpdateBeacon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int cBeaconEntity::GetPyramidLevel(void)
|
char cBeaconEntity::CalculatePyramidLevel(void)
|
||||||
{
|
{
|
||||||
cBlockArea Area;
|
cBlockArea Area;
|
||||||
int MinY = GetPosY() - 4;
|
int MinY = std::max(GetPosY() - 4, 0);
|
||||||
if (MinY < 0)
|
int MaxY = std::max(GetPosY() - 1, 0);
|
||||||
{
|
|
||||||
MinY = 0;
|
|
||||||
}
|
|
||||||
int MaxY = GetPosY() - 1;
|
|
||||||
if (MaxY < 0)
|
|
||||||
{
|
|
||||||
MaxY = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Area.Read(
|
Area.Read(
|
||||||
m_World,
|
m_World,
|
||||||
|
@ -42,7 +40,7 @@ int cBeaconEntity::GetPyramidLevel(void)
|
||||||
int Layer = 1;
|
int Layer = 1;
|
||||||
int MiddleXZ = 4;
|
int MiddleXZ = 4;
|
||||||
|
|
||||||
for (int Y = Area.GetSizeY() - 1; Y > 0; Y--)
|
for (int Y = (Area.GetSizeY() - 1); Y >= 0; Y--)
|
||||||
{
|
{
|
||||||
for (int X = MiddleXZ - Layer; X <= (MiddleXZ + Layer); X++)
|
for (int X = MiddleXZ - Layer; X <= (MiddleXZ + Layer); X++)
|
||||||
{
|
{
|
||||||
|
@ -50,14 +48,122 @@ int cBeaconEntity::GetPyramidLevel(void)
|
||||||
{
|
{
|
||||||
if (!IsMineralBlock(Area.GetRelBlockType(X, Y, Z)))
|
if (!IsMineralBlock(Area.GetRelBlockType(X, Y, Z)))
|
||||||
{
|
{
|
||||||
return Layer - 1;
|
return (Layer - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Layer++;
|
Layer++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Layer - 1;
|
return (Layer - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cBeaconEntity::IsValidPotion(cEntityEffect::eType a_Potion, char a_BeaconLevel)
|
||||||
|
{
|
||||||
|
if (a_Potion == cEntityEffect::effNoEffect)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (a_BeaconLevel)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
// Beacon level 4
|
||||||
|
if (a_Potion == cEntityEffect::effRegeneration)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
// Beacon level 3
|
||||||
|
if (a_Potion == cEntityEffect::effStrength)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
// Beacon level 2
|
||||||
|
switch (a_Potion)
|
||||||
|
{
|
||||||
|
case cEntityEffect::effResistance:
|
||||||
|
case cEntityEffect::effJumpBoost:
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
// Beacon level 1
|
||||||
|
switch (a_Potion)
|
||||||
|
{
|
||||||
|
case cEntityEffect::effSpeed:
|
||||||
|
case cEntityEffect::effHaste:
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cBeaconEntity::SelectPrimaryPotion(cEntityEffect::eType a_Potion)
|
||||||
|
{
|
||||||
|
LOG("SelectPrimaryPotion!");
|
||||||
|
if (!IsValidPotion(a_Potion, m_BeaconLevel))
|
||||||
|
{
|
||||||
|
LOG("FALLSE!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_PrimaryPotion = a_Potion;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cBeaconEntity::SelectSecondaryPotion(cEntityEffect::eType a_Potion)
|
||||||
|
{
|
||||||
|
if (!IsValidPotion(a_Potion, m_BeaconLevel))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_SecondaryPotion = a_Potion;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cBeaconEntity::IsBeaconBlocked(void)
|
||||||
|
{
|
||||||
|
bool IsBlocked = false;
|
||||||
|
for (int Y = m_PosY; Y < cChunkDef::Height; ++Y)
|
||||||
|
{
|
||||||
|
BLOCKTYPE Block = m_World->GetBlock(m_PosX, Y, m_PosZ);
|
||||||
|
if (!cBlockInfo::IsTransparent(Block))
|
||||||
|
{
|
||||||
|
IsBlocked = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return IsBlocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,8 +189,102 @@ bool cBeaconEntity::IsMineralBlock(BLOCKTYPE a_BlockType)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cBeaconEntity::UpdateBeacon(void)
|
||||||
|
{
|
||||||
|
if (IsBeaconBlocked())
|
||||||
|
{
|
||||||
|
m_IsActive = false;
|
||||||
|
m_BeaconLevel = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_BeaconLevel = CalculatePyramidLevel();
|
||||||
|
m_IsActive = (m_BeaconLevel > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add achievement
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cBeaconEntity::GiveEffects(void)
|
||||||
|
{
|
||||||
|
if (!m_IsActive || (m_BeaconLevel < 0))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Radius = m_BeaconLevel * 10 + 10;
|
||||||
|
short EffectLevel = 0;
|
||||||
|
if ((m_BeaconLevel >= 4) && (m_PrimaryPotion == m_SecondaryPotion))
|
||||||
|
{
|
||||||
|
EffectLevel = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cEntityEffect::eType SecondaryPotion = cEntityEffect::effNoEffect;
|
||||||
|
if ((m_BeaconLevel >= 4) && (m_PrimaryPotion != m_SecondaryPotion) && (m_SecondaryPotion > 0))
|
||||||
|
{
|
||||||
|
SecondaryPotion = m_SecondaryPotion;
|
||||||
|
}
|
||||||
|
|
||||||
|
class cPlayerCallback : public cPlayerListCallback
|
||||||
|
{
|
||||||
|
int m_Radius;
|
||||||
|
int m_PosX, m_PosY, m_PosZ;
|
||||||
|
cEntityEffect::eType m_PrimaryPotion, m_SecondaryPotion;
|
||||||
|
short m_EffectLevel;
|
||||||
|
|
||||||
|
virtual bool Item(cPlayer * a_Player)
|
||||||
|
{
|
||||||
|
Vector3d PlayerPosition = Vector3d(a_Player->GetPosition());
|
||||||
|
if (PlayerPosition.y > (double)m_PosY)
|
||||||
|
{
|
||||||
|
PlayerPosition.y = (double)m_PosY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Vanilla minecraft uses an AABB check instead of a radius one
|
||||||
|
Vector3d BeaconPosition = Vector3d(m_PosX, m_PosY, m_PosZ);
|
||||||
|
if ((PlayerPosition - BeaconPosition).Length() <= m_Radius)
|
||||||
|
{
|
||||||
|
a_Player->AddEntityEffect(m_PrimaryPotion, 180, m_EffectLevel);
|
||||||
|
|
||||||
|
if (m_SecondaryPotion != cEntityEffect::effNoEffect)
|
||||||
|
{
|
||||||
|
a_Player->AddEntityEffect(m_SecondaryPotion, 180, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
cPlayerCallback(int a_Radius, int a_PosX, int a_PosY, int a_PosZ, cEntityEffect::eType a_PrimaryPotion, cEntityEffect::eType a_SecondaryPotion, short a_EffectLevel)
|
||||||
|
: m_Radius(a_Radius)
|
||||||
|
, m_PosX(a_PosX)
|
||||||
|
, m_PosY(a_PosY)
|
||||||
|
, m_PosZ(a_PosZ)
|
||||||
|
, m_PrimaryPotion(a_PrimaryPotion)
|
||||||
|
, m_SecondaryPotion(a_SecondaryPotion)
|
||||||
|
, m_EffectLevel(a_EffectLevel)
|
||||||
|
{};
|
||||||
|
|
||||||
|
} PlayerCallback(Radius, m_PosX, m_PosY, m_PosZ, m_PrimaryPotion, SecondaryPotion, EffectLevel);
|
||||||
|
GetWorld()->ForEachPlayer(PlayerCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cBeaconEntity::Tick(float a_Dt, cChunk & a_Chunk)
|
bool cBeaconEntity::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
|
// Update the beacon every 4 seconds
|
||||||
|
if ((GetWorld()->GetWorldAge() % 80) == 0)
|
||||||
|
{
|
||||||
|
UpdateBeacon();
|
||||||
|
GiveEffects();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,23 +292,94 @@ bool cBeaconEntity::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cBeaconEntity::SaveToJson(Json::Value& a_Value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cBeaconEntity::SendTo(cClientHandle & a_Client)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cBeaconEntity::UsedBy(cPlayer * a_Player)
|
void cBeaconEntity::UsedBy(cPlayer * a_Player)
|
||||||
{
|
{
|
||||||
|
cWindow * Window = GetWindow();
|
||||||
|
if (Window == NULL)
|
||||||
|
{
|
||||||
|
OpenWindow(new cBeaconWindow(m_PosX, m_PosY, m_PosZ, this));
|
||||||
|
Window = GetWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Window != NULL)
|
||||||
|
{
|
||||||
|
// if (a_Player->GetWindow() != Window)
|
||||||
|
// -> Because mojang doesn't send a 'close window' packet when you click the cancel button in the beacon inventory ...
|
||||||
|
{
|
||||||
|
a_Player->OpenWindow(Window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cBeaconEntity::LoadFromJson(const Json::Value & a_Value)
|
||||||
|
{
|
||||||
|
m_PosX = a_Value.get("x", 0).asInt();
|
||||||
|
m_PosY = a_Value.get("y", 0).asInt();
|
||||||
|
m_PosZ = a_Value.get("z", 0).asInt();
|
||||||
|
|
||||||
|
Json::Value AllSlots = a_Value.get("Slots", 0);
|
||||||
|
int SlotIdx = 0;
|
||||||
|
for (Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr)
|
||||||
|
{
|
||||||
|
cItem Item;
|
||||||
|
Item.FromJson(*itr);
|
||||||
|
SetSlot(SlotIdx, Item);
|
||||||
|
SlotIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_BeaconLevel = (char)a_Value.get("Level", 0).asInt();
|
||||||
|
int PrimaryPotion = a_Value.get("PrimaryPotion", 0).asInt();
|
||||||
|
int SecondaryPotion = a_Value.get("SecondaryPotion", 0).asInt();
|
||||||
|
|
||||||
|
if ((PrimaryPotion >= 0) && (PrimaryPotion <= (int)cEntityEffect::effSaturation))
|
||||||
|
{
|
||||||
|
m_PrimaryPotion = (cEntityEffect::eType)PrimaryPotion;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((SecondaryPotion >= 0) && (SecondaryPotion <= (int)cEntityEffect::effSaturation))
|
||||||
|
{
|
||||||
|
m_SecondaryPotion = (cEntityEffect::eType)SecondaryPotion;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cBeaconEntity::SaveToJson(Json::Value& a_Value)
|
||||||
|
{
|
||||||
|
a_Value["x"] = m_PosX;
|
||||||
|
a_Value["y"] = m_PosY;
|
||||||
|
a_Value["z"] = m_PosZ;
|
||||||
|
|
||||||
|
Json::Value AllSlots;
|
||||||
|
int NumSlots = m_Contents.GetNumSlots();
|
||||||
|
for (int i = 0; i < NumSlots; i++)
|
||||||
|
{
|
||||||
|
Json::Value Slot;
|
||||||
|
m_Contents.GetSlot(i).GetJson(Slot);
|
||||||
|
AllSlots.append(Slot);
|
||||||
|
}
|
||||||
|
a_Value["Slots"] = AllSlots;
|
||||||
|
|
||||||
|
a_Value["Level"] = m_BeaconLevel;
|
||||||
|
a_Value["PrimaryPotion"] = (int)m_PrimaryPotion;
|
||||||
|
a_Value["SecondaryPotion"] = (int)m_SecondaryPotion;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cBeaconEntity::SendTo(cClientHandle & a_Client)
|
||||||
|
{
|
||||||
|
a_Client.SendUpdateBlockEntity(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "BlockEntity.h"
|
#include "BlockEntityWithItems.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,26 +17,60 @@ namespace Json
|
||||||
|
|
||||||
|
|
||||||
class cBeaconEntity :
|
class cBeaconEntity :
|
||||||
public cBlockEntity
|
public cBlockEntityWithItems
|
||||||
{
|
{
|
||||||
typedef cBlockEntity super;
|
typedef cBlockEntityWithItems super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** The initial constructor */
|
|
||||||
cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
|
cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
|
||||||
|
|
||||||
/** Returns the amount of layers the pyramid below the beacon has. */
|
/** Is the beacon active? */
|
||||||
int GetPyramidLevel(void);
|
bool IsActive(void) const { return m_IsActive; }
|
||||||
|
|
||||||
|
/** Returns the beacon level. (0 - 4) */
|
||||||
|
char GetBeaconLevel(void) const { return m_BeaconLevel; }
|
||||||
|
|
||||||
|
char GetPrimaryPotion(void) const { return m_PrimaryPotion; }
|
||||||
|
char GetSecondaryPotion(void) const { return m_SecondaryPotion; }
|
||||||
|
|
||||||
|
/** Select the primary potion. Returns false when the potion is invalid.*/
|
||||||
|
bool SelectPrimaryPotion(cEntityEffect::eType a_Potion);
|
||||||
|
|
||||||
|
/** Select the secondary potion. Returns false when the potion is invalid. */
|
||||||
|
bool SelectSecondaryPotion(cEntityEffect::eType a_Potion);
|
||||||
|
|
||||||
|
/** Calculate the amount of layers the pyramid below the beacon has. */
|
||||||
|
char CalculatePyramidLevel(void);
|
||||||
|
|
||||||
|
/** Is the beacon blocked by non-transparent blocks that are higher than the beacon? */
|
||||||
|
bool IsBeaconBlocked(void);
|
||||||
|
|
||||||
/** Returns true if the block is a diamond block, a golden block, an iron block or an emerald block. */
|
/** 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);
|
static bool IsMineralBlock(BLOCKTYPE a_BlockType);
|
||||||
|
|
||||||
|
/** Returns true if the potion can be used. */
|
||||||
|
static bool IsValidPotion(cEntityEffect::eType a_Potion, char a_BeaconLevel);
|
||||||
|
|
||||||
|
/** Update the beacon. */
|
||||||
|
void UpdateBeacon(void);
|
||||||
|
|
||||||
|
/** Give the near-players the effects. */
|
||||||
|
void GiveEffects(void);
|
||||||
|
|
||||||
|
bool LoadFromJson(const Json::Value & a_Value);
|
||||||
|
|
||||||
// cBlockEntity overrides:
|
// cBlockEntity overrides:
|
||||||
virtual void SaveToJson(Json::Value& a_Value) override;
|
virtual void SaveToJson(Json::Value& a_Value) override;
|
||||||
virtual void SendTo(cClientHandle & a_Client) 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;
|
||||||
virtual bool Tick(float a_Dt, cChunk & /* a_Chunk */) override;
|
virtual void UsedBy(cPlayer * a_Player) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool m_IsActive;
|
||||||
|
char m_BeaconLevel;
|
||||||
|
|
||||||
|
cEntityEffect::eType m_PrimaryPotion, m_SecondaryPotion;
|
||||||
|
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
// FlowerPotEntity.cpp
|
// FlowerPotEntity.cpp
|
||||||
|
|
||||||
// Implements the cFlowerPotEntity class representing a single sign in the world
|
// Implements the cFlowerPotEntity class representing a single flower pot in the world
|
||||||
|
|
||||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||||
#include "json/json.h"
|
#include "json/json.h"
|
||||||
|
|
|
@ -181,6 +181,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
|
||||||
case E_BLOCK_ACACIA_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
|
case E_BLOCK_ACACIA_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
|
||||||
case E_BLOCK_ACTIVATOR_RAIL: return new cBlockRailHandler (a_BlockType);
|
case E_BLOCK_ACTIVATOR_RAIL: return new cBlockRailHandler (a_BlockType);
|
||||||
case E_BLOCK_ANVIL: return new cBlockAnvilHandler (a_BlockType);
|
case E_BLOCK_ANVIL: return new cBlockAnvilHandler (a_BlockType);
|
||||||
|
case E_BLOCK_BEACON: return new cBlockEntityHandler (a_BlockType);
|
||||||
case E_BLOCK_BED: return new cBlockBedHandler (a_BlockType);
|
case E_BLOCK_BED: return new cBlockBedHandler (a_BlockType);
|
||||||
case E_BLOCK_BIG_FLOWER: return new cBlockBigFlowerHandler (a_BlockType);
|
case E_BLOCK_BIG_FLOWER: return new cBlockBigFlowerHandler (a_BlockType);
|
||||||
case E_BLOCK_BIRCH_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
|
case E_BLOCK_BIRCH_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
|
||||||
|
|
|
@ -94,6 +94,7 @@ private:
|
||||||
switch (a_BlockType)
|
switch (a_BlockType)
|
||||||
{
|
{
|
||||||
case E_BLOCK_ANVIL:
|
case E_BLOCK_ANVIL:
|
||||||
|
case E_BLOCK_BEACON:
|
||||||
case E_BLOCK_BEDROCK:
|
case E_BLOCK_BEDROCK:
|
||||||
case E_BLOCK_BREWING_STAND:
|
case E_BLOCK_BREWING_STAND:
|
||||||
case E_BLOCK_CHEST:
|
case E_BLOCK_CHEST:
|
||||||
|
|
|
@ -1839,6 +1839,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_
|
||||||
}
|
}
|
||||||
|
|
||||||
case E_BLOCK_OBSIDIAN:
|
case E_BLOCK_OBSIDIAN:
|
||||||
|
case E_BLOCK_BEACON:
|
||||||
case E_BLOCK_BEDROCK:
|
case E_BLOCK_BEDROCK:
|
||||||
case E_BLOCK_WATER:
|
case E_BLOCK_WATER:
|
||||||
case E_BLOCK_LAVA:
|
case E_BLOCK_LAVA:
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "Items/ItemSword.h"
|
#include "Items/ItemSword.h"
|
||||||
|
|
||||||
#include "polarssl/md5.h"
|
#include "polarssl/md5.h"
|
||||||
|
#include "BlockEntities/BeaconEntity.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -659,6 +660,10 @@ void cClientHandle::HandlePluginMessage(const AString & a_Channel, const AString
|
||||||
// Client <-> Server branding exchange
|
// Client <-> Server branding exchange
|
||||||
SendPluginMessage("MC|Brand", "MCServer");
|
SendPluginMessage("MC|Brand", "MCServer");
|
||||||
}
|
}
|
||||||
|
else if (a_Channel == "MC|Beacon")
|
||||||
|
{
|
||||||
|
HandleBeaconSelection(a_Message.c_str(), a_Message.size());
|
||||||
|
}
|
||||||
else if (a_Channel == "MC|ItemName")
|
else if (a_Channel == "MC|ItemName")
|
||||||
{
|
{
|
||||||
HandleAnvilItemName(a_Message.c_str(), a_Message.size());
|
HandleAnvilItemName(a_Message.c_str(), a_Message.size());
|
||||||
|
@ -746,6 +751,55 @@ void cClientHandle::UnregisterPluginChannels(const AStringVector & a_ChannelList
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cClientHandle::HandleBeaconSelection(const char * a_Data, size_t a_Length)
|
||||||
|
{
|
||||||
|
if (a_Length < 14)
|
||||||
|
{
|
||||||
|
SendChat("Failure setting beacon selection; bad request", mtFailure);
|
||||||
|
LOGD("Malformed MC|Beacon packet.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cWindow * Window = m_Player->GetWindow();
|
||||||
|
if ((Window == NULL) || (Window->GetWindowType() != cWindow::wtBeacon))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cBeaconWindow * BeaconWindow = (cBeaconWindow *) Window;
|
||||||
|
|
||||||
|
if (Window->GetSlot(*m_Player, 0)->IsEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cByteBuffer Buffer(a_Length);
|
||||||
|
Buffer.Write(a_Data, a_Length);
|
||||||
|
|
||||||
|
int PrimaryPotionID, SecondaryPotionID;
|
||||||
|
Buffer.ReadBEInt(PrimaryPotionID);
|
||||||
|
Buffer.ReadBEInt(SecondaryPotionID);
|
||||||
|
|
||||||
|
cEntityEffect::eType PrimaryPotion = cEntityEffect::effNoEffect;
|
||||||
|
if ((PrimaryPotionID >= 0) && (PrimaryPotionID <= (int)cEntityEffect::effSaturation))
|
||||||
|
{
|
||||||
|
PrimaryPotion = (cEntityEffect::eType)PrimaryPotionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
cEntityEffect::eType SecondaryPotion = cEntityEffect::effNoEffect;
|
||||||
|
if ((SecondaryPotionID >= 0) && (SecondaryPotionID <= (int)cEntityEffect::effSaturation))
|
||||||
|
{
|
||||||
|
SecondaryPotion = (cEntityEffect::eType)SecondaryPotionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
Window->SetSlot(*m_Player, 0, cItem());
|
||||||
|
BeaconWindow->GetBeaconEntity()->SelectPrimaryPotion(PrimaryPotion);
|
||||||
|
BeaconWindow->GetBeaconEntity()->SelectSecondaryPotion(SecondaryPotion);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cClientHandle::HandleCommandBlockMessage(const char * a_Data, size_t a_Length)
|
void cClientHandle::HandleCommandBlockMessage(const char * a_Data, size_t a_Length)
|
||||||
{
|
{
|
||||||
if (a_Length < 14)
|
if (a_Length < 14)
|
||||||
|
|
|
@ -399,7 +399,10 @@ private:
|
||||||
|
|
||||||
/** Removes all of the channels from the list of current plugin channels. Ignores channels that are not found. */
|
/** Removes all of the channels from the list of current plugin channels. Ignores channels that are not found. */
|
||||||
void UnregisterPluginChannels(const AStringVector & a_ChannelList);
|
void UnregisterPluginChannels(const AStringVector & a_ChannelList);
|
||||||
|
|
||||||
|
/** Handles the "MC|Beacon" plugin message */
|
||||||
|
void HandleBeaconSelection(const char * a_Data, size_t a_Length);
|
||||||
|
|
||||||
/** Handles the "MC|AdvCdm" plugin message */
|
/** Handles the "MC|AdvCdm" plugin message */
|
||||||
void HandleCommandBlockMessage(const char * a_Data, size_t a_Length);
|
void HandleCommandBlockMessage(const char * a_Data, size_t a_Length);
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ Implements the 1.7.x protocol classes:
|
||||||
#include "../Mobs/IncludeAllMonsters.h"
|
#include "../Mobs/IncludeAllMonsters.h"
|
||||||
#include "../UI/Window.h"
|
#include "../UI/Window.h"
|
||||||
|
|
||||||
|
#include "../BlockEntities/BeaconEntity.h"
|
||||||
#include "../BlockEntities/CommandBlockEntity.h"
|
#include "../BlockEntities/CommandBlockEntity.h"
|
||||||
#include "../BlockEntities/MobHeadEntity.h"
|
#include "../BlockEntities/MobHeadEntity.h"
|
||||||
#include "../BlockEntities/FlowerPotEntity.h"
|
#include "../BlockEntities/FlowerPotEntity.h"
|
||||||
|
@ -1328,6 +1329,7 @@ void cProtocol172::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity)
|
||||||
{
|
{
|
||||||
case E_BLOCK_MOB_SPAWNER: Action = 1; break; // Update mob spawner spinny mob thing
|
case E_BLOCK_MOB_SPAWNER: Action = 1; break; // Update mob spawner spinny mob thing
|
||||||
case E_BLOCK_COMMAND_BLOCK: Action = 2; break; // Update command block text
|
case E_BLOCK_COMMAND_BLOCK: Action = 2; break; // Update command block text
|
||||||
|
case E_BLOCK_BEACON: Action = 3; break; // Update beacon entity
|
||||||
case E_BLOCK_HEAD: Action = 4; break; // Update Mobhead entity
|
case E_BLOCK_HEAD: Action = 4; break; // Update Mobhead entity
|
||||||
case E_BLOCK_FLOWER_POT: Action = 5; break; // Update flower pot
|
case E_BLOCK_FLOWER_POT: Action = 5; break; // Update flower pot
|
||||||
default: ASSERT(!"Unhandled or unimplemented BlockEntity update request!"); break;
|
default: ASSERT(!"Unhandled or unimplemented BlockEntity update request!"); break;
|
||||||
|
@ -2581,6 +2583,19 @@ void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt
|
||||||
|
|
||||||
switch (a_BlockEntity.GetBlockType())
|
switch (a_BlockEntity.GetBlockType())
|
||||||
{
|
{
|
||||||
|
case E_BLOCK_BEACON:
|
||||||
|
{
|
||||||
|
cBeaconEntity & BeaconEntity = (cBeaconEntity &)a_BlockEntity;
|
||||||
|
|
||||||
|
Writer.AddInt("x", BeaconEntity.GetPosX());
|
||||||
|
Writer.AddInt("y", BeaconEntity.GetPosY());
|
||||||
|
Writer.AddInt("z", BeaconEntity.GetPosZ());
|
||||||
|
Writer.AddInt("Primary", BeaconEntity.GetPrimaryPotion());
|
||||||
|
Writer.AddInt("Secondary", BeaconEntity.GetSecondaryPotion());
|
||||||
|
Writer.AddInt("Levels", BeaconEntity.GetBeaconLevel());
|
||||||
|
Writer.AddString("id", "Beacon"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though
|
||||||
|
break;
|
||||||
|
}
|
||||||
case E_BLOCK_COMMAND_BLOCK:
|
case E_BLOCK_COMMAND_BLOCK:
|
||||||
{
|
{
|
||||||
cCommandBlockEntity & CommandBlockEntity = (cCommandBlockEntity &)a_BlockEntity;
|
cCommandBlockEntity & CommandBlockEntity = (cCommandBlockEntity &)a_BlockEntity;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "SlotArea.h"
|
#include "SlotArea.h"
|
||||||
#include "../Entities/Player.h"
|
#include "../Entities/Player.h"
|
||||||
|
#include "../BlockEntities/BeaconEntity.h"
|
||||||
#include "../BlockEntities/ChestEntity.h"
|
#include "../BlockEntities/ChestEntity.h"
|
||||||
#include "../BlockEntities/DropSpenserEntity.h"
|
#include "../BlockEntities/DropSpenserEntity.h"
|
||||||
#include "../BlockEntities/EnderChestEntity.h"
|
#include "../BlockEntities/EnderChestEntity.h"
|
||||||
|
@ -1190,6 +1191,200 @@ void cSlotAreaAnvil::UpdateResult(cPlayer & a_Player)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cSlotAreaBeacon:
|
||||||
|
|
||||||
|
cSlotAreaBeacon::cSlotAreaBeacon(cBeaconEntity * a_Beacon, cWindow & a_ParentWindow) :
|
||||||
|
cSlotArea(1, a_ParentWindow),
|
||||||
|
m_Beacon(a_Beacon)
|
||||||
|
{
|
||||||
|
m_Beacon->GetContents().AddListener(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cSlotAreaBeacon::~cSlotAreaBeacon()
|
||||||
|
{
|
||||||
|
m_Beacon->GetContents().RemoveListener(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cSlotAreaBeacon::IsPlaceableItem(short a_ItemType)
|
||||||
|
{
|
||||||
|
switch (a_ItemType)
|
||||||
|
{
|
||||||
|
case E_ITEM_EMERALD:
|
||||||
|
case E_ITEM_DIAMOND:
|
||||||
|
case E_ITEM_GOLD:
|
||||||
|
case E_ITEM_IRON:
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cSlotAreaBeacon::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 caMiddleClick:
|
||||||
|
{
|
||||||
|
MiddleClicked(a_Player, a_SlotNum);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case caDropKey:
|
||||||
|
case caCtrlDropKey:
|
||||||
|
{
|
||||||
|
DropClicked(a_Player, a_SlotNum, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case caNumber1:
|
||||||
|
case caNumber2:
|
||||||
|
case caNumber3:
|
||||||
|
case caNumber4:
|
||||||
|
case caNumber5:
|
||||||
|
case caNumber6:
|
||||||
|
case caNumber7:
|
||||||
|
case caNumber8:
|
||||||
|
case caNumber9:
|
||||||
|
{
|
||||||
|
NumberClicked(a_Player, a_SlotNum, a_ClickAction);
|
||||||
|
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();
|
||||||
|
|
||||||
|
if (DraggingItem.IsEmpty())
|
||||||
|
{
|
||||||
|
DraggingItem = Slot;
|
||||||
|
Slot.Empty();
|
||||||
|
}
|
||||||
|
else if (Slot.IsEmpty())
|
||||||
|
{
|
||||||
|
if (!IsPlaceableItem(DraggingItem.m_ItemType))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Slot = DraggingItem.CopyOne();
|
||||||
|
DraggingItem.m_ItemCount -= 1;
|
||||||
|
if (DraggingItem.m_ItemCount <= 0)
|
||||||
|
{
|
||||||
|
DraggingItem.Empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (DraggingItem.m_ItemCount == 1)
|
||||||
|
{
|
||||||
|
if (!IsPlaceableItem(DraggingItem.m_ItemCount))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch contents
|
||||||
|
cItem tmp(DraggingItem);
|
||||||
|
DraggingItem = Slot;
|
||||||
|
Slot = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetSlot(a_SlotNum, a_Player, Slot);
|
||||||
|
if (bAsync)
|
||||||
|
{
|
||||||
|
m_ParentWindow.BroadcastWholeWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cSlotAreaBeacon::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots)
|
||||||
|
{
|
||||||
|
const cItem * Slot = GetSlot(0, a_Player);
|
||||||
|
if (!Slot->IsEmpty() || !IsPlaceableItem(a_ItemStack.m_ItemType) || (a_ItemStack.m_ItemCount != 1))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a_ShouldApply)
|
||||||
|
{
|
||||||
|
SetSlot(0, a_Player, a_ItemStack.CopyOne());
|
||||||
|
}
|
||||||
|
a_ItemStack.Empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const cItem * cSlotAreaBeacon::GetSlot(int a_SlotNum, cPlayer & a_Player) const
|
||||||
|
{
|
||||||
|
UNUSED(a_Player);
|
||||||
|
return &(m_Beacon->GetSlot(a_SlotNum));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cSlotAreaBeacon::SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item)
|
||||||
|
{
|
||||||
|
UNUSED(a_Player);
|
||||||
|
m_Beacon->SetSlot(a_SlotNum, a_Item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cSlotAreaBeacon::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
|
||||||
|
{
|
||||||
|
UNUSED(a_SlotNum);
|
||||||
|
// Something has changed in the window, broadcast the entire window to all clients
|
||||||
|
ASSERT(a_ItemGrid == &(m_Beacon->GetContents()));
|
||||||
|
|
||||||
|
m_ParentWindow.BroadcastWholeWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// cSlotAreaEnchanting:
|
// cSlotAreaEnchanting:
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
class cWindow;
|
class cWindow;
|
||||||
class cPlayer;
|
class cPlayer;
|
||||||
|
class cBeaconEntity;
|
||||||
class cChestEntity;
|
class cChestEntity;
|
||||||
class cDropSpenserEntity;
|
class cDropSpenserEntity;
|
||||||
class cEnderChestEntity;
|
class cEnderChestEntity;
|
||||||
|
@ -314,6 +315,34 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class cSlotAreaBeacon :
|
||||||
|
public cSlotArea,
|
||||||
|
public cItemGrid::cListener
|
||||||
|
{
|
||||||
|
typedef cSlotArea super;
|
||||||
|
|
||||||
|
public:
|
||||||
|
cSlotAreaBeacon(cBeaconEntity * a_Beacon, cWindow & a_ParentWindow);
|
||||||
|
virtual ~cSlotAreaBeacon();
|
||||||
|
|
||||||
|
bool IsPlaceableItem(short a_ItemType);
|
||||||
|
|
||||||
|
virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
|
||||||
|
virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) override;
|
||||||
|
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override;
|
||||||
|
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
cBeaconEntity * m_Beacon;
|
||||||
|
|
||||||
|
// cItemGrid::cListener overrides:
|
||||||
|
virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cSlotAreaEnchanting :
|
class cSlotAreaEnchanting :
|
||||||
public cSlotAreaTemporary
|
public cSlotAreaTemporary
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "../Entities/Pickup.h"
|
#include "../Entities/Pickup.h"
|
||||||
#include "../Inventory.h"
|
#include "../Inventory.h"
|
||||||
#include "../Items/ItemHandler.h"
|
#include "../Items/ItemHandler.h"
|
||||||
|
#include "../BlockEntities/BeaconEntity.h"
|
||||||
#include "../BlockEntities/ChestEntity.h"
|
#include "../BlockEntities/ChestEntity.h"
|
||||||
#include "../BlockEntities/DropSpenserEntity.h"
|
#include "../BlockEntities/DropSpenserEntity.h"
|
||||||
#include "../BlockEntities/EnderChestEntity.h"
|
#include "../BlockEntities/EnderChestEntity.h"
|
||||||
|
@ -840,6 +841,36 @@ void cAnvilWindow::GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cBeaconWindow:
|
||||||
|
|
||||||
|
cBeaconWindow::cBeaconWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconEntity * a_Beacon) :
|
||||||
|
cWindow(wtBeacon, "Beacon"),
|
||||||
|
m_Beacon(a_Beacon)
|
||||||
|
{
|
||||||
|
m_ShouldDistributeToHotbarFirst = true;
|
||||||
|
m_SlotAreas.push_back(new cSlotAreaBeacon(m_Beacon, *this));
|
||||||
|
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
|
||||||
|
m_SlotAreas.push_back(new cSlotAreaHotBar(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cBeaconWindow::OpenedByPlayer(cPlayer & a_Player)
|
||||||
|
{
|
||||||
|
super::OpenedByPlayer(a_Player);
|
||||||
|
|
||||||
|
a_Player.GetClientHandle()->SendWindowProperty(*this, 0, m_Beacon->GetBeaconLevel());
|
||||||
|
a_Player.GetClientHandle()->SendWindowProperty(*this, 1, m_Beacon->GetPrimaryPotion());
|
||||||
|
a_Player.GetClientHandle()->SendWindowProperty(*this, 2, m_Beacon->GetSecondaryPotion());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// cEnchantingWindow:
|
// cEnchantingWindow:
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ class cDropSpenserEntity;
|
||||||
class cEnderChestEntity;
|
class cEnderChestEntity;
|
||||||
class cFurnaceEntity;
|
class cFurnaceEntity;
|
||||||
class cHopperEntity;
|
class cHopperEntity;
|
||||||
|
class cBeaconEntity;
|
||||||
class cSlotArea;
|
class cSlotArea;
|
||||||
class cSlotAreaAnvil;
|
class cSlotAreaAnvil;
|
||||||
class cWorld;
|
class cWorld;
|
||||||
|
@ -258,6 +259,26 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class cBeaconWindow :
|
||||||
|
public cWindow
|
||||||
|
{
|
||||||
|
typedef cWindow super;
|
||||||
|
public:
|
||||||
|
cBeaconWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconEntity * a_Beacon);
|
||||||
|
|
||||||
|
cBeaconEntity * GetBeaconEntity(void) const { return m_Beacon; }
|
||||||
|
|
||||||
|
// cWindow Overrides:
|
||||||
|
virtual void OpenedByPlayer(cPlayer & a_Player) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
cBeaconEntity * m_Beacon;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cEnchantingWindow :
|
class cEnchantingWindow :
|
||||||
public cWindow
|
public cWindow
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user