Merge pull request #696 from mc-server/paintings
Implemented paintings, fixes #689
This commit is contained in:
commit
98332c5b76
@ -713,6 +713,7 @@ end
|
||||
IsMinecart = { Params = "", Return = "bool", Notes = "Returns true if the entity represents a {{cMinecart|minecart}}" },
|
||||
IsMob = { Params = "", Return = "bool", Notes = "Returns true if the entity represents any {{cMonster|mob}}." },
|
||||
IsOnFire = { Params = "", Return = "bool", Notes = "Returns true if the entity is on fire" },
|
||||
IsPainting = { Params = "", Return = "bool", Notes = "Returns if this entity is a painting." },
|
||||
IsPickup = { Params = "", Return = "bool", Notes = "Returns true if the entity represents a {{cPickup|pickup}}." },
|
||||
IsPlayer = { Params = "", Return = "bool", Notes = "Returns true if the entity represents a {{cPlayer|player}}" },
|
||||
IsProjectile = { Params = "", Return = "bool", Notes = "Returns true if the entity is a {{cProjectileEntity}} descendant." },
|
||||
@ -779,6 +780,7 @@ end
|
||||
etPickup = { Notes = "The entity is a {{cPickup}}" },
|
||||
etProjectile = { Notes = "The entity is a {{cProjectileEntity}} descendant" },
|
||||
etTNT = { Notes = "The entity is a {{cTNTEntity}}" },
|
||||
etPainting = { Notes = "The entity is a {{cPainting}}" },
|
||||
},
|
||||
ConstantGroups =
|
||||
{
|
||||
@ -1109,6 +1111,9 @@ These ItemGrids are available in the API and can be manipulated by the plugins,
|
||||
IsFullStack = { Params = "", Return = "bool", Notes = "Returns true if the item is stacked up to its maximum stacking" },
|
||||
IsSameType = { Params = "cItem", Return = "bool", Notes = "Returns true if the item in the parameter is of the same ItemType as the one stored in the object. This is true even if the two items have different enchantments" },
|
||||
IsStackableWith = { Params = "cItem", Return = "bool", Notes = "Returns true if the item in the parameter is stackable with the one stored in the object. Two items with different enchantments cannot be stacked" },
|
||||
IsBothNameAndLoreEmpty = { Params = "", Return = "bool", Notes = "Returns if both the custom name and lore are not set." },
|
||||
IsCustomNameEmpty = { Params = "", Return = "bool", Notes = "Returns if the custom name of the cItem is empty." },
|
||||
IsLoreEmpty = { Params = "", Return = "", Notes = "Returns if the lore of the cItem is empty." },
|
||||
},
|
||||
Variables =
|
||||
{
|
||||
@ -1116,6 +1121,8 @@ These ItemGrids are available in the API and can be manipulated by the plugins,
|
||||
m_ItemCount = { Type = "number", Notes = "Number of items in this stack" },
|
||||
m_ItemDamage = { Type = "number", Notes = "The damage of the item. Zero means no damage. Maximum damage can be queried with GetMaxDamage()" },
|
||||
m_ItemType = { Type = "number", Notes = "The item type. One of E_ITEM_ or E_BLOCK_ constants" },
|
||||
m_CustomName = { Type = "string", Notes = "The custom name for an item." },
|
||||
m_Lore = { Type = "string", Notes = "The lore for an item. Line breaks are represented by the ` character." },
|
||||
},
|
||||
AdditionalInfo =
|
||||
{
|
||||
@ -1160,6 +1167,17 @@ local Item5 = cItem(E_ITEM_DIAMOND_CHESTPLATE, 1, 0, "thorns=1;unbreaking=3");
|
||||
},
|
||||
}, -- cItem
|
||||
|
||||
cPainting =
|
||||
{
|
||||
Desc = "This class represents a painting in the world. These paintings are special and different from Vanilla in that they can be critical-hit.",
|
||||
Functions =
|
||||
{
|
||||
GetDirection = { Params = "", Return = "number", Notes = "Returns the direction the painting faces. Directions: ZP - 0, ZM - 2, XM - 1, XP - 3. Note that these are not the BLOCK_FACE constants." },
|
||||
GetName = { Params = "", Return = "string", Notes = "Returns the name of the painting" },
|
||||
},
|
||||
|
||||
}, -- cPainting
|
||||
|
||||
cItemGrid =
|
||||
{
|
||||
Desc = [[This class represents a 2D array of items. It is used as the underlying storage and API for all cases that use a grid of items:
|
||||
|
@ -34,6 +34,7 @@ $cfile "../Entities/Entity.h"
|
||||
$cfile "../Entities/Floater.h"
|
||||
$cfile "../Entities/Pawn.h"
|
||||
$cfile "../Entities/Player.h"
|
||||
$cfile "../Entities/Painting.h"
|
||||
$cfile "../Entities/Pickup.h"
|
||||
$cfile "../Entities/ProjectileEntity.h"
|
||||
$cfile "../Entities/TNTEntity.h"
|
||||
|
@ -266,7 +266,7 @@ enum ENUM_ITEM_ID
|
||||
E_ITEM_FLINT = 318,
|
||||
E_ITEM_RAW_PORKCHOP = 319,
|
||||
E_ITEM_COOKED_PORKCHOP = 320,
|
||||
E_ITEM_PAINTINGS = 321,
|
||||
E_ITEM_PAINTING = 321,
|
||||
E_ITEM_GOLDEN_APPLE = 322,
|
||||
E_ITEM_SIGN = 323,
|
||||
E_ITEM_WOODEN_DOOR = 324,
|
||||
|
@ -52,6 +52,7 @@ if (NOT MSVC)
|
||||
Entities/Entity.h
|
||||
Entities/Floater.h
|
||||
Entities/Pawn.h
|
||||
Entities/Painting.h
|
||||
Entities/Pickup.h
|
||||
Entities/Player.h
|
||||
Entities/ProjectileEntity.h
|
||||
|
@ -2091,6 +2091,14 @@ void cClientHandle::SendPickupSpawn(const cPickup & a_Pickup)
|
||||
|
||||
|
||||
|
||||
void cClientHandle::SendPaintingSpawn(const cPainting & a_Painting)
|
||||
{
|
||||
m_Protocol->SendPaintingSpawn(a_Painting);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cClientHandle::SendEntityAnimation(const cEntity & a_Entity, char a_Animation)
|
||||
{
|
||||
|
@ -27,6 +27,7 @@ class cInventory;
|
||||
class cMonster;
|
||||
class cPawn;
|
||||
class cExpOrb;
|
||||
class cPainting;
|
||||
class cPickup;
|
||||
class cPlayer;
|
||||
class cProtocol;
|
||||
@ -111,6 +112,7 @@ public:
|
||||
void SendGameMode (eGameMode a_GameMode);
|
||||
void SendHealth (void);
|
||||
void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item);
|
||||
void SendPaintingSpawn (const cPainting & a_Painting);
|
||||
void SendPickupSpawn (const cPickup & a_Pickup);
|
||||
void SendEntityAnimation (const cEntity & a_Entity, char a_Animation);
|
||||
void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount);
|
||||
|
@ -81,6 +81,7 @@ public:
|
||||
etProjectile,
|
||||
etExpOrb,
|
||||
etFloater,
|
||||
etPainting,
|
||||
|
||||
// Common variations
|
||||
etMob = etMonster, // DEPRECATED, use etMonster instead!
|
||||
@ -139,6 +140,7 @@ public:
|
||||
bool IsProjectile (void) const { return (m_EntityType == etProjectile); }
|
||||
bool IsExpOrb (void) const { return (m_EntityType == etExpOrb); }
|
||||
bool IsFloater (void) const { return (m_EntityType == etFloater); }
|
||||
bool IsPainting (void) const { return (m_EntityType == etPainting); }
|
||||
|
||||
/// Returns true if the entity is of the specified class or a subclass (cPawn's IsA("cEntity") returns true)
|
||||
virtual bool IsA(const char * a_ClassName) const;
|
||||
|
43
src/Entities/Painting.cpp
Normal file
43
src/Entities/Painting.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "Painting.h"
|
||||
#include "ClientHandle.h"
|
||||
#include "Player.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cPainting::cPainting(const AString & a_Name, int a_Direction, double a_X, double a_Y, double a_Z)
|
||||
: cEntity(etPainting, a_X, a_Y, a_Z, 1, 1),
|
||||
m_Name(a_Name),
|
||||
m_Direction(a_Direction)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPainting::SpawnOn(cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendPaintingSpawn(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPainting::GetDrops(cItems & a_Items, cEntity * a_Killer)
|
||||
{
|
||||
if ((a_Killer != NULL) && a_Killer->IsPlayer() && !((cPlayer *)a_Killer)->IsGameModeCreative())
|
||||
{
|
||||
a_Items.push_back(cItem(E_ITEM_PAINTING));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
42
src/Entities/Painting.h
Normal file
42
src/Entities/Painting.h
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Entity.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// tolua_begin
|
||||
class cPainting :
|
||||
public cEntity
|
||||
{
|
||||
// tolua_end
|
||||
typedef cEntity super;
|
||||
|
||||
public:
|
||||
CLASS_PROTODEF(cPainting);
|
||||
|
||||
cPainting(const AString & a_Name, int a_Direction, double a_X, double a_Y, double a_Z);
|
||||
const AString & GetName(void) const { return m_Name; } // tolua_export
|
||||
int GetDirection(void) const { return m_Direction; } // tolua_export
|
||||
|
||||
private:
|
||||
|
||||
virtual void SpawnOn(cClientHandle & a_Client) override;
|
||||
virtual void Tick(float a_Dt, cChunk & a_Chunk) override {};
|
||||
virtual void GetDrops(cItems & a_Items, cEntity * a_Killer) override;
|
||||
virtual void KilledBy(cEntity * a_Killer) override
|
||||
{
|
||||
super::KilledBy(a_Killer);
|
||||
Destroy();
|
||||
}
|
||||
|
||||
AString m_Name;
|
||||
int m_Direction;
|
||||
|
||||
}; // tolua_export
|
||||
|
||||
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "ItemLighter.h"
|
||||
#include "ItemMinecart.h"
|
||||
#include "ItemNetherWart.h"
|
||||
#include "ItemPainting.h"
|
||||
#include "ItemPickaxe.h"
|
||||
#include "ItemThrowable.h"
|
||||
#include "ItemRedstoneDust.h"
|
||||
@ -106,6 +107,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
|
||||
case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType);
|
||||
case E_ITEM_FLOWER_POT: return new cItemFlowerPotHandler(a_ItemType);
|
||||
case E_ITEM_NETHER_WART: return new cItemNetherWartHandler(a_ItemType);
|
||||
case E_ITEM_PAINTING: return new cItemPaintingHandler(a_ItemType);
|
||||
case E_ITEM_REDSTONE_DUST: return new cItemRedstoneDustHandler(a_ItemType);
|
||||
case E_ITEM_REDSTONE_REPEATER: return new cItemRedstoneRepeaterHandler(a_ItemType);
|
||||
case E_ITEM_SHEARS: return new cItemShearsHandler(a_ItemType);
|
||||
@ -305,7 +307,7 @@ char cItemHandler::GetMaxStackSize(void)
|
||||
case E_ITEM_BOWL: return 64;
|
||||
case E_ITEM_BREAD: return 64;
|
||||
case E_ITEM_BREWING_STAND: return 64;
|
||||
case E_ITEM_BUCKET: return 1; // TODO: change this to 16 when turning compatibility to 1.3
|
||||
case E_ITEM_BUCKET: return 16;
|
||||
case E_ITEM_CARROT: return 64;
|
||||
case E_ITEM_CAULDRON: return 64;
|
||||
case E_ITEM_CLAY: return 64;
|
||||
@ -349,7 +351,7 @@ char cItemHandler::GetMaxStackSize(void)
|
||||
case E_ITEM_MELON_SLICE: return 64;
|
||||
case E_ITEM_NETHER_BRICK: return 64;
|
||||
case E_ITEM_NETHER_WART: return 64;
|
||||
case E_ITEM_PAINTINGS: return 64;
|
||||
case E_ITEM_PAINTING: return 64;
|
||||
case E_ITEM_PAPER: return 64;
|
||||
case E_ITEM_POISONOUS_POTATO: return 64;
|
||||
case E_ITEM_POTATO: return 64;
|
||||
|
98
src/Items/ItemPainting.h
Normal file
98
src/Items/ItemPainting.h
Normal file
@ -0,0 +1,98 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ItemHandler.h"
|
||||
#include "../World.h"
|
||||
#include "../Entities/Player.h"
|
||||
#include "../Entities/Painting.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cItemPaintingHandler :
|
||||
public cItemHandler
|
||||
{
|
||||
public:
|
||||
cItemPaintingHandler(int a_ItemType)
|
||||
: cItemHandler(a_ItemType)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) override
|
||||
{
|
||||
if (a_Dir == BLOCK_FACE_NONE)
|
||||
{
|
||||
// Client sends this if clicked on top or bottom face
|
||||
return false;
|
||||
}
|
||||
|
||||
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_Dir); // Make sure block that will be occupied is free
|
||||
BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
|
||||
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_Dir, true); // We want the clicked block, so go back again
|
||||
|
||||
if (Block == E_BLOCK_AIR)
|
||||
{
|
||||
int Dir = 0;
|
||||
|
||||
// The client uses different values for painting directions and block faces. Our constants are for the block faces, so we convert them here to painting faces
|
||||
switch (a_Dir)
|
||||
{
|
||||
case BLOCK_FACE_ZP: break; // Initialised to zero
|
||||
case BLOCK_FACE_ZM: Dir = 2; break;
|
||||
case BLOCK_FACE_XM: Dir = 1; break;
|
||||
case BLOCK_FACE_XP: Dir = 3; break;
|
||||
default: ASSERT(!"Unhandled block face when trying spawn painting!"); return false;
|
||||
}
|
||||
|
||||
static const struct // Define all the possible painting titles
|
||||
{
|
||||
AString Title;
|
||||
} gPaintingTitlesList[] =
|
||||
{
|
||||
{ "Kebab" },
|
||||
{ "Aztec" },
|
||||
{ "Alban" },
|
||||
{ "Aztec2" },
|
||||
{ "Bomb" },
|
||||
{ "Plant" },
|
||||
{ "Wasteland" },
|
||||
{ "Wanderer" },
|
||||
{ "Graham" },
|
||||
{ "Pool" },
|
||||
{ "Courbet" },
|
||||
{ "Sunset" },
|
||||
{ "Sea" },
|
||||
{ "Creebet" },
|
||||
{ "Match" },
|
||||
{ "Bust" },
|
||||
{ "Stage" },
|
||||
{ "Void" },
|
||||
{ "SkullAndRoses" },
|
||||
{ "Wither" },
|
||||
{ "Fighters" },
|
||||
{ "Skeleton" },
|
||||
{ "DonkeyKong" },
|
||||
{ "Pointer" },
|
||||
{ "Pigscene" },
|
||||
{ "BurningSkull" }
|
||||
};
|
||||
|
||||
cPainting * Painting = new cPainting(gPaintingTitlesList[a_World->GetTickRandomNumber(ARRAYCOUNT(gPaintingTitlesList) - 1)].Title, Dir, a_BlockX, a_BlockY, a_BlockZ);
|
||||
Painting->Initialize(a_World);
|
||||
|
||||
if (!a_Player->IsGameModeCreative())
|
||||
{
|
||||
a_Player->GetInventory().RemoveOneEquippedItem();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -24,6 +24,7 @@ class cWindow;
|
||||
class cInventory;
|
||||
class cPawn;
|
||||
class cPickup;
|
||||
class cPainting;
|
||||
class cWorld;
|
||||
class cMonster;
|
||||
class cChunkDataSerializer;
|
||||
@ -81,6 +82,7 @@ public:
|
||||
virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) = 0;
|
||||
virtual void SendKeepAlive (int a_PingID) = 0;
|
||||
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) = 0;
|
||||
virtual void SendPaintingSpawn (const cPainting & a_Painting) = 0;
|
||||
virtual void SendPickupSpawn (const cPickup & a_Pickup) = 0;
|
||||
virtual void SendPlayerAbilities (void) = 0;
|
||||
virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) = 0;
|
||||
|
@ -56,6 +56,7 @@ public:
|
||||
virtual void SendKeepAlive (int a_PingID) override;
|
||||
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
|
||||
virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override;
|
||||
virtual void SendPaintingSpawn (const cPainting & a_Painting) override {};
|
||||
virtual void SendPickupSpawn (const cPickup & a_Pickup) override;
|
||||
virtual void SendPlayerAbilities (void) override {} // This protocol doesn't support such message
|
||||
virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override;
|
||||
|
@ -21,6 +21,7 @@ Implements the 1.7.x protocol classes:
|
||||
#include "../Entities/ExpOrb.h"
|
||||
#include "../Entities/Minecart.h"
|
||||
#include "../Entities/FallingBlock.h"
|
||||
#include "../Entities/Painting.h"
|
||||
#include "../Entities/Pickup.h"
|
||||
#include "../Entities/Player.h"
|
||||
#include "../Mobs/IncludeAllMonsters.h"
|
||||
@ -569,6 +570,20 @@ void cProtocol172::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
|
||||
|
||||
|
||||
|
||||
void cProtocol172::SendPaintingSpawn(const cPainting & a_Painting)
|
||||
{
|
||||
cPacketizer Pkt(*this, 0x10); // Spawn Painting packet
|
||||
Pkt.WriteVarInt(a_Painting.GetUniqueID());
|
||||
Pkt.WriteString(a_Painting.GetName().c_str());
|
||||
Pkt.WriteInt((int)a_Painting.GetPosX());
|
||||
Pkt.WriteInt((int)a_Painting.GetPosY());
|
||||
Pkt.WriteInt((int)a_Painting.GetPosZ());
|
||||
Pkt.WriteInt(a_Painting.GetDirection());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol172::SendPickupSpawn(const cPickup & a_Pickup)
|
||||
{
|
||||
|
@ -87,6 +87,7 @@ public:
|
||||
virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override;
|
||||
virtual void SendKeepAlive (int a_PingID) override;
|
||||
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
|
||||
virtual void SendPaintingSpawn (const cPainting & a_Painting) override;
|
||||
virtual void SendPickupSpawn (const cPickup & a_Pickup) override;
|
||||
virtual void SendPlayerAbilities (void) override;
|
||||
virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override;
|
||||
|
@ -405,6 +405,14 @@ void cProtocolRecognizer::SendParticleEffect(const AString & a_ParticleName, flo
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendPaintingSpawn(const cPainting & a_Painting)
|
||||
{
|
||||
m_Protocol->SendPaintingSpawn(a_Painting);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendPickupSpawn(const cPickup & a_Pickup)
|
||||
{
|
||||
|
@ -91,6 +91,7 @@ public:
|
||||
virtual void SendKeepAlive (int a_PingID) override;
|
||||
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
|
||||
virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override;
|
||||
virtual void SendPaintingSpawn (const cPainting & a_Painting) override;
|
||||
virtual void SendPickupSpawn (const cPickup & a_Pickup) override;
|
||||
virtual void SendPlayerAbilities (void) override;
|
||||
virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override;
|
||||
|
@ -627,6 +627,7 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity)
|
||||
case cEntity::etProjectile: AddProjectileEntity ((cProjectileEntity *)a_Entity); break;
|
||||
case cEntity::etTNT: /* TODO */ break;
|
||||
case cEntity::etExpOrb: /* TODO */ break;
|
||||
case cEntity::etPainting: /* TODO */ break;
|
||||
case cEntity::etPlayer: return; // Players aren't saved into the world
|
||||
default:
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user