1
0

Merged branch "branches/hooks" into "trunk".

git-svn-id: http://mc-server.googlecode.com/svn/trunk@1139 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com 2013-01-12 04:46:01 +00:00
parent 71d71410fd
commit 43e6840719
113 changed files with 3762 additions and 5535 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* /*
** Lua binding: AllToLua ** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 01/04/13 18:19:46. ** Generated automatically by tolua++-1.0.92 on 01/12/13 17:47:55.
*/ */
/* Exported function */ /* Exported function */

View File

@ -255,7 +255,7 @@ AString ItemTypeToString(short a_ItemType)
AString ItemToFullString(const cItem & a_Item) AString ItemToFullString(const cItem & a_Item)
{ {
AString res; AString res;
Printf(res, "%s:%d * %d", ItemToString(a_Item).c_str(), a_Item.m_ItemHealth, a_Item.m_ItemCount); Printf(res, "%s:%d * %d", ItemToString(a_Item).c_str(), a_Item.m_ItemDamage, a_Item.m_ItemCount);
return res; return res;
} }

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
//tolua_begin // tolua_begin
enum ENUM_BLOCK_ID enum ENUM_BLOCK_ID
{ {
E_BLOCK_AIR = 0, E_BLOCK_AIR = 0,
@ -161,10 +161,15 @@ enum ENUM_BLOCK_ID
E_BLOCK_POTATOES = 142, E_BLOCK_POTATOES = 142,
E_BLOCK_WOODEN_BUTTON = 143, E_BLOCK_WOODEN_BUTTON = 143,
E_BLOCK_HEAD = 144, E_BLOCK_HEAD = 144,
};
//tolua_end
//tolua_begin // Keep these two as the last values, without a number - they will get their correct number assigned automagically by C++
// IsValidBlock() depends on this
E_BLOCK_NUMBER_OF_TYPES, ///< Number of individual (different) blocktypes
E_BLOCK_MAX_TYPE_ID = E_BLOCK_NUMBER_OF_TYPES - 1 ///< Maximum BlockType number used
};
// tolua_end
// tolua_begin
enum ENUM_ITEM_ID enum ENUM_ITEM_ID
{ {
E_ITEM_EMPTY = -1, E_ITEM_EMPTY = -1,
@ -303,6 +308,8 @@ enum ENUM_ITEM_ID
E_ITEM_TRIPWIRE = 132, E_ITEM_TRIPWIRE = 132,
E_ITEM_EMERALD_BLOCK = 133, E_ITEM_EMERALD_BLOCK = 133,
E_ITEM_FIRST = 256, // First true item type
E_ITEM_IRON_SHOVEL = 256, E_ITEM_IRON_SHOVEL = 256,
E_ITEM_IRON_PICKAXE = 257, E_ITEM_IRON_PICKAXE = 257,
E_ITEM_IRON_AXE = 258, E_ITEM_IRON_AXE = 258,
@ -446,6 +453,12 @@ enum ENUM_ITEM_ID
E_ITEM_FIREWORK_STAR = 402, E_ITEM_FIREWORK_STAR = 402,
E_ITEM_ENCHANTED_BOOK = 403, E_ITEM_ENCHANTED_BOOK = 403,
// Keep these two as the last values of the consecutive list, without a number - they will get their correct number assigned automagically by C++
// IsValidItem() depends on this!
E_ITEM_NUMBER_OF_CONSECUTIVE_TYPES, ///< Number of individual (different) consecutive itemtypes
E_ITEM_MAX_CONSECUTIVE_TYPE_ID = E_ITEM_NUMBER_OF_CONSECUTIVE_TYPES - 1, ///< Maximum consecutive ItemType number used
E_ITEM_FIRST_DISC = 2256,
E_ITEM_13_DISC = 2256, E_ITEM_13_DISC = 2256,
E_ITEM_CAT_DISC = 2257, E_ITEM_CAT_DISC = 2257,
E_ITEM_BLOCKS_DISC = 2258, E_ITEM_BLOCKS_DISC = 2258,
@ -457,7 +470,12 @@ enum ENUM_ITEM_ID
E_ITEM_STRAD_DISC = 2264, E_ITEM_STRAD_DISC = 2264,
E_ITEM_WARD_DISC = 2265, E_ITEM_WARD_DISC = 2265,
E_ITEM_11_DISC = 2266, E_ITEM_11_DISC = 2266,
E_ITEM_WAIT_DISC = 2267 E_ITEM_WAIT_DISC = 2267,
// Keep these two as the last values of the disc list, without a number - they will get their correct number assigned automagically by C++
// IsValidItem() depends on this!
E_ITEM_LAST_DISC_PLUS_ONE, ///< Useless, really, but needs to be present for the following value
E_ITEM_LAST_DISC = E_ITEM_LAST_DISC_PLUS_ONE - 1 ///< Maximum disc itemtype number used
}; };
@ -667,7 +685,7 @@ enum
E_ENTITY_TYPE_IRON_GOLEM = 99, E_ENTITY_TYPE_IRON_GOLEM = 99,
E_ENTITY_TYPE_VILLAGER = 120, E_ENTITY_TYPE_VILLAGER = 120,
} ; } ;
//tolua_end // tolua_end

View File

@ -5,25 +5,18 @@
void cBlockBedHandler::PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) void cBlockBedHandler::OnPlacedByPlayer(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
)
{ {
if (a_Dir != 1) // Can only be placed on the floor if (a_BlockMeta < 8)
{ {
return; Vector3i Direction = MetaDataToDirection(a_BlockMeta);
a_World->SetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z, E_BLOCK_BED, a_BlockMeta | 0x8);
} }
NIBBLETYPE Meta = RotationToMetaData( a_Player->GetRotation() );
Vector3i Direction = MetaDataToDirection( Meta );
if (a_World->GetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z) != E_BLOCK_AIR)
{
return;
}
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_BED, Meta);
a_World->SetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z, E_BLOCK_BED, Meta | 0x8);
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
} }
@ -58,13 +51,13 @@ void cBlockBedHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY,
void cBlockBedHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) void cBlockBedHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
{ {
NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
if (Meta & 0x8) if (Meta & 0x8)
{ {
// Is pillow // Is pillow
a_World->BroadcastUseBed( *a_Player, a_BlockX, a_BlockY, a_BlockZ ); a_World->BroadcastUseBed(*a_Player, a_BlockX, a_BlockY, a_BlockZ);
} }
else else
{ {
@ -72,9 +65,8 @@ void cBlockBedHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, i
Vector3i Direction = MetaDataToDirection( Meta & 0x7 ); Vector3i Direction = MetaDataToDirection( Meta & 0x7 );
if (a_World->GetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z) == E_BLOCK_BED) // Must always use pillow location for sleeping if (a_World->GetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z) == E_BLOCK_BED) // Must always use pillow location for sleeping
{ {
a_World->BroadcastUseBed(*a_Player, a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z ); a_World->BroadcastUseBed(*a_Player, a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z);
} }
} }
} }

View File

@ -20,9 +20,9 @@ public:
} }
virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override; virtual void OnPlacedByPlayer(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override;
virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override;
virtual bool IsUseable(void) override virtual bool IsUseable(void) override

View File

@ -19,41 +19,89 @@ public:
} }
virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
a_BlockType = m_BlockType;
// Is there a doublechest already next to this block?
if (!CanBeAt(a_World, a_BlockX, a_BlockY, a_BlockZ))
{
// Yup, cannot form a triple-chest, refuse:
return false;
}
// Check if this forms a doublechest, if so, need to adjust the meta:
cBlockArea Area;
if (!Area.Read(a_World, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1))
{
return false;
}
float rot = a_Player->GetRotation();
if (
(Area.GetRelBlockType(0, 0, 1) == E_BLOCK_CHEST) ||
(Area.GetRelBlockType(2, 0, 1) == E_BLOCK_CHEST)
)
{
a_BlockMeta = ((rot >= -90) && (rot < 90)) ? 2 : 3;
return true;
}
if (
(Area.GetRelBlockType(0, 0, 1) == E_BLOCK_CHEST) ||
(Area.GetRelBlockType(2, 0, 1) == E_BLOCK_CHEST)
)
{
a_BlockMeta = (rot < 0) ? 4 : 5;
return true;
}
// Single chest, get meta from rotation only
a_BlockMeta = RotationToMetaData(rot);
return true;
}
virtual void OnPlacedByPlayer(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
) override
{ {
// Check if this forms a doublechest, if so, need to adjust the meta: // Check if this forms a doublechest, if so, need to adjust the meta:
cBlockArea Area; cBlockArea Area;
if (Area.Read(a_World, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1)) if (!Area.Read(a_World, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1))
{ {
float rot = a_Player->GetRotation(); return;
// Choose meta from player rotation, choose only between 2 or 3
NIBBLETYPE NewMeta = ((rot >= -90) && (rot < 90)) ? 2 : 3;
if (
CheckAndAdjustNeighbor(a_World, Area, 0, 1, NewMeta) ||
CheckAndAdjustNeighbor(a_World, Area, 2, 1, NewMeta)
)
{
// Forming a double chest in the X direction
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, NewMeta);
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
return;
}
// Choose meta from player rotation, choose only between 4 or 5
NewMeta = (rot < 0) ? 4 : 5;
if (
CheckAndAdjustNeighbor(a_World, Area, 1, 0, NewMeta) ||
CheckAndAdjustNeighbor(a_World, Area, 2, 2, NewMeta)
)
{
// Forming a double chest in the Z direction
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, NewMeta);
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
return;
}
} }
// Single chest or unable to read neighbors (don't really care, then):
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, RotationToMetaData(a_Player->GetRotation())); float rot = a_Player->GetRotation();
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); // Choose meta from player rotation, choose only between 2 or 3
NIBBLETYPE NewMeta = ((rot >= -90) && (rot < 90)) ? 2 : 3;
if (
CheckAndAdjustNeighbor(a_World, Area, 0, 1, NewMeta) ||
CheckAndAdjustNeighbor(a_World, Area, 2, 1, NewMeta)
)
{
// Forming a double chest in the X direction
return;
}
// Choose meta from player rotation, choose only between 4 or 5
NewMeta = (rot < 0) ? 4 : 5;
if (
CheckAndAdjustNeighbor(a_World, Area, 1, 0, NewMeta) ||
CheckAndAdjustNeighbor(a_World, Area, 2, 2, NewMeta)
)
{
// Forming a double chest in the Z direction
return;
}
// Single chest, no further processing needed
} }

View File

@ -14,16 +14,25 @@ class cBlockDispenserHandler :
public cBlockEntityHandler public cBlockEntityHandler
{ {
public: public:
cBlockDispenserHandler(BLOCKTYPE a_BlockType) cBlockDispenserHandler(BLOCKTYPE a_BlockType) :
: cBlockEntityHandler(a_BlockType) cBlockEntityHandler(a_BlockType)
{ {
} }
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override
virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0)); a_BlockType = m_BlockType;
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0);
return true;
} }
} ;
};

View File

@ -19,18 +19,9 @@ cBlockDoorHandler::cBlockDoorHandler(BLOCKTYPE a_BlockType)
void cBlockDoorHandler::OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir)
{
}
void cBlockDoorHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) void cBlockDoorHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
char OldMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); NIBBLETYPE OldMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
if (OldMeta & 8) if (OldMeta & 8)
{ {
@ -54,7 +45,7 @@ void cBlockDoorHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY
void cBlockDoorHandler::OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) void cBlockDoorHandler::OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
{ {
cDoors::ChangeDoor(a_World, a_BlockX, a_BlockY, a_BlockZ); cDoors::ChangeDoor(a_World, a_BlockX, a_BlockY, a_BlockZ);
} }
@ -63,23 +54,24 @@ void cBlockDoorHandler::OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX
void cBlockDoorHandler::PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) void cBlockDoorHandler::OnPlacedByPlayer(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
)
{ {
if (a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ) == E_BLOCK_AIR) NIBBLETYPE a_TopBlockMeta = 8;
if (
(a_BlockMeta == 0) && (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) == m_BlockType) ||
(a_BlockMeta == 1) && (a_World->GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) == m_BlockType) ||
(a_BlockMeta == 2) && (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) == m_BlockType) ||
(a_BlockMeta == 3) && (a_World->GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) == m_BlockType)
)
{ {
a_BlockMeta = cDoors::RotationToMetaData(a_Player->GetRotation()); a_TopBlockMeta = 9;
char a_TopBlockMeta = 8;
if( (a_BlockMeta == 0) && (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) == m_BlockType) ||
(a_BlockMeta == 1) && (a_World->GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) == m_BlockType) ||
(a_BlockMeta == 2) && (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) == m_BlockType) ||
(a_BlockMeta == 3) && (a_World->GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) == m_BlockType))
{
a_TopBlockMeta = 9;
}
a_World->SetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, a_TopBlockMeta);
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, a_BlockMeta);
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
} }
a_World->SetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, a_TopBlockMeta);
} }

View File

@ -3,6 +3,8 @@
#include "BlockHandler.h" #include "BlockHandler.h"
#include "../World.h" #include "../World.h"
#include "../Doors.h"
#include "../Player.h"
@ -13,32 +15,89 @@ class cBlockDoorHandler :
{ {
public: public:
cBlockDoorHandler(BLOCKTYPE a_BlockType); cBlockDoorHandler(BLOCKTYPE a_BlockType);
virtual void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) override;
virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override;
virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override;
virtual const char * GetStepSound(void) override; virtual const char * GetStepSound(void) override;
virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
// If clicking a bottom face, place the door one block lower:
if (a_BlockFace == BLOCK_FACE_BOTTOM)
{
a_BlockY--;
}
if (
!CanReplaceBlock(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ)) ||
!CanReplaceBlock(a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))
)
{
return false;
}
a_BlockType = m_BlockType;
a_BlockMeta = cDoors::RotationToMetaData(a_Player->GetRotation());
return true;
}
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{ {
a_Pickups.push_back(cItem((m_BlockType == E_BLOCK_WOODEN_DOOR) ? E_ITEM_WOODEN_DOOR : E_ITEM_IRON_DOOR, 1, 0)); a_Pickups.push_back(cItem((m_BlockType == E_BLOCK_WOODEN_DOOR) ? E_ITEM_WOODEN_DOOR : E_ITEM_IRON_DOOR, 1, 0));
} }
virtual bool IsUseable() override
virtual void OnPlacedByPlayer(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
) override;
virtual bool IsUseable(void) override
{ {
return true; return true;
} }
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override;
virtual bool CanBePlacedOnSide(void) override virtual bool CanBePlacedOnSide(void) override
{ {
return false; return false;
} }
virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
{ {
return (a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) != E_BLOCK_AIR); return (a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) != E_BLOCK_AIR);
} }
bool CanReplaceBlock(BLOCKTYPE a_BlockType)
{
switch (a_BlockType)
{
case E_BLOCK_AIR:
case E_BLOCK_TALL_GRASS:
case E_BLOCK_WATER:
case E_BLOCK_STATIONARY_WATER:
case E_BLOCK_LAVA:
case E_BLOCK_STATIONARY_LAVA:
case E_BLOCK_SNOW:
case E_BLOCK_FIRE:
{
return true;
}
}
return false;
}
} ; } ;

View File

@ -15,7 +15,7 @@ public:
{ {
} }
virtual void OnUse(cWorld * a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override virtual void OnUse(cWorld * a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
{ {
a_World->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); a_World->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ);
} }

View File

@ -12,41 +12,44 @@ class cBlockFenceGateHandler :
public cBlockHandler public cBlockHandler
{ {
public: public:
cBlockFenceGateHandler(BLOCKTYPE a_BlockType) cBlockFenceGateHandler(BLOCKTYPE a_BlockType) :
: cBlockHandler(a_BlockType) cBlockHandler(a_BlockType)
{ {
} }
void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir)
{
} virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
a_BlockType = m_BlockType;
a_BlockMeta = cDoors::RotationToMetaData(a_Player->GetRotation() + 270); a_BlockMeta = cDoors::RotationToMetaData(a_Player->GetRotation() + 270);
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, a_BlockMeta); return true;
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
} }
void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
{ {
char OldMetaData = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); NIBBLETYPE OldMetaData = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
char NewMetaData = cDoors::RotationToMetaData(a_Player->GetRotation() + 270); NIBBLETYPE NewMetaData = cDoors::RotationToMetaData(a_Player->GetRotation() + 270);
OldMetaData ^= 4; //Toggle the gate OldMetaData ^= 4; //Toggle the gate
if((OldMetaData & 1) == (NewMetaData & 1)) if ((OldMetaData & 1) == (NewMetaData & 1))
{ {
//Standing in front of the gate - apply new direction // Standing in front of the gate - apply new direction
a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, (OldMetaData & 4) | (NewMetaData & 3)); a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, (OldMetaData & 4) | (NewMetaData & 3));
} }
else else
{ {
//Standing aside - use last direction // Standing aside - use last direction
a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, OldMetaData); a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, OldMetaData);
} }
} }
virtual bool IsUseable() override
virtual bool IsUseable(void) override
{ {
return true; return true;
} }

View File

@ -11,17 +11,21 @@ class cBlockFlowerPotHandler :
public cBlockHandler public cBlockHandler
{ {
public: public:
cBlockFlowerPotHandler(BLOCKTYPE a_BlockType) cBlockFlowerPotHandler(BLOCKTYPE a_BlockType) :
: cBlockHandler(a_BlockType) cBlockHandler(a_BlockType)
{ {
} }
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{ {
a_Pickups.push_back(cItem(E_ITEM_FLOWER_POT, 1, 0)); a_Pickups.push_back(cItem(E_ITEM_FLOWER_POT, 1, 0));
if( a_BlockMeta == 0 ) return; if (a_BlockMeta == 0)
{
return;
}
cItem Plant; cItem Plant;
switch( a_BlockMeta ) switch (a_BlockMeta)
{ {
case 1: Plant = cItem(E_ITEM_RED_ROSE, 1, 0); break; case 1: Plant = cItem(E_ITEM_RED_ROSE, 1, 0); break;
case 2: Plant = cItem(E_ITEM_YELLOW_FLOWER, 1, 0); break; case 2: Plant = cItem(E_ITEM_YELLOW_FLOWER, 1, 0); break;
@ -34,21 +38,28 @@ public:
case 9: Plant = cItem(E_ITEM_CACTUS, 1, 0); break; case 9: Plant = cItem(E_ITEM_CACTUS, 1, 0); break;
case 10: Plant = cItem(E_BLOCK_DEAD_BUSH, 1, 0); break; case 10: Plant = cItem(E_BLOCK_DEAD_BUSH, 1, 0); break;
case 11: Plant = cItem(E_BLOCK_TALL_GRASS, 1, E_META_TALL_GRASS_FERN); break; case 11: Plant = cItem(E_BLOCK_TALL_GRASS, 1, E_META_TALL_GRASS_FERN); break;
default: return;
} }
a_Pickups.push_back(Plant); a_Pickups.push_back(Plant);
} }
void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
char Meta = a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ ); NIBBLETYPE Meta = a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ );
if( Meta ) return; if (Meta != 0)
switch( a_Player->GetEquippedItem().m_ItemType ) {
// Already filled
return;
}
switch (a_Player->GetEquippedItem().m_ItemType)
{ {
case E_ITEM_RED_ROSE: Meta = 1; break; case E_ITEM_RED_ROSE: Meta = 1; break;
case E_ITEM_YELLOW_FLOWER: Meta = 2; break; case E_ITEM_YELLOW_FLOWER: Meta = 2; break;
case E_ITEM_SAPLING: case E_ITEM_SAPLING:
{ {
switch( a_Player->GetEquippedItem().m_ItemDamage ) switch (a_Player->GetEquippedItem().m_ItemDamage)
{ {
case E_META_SAPLING_APPLE: Meta = 3; break; case E_META_SAPLING_APPLE: Meta = 3; break;
case E_META_SAPLING_CONIFER: Meta = 4; break; case E_META_SAPLING_CONIFER: Meta = 4; break;
@ -62,17 +73,29 @@ public:
case E_ITEM_CACTUS: Meta = 9; break; case E_ITEM_CACTUS: Meta = 9; break;
case E_BLOCK_DEAD_BUSH: Meta = 10; break; case E_BLOCK_DEAD_BUSH: Meta = 10; break;
case E_BLOCK_TALL_GRASS: case E_BLOCK_TALL_GRASS:
if( a_Player->GetEquippedItem().m_ItemDamage == E_META_TALL_GRASS_FERN ) Meta = 11; break; {
if (a_Player->GetEquippedItem().m_ItemDamage == E_META_TALL_GRASS_FERN)
{
Meta = 11;
}
else
{
return;
}
break;
}
} }
if(a_Player->GetGameMode() != eGameMode_Creative)
if (a_Player->GetGameMode() != eGameMode_Creative)
{ {
cItem Item(a_Player->GetEquippedItem().m_ItemType, 1); cItem Item(a_Player->GetEquippedItem().m_ItemType, 1);
a_Player->GetInventory().RemoveItem(Item); a_Player->GetInventory().RemoveItem(Item);
} }
a_World->SetBlockMeta( a_BlockX, a_BlockY, a_BlockZ, Meta ); a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
} }
virtual bool IsUseable() override
virtual bool IsUseable(void) override
{ {
return true; return true;
} }

View File

@ -14,8 +14,8 @@ class cBlockFurnaceHandler :
public cBlockEntityHandler public cBlockEntityHandler
{ {
public: public:
cBlockFurnaceHandler(BLOCKTYPE a_BlockType) cBlockFurnaceHandler(BLOCKTYPE a_BlockType) :
: cBlockEntityHandler(a_BlockType) cBlockEntityHandler(a_BlockType)
{ {
} }
@ -26,10 +26,16 @@ public:
} }
virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0)); a_BlockType = m_BlockType;
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0);
return true;
} }
} ; } ;

View File

@ -207,6 +207,23 @@ cBlockHandler::cBlockHandler(BLOCKTYPE a_BlockType)
bool cBlockHandler::GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
)
{
// By default, all blocks can be placed and the meta is copied over from the item's damage value:
a_BlockType = m_BlockType;
a_BlockMeta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage & 0x0f);
return true;
}
void cBlockHandler::OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) void cBlockHandler::OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
} }
@ -215,7 +232,7 @@ void cBlockHandler::OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a
void cBlockHandler::OnPlacedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) void cBlockHandler::OnPlacedByPlayer(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{ {
} }
@ -231,9 +248,9 @@ void cBlockHandler::OnDestroyedByPlayer(cWorld *a_World, cPlayer * a_Player, int
void cBlockHandler::OnPlaced(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) void cBlockHandler::OnPlaced(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{ {
//Notify the neighbors // Notify the neighbors
NeighborChanged(a_World, a_BlockX - 1, a_BlockY, a_BlockZ); NeighborChanged(a_World, a_BlockX - 1, a_BlockY, a_BlockZ);
NeighborChanged(a_World, a_BlockX + 1, a_BlockY, a_BlockZ); NeighborChanged(a_World, a_BlockX + 1, a_BlockY, a_BlockZ);
NeighborChanged(a_World, a_BlockX, a_BlockY - 1, a_BlockZ); NeighborChanged(a_World, a_BlockX, a_BlockY - 1, a_BlockZ);
@ -248,7 +265,7 @@ void cBlockHandler::OnPlaced(cWorld *a_World, int a_BlockX, int a_BlockY, int a_
void cBlockHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) void cBlockHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
//Notify the neighbors // Notify the neighbors
NeighborChanged(a_World, a_BlockX - 1, a_BlockY, a_BlockZ); NeighborChanged(a_World, a_BlockX - 1, a_BlockY, a_BlockZ);
NeighborChanged(a_World, a_BlockX + 1, a_BlockY, a_BlockZ); NeighborChanged(a_World, a_BlockX + 1, a_BlockY, a_BlockZ);
NeighborChanged(a_World, a_BlockX, a_BlockY - 1, a_BlockZ); NeighborChanged(a_World, a_BlockX, a_BlockY - 1, a_BlockZ);
@ -286,7 +303,7 @@ void cBlockHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_BlockX,
void cBlockHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) void cBlockHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
{ {
} }
@ -294,16 +311,6 @@ void cBlockHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int
void cBlockHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir)
{
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, a_BlockMeta);
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
}
void cBlockHandler::ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) void cBlockHandler::ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta)
{ {
// Setting the meta to a_BlockMeta keeps most textures. The few other blocks have to override this. // Setting the meta to a_BlockMeta keeps most textures. The few other blocks have to override this.

View File

@ -21,18 +21,35 @@ class cBlockHandler
public: public:
cBlockHandler(BLOCKTYPE a_BlockType); cBlockHandler(BLOCKTYPE a_BlockType);
// Called when the block gets ticked either by a random tick or by a queued tick /// Called when the block gets ticked either by a random tick or by a queued tick
virtual void OnUpdate(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ); virtual void OnUpdate(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ);
/// Called by cBlockHandler::PlaceBlock after the player has placed a new block /** Called before a block is placed into a world.
virtual void OnPlacedByPlayer(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir); The handler should return true to allow placement, false to refuse.
Also, the handler should set a_BlockType and a_BlockMeta to correct values for the newly placed block.
Called by cItemHandler::GetPlacementBlockTypeMeta() if the item is a block
*/
virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
);
/// Called by cWorld::SetBlock() after the block has been set
virtual void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
/// Called by cClientHandle::HandlePlaceBlock() after the player has placed a new block. Called after OnPlaced().
virtual void OnPlacedByPlayer(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
);
/// Called before the player has destroyed a block /// Called before the player has destroyed a block
virtual void OnDestroyedByPlayer(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ); virtual void OnDestroyedByPlayer(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ);
/// Called when a new block was placed. Called before OnPlacedByPlayer
virtual void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir);
/// Called before a block gets destroyed / replaced with air /// Called before a block gets destroyed / replaced with air
virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ); virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ);
@ -46,10 +63,7 @@ public:
virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ); virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ);
/// Called if the user right clicks the block and the block is useable /// Called if the user right clicks the block and the block is useable
virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ); virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ);
/// This function handles the real block placement for the give block by a player and also calls OnPlacedByPlayer()
virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir);
/// Called when the item is mined to convert it into pickups. Pickups may specify multiple items. /// Called when the item is mined to convert it into pickups. Pickups may specify multiple items.
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta); virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta);

View File

@ -19,61 +19,70 @@ public:
} }
virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
if (!LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_Dir)) if (!LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace))
{ {
a_Dir = FindSuitableDirection(a_World, a_BlockX, a_BlockY, a_BlockZ); a_BlockFace = FindSuitableBlockFace(a_World, a_BlockX, a_BlockY, a_BlockZ);
if (a_Dir == BLOCK_FACE_BOTTOM) if (a_BlockFace == BLOCK_FACE_BOTTOM)
{ {
return; return false;
} }
} }
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cLadder::DirectionToMetaData(a_Dir)); a_BlockType = m_BlockType;
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); a_BlockMeta = cLadder::DirectionToMetaData(a_BlockFace);
return true;
} }
/// Finds a suitable Direction for the Ladder. Returns BLOCK_FACE_BOTTOM on failure /// Finds a suitable Direction for the Ladder. Returns BLOCK_FACE_BOTTOM on failure
static char FindSuitableDirection(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) static char FindSuitableBlockFace(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
for (int i = 2; i <= 5; i++) for (int Face = 2; Face <= 5; Face++)
{ {
if (LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, i)) if (LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Face))
{ {
return i; return Face;
} }
} }
return BLOCK_FACE_BOTTOM; return BLOCK_FACE_BOTTOM;
} }
static bool LadderCanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) static bool LadderCanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace)
{ {
if (a_Dir == BLOCK_FACE_BOTTOM || a_Dir == BLOCK_FACE_TOP ) if ((a_BlockFace == BLOCK_FACE_BOTTOM) || (a_BlockFace == BLOCK_FACE_TOP))
{ {
return false; return false;
} }
AddDirection( a_BlockX, a_BlockY, a_BlockZ, a_Dir, true ); AddFaceDirection( a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true);
return g_BlockIsSolid[a_World->GetBlock( a_BlockX, a_BlockY, a_BlockZ)]; return g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ)];
} }
virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override
{ {
if (LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_Dir)) if (LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace))
{
return true; return true;
return FindSuitableDirection(a_World, a_BlockX, a_BlockY, a_BlockZ) != BLOCK_FACE_BOTTOM; }
return (FindSuitableBlockFace(a_World, a_BlockX, a_BlockY, a_BlockZ) != BLOCK_FACE_BOTTOM);
} }
virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
{ {
char Dir = cLadder::MetaDataToDirection(a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ)); char BlockFace = cLadder::MetaDataToDirection(a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ));
return CanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Dir); return CanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, BlockFace);
} }

View File

@ -19,30 +19,12 @@ cBlockLeverHandler::cBlockLeverHandler(BLOCKTYPE a_BlockType)
void cBlockLeverHandler::OnPlaced(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) void cBlockLeverHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
{ {
// Noting needed yet // Flip the ON bit on/off. Using XOR bitwise operation to turn it on/off.
}
void cBlockLeverHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Nothing needed yet
}
void cBlockLeverHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
{
//Flip the ON bit on/off. Using XOR bitwise operation to turn it on/off.
NIBBLETYPE Meta = ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08) & 0x0f); NIBBLETYPE Meta = ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08) & 0x0f);
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta); a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta);
if(Meta & 0x08) if (Meta & 0x08)
{ {
a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f); a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f);
} }
@ -58,17 +40,7 @@ void cBlockLeverHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX,
void cBlockLeverHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) void cBlockLeverHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
OnUse(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ); OnUse(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NONE, 8, 8, 8);
}
void cBlockLeverHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir)
{
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cRedstoneSimulator::LeverDirectionToMetaData(a_Dir));
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
} }

View File

@ -2,6 +2,9 @@
#include "BlockHandler.h" #include "BlockHandler.h"
#include "../World.h" #include "../World.h"
#include "../Simulator/RedstoneSimulator.h"
@ -10,11 +13,9 @@ class cBlockLeverHandler :
{ {
public: public:
cBlockLeverHandler(BLOCKTYPE a_BlockType); cBlockLeverHandler(BLOCKTYPE a_BlockType);
virtual void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) override;
virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override;
virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override;
virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override;
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
@ -30,7 +31,17 @@ public:
} }
virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override; virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
a_BlockType = m_BlockType;
a_BlockMeta = cRedstoneSimulator::LeverDirectionToMetaData(a_BlockFace);
return true;
}
virtual bool DoesAllowBlockOnTop(void) override virtual bool DoesAllowBlockOnTop(void) override
@ -38,8 +49,13 @@ public:
return false; return false;
} }
virtual const char * GetStepSound(void) override virtual const char * GetStepSound(void) override
{ {
return "step.wood"; return "step.wood";
} }
} ; } ;

View File

@ -33,14 +33,6 @@ cBlockPistonHandler::cBlockPistonHandler(BLOCKTYPE a_BlockType)
void cBlockPistonHandler::OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir)
{
}
void cBlockPistonHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) void cBlockPistonHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
char OldMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); char OldMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
@ -60,11 +52,16 @@ void cBlockPistonHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_Bloc
void cBlockPistonHandler::PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) bool cBlockPistonHandler::GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
)
{ {
a_BlockType = E_BLOCK_REDSTONE_REPEATER_OFF;
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cPiston::RotationPitchToMetaData(a_Player->GetRotation(), a_Player->GetPitch())); a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), a_Player->GetPitch());
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); return true;
} }

View File

@ -1,15 +1,28 @@
#pragma once #pragma once
#include "BlockHandler.h" #include "BlockHandler.h"
class cBlockPistonHandler : public cBlockHandler
class cBlockPistonHandler :
public cBlockHandler
{ {
public: public:
cBlockPistonHandler(BLOCKTYPE a_BlockType); cBlockPistonHandler(BLOCKTYPE a_BlockType);
virtual void OnPlaced(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) override;
virtual void OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override;
virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override;
} ;
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override;
};

View File

@ -42,137 +42,144 @@ public:
{ {
} }
virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ)); a_BlockType = m_BlockType;
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); a_BlockMeta = FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ);
NeighborChanged(a_World, a_BlockX - 1, a_BlockY + 1, a_BlockZ); return true;
NeighborChanged(a_World, a_BlockX + 1, a_BlockY + 1, a_BlockZ);
NeighborChanged(a_World, a_BlockX, a_BlockY + 1, a_BlockZ - 1);
NeighborChanged(a_World, a_BlockX, a_BlockY + 1, a_BlockZ + 1);
NeighborChanged(a_World, a_BlockX - 1, a_BlockY - 1, a_BlockZ);
NeighborChanged(a_World, a_BlockX + 1, a_BlockY - 1, a_BlockZ);
NeighborChanged(a_World, a_BlockX, a_BlockY - 1, a_BlockZ - 1);
NeighborChanged(a_World, a_BlockX, a_BlockY - 1, a_BlockZ + 1);
} }
virtual void OnNeighborChanged(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override virtual void OnNeighborChanged(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
{ {
char Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
if(IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ) && Meta != FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ)) if (IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ) && (Meta != FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ)))
{
a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ)); a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ));
}
} }
virtual bool CanBeAt(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override virtual bool CanBeAt(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
{ {
if(!g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)]) if (!g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)])
{
return false; return false;
char Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); }
switch(Meta) NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
switch (Meta)
{ {
case E_RAIL_ASCEND_EAST: case E_RAIL_ASCEND_EAST:
{ {
if(!g_BlockIsSolid[a_World->GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ)]) if (!g_BlockIsSolid[a_World->GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ)])
{
return false; return false;
}
break; break;
} }
case E_RAIL_ASCEND_WEST: case E_RAIL_ASCEND_WEST:
{ {
if(!g_BlockIsSolid[a_World->GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ)]) if (!g_BlockIsSolid[a_World->GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ)])
{
return false; return false;
}
break; break;
} }
case E_RAIL_ASCEND_NORTH: case E_RAIL_ASCEND_NORTH:
{ {
if(!g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1)]) if (!g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1)])
{
return false; return false;
}
break; break;
} }
case E_RAIL_ASCEND_SOUTH: case E_RAIL_ASCEND_SOUTH:
{ {
if(!g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1)]) if (!g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1)])
{
return false; return false;
}
break; break;
} }
} }
return true; return true;
} }
char FindMeta(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) NIBBLETYPE FindMeta(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
char Meta = 0; NIBBLETYPE Meta = 0;
char RailsCnt = 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 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, false, sizeof(Neighbors));
if(IsUnstable(a_World, a_BlockX + 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST, E_PURE_DOWN)) Neighbors[0] = (IsUnstable(a_World, a_BlockX + 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST, E_PURE_DOWN));
Neighbors[1] = (IsUnstable(a_World, a_BlockX - 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST, E_PURE_DOWN));
Neighbors[2] = (IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_DOWN));
Neighbors[3] = (IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_DOWN));
Neighbors[4] = (IsUnstable(a_World, a_BlockX + 1, a_BlockY + 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_EAST, E_PURE_NONE));
Neighbors[5] = (IsUnstable(a_World, a_BlockX - 1, a_BlockY + 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_WEST, E_PURE_NONE));
Neighbors[6] = (IsUnstable(a_World, a_BlockX, a_BlockY + 1, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_NONE));
Neighbors[7] = (IsUnstable(a_World, a_BlockX, a_BlockY + 1, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_NONE));
if (IsUnstable(a_World, a_BlockX + 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_EAST))
Neighbors[0] = true; Neighbors[0] = true;
if(IsUnstable(a_World, a_BlockX - 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST, E_PURE_DOWN)) if (IsUnstable(a_World, a_BlockX - 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_WEST))
Neighbors[1] = true; Neighbors[1] = true;
if(IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_DOWN)) if (IsUnstable(a_World, a_BlockX, a_BlockY - 1, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_NORTH))
Neighbors[2] = true; Neighbors[2] = true;
if(IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_DOWN)) if (IsUnstable(a_World, a_BlockX, a_BlockY - 1, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_SOUTH))
Neighbors[3] = true; Neighbors[3] = true;
if(IsUnstable(a_World, a_BlockX + 1, a_BlockY + 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_EAST, E_PURE_NONE)) for (int i = 0; i < 8; i++)
Neighbors[4] = true;
if(IsUnstable(a_World, a_BlockX - 1, a_BlockY + 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_WEST, E_PURE_NONE))
Neighbors[5] = true;
if(IsUnstable(a_World, a_BlockX, a_BlockY + 1, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_NONE))
Neighbors[6] = true;
if(IsUnstable(a_World, a_BlockX, a_BlockY + 1, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_NONE))
Neighbors[7] = true;
if(IsUnstable(a_World, a_BlockX + 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_EAST))
Neighbors[0] = true;
if(IsUnstable(a_World, a_BlockX - 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_WEST))
Neighbors[1] = true;
if(IsUnstable(a_World, a_BlockX, a_BlockY - 1, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_NORTH))
Neighbors[2] = true;
if(IsUnstable(a_World, a_BlockX, a_BlockY - 1, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_SOUTH))
Neighbors[3] = true;
for(int i = 0; i < 8; i++)
{ {
if(Neighbors[i]) if (Neighbors[i])
{ {
RailsCnt++; RailsCnt++;
} }
} }
if(RailsCnt == 1) if (RailsCnt == 1)
{ {
if(Neighbors[7]) Meta = E_RAIL_ASCEND_SOUTH; if (Neighbors[7]) return E_RAIL_ASCEND_SOUTH;
else if(Neighbors[6]) Meta = E_RAIL_ASCEND_NORTH; else if (Neighbors[6]) return E_RAIL_ASCEND_NORTH;
else if(Neighbors[5]) Meta = E_RAIL_ASCEND_WEST; else if (Neighbors[5]) return E_RAIL_ASCEND_WEST;
else if(Neighbors[4]) Meta = E_RAIL_ASCEND_EAST; else if (Neighbors[4]) return E_RAIL_ASCEND_EAST;
else if(Neighbors[0] || Neighbors[1]) Meta = E_RAIL_EAST_WEST; else if (Neighbors[0] || Neighbors[1]) return E_RAIL_EAST_WEST;
else if(Neighbors[2] || Neighbors[3]) Meta = E_RAIL_NORTH_SOUTH; else if (Neighbors[2] || Neighbors[3]) return E_RAIL_NORTH_SOUTH;
ASSERT(!"Weird neighbor count");
return Meta; return Meta;
} }
for(int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
if(Neighbors[i+4]) if (Neighbors[i + 4])
{ {
Neighbors[i] = true; Neighbors[i] = true;
} }
} }
if(RailsCnt > 1) if (RailsCnt > 1)
{ {
if(Neighbors[3] && Neighbors[0]) Meta = E_RAIL_CURVED_SOUTH_EAST; if (Neighbors[3] && Neighbors[0]) return E_RAIL_CURVED_SOUTH_EAST;
else if(Neighbors[3] && Neighbors[1]) Meta = E_RAIL_CURVED_SOUTH_WEST; else if(Neighbors[3] && Neighbors[1]) return E_RAIL_CURVED_SOUTH_WEST;
else if(Neighbors[2] && Neighbors[0]) Meta = E_RAIL_CURVED_NORTH_EAST; else if(Neighbors[2] && Neighbors[0]) return E_RAIL_CURVED_NORTH_EAST;
else if(Neighbors[2] && Neighbors[1]) Meta = E_RAIL_CURVED_NORTH_WEST; else if(Neighbors[2] && Neighbors[1]) return E_RAIL_CURVED_NORTH_WEST;
else if(Neighbors[7] && Neighbors[2]) Meta = E_RAIL_ASCEND_SOUTH; else if(Neighbors[7] && Neighbors[2]) return E_RAIL_ASCEND_SOUTH;
else if(Neighbors[3] && Neighbors[6]) Meta = E_RAIL_ASCEND_NORTH; else if(Neighbors[3] && Neighbors[6]) return E_RAIL_ASCEND_NORTH;
else if(Neighbors[5] && Neighbors[0]) Meta = E_RAIL_ASCEND_WEST; else if(Neighbors[5] && Neighbors[0]) return E_RAIL_ASCEND_WEST;
else if(Neighbors[4] && Neighbors[1]) Meta = E_RAIL_ASCEND_EAST; else if(Neighbors[4] && Neighbors[1]) return E_RAIL_ASCEND_EAST;
else if(Neighbors[0] && Neighbors[1]) Meta = E_RAIL_EAST_WEST; else if(Neighbors[0] && Neighbors[1]) return E_RAIL_EAST_WEST;
else if(Neighbors[2] && Neighbors[3]) Meta = E_RAIL_NORTH_SOUTH; else if(Neighbors[2] && Neighbors[3]) return E_RAIL_NORTH_SOUTH;
ASSERT(!"Weird neighbor count");
} }
return Meta; return Meta;
} }
bool IsUnstable(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
bool IsUnstable(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
if(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL) return false; if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL) return false;
char Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
switch(Meta) switch (Meta)
{ {
case E_RAIL_NORTH_SOUTH: case E_RAIL_NORTH_SOUTH:
{ {
@ -238,15 +245,16 @@ public:
return false; return false;
} }
bool IsNotConnected(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, char a_Pure = 0)
bool IsNotConnected(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Pure = 0)
{ {
AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_Direction, false); AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false);
char Meta; NIBBLETYPE Meta;
if(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL) if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL)
{ {
if((a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure != E_PURE_UPDOWN)) if ((a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure != E_PURE_UPDOWN))
{ {
if((a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure == E_PURE_NONE)) if ((a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure == E_PURE_NONE))
{ {
return true; return true;
} }
@ -264,46 +272,65 @@ public:
{ {
Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
} }
switch(a_Direction)
switch (a_BlockFace)
{ {
case BLOCK_FACE_NORTH: case BLOCK_FACE_NORTH:
{ {
if(Meta == E_RAIL_NORTH_SOUTH || if (
Meta == E_RAIL_ASCEND_NORTH || (Meta == E_RAIL_NORTH_SOUTH) ||
Meta == E_RAIL_ASCEND_SOUTH || (Meta == E_RAIL_ASCEND_NORTH) ||
Meta == E_RAIL_CURVED_SOUTH_EAST || (Meta == E_RAIL_ASCEND_SOUTH) ||
Meta == E_RAIL_CURVED_SOUTH_WEST) (Meta == E_RAIL_CURVED_SOUTH_EAST) ||
return false; (Meta == E_RAIL_CURVED_SOUTH_WEST)
)
{
return false;
}
break; break;
} }
case BLOCK_FACE_SOUTH: case BLOCK_FACE_SOUTH:
{ {
if(Meta == E_RAIL_NORTH_SOUTH || if (
Meta == E_RAIL_ASCEND_NORTH || (Meta == E_RAIL_NORTH_SOUTH) ||
Meta == E_RAIL_ASCEND_SOUTH || (Meta == E_RAIL_ASCEND_NORTH) ||
Meta == E_RAIL_CURVED_NORTH_EAST || (Meta == E_RAIL_ASCEND_SOUTH) ||
Meta == E_RAIL_CURVED_NORTH_WEST) (Meta == E_RAIL_CURVED_NORTH_EAST) ||
return false; (Meta == E_RAIL_CURVED_NORTH_WEST)
)
{
return false;
}
break; break;
} }
case BLOCK_FACE_EAST: case BLOCK_FACE_EAST:
{ {
if(Meta == E_RAIL_EAST_WEST || if (
Meta == E_RAIL_ASCEND_EAST || (Meta == E_RAIL_EAST_WEST) ||
Meta == E_RAIL_ASCEND_WEST || (Meta == E_RAIL_ASCEND_EAST) ||
Meta == E_RAIL_CURVED_SOUTH_WEST || (Meta == E_RAIL_ASCEND_WEST) ||
Meta == E_RAIL_CURVED_NORTH_WEST) (Meta == E_RAIL_CURVED_SOUTH_WEST) ||
return false; (Meta == E_RAIL_CURVED_NORTH_WEST)
)
{
return false;
}
break; break;
} }
case BLOCK_FACE_WEST: case BLOCK_FACE_WEST:
{ {
if(Meta == E_RAIL_EAST_WEST || if (
Meta == E_RAIL_ASCEND_EAST || (Meta == E_RAIL_EAST_WEST) ||
Meta == E_RAIL_ASCEND_WEST || (Meta == E_RAIL_ASCEND_EAST) ||
Meta == E_RAIL_CURVED_SOUTH_EAST || (Meta == E_RAIL_ASCEND_WEST) ||
Meta == E_RAIL_CURVED_NORTH_EAST) (Meta == E_RAIL_CURVED_SOUTH_EAST) ||
return false; (Meta == E_RAIL_CURVED_NORTH_EAST)
)
{
return false;
}
break; break;
} }
} }

View File

@ -18,15 +18,6 @@ cBlockRedstoneHandler::cBlockRedstoneHandler(BLOCKTYPE a_BlockType)
void cBlockRedstoneHandler::OnPlaced(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir)
{
// Nothing needed yet
}
void cBlockRedstoneHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) void cBlockRedstoneHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
// Nothing needed yet // Nothing needed yet
@ -35,22 +26,3 @@ void cBlockRedstoneHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_Blo
void cBlockRedstoneHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir)
{
switch(m_BlockType)
{
case E_BLOCK_REDSTONE_TORCH_ON:
case E_BLOCK_REDSTONE_TORCH_OFF:
{
a_BlockMeta = cTorch::DirectionToMetaData(a_Dir);
break;
}
}
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, a_BlockMeta);
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
}

View File

@ -13,12 +13,9 @@ class cBlockRedstoneHandler :
{ {
public: public:
cBlockRedstoneHandler(BLOCKTYPE a_BlockType); cBlockRedstoneHandler(BLOCKTYPE a_BlockType);
virtual void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) override;
virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override;
virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override;
virtual bool DoesAllowBlockOnTop(void) override virtual bool DoesAllowBlockOnTop(void) override
{ {
return false; return false;

View File

@ -19,15 +19,6 @@ cBlockRedstoneRepeaterHandler::cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockTy
void cBlockRedstoneRepeaterHandler::OnPlaced(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir)
{
// Noting needed yet
}
void cBlockRedstoneRepeaterHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) void cBlockRedstoneRepeaterHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
// Nothing needed yet // Nothing needed yet
@ -37,7 +28,7 @@ void cBlockRedstoneRepeaterHandler::OnDestroyed(cWorld *a_World, int a_BlockX, i
void cBlockRedstoneRepeaterHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) void cBlockRedstoneRepeaterHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
{ {
a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) + 0x04) & 0x0f)); a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) + 0x04) & 0x0f));
} }
@ -48,17 +39,7 @@ void cBlockRedstoneRepeaterHandler::OnUse(cWorld *a_World, cPlayer *a_Player, in
void cBlockRedstoneRepeaterHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) void cBlockRedstoneRepeaterHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
OnUse(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ); OnUse(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NONE, 8, 8, 8);
}
void cBlockRedstoneRepeaterHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir)
{
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cRedstoneSimulator::RepeaterRotationToMetaData(a_Player->GetRotation()));
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
} }

View File

@ -13,11 +13,10 @@ class cBlockRedstoneRepeaterHandler :
{ {
public: public:
cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType); cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType);
virtual void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) override;
virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override;
virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override;
virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override;
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
@ -33,9 +32,6 @@ public:
} }
virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override;
virtual bool DoesAllowBlockOnTop(void) override virtual bool DoesAllowBlockOnTop(void) override
{ {
return false; return false;

View File

@ -20,26 +20,6 @@ public:
} }
virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override
{
BLOCKTYPE Block;
NIBBLETYPE Meta;
if (a_Dir == BLOCK_FACE_TOP)
{
Meta = cSign::RotationToMetaData(a_Player->GetRotation());
Block = E_BLOCK_SIGN_POST;
}
else
{
Meta = cSign::DirectionToMetaData(a_Dir);
Block = E_BLOCK_WALLSIGN;
}
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, Block, Meta);
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
}
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{ {
a_Pickups.push_back(cItem(E_ITEM_SIGN, 1, 0)); a_Pickups.push_back(cItem(E_ITEM_SIGN, 1, 0));

View File

@ -24,21 +24,38 @@ public:
} }
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, DirectionToMetaData( a_Dir, a_BlockMeta )); a_BlockType = m_BlockType;
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage & 0x07);
} switch (a_BlockFace)
static char DirectionToMetaData( char a_Direction, NIBBLETYPE Meta )
{
char result = Meta;
if( a_Direction == 0)
{ {
result |= 0x8; case BLOCK_FACE_TOP: a_BlockMeta = Meta & 0x7; break; // Always bottom half of the slab when placing on top of something
} case BLOCK_FACE_BOTTOM: a_BlockMeta = Meta | 0x8; break; // Always top half of the slab when placing on bottom of something
return result; case BLOCK_FACE_EAST:
case BLOCK_FACE_NORTH:
case BLOCK_FACE_SOUTH:
case BLOCK_FACE_WEST:
{
if (a_CursorY > 7)
{
// Cursor at the top half of the face, place a top half of slab
a_BlockMeta = Meta | 0x8;
}
else
{
// Cursor at the bottom half of the face, place a bottom half of slab:
a_BlockMeta = Meta & 0x7;
}
break;
}
} // switch (a_BlockFace)
return true;
} }

View File

@ -1,22 +1,56 @@
#pragma once #pragma once
#include "BlockHandler.h" #include "BlockHandler.h"
#include "../Stairs.h" #include "../Stairs.h"
class cBlockStairsHandler : public cBlockHandler
class cBlockStairsHandler :
public cBlockHandler
{ {
public: public:
cBlockStairsHandler(BLOCKTYPE a_BlockType) cBlockStairsHandler(BLOCKTYPE a_BlockType) :
: cBlockHandler(a_BlockType) cBlockHandler(a_BlockType)
{ {
} }
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cStairs::RotationToMetaData(a_Player->GetRotation(), a_Dir)); a_BlockType = m_BlockType;
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); a_BlockMeta = cStairs::RotationToMetaData(a_Player->GetRotation());
switch (a_BlockFace)
{
case BLOCK_FACE_TOP: break;
case BLOCK_FACE_BOTTOM: a_BlockMeta = a_BlockMeta | 0x4; break; // When placing onto a bottom face, always place an upside-down stairs block
case BLOCK_FACE_EAST:
case BLOCK_FACE_NORTH:
case BLOCK_FACE_SOUTH:
case BLOCK_FACE_WEST:
{
// When placing onto a sideways face, check cursor, if in top half, make it an upside-down stairs block
if (a_CursorY < 8)
{
a_BlockMeta |= 0x4;
}
break;
}
}
return true;
} }
//TODO: step sound // TODO: step sound
}; } ;

View File

@ -19,20 +19,26 @@ public:
} }
virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
if (!TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_Dir)) // Find proper placement. Use the player-supplied one as the default, but fix if not okay:
if (!TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace))
{ {
a_Dir = FindSuitableDirection(a_World, a_BlockX, a_BlockY, a_BlockZ); a_BlockFace = FindSuitableFace(a_World, a_BlockX, a_BlockY, a_BlockZ);
if (a_Dir == BLOCK_FACE_BOTTOM) if (a_BlockFace == BLOCK_FACE_BOTTOM)
{ {
return; return false;
} }
} }
a_BlockType = m_BlockType;
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cTorch::DirectionToMetaData(a_Dir)); a_BlockMeta = cTorch::DirectionToMetaData(a_BlockFace);
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); return true;
} }
@ -61,25 +67,25 @@ public:
} }
static bool TorchCanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) static bool TorchCanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace)
{ {
// TODO: If placing a torch from below, check all 4 XZ neighbors, place it on that neighbor instead // TODO: If placing a torch from below, check all 4 XZ neighbors, place it on that neighbor instead
// How to propagate that change up? // How to propagate that change up?
// Simon: The easiest way is to calculate the position two times, shouldn´t cost much cpu power :) // Simon: The easiest way is to calculate the position two times, shouldn´t cost much cpu power :)
if (a_Dir == BLOCK_FACE_BOTTOM) if (a_BlockFace == BLOCK_FACE_BOTTOM)
{ {
return false; return false;
} }
AddDirection( a_BlockX, a_BlockY, a_BlockZ, a_Dir, true ); AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true);
return CanBePlacedOn(a_World->GetBlock( a_BlockX, a_BlockY, a_BlockZ ), a_Dir); return CanBePlacedOn(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ), a_BlockFace);
} }
/// Finds a suitable Direction for the Torch. Returns BLOCK_FACE_BOTTOM on failure /// Finds a suitable Face for the Torch. Returns BLOCK_FACE_BOTTOM on failure
static char FindSuitableDirection(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) static char FindSuitableFace(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
for (int i = 1; i <= 5; i++) for (int i = 1; i <= 5; i++)
{ {
@ -92,19 +98,21 @@ public:
} }
virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override
{ {
if(TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_Dir)) if (TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace))
{
return true; return true;
}
return FindSuitableDirection(a_World, a_BlockX, a_BlockY, a_BlockZ) != BLOCK_FACE_BOTTOM; return (FindSuitableFace(a_World, a_BlockX, a_BlockY, a_BlockZ) != BLOCK_FACE_BOTTOM);
} }
virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
{ {
char Dir = cTorch::MetaDataToDirection(a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ)); char Face = cTorch::MetaDataToDirection(a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ));
return TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Dir); return TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Face);
} }

View File

@ -18,18 +18,24 @@ public:
} }
virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cVine::DirectionToMetaData(a_Dir)); a_BlockType = m_BlockType;
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); a_BlockMeta = cVine::DirectionToMetaData(a_BlockFace);
return true;
} }
virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override
{ {
if ( if (
(a_World->GetBlock( a_BlockX, a_BlockY + 1, a_BlockZ ) == E_BLOCK_VINES) && (a_World->GetBlock( a_BlockX, a_BlockY + 1, a_BlockZ ) == E_BLOCK_VINES) &&
(cVine::MetaDataToDirection(a_World->GetBlockMeta( a_BlockX, a_BlockY + 1, a_BlockZ )) == a_Dir) (cVine::MetaDataToDirection(a_World->GetBlockMeta(a_BlockX, a_BlockY + 1, a_BlockZ)) == a_BlockFace)
) )
{ {
return true; return true;
@ -38,18 +44,18 @@ public:
BLOCKTYPE TopBlock = a_World->GetBlock( a_BlockX, a_BlockY + 1, a_BlockZ); BLOCKTYPE TopBlock = a_World->GetBlock( a_BlockX, a_BlockY + 1, a_BlockZ);
if (g_BlockIsSolid[TopBlock] || (TopBlock == E_BLOCK_LEAVES)) if (g_BlockIsSolid[TopBlock] || (TopBlock == E_BLOCK_LEAVES))
{ {
AddDirection( a_BlockX, a_BlockY, a_BlockZ, a_Dir, true ); AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true);
BLOCKTYPE BaseBlock = a_World->GetBlock( a_BlockX, a_BlockY, a_BlockZ); BLOCKTYPE BaseBlock = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
if (!g_BlockIsSolid[BaseBlock] && (BaseBlock != E_BLOCK_LEAVES)) if (!g_BlockIsSolid[BaseBlock] && (BaseBlock != E_BLOCK_LEAVES))
{ {
AddDirection( a_BlockX, a_BlockY, a_BlockZ, a_Dir, false ); AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false);
a_World->SetBlock( a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_VINES, 0); a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_VINES, 0);
} }
return true; return true;
} }
AddDirection( a_BlockX, a_BlockY, a_BlockZ, a_Dir, true ); AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true);
BLOCKTYPE BaseBlock = a_World->GetBlock( a_BlockX, a_BlockY, a_BlockZ); BLOCKTYPE BaseBlock = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
return (g_BlockIsSolid[BaseBlock] || (BaseBlock == E_BLOCK_LEAVES)); return (g_BlockIsSolid[BaseBlock] || (BaseBlock == E_BLOCK_LEAVES));
} }

View File

@ -19,7 +19,7 @@ public:
} }
virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
{ {
cWindow * Window = new cCraftingWindow(a_BlockX, a_BlockY, a_BlockZ); cWindow * Window = new cCraftingWindow(a_BlockX, a_BlockY, a_BlockZ);
a_Player->OpenWindow(Window); a_Player->OpenWindow(Window);

View File

@ -52,7 +52,7 @@ public:
private: private:
cItem * m_Content; cItem * m_Content;
}; //tolua_export }; // tolua_export

View File

@ -128,8 +128,6 @@ public:
int GetPosZ() { return m_PosZ; } int GetPosZ() { return m_PosZ; }
cWorld * GetWorld() { return m_World; } cWorld * GetWorld() { return m_World; }
// OBSOLETE void SendTo( cClientHandle * a_Client );
void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ); void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta );
// SetBlock() does a lot of work (heightmap, tickblocks, blockentities) so a BlockIdx version doesn't make sense // SetBlock() does a lot of work (heightmap, tickblocks, blockentities) so a BlockIdx version doesn't make sense
void SetBlock( const Vector3i & a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) { SetBlock( a_RelBlockPos.x, a_RelBlockPos.y, a_RelBlockPos.z, a_BlockType, a_BlockMeta ); } void SetBlock( const Vector3i & a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) { SetBlock( a_RelBlockPos.x, a_RelBlockPos.y, a_RelBlockPos.z, a_BlockType, a_BlockMeta ); }

View File

@ -89,8 +89,8 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance)
, m_LastStreamedChunkZ(0x7fffffff) , m_LastStreamedChunkZ(0x7fffffff)
, m_ShouldCheckDownloaded(false) , m_ShouldCheckDownloaded(false)
, m_UniqueID(0) , m_UniqueID(0)
, m_BlockDigAnim(-1) , m_BlockDigAnimStage(-1)
, m_LastDigStatus(-1) , m_HasStartedDigging(false)
{ {
m_Protocol = new cProtocolRecognizer(this); m_Protocol = new cProtocolRecognizer(this);
@ -231,7 +231,7 @@ void cClientHandle::Authenticate(void)
m_Player->SetIP (m_IPString); m_Player->SetIP (m_IPString);
cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::HOOK_PLAYER_JOIN, 1, m_Player); cRoot::Get()->GetPluginManager()->CallHookPlayerJoined(*m_Player);
m_ConfirmPosition = m_Player->GetPosition(); m_ConfirmPosition = m_Player->GetPosition();
@ -260,7 +260,7 @@ void cClientHandle::Authenticate(void)
// Broadcast this player's spawning to all other players in the same chunk // Broadcast this player's spawning to all other players in the same chunk
m_Player->GetWorld()->BroadcastSpawn(*m_Player, this); m_Player->GetWorld()->BroadcastSpawn(*m_Player, this);
cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::HOOK_PLAYER_SPAWN, 1, m_Player); cRoot::Get()->GetPluginManager()->CallHookPlayerSpawned(*m_Player);
} }
@ -501,111 +501,158 @@ void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ,
void cClientHandle::HandleBlockDig(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status)
{ {
LOGD("HandleLeftClick: {%i, %i, %i}; Face: %i; Stat: %i",
a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status
);
cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager();
if (PlgMgr->CallHookPlayerLeftClick(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status))
{
// A plugin doesn't agree with the action, replace the block on the client and quit:
m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
return;
}
if (!CheckBlockInteractionsRate()) if (!CheckBlockInteractionsRate())
{ {
// Too many interactions per second, simply ignore. Probably a hacked client, so don't even send bak the block
return; return;
} }
LOGD("OnBlockDig: {%i, %i, %i}; Face: %i; Stat: %i LastStat: %i", switch (a_Status)
a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status, m_LastDigStatus
);
// Do we want plugins to disable tossing items? Probably no, so toss item before asking plugins for permission
if (a_Status == DIG_STATUS_DROP_HELD) // Drop held item
{ {
m_Player->TossItem(false); case DIG_STATUS_DROP_HELD: // Drop held item
{
if (PlgMgr->CallHookPlayerTossingItem(*m_Player))
{
// A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch)
return;
}
m_Player->TossItem(false);
return;
}
case DIG_STATUS_SHOOT_EAT:
{
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
if (ItemHandler->IsFood())
{
if (PlgMgr->CallHookPlayerEating(*m_Player))
{
// A plugin doesn't agree with the action. The plugin itself is responsible for handling the consequences (possible inventory mismatch)
return;
}
}
else
{
if (PlgMgr->CallHookPlayerShooting(*m_Player))
{
// A plugin doesn't agree with the action. The plugin itself is responsible for handling the consequences (possible inventory mismatch)
return;
}
}
LOGINFO("%s: Status SHOOT / EAT not implemented", __FUNCTION__);
return;
}
case DIG_STATUS_STARTED:
{
BLOCKTYPE OldBlock;
NIBBLETYPE OldMeta;
m_Player->GetWorld()->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, OldBlock, OldMeta);
HandleBlockDigStarted(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, OldBlock, OldMeta);
return;
}
case DIG_STATUS_FINISHED:
{
BLOCKTYPE OldBlock;
NIBBLETYPE OldMeta;
m_Player->GetWorld()->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, OldBlock, OldMeta);
HandleBlockDigFinished(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, OldBlock, OldMeta);
return;
}
default:
{
ASSERT(!"Unhandled DIG_STATUS");
return;
}
} // switch (a_Status)
}
void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta)
{
if (
m_HasStartedDigging &&
(a_BlockX == m_LastDigBlockX) &&
(a_BlockY == m_LastDigBlockY) &&
(a_BlockZ == m_LastDigBlockZ)
)
{
// It is a duplicate packet, drop it right away
return; return;
} }
if (a_Status == DIG_STATUS_SHOOT_EAT) if (cRoot::Get()->GetPluginManager()->CallHookPlayerBreakingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_OldBlock, a_OldMeta))
{ {
LOGINFO("BlockDig: Status SHOOT/EAT not implemented"); // A plugin doesn't agree with the breaking. Bail out. Send the block back to the client, so that it knows:
m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
return; return;
} }
// Set the last digging coords to the block being dug, so that they can be checked in DIG_FINISHED to avoid dig/aim bug in the client:
m_HasStartedDigging = true;
m_LastDigBlockX = a_BlockX;
m_LastDigBlockY = a_BlockY;
m_LastDigBlockZ = a_BlockZ;
// In creative mode, digging is done immediately
if (m_Player->GetGameMode() == eGameMode_Creative)
{
HandleBlockDigFinished(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_OldBlock, a_OldMeta);
return;
}
// Start dig animation
// TODO: calculate real animation speed
// TODO: Send animation packets even without receiving any other packets
m_BlockDigAnimSpeed = 10;
m_BlockDigAnimX = a_BlockX;
m_BlockDigAnimY = a_BlockY;
m_BlockDigAnimZ = a_BlockZ;
m_BlockDigAnimStage = 0;
m_Player->GetWorld()->BroadcastBlockBreakAnimation(m_UniqueID, m_BlockDigAnimX, m_BlockDigAnimY, m_BlockDigAnimZ, 0, this);
cWorld * World = m_Player->GetWorld(); cWorld * World = m_Player->GetWorld();
BLOCKTYPE OldBlock;
NIBBLETYPE OldMeta;
World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, OldBlock, OldMeta);
if (cRoot::Get()->GetPluginManager()->CallHookBlockDig(m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status, OldBlock, OldMeta)) cBlockHandler * Handler = cBlockHandler::GetBlockHandler(a_OldBlock);
Handler->OnDigging(World, m_Player, a_BlockX, a_BlockY, a_BlockZ);
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
ItemHandler->OnDiggingBlock(World, m_Player, &m_Player->GetEquippedItem(), a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
// Check for clickthrough-blocks:
if (a_BlockFace != BLOCK_FACE_NONE)
{ {
// The plugin doesn't agree with the digging, replace the block on the client and quit: int pX = a_BlockX;
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); int pY = a_BlockY;
return; int pZ = a_BlockZ;
} AddFaceDirection(pX, pY, pZ, a_BlockFace);
bool bBroken = ( Handler = cBlockHandler::GetBlockHandler(World->GetBlock(pX, pY, pZ));
((a_Status == DIG_STATUS_FINISHED) &&
//Don't allow to finish digging if not started yet:
(m_LastDigStatus == 0) &&
(m_LastDigX == a_BlockX) &&
(m_LastDigY == a_BlockY) &&
(m_LastDigZ == a_BlockZ)) ||
(g_BlockOneHitDig[(int)OldBlock]) ||
((a_Status == DIG_STATUS_STARTED) && (m_Player->GetGameMode() == 1))
);
m_LastDigStatus = a_Status; // 2013_01_05 _X: This looks weird
m_LastDigX = a_BlockX; // Why do we ask the block "behind" the one being clicked if it is clicked through? Shouldn't we ask the primary block instead?
m_LastDigY = a_BlockY; if (Handler->IsClickedThrough())
m_LastDigZ = a_BlockZ;
if ((a_Status == DIG_STATUS_STARTED) && (m_Player->GetGameMode() != eGameMode_Creative))
{
// Start dig animation
// TODO: calculate real animation speed
m_BlockDigAnimSpeed = 10;
m_BlockDigX = a_BlockX;
m_BlockDigY = a_BlockY;
m_BlockDigZ = a_BlockZ;
m_BlockDigAnim = 0;
m_Player->GetWorld()->BroadcastBlockBreakAnimation(m_UniqueID, m_BlockDigX, m_BlockDigY, m_BlockDigZ, 0, this);
}
else if (m_BlockDigAnim != -1)
{
// End dig animation
m_BlockDigAnim = -1;
// It seems that 10 ends block animation
m_Player->GetWorld()->BroadcastBlockBreakAnimation(m_UniqueID, m_BlockDigX, m_BlockDigY, m_BlockDigZ, 10, this);
}
cItem & Equipped = m_Player->GetInventory().GetEquippedItem();
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemID);
if (bBroken)
{
if(World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_AIR)
{ {
ItemHandler->OnBlockDestroyed(World, m_Player, &Equipped, a_BlockX, a_BlockY, a_BlockZ); Handler->OnDigging(World, m_Player, pX, pY, pZ);
BlockHandler(OldBlock)->OnDestroyedByPlayer(World, m_Player, a_BlockX, a_BlockY, a_BlockZ);
World->BroadcastSoundParticleEffect(2001, a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, OldBlock, this);
World->DigBlock(a_BlockX, a_BlockY, a_BlockZ);
}
}
else
{
cBlockHandler * Handler = cBlockHandler::GetBlockHandler(OldBlock);
Handler->OnDigging(World, m_Player, a_BlockX, a_BlockY, a_BlockZ);
ItemHandler->OnDiggingBlock(World, m_Player, &Equipped, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
// Check for clickthrough-blocks:
if (a_BlockFace != BLOCK_FACE_NONE)
{
int pX = a_BlockX;
int pY = a_BlockY;
int pZ = a_BlockZ;
AddDirection(pX, pY, pZ, a_BlockFace);
Handler = cBlockHandler::GetBlockHandler(World->GetBlock(pX, pY, pZ));
if (Handler->IsClickedThrough())
{
Handler->OnDigging(World, m_Player, pX, pY, pZ);
}
} }
} }
} }
@ -614,12 +661,72 @@ void cClientHandle::HandleBlockDig(int a_BlockX, int a_BlockY, int a_BlockZ, cha
void cClientHandle::HandleBlockPlace(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem) void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta)
{ {
LOGD("HandleBlockPlace: {%d, %d, %d}, face %d, HeldItem: %s", if (
!m_HasStartedDigging || // Hasn't received the DIG_STARTED packet
(m_LastDigBlockX != a_BlockX) || // DIG_STARTED has had different pos
(m_LastDigBlockY != a_BlockY) ||
(m_LastDigBlockZ != a_BlockZ)
)
{
LOGD("Prevented a dig/aim bug in the client (finish {%d, %d, %d} vs start {%d, %d, %d}, HSD: %s)",
a_BlockX, a_BlockY, a_BlockZ,
m_LastDigBlockX, m_LastDigBlockY, m_LastDigBlockZ,
m_HasStartedDigging
);
return;
}
m_HasStartedDigging = false;
if (m_BlockDigAnimStage != -1)
{
// End dig animation
m_BlockDigAnimStage = -1;
// It seems that 10 ends block animation
m_Player->GetWorld()->BroadcastBlockBreakAnimation(m_UniqueID, m_BlockDigAnimX, m_BlockDigAnimY, m_BlockDigAnimZ, 10, this);
}
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
if (a_OldBlock == E_BLOCK_AIR)
{
LOGD("Digged air? wtf?");
return;
}
cWorld * World = m_Player->GetWorld();
ItemHandler->OnBlockDestroyed(World, m_Player, &m_Player->GetEquippedItem(), a_BlockX, a_BlockY, a_BlockZ);
BlockHandler(a_OldBlock)->OnDestroyedByPlayer(World, m_Player, a_BlockX, a_BlockY, a_BlockZ);
World->BroadcastSoundParticleEffect(2001, a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, a_OldBlock, this);
World->DigBlock(a_BlockX, a_BlockY, a_BlockZ);
cRoot::Get()->GetPluginManager()->CallHookPlayerBrokenBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_OldBlock, a_OldMeta);
}
void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, const cItem & a_HeldItem)
{
LOGD("HandleRightClick: {%d, %d, %d}, face %d, HeldItem: %s",
a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, ItemToFullString(a_HeldItem).c_str() a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, ItemToFullString(a_HeldItem).c_str()
); );
cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager();
if (PlgMgr->CallHookPlayerRightClick(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ))
{
// A plugin doesn't agree with the action, replace the block on the client and quit:
if (a_BlockFace > -1)
{
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
}
return;
}
if (!CheckBlockInteractionsRate()) if (!CheckBlockInteractionsRate())
{ {
LOGD("Too many block interactions, aborting placement"); LOGD("Too many block interactions, aborting placement");
@ -640,7 +747,7 @@ void cClientHandle::HandleBlockPlace(int a_BlockX, int a_BlockY, int a_BlockZ, c
// Let's send the current world block to the client, so that it can immediately "let the user know" that they haven't placed the block // Let's send the current world block to the client, so that it can immediately "let the user know" that they haven't placed the block
if (a_BlockFace > -1) if (a_BlockFace > -1)
{ {
AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
} }
return; return;
@ -648,104 +755,133 @@ void cClientHandle::HandleBlockPlace(int a_BlockX, int a_BlockY, int a_BlockZ, c
cWorld * World = m_Player->GetWorld(); cWorld * World = m_Player->GetWorld();
cBlockHandler *Handler = cBlockHandler::GetBlockHandler(World->GetBlock(a_BlockX, a_BlockY, a_BlockZ)); BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta);
cBlockHandler * Handler = cBlockHandler::GetBlockHandler(BlockType);
// TODO: Wrap following if into another if which will call hook 'OnBlockUse' (or some nicer name)
if (Handler->IsUseable()) if (Handler->IsUseable())
{ {
Handler->OnUse(World, m_Player, a_BlockX, a_BlockY, a_BlockZ); if (PlgMgr->CallHookPlayerUsingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta))
{
// A plugin doesn't agree with using the block, abort
return;
}
Handler->OnUse(World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ);
PlgMgr->CallHookPlayerUsedBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta);
return;
}
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemType);
if (ItemHandler->IsPlaceable())
{
HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler);
}
else if (ItemHandler->IsFood())
{
cItem Item;
Item.m_ItemType = Equipped.m_ItemType;
Item.m_ItemCount = 1;
if (ItemHandler->EatItem(m_Player, &Item))
{
ItemHandler->OnFoodEaten(World, m_Player, &Item);
m_Player->GetInventory().RemoveItem(Item);
return;
}
} }
else else
{ {
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemID); if (PlgMgr->CallHookPlayerUsingItem(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ))
if (ItemHandler->OnItemUse(World, m_Player, &Equipped, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace))
{ {
// Nothing here :P // A plugin doesn't agree with using the item, abort
return;
} }
else if (ItemHandler->IsPlaceable()) ItemHandler->OnItemUse(World, m_Player, &Equipped, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
PlgMgr->CallHookPlayerUsedItem(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ);
}
}
void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler)
{
if (a_BlockFace < 0)
{
// Clicked in air
return;
}
cWorld * World = m_Player->GetWorld();
// Check if the block ignores build collision (water, grass etc.):
BLOCKTYPE ClickedBlock = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
cBlockHandler * Handler = cBlockHandler::GetBlockHandler(ClickedBlock);
if (Handler->DoesIgnoreBuildCollision())
{
Handler->OnDestroyedByPlayer(World, m_Player, a_BlockX, a_BlockY, a_BlockZ);
// World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
}
else
{
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
// Check for Blocks not allowing placement on top
if ((a_BlockFace == BLOCK_FACE_TOP) && !Handler->DoesAllowBlockOnTop())
{ {
if (cRoot::Get()->GetPluginManager()->CallHookBlockPlace(m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, Equipped)) // Resend the old block
{ // Some times the client still places the block O.o
if (a_BlockFace > -1) World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
{ return;
AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
}
return;
}
if (a_BlockFace < 0)
{
// clicked in air
return;
}
BLOCKTYPE ClickedBlock = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
cBlockHandler *Handler = cBlockHandler::GetBlockHandler(ClickedBlock);
if (Handler->DoesIgnoreBuildCollision())
{
Handler->OnDestroyedByPlayer(World, m_Player, a_BlockX, a_BlockY, a_BlockZ);
// World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
}
else
{
AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
// Check for Blocks not allowing placement on top
if ((a_BlockFace == BLOCK_FACE_TOP) && !Handler->DoesAllowBlockOnTop())
{
// Resend the old block
// Some times the client still places the block O.o
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
return;
}
BLOCKTYPE PlaceBlock = m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
if (!BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision())
{
// Tried to place a block *into* another?
return; // Happens when you place a block aiming at side of block like torch or stem
}
}
cBlockHandler * NewBlock = BlockHandler(ItemHandler->GetBlockType());
// Cannot be placed on the side of an other block
if ((a_BlockFace != BLOCK_FACE_TOP) && !NewBlock->CanBePlacedOnSide())
{
return;
}
if (NewBlock->CanBePlacedAt(World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace))
{
ItemHandler->PlaceBlock(World, m_Player, &m_Player->GetInventory().GetEquippedItem(), a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
// Step sound with 0.8f pitch is used as block placement sound
World->BroadcastSoundEffect(NewBlock->GetStepSound(),a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 1.0f, 0.8f);
}
else
{
LOGD("Block refused placement here, aborting");
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); // Send the old block back to the player
return;
}
} }
else if (ItemHandler->IsFood())
BLOCKTYPE PlaceBlock = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
if (!BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision())
{ {
cItem Item; // Tried to place a block *into* another?
Item.m_ItemID = Equipped.m_ItemID; return; // Happens when you place a block aiming at side of block like torch or stem
Item.m_ItemCount = 1;
if (ItemHandler->EatItem(m_Player, &Item))
{
ItemHandler->OnFoodEaten(World, m_Player, &Item);
m_Player->GetInventory().RemoveItem(Item);
return;
}
} }
} }
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
if (!a_ItemHandler.GetPlacementBlockTypeMeta(World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta))
{
// Handler refused the placement, send that information back to the client:
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockY, m_Player);
return;
}
cBlockHandler * NewBlock = BlockHandler(BlockType);
if ((a_BlockFace != BLOCK_FACE_TOP) && !NewBlock->CanBePlacedOnSide())
{
// Cannot be placed on the side of an other block
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
return;
}
if (cRoot::Get()->GetPluginManager()->CallHookPlayerPlacingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta))
{
// A plugin doesn't agree with placing the block, revert the block on the client:
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
return;
}
// The actual block placement:
World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta);
if (m_Player->GetGameMode() == eGameMode_Survival)
{
cItem Item(m_Player->GetEquippedItem().m_ItemType, 1);
m_Player->GetInventory().RemoveItem(Item);
}
NewBlock->OnPlacedByPlayer(World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta);
// Step sound with 0.8f pitch is used as block placement sound
World->BroadcastSoundEffect(NewBlock->GetStepSound(),a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 1.0f, 0.8f);
cRoot::Get()->GetPluginManager()->CallHookPlayerPlacedBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta);
} }
@ -951,7 +1087,7 @@ void cClientHandle::HandleRespawn(void)
return; return;
} }
m_Player->Respawn(); m_Player->Respawn();
cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::HOOK_PLAYER_SPAWN, 1, m_Player); cRoot::Get()->GetPluginManager()->CallHookPlayerSpawned(*m_Player);
} }
@ -1129,17 +1265,17 @@ void cClientHandle::Tick(float a_Dt)
} }
// Handle block break animation: // Handle block break animation:
if ((m_Player != NULL) && (m_BlockDigAnim > -1)) if ((m_Player != NULL) && (m_BlockDigAnimStage > -1))
{ {
int lastAnimVal = m_BlockDigAnim; int lastAnimVal = m_BlockDigAnimStage;
m_BlockDigAnim += (int)(m_BlockDigAnimSpeed * a_Dt); m_BlockDigAnimStage += (int)(m_BlockDigAnimSpeed * a_Dt);
if (m_BlockDigAnim > 9000) if (m_BlockDigAnimStage > 9000)
{ {
m_BlockDigAnim = 9000; m_BlockDigAnimStage = 9000;
} }
if (m_BlockDigAnim / 1000 != lastAnimVal / 1000) if (m_BlockDigAnimStage / 1000 != lastAnimVal / 1000)
{ {
m_Player->GetWorld()->BroadcastBlockBreakAnimation(m_UniqueID, m_BlockDigX, m_BlockDigY, m_BlockDigZ, (char)(m_BlockDigAnim / 1000), this); m_Player->GetWorld()->BroadcastBlockBreakAnimation(m_UniqueID, m_BlockDigAnimX, m_BlockDigAnimY, m_BlockDigAnimZ, (char)(m_BlockDigAnimStage / 1000), this);
} }
} }
} }
@ -1626,7 +1762,7 @@ void cClientHandle::SendConfirmPosition(void)
m_State = csConfirmingPos; m_State = csConfirmingPos;
if (!cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::HOOK_PLAYER_JOIN, 1, m_Player)) if (!cRoot::Get()->GetPluginManager()->CallHookPlayerJoined(*m_Player))
{ {
// Broadcast that this player has joined the game! Yay~ // Broadcast that this player has joined the game! Yay~
cRoot::Get()->GetServer()->BroadcastChat(m_Username + " joined the game!", this); cRoot::Get()->GetServer()->BroadcastChat(m_Username + " joined the game!", this);

View File

@ -31,6 +31,7 @@ class cProtocol;
class cRedstone; class cRedstone;
class cWindow; class cWindow;
class cFallingBlock; class cFallingBlock;
class cItemHandler;
@ -63,7 +64,7 @@ public:
cPlayer* GetPlayer() { return m_Player; } // tolua_export cPlayer* GetPlayer() { return m_Player; } // tolua_export
void Kick(const AString & a_Reason); //tolua_export void Kick(const AString & a_Reason); // tolua_export
void Authenticate(void); // Called by cAuthenticator when the user passes authentication void Authenticate(void); // Called by cAuthenticator when the user passes authentication
void StreamChunks(void); void StreamChunks(void);
@ -125,15 +126,15 @@ public:
void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots); void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots);
void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ); void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ );
const AString & GetUsername(void) const; //tolua_export const AString & GetUsername(void) const; // tolua_export
void SetUsername( const AString & a_Username ); //tolua_export void SetUsername( const AString & a_Username ); // tolua_export
inline short GetPing(void) const { return m_Ping; } //tolua_export inline short GetPing(void) const { return m_Ping; } // tolua_export
void SetViewDistance(int a_ViewDistance); // tolua_export void SetViewDistance(int a_ViewDistance); // tolua_export
int GetViewDistance(void) const { return m_ViewDistance; } // tolua_export int GetViewDistance(void) const { return m_ViewDistance; } // tolua_export
int GetUniqueID() const { return m_UniqueID; } //tolua_export int GetUniqueID() const { return m_UniqueID; } // tolua_export
/// Returns true if the client wants the chunk specified to be sent (in m_ChunksToSend) /// Returns true if the client wants the chunk specified to be sent (in m_ChunksToSend)
bool WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); bool WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
@ -150,8 +151,8 @@ public:
void HandlePing (void); void HandlePing (void);
void HandleCreativeInventory(short a_SlotNum, const cItem & a_HeldItem); void HandleCreativeInventory(short a_SlotNum, const cItem & a_HeldItem);
void HandlePlayerPos (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround); void HandlePlayerPos (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround);
void HandleBlockDig (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status); void HandleLeftClick (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status);
void HandleBlockPlace (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem); void HandleRightClick (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, const cItem & a_HeldItem);
void HandleChat (const AString & a_Message); void HandleChat (const AString & a_Message);
void HandlePlayerLook (float a_Rotation, float a_Pitch, bool a_IsOnGround); void HandlePlayerLook (float a_Rotation, float a_Pitch, bool a_IsOnGround);
void HandlePlayerMoveLook (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround); // While m_bPositionConfirmed (normal gameplay) void HandlePlayerMoveLook (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround); // While m_bPositionConfirmed (normal gameplay)
@ -221,16 +222,17 @@ private:
static const unsigned short PING_TIME_MS = 1000; //minecraft sends 1 per 20 ticks (1 second or every 1000 ms) static const unsigned short PING_TIME_MS = 1000; //minecraft sends 1 per 20 ticks (1 second or every 1000 ms)
// Values required for block dig animation // Values required for block dig animation
int m_BlockDigAnim; // Current stage of the animation; -1 if not digging int m_BlockDigAnimStage; // Current stage of the animation; -1 if not digging
int m_BlockDigAnimSpeed; // Current speed of the animation (units ???) int m_BlockDigAnimSpeed; // Current speed of the animation (units ???)
int m_BlockDigX; int m_BlockDigAnimX;
int m_BlockDigY; int m_BlockDigAnimY;
int m_BlockDigZ; int m_BlockDigAnimZ;
char m_LastDigStatus; // To avoid dig/aim bug in the client, store the last position given in a DIG_START packet and compare to that when processing the DIG_FINISH packet:
int m_LastDigX; bool m_HasStartedDigging;
int m_LastDigY; int m_LastDigBlockX;
int m_LastDigZ; int m_LastDigBlockY;
int m_LastDigBlockZ;
enum eState enum eState
{ {
@ -264,6 +266,15 @@ private:
/// Adds a single chunk to be streamed to the client; used by StreamChunks() /// Adds a single chunk to be streamed to the client; used by StreamChunks()
void StreamChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); void StreamChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
/// Handles the DIG_STARTED dig packet:
void HandleBlockDigStarted (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta);
/// Handles the DIG_FINISHED dig packet:
void HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta);
/// Handles the block placing packet when it is a real block placement (not block-using, item-using or eating)
void HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler);
// cSocketThreads::cCallback overrides: // cSocketThreads::cCallback overrides:
virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client
virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client

View File

@ -148,10 +148,10 @@ void cCraftingGrid::ConsumeGrid(const cCraftingGrid & a_Grid)
continue; continue;
} }
int ThisIdx = x + m_Width * y; int ThisIdx = x + m_Width * y;
if (a_Grid.m_Items[ThatIdx].m_ItemID != m_Items[ThisIdx].m_ItemID) if (a_Grid.m_Items[ThatIdx].m_ItemType != m_Items[ThisIdx].m_ItemType)
{ {
LOGWARNING("Consuming incompatible grids: item at (%d, %d) is %d in grid and %d in ingredients. Item not consumed.", LOGWARNING("Consuming incompatible grids: item at (%d, %d) is %d in grid and %d in ingredients. Item not consumed.",
x, y, m_Items[ThisIdx].m_ItemID, a_Grid.m_Items[ThatIdx].m_ItemID x, y, m_Items[ThisIdx].m_ItemType, a_Grid.m_Items[ThatIdx].m_ItemType
); );
continue; continue;
} }
@ -159,7 +159,7 @@ void cCraftingGrid::ConsumeGrid(const cCraftingGrid & a_Grid)
if (NumWantedItems > m_Items[ThisIdx].m_ItemCount) if (NumWantedItems > m_Items[ThisIdx].m_ItemCount)
{ {
LOGWARNING("Consuming more items than there actually are in slot (%d, %d), item %d (want %d, have %d). Item zeroed out.", LOGWARNING("Consuming more items than there actually are in slot (%d, %d), item %d (want %d, have %d). Item zeroed out.",
x, y, m_Items[ThisIdx].m_ItemID, x, y, m_Items[ThisIdx].m_ItemType,
NumWantedItems, m_Items[ThisIdx].m_ItemCount NumWantedItems, m_Items[ThisIdx].m_ItemCount
); );
NumWantedItems = m_Items[ThisIdx].m_ItemCount; NumWantedItems = m_Items[ThisIdx].m_ItemCount;
@ -194,7 +194,7 @@ void cCraftingGrid::Dump(void)
{ {
int idx = x + m_Width * y; int idx = x + m_Width * y;
LOGD("Slot (%d, %d): Type %d, health %d, count %d", LOGD("Slot (%d, %d): Type %d, health %d, count %d",
x, y, m_Items[idx].m_ItemID, m_Items[idx].m_ItemHealth, m_Items[idx].m_ItemCount x, y, m_Items[idx].m_ItemType, m_Items[idx].m_ItemDamage, m_Items[idx].m_ItemCount
); );
} }
} }
@ -248,7 +248,7 @@ void cCraftingRecipe::Dump(void)
LOGD("Recipe ingredients:"); LOGD("Recipe ingredients:");
m_Ingredients.Dump(); m_Ingredients.Dump();
LOGD("Result: Type %d, health %d, count %d", LOGD("Result: Type %d, health %d, count %d",
m_Result.m_ItemID, m_Result.m_ItemHealth, m_Result.m_ItemCount m_Result.m_ItemType, m_Result.m_ItemDamage, m_Result.m_ItemCount
); );
} }
@ -438,8 +438,8 @@ bool cCraftingRecipes::ParseItem(const AString & a_String, cItem & a_Item)
if (Split.size() > 1) if (Split.size() > 1)
{ {
AString Damage = TrimString(Split[1]); AString Damage = TrimString(Split[1]);
a_Item.m_ItemHealth = atoi(Damage.c_str()); a_Item.m_ItemDamage = atoi(Damage.c_str());
if ((a_Item.m_ItemHealth == 0) && (Damage.compare("0") != 0)) if ((a_Item.m_ItemDamage == 0) && (Damage.compare("0") != 0))
{ {
// Parsing the number failed // Parsing the number failed
return false; return false;
@ -662,11 +662,11 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti
if ( if (
(itrS->x >= a_GridWidth) || (itrS->x >= a_GridWidth) ||
(itrS->y >= a_GridHeight) || (itrS->y >= a_GridHeight) ||
(itrS->m_Item.m_ItemID != a_CraftingGrid[GridID].m_ItemID) || // same item type? (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 (itrS->m_Item.m_ItemCount > a_CraftingGrid[GridID].m_ItemCount) || // not enough items
( (
(itrS->m_Item.m_ItemHealth > 0) && // should compare damage values? (itrS->m_Item.m_ItemDamage > 0) && // should compare damage values?
(itrS->m_Item.m_ItemHealth != a_CraftingGrid[GridID].m_ItemHealth) (itrS->m_Item.m_ItemDamage != a_CraftingGrid[GridID].m_ItemDamage)
) )
) )
{ {
@ -711,10 +711,10 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti
} }
int GridIdx = x + a_GridStride * y; int GridIdx = x + a_GridStride * y;
if ( if (
(a_CraftingGrid[GridIdx].m_ItemID == itrS->m_Item.m_ItemID) && (a_CraftingGrid[GridIdx].m_ItemType == itrS->m_Item.m_ItemType) &&
( (
(itrS->m_Item.m_ItemHealth < 0) || // doesn't want damage comparison (itrS->m_Item.m_ItemDamage < 0) || // doesn't want damage comparison
(itrS->m_Item.m_ItemHealth == a_CraftingGrid[GridIdx].m_ItemHealth) // the damage matches (itrS->m_Item.m_ItemDamage == a_CraftingGrid[GridIdx].m_ItemDamage) // the damage matches
) )
) )
{ {

View File

@ -3,20 +3,20 @@
#include "Vector3i.h" #include "Vector3i.h"
#include "Vector3d.h" #include "Vector3d.h"
class cCuboid //tolua_export class cCuboid // tolua_export
{ //tolua_export { // tolua_export
public: //tolua_export public: // tolua_export
cCuboid() {} //tolua_export cCuboid() {} // tolua_export
cCuboid( const cCuboid & a_Cuboid ) : p1( a_Cuboid.p1 ), p2( a_Cuboid.p2 ) {} //tolua_export cCuboid( const cCuboid & a_Cuboid ) : p1( a_Cuboid.p1 ), p2( a_Cuboid.p2 ) {} // tolua_export
cCuboid( const Vector3i & a_p1, const Vector3i & a_p2 ) : p1( a_p1 ), p2( a_p2 ) {} //tolua_export cCuboid( const Vector3i & a_p1, const Vector3i & a_p2 ) : p1( a_p1 ), p2( a_p2 ) {} // tolua_export
Vector3i p1, p2; //tolua_export Vector3i p1, p2; // tolua_export
void Sort(); //tolua_export void Sort(); // tolua_export
bool IsInside( const Vector3i & v ) const //tolua_export bool IsInside( const Vector3i & v ) const // tolua_export
{ //tolua_export { // tolua_export
if( v.x >= p1.x && v.x <= p2.x if( v.x >= p1.x && v.x <= p2.x
&& v.y >= p1.y && v.y <= p2.y && v.y >= p1.y && v.y <= p2.y
&& v.z >= p1.z && v.z <= p2.z ) && v.z >= p1.z && v.z <= p2.z )
@ -24,10 +24,10 @@ public: //tolua_export
return true; return true;
} }
return false; return false;
} //tolua_export } // tolua_export
bool IsInside( const Vector3d & v ) const //tolua_export bool IsInside( const Vector3d & v ) const // tolua_export
{ //tolua_export { // tolua_export
if( v.x >= p1.x && v.x <= p2.x if( v.x >= p1.x && v.x <= p2.x
&& v.y >= p1.y && v.y <= p2.y && v.y >= p1.y && v.y <= p2.y
&& v.z >= p1.z && v.z <= p2.z ) && v.z >= p1.z && v.z <= p2.z )
@ -35,6 +35,6 @@ public: //tolua_export
return true; return true;
} }
return false; return false;
} //tolua_export } // tolua_export
}; //tolua_export }; // tolua_export

View File

@ -5,17 +5,19 @@
typedef unsigned char Byte; typedef unsigned char Byte;
//tolua_begin // tolua_begin
// emissive blocks
extern unsigned char g_BlockLightValue[];
// whether blocks allow spreading
extern unsigned char g_BlockSpreadLightFalloff[];
// whether blocks are transparent (light can shine though)
extern bool g_BlockTransparent[];
// one hit break blocks
extern bool g_BlockOneHitDig[];
//--DO NOT DELETE THIS COMMENT-- //tolua_export /// How much light do the blocks emit on their own?
extern unsigned char g_BlockLightValue[];
/// How much light do the block consume?
extern unsigned char g_BlockSpreadLightFalloff[];
/// Is a block completely transparent? (light doesn't get decreased(?))
extern bool g_BlockTransparent[];
/// Is a block destroyed after a single hit?
extern bool g_BlockOneHitDig[];
@ -41,45 +43,47 @@ enum
DIG_STATUS_DROP_HELD = 4, DIG_STATUS_DROP_HELD = 4,
DIG_STATUS_SHOOT_EAT = 5, DIG_STATUS_SHOOT_EAT = 5,
} ; } ;
//tolua_end // tolua_end
inline bool IsValidBlock( int a_BlockType ) //tolua_export inline bool IsValidBlock(int a_BlockType) // tolua_export
{ //tolua_export { // tolua_export
if( a_BlockType > -1 && if (
a_BlockType <= 145 && //items to 109 are valid for Beta1.8.1.. 1.2.5 is up to 126 (a_BlockType > -1) &&
//a_BlockType != 29 && allow pistons (a_BlockType <= E_BLOCK_MAX_TYPE_ID) &&
//a_BlockType != 33 && allow pistons (a_BlockType != 34) && // Piston extension
a_BlockType != 34 && (a_BlockType != 36) // Piston moved block
a_BlockType != 36 ) )
{ {
return true; return true;
} }
return false; return false;
} //tolua_export } // tolua_export
// Was old :o inline bool IsValidItem(int a_ItemType) // tolua_export
// Changed to fit the style ;) { // tolua_export
inline bool IsValidItem( int a_ItemID ) //tolua_export if (
{ //tolua_export ((a_ItemType >= E_ITEM_FIRST) && (a_ItemType <= E_ITEM_MAX_CONSECUTIVE_TYPE_ID)) || // Basic items range
if( (a_ItemID >= 256 && a_ItemID <= 400) ((a_ItemType >= E_ITEM_FIRST_DISC) && (a_ItemType <= E_ITEM_LAST_DISC)) // Music discs' special range
|| (a_ItemID >= 2256 && a_ItemID <= 2267) ) )
{ {
return true; return true;
} }
if( a_ItemID == 0 ) if (a_ItemType == 0)
{
return false; return false;
}
return IsValidBlock( a_ItemID ); return IsValidBlock(a_ItemType);
} //tolua_export } // tolua_export
@ -87,7 +91,7 @@ inline bool IsValidItem( int a_ItemID ) //tolua_export
inline bool IsBlockWater(BLOCKTYPE a_BlockType) inline bool IsBlockWater(BLOCKTYPE a_BlockType)
{ {
return (a_BlockType == E_BLOCK_WATER || a_BlockType == E_BLOCK_STATIONARY_WATER); return ((a_BlockType == E_BLOCK_WATER) || (a_BlockType == E_BLOCK_STATIONARY_WATER));
} }
@ -96,15 +100,22 @@ inline bool IsBlockWater(BLOCKTYPE a_BlockType)
inline bool IsBlockLava(BLOCKTYPE a_BlockType) inline bool IsBlockLava(BLOCKTYPE a_BlockType)
{ {
return (a_BlockType == E_BLOCK_LAVA || a_BlockType == E_BLOCK_STATIONARY_LAVA); return ((a_BlockType == E_BLOCK_LAVA) || (a_BlockType == E_BLOCK_STATIONARY_LAVA));
} }
inline bool IsBlockLiquid(BLOCKTYPE a_BlockType) inline bool IsBlockLiquid(BLOCKTYPE a_BlockType)
{ {
return IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType); return IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType);
} }
inline bool IsBlockTypeOfDirt(BLOCKTYPE a_BlockType) inline bool IsBlockTypeOfDirt(BLOCKTYPE a_BlockType)
{ {
switch (a_BlockType) switch (a_BlockType)
@ -112,7 +123,9 @@ inline bool IsBlockTypeOfDirt(BLOCKTYPE a_BlockType)
case E_BLOCK_DIRT: case E_BLOCK_DIRT:
case E_BLOCK_GRASS: case E_BLOCK_GRASS:
case E_BLOCK_FARMLAND: case E_BLOCK_FARMLAND:
{
return true; return true;
}
} }
return false; return false;
} }
@ -120,63 +133,72 @@ inline bool IsBlockTypeOfDirt(BLOCKTYPE a_BlockType)
inline void AddDirection( int & a_X, int & a_Y, int & a_Z, char a_Direction, bool a_bInverse = false ) inline void AddFaceDirection(int & a_BlockX, int & a_BlockY, int & a_BlockZ, char a_BlockFace, bool a_bInverse = false) // tolua_export
{ { // tolua_export
if (!a_bInverse) if (!a_bInverse)
{ {
switch (a_Direction) switch (a_BlockFace)
{ {
case BLOCK_FACE_BOTTOM: a_Y--; break; case BLOCK_FACE_BOTTOM: a_BlockY--; break;
case BLOCK_FACE_TOP: a_Y++; break; case BLOCK_FACE_TOP: a_BlockY++; break;
case BLOCK_FACE_EAST: a_X++; break; case BLOCK_FACE_EAST: a_BlockX++; break;
case BLOCK_FACE_WEST: a_X--; break; case BLOCK_FACE_WEST: a_BlockX--; break;
case BLOCK_FACE_NORTH: a_Z--; break; case BLOCK_FACE_NORTH: a_BlockZ--; break;
case BLOCK_FACE_SOUTH: a_Z++; break; case BLOCK_FACE_SOUTH: a_BlockZ++; break;
default: default:
{ {
LOGWARNING("AddDirection(): Unknown direction: %d", a_Direction); LOGWARNING("%s: Unknown face: %d", __FUNCTION__, a_BlockFace);
ASSERT(!"AddDirection(): Unknown direction"); ASSERT(!"AddFaceDirection(): Unknown face");
break; break;
} }
} }
} }
else else
{ {
switch( a_Direction ) // other way around switch (a_BlockFace)
{ {
case BLOCK_FACE_BOTTOM: a_Y++; break; case BLOCK_FACE_BOTTOM: a_BlockY++; break;
case BLOCK_FACE_TOP: a_Y--; break; case BLOCK_FACE_TOP: a_BlockY--; break;
case BLOCK_FACE_EAST: a_X--; break; case BLOCK_FACE_EAST: a_BlockX--; break;
case BLOCK_FACE_WEST: a_X++; break; case BLOCK_FACE_WEST: a_BlockX++; break;
case BLOCK_FACE_NORTH: a_Z++; break; case BLOCK_FACE_NORTH: a_BlockZ++; break;
case BLOCK_FACE_SOUTH: a_Z--; break; case BLOCK_FACE_SOUTH: a_BlockZ--; break;
default: default:
{ {
LOGWARNING("AddDirection(): Unknown inv direction: %d", a_Direction); LOGWARNING("%s: Unknown inv face: %d", __FUNCTION__, a_BlockFace);
ASSERT(!"AddDirection(): Unknown direction"); ASSERT(!"AddFaceDirection(): Unknown face");
break; break;
} }
} }
} }
} // tolua_export
inline void AddFaceDirection(int & a_BlockX, unsigned char & a_BlockY, int & a_BlockZ, char a_BlockFace, bool a_bInverse = false)
{
int Y = a_BlockY;
AddFaceDirection(a_BlockX, Y, a_BlockZ, a_BlockFace, a_bInverse);
if (Y < 0)
{
a_BlockY = 0;
}
else if (Y > 255)
{
a_BlockY = 255;
}
else
{
a_BlockY = (unsigned char)Y;
}
} }
inline void AddDirection( int & a_X, unsigned char & a_Y, int & a_Z, char a_Direction, bool a_bInverse = false ) //tolua_export
{//tolua_export
int Y = a_Y;
AddDirection( a_X, Y, a_Z, a_Direction, a_bInverse );
if( Y < 0 ) a_Y = 0;
else if( Y > 255 ) a_Y = 255;
else a_Y = (unsigned char)Y;
}//tolua_export
#include <math.h> #include <math.h>
#define PI 3.14159265358979323846264338327950288419716939937510582097494459072381640628620899862803482534211706798f #define PI 3.14159265358979323846264338327950288419716939937510582097494459072381640628620899862803482534211706798f
#define MIN(a,b) (((a)>(b))?(b):(a)) #define MIN(a,b) (((a)>(b))?(b):(a))
@ -225,7 +247,7 @@ inline float GetSpecialSignf( float a_Val )
//tolua_begin // tolua_begin
namespace ItemCategory namespace ItemCategory
{ {
inline bool IsPickaxe(short a_ItemID) inline bool IsPickaxe(short a_ItemID)
@ -344,7 +366,7 @@ namespace ItemCategory
); );
} }
} }
//tolua_end // tolua_end
inline bool BlockRequiresSpecialTool(BLOCKTYPE a_BlockType) inline bool BlockRequiresSpecialTool(BLOCKTYPE a_BlockType)
@ -354,7 +376,7 @@ inline bool BlockRequiresSpecialTool(BLOCKTYPE a_BlockType)
} }
//tolua_begin // tolua_begin
enum eGameMode enum eGameMode
{ {
eGameMode_NotSet = -1, eGameMode_NotSet = -1,
@ -377,7 +399,7 @@ enum eWeather
//tolua_end // tolua_end

View File

@ -121,7 +121,7 @@ void cDispenserEntity::Dispense()
else else
{ {
cItems Pickups; cItems Pickups;
Pickups.push_back(cItem(Drop.m_ItemType, 1, Drop.m_ItemHealth)); Pickups.push_back(cItem(Drop.m_ItemType, 1, Drop.m_ItemDamage));
m_World->SpawnItemPickups(Pickups, Disp_X, Disp_Y, Disp_Z); m_World->SpawnItemPickups(Pickups, Disp_X, Disp_Y, Disp_Z);
m_Items[OccupiedSlots[RandomSlot]].m_ItemCount--; m_Items[OccupiedSlots[RandomSlot]].m_ItemCount--;
} }
@ -138,7 +138,7 @@ void cDispenserEntity::Dispense()
else else
{ {
cItems Pickups; cItems Pickups;
Pickups.push_back(cItem(Drop.m_ItemType, 1, Drop.m_ItemHealth)); Pickups.push_back(cItem(Drop.m_ItemType, 1, Drop.m_ItemDamage));
m_World->SpawnItemPickups(Pickups, Disp_X, Disp_Y, Disp_Z); m_World->SpawnItemPickups(Pickups, Disp_X, Disp_Y, Disp_Z);
m_Items[OccupiedSlots[RandomSlot]].m_ItemCount--; m_Items[OccupiedSlots[RandomSlot]].m_ItemCount--;
} }
@ -155,7 +155,7 @@ void cDispenserEntity::Dispense()
else else
{ {
cItems Pickups; cItems Pickups;
Pickups.push_back(cItem(Drop.m_ItemType, 1, Drop.m_ItemHealth)); Pickups.push_back(cItem(Drop.m_ItemType, 1, Drop.m_ItemDamage));
m_World->SpawnItemPickups(Pickups, Disp_X, Disp_Y, Disp_Z); m_World->SpawnItemPickups(Pickups, Disp_X, Disp_Y, Disp_Z);
m_Items[OccupiedSlots[RandomSlot]].m_ItemCount--; m_Items[OccupiedSlots[RandomSlot]].m_ItemCount--;
} }
@ -172,7 +172,7 @@ void cDispenserEntity::Dispense()
default: default:
{ {
cItems Pickups; cItems Pickups;
Pickups.push_back(cItem(Drop.m_ItemType, 1, Drop.m_ItemHealth)); Pickups.push_back(cItem(Drop.m_ItemType, 1, Drop.m_ItemDamage));
m_World->SpawnItemPickups(Pickups, Disp_X, Disp_Y, Disp_Z); m_World->SpawnItemPickups(Pickups, Disp_X, Disp_Y, Disp_Z);
m_Items[OccupiedSlots[RandomSlot]].m_ItemCount--; m_Items[OccupiedSlots[RandomSlot]].m_ItemCount--;
break; break;
@ -280,9 +280,9 @@ bool cDispenserEntity::LoadFromFile(cFile & f)
for(unsigned int i = 0; i < NumSlots; i++) for(unsigned int i = 0; i < NumSlots; i++)
{ {
cItem & Item = m_Items[i]; cItem & Item = m_Items[i];
READ(f, Item.m_ItemID); READ(f, Item.m_ItemType);
READ(f, Item.m_ItemCount); READ(f, Item.m_ItemCount);
READ(f, Item.m_ItemHealth); READ(f, Item.m_ItemDamage);
} }
return true; return true;

View File

@ -1,11 +1,11 @@
#pragma once #pragma once
class cDoors //tolua_export class cDoors // tolua_export
{ //tolua_export { // tolua_export
public: public:
static char RotationToMetaData( float a_Rotation ) //tolua_export static char RotationToMetaData( float a_Rotation ) // tolua_export
{ //tolua_export { // tolua_export
a_Rotation += 90 + 45; // So its not aligned with axis a_Rotation += 90 + 45; // So its not aligned with axis
if( a_Rotation > 360.f ) a_Rotation -= 360.f; if( a_Rotation > 360.f ) a_Rotation -= 360.f;
if( a_Rotation >= 0.f && a_Rotation < 90.f ) if( a_Rotation >= 0.f && a_Rotation < 90.f )
@ -16,18 +16,18 @@ public:
return 0x1; return 0x1;
else else
return 0x3; return 0x3;
} //tolua_export } // tolua_export
static char ChangeStateMetaData( char a_MetaData ) //tolua_export static char ChangeStateMetaData( char a_MetaData ) // tolua_export
{ //tolua_export { // tolua_export
a_MetaData ^= 4; //XOR bit 2 aka 3. bit (Door open state) a_MetaData ^= 4; //XOR bit 2 aka 3. bit (Door open state)
return a_MetaData; return a_MetaData;
} //tolua_export } // tolua_export
static void ChangeDoor(cWorld *a_World, int a_X, int a_Y, int a_Z) //tolua_export static void ChangeDoor(cWorld *a_World, int a_X, int a_Y, int a_Z) // tolua_export
{ //tolua_export { // tolua_export
char OldMetaData = a_World->GetBlockMeta(a_X, a_Y, a_Z); char OldMetaData = a_World->GetBlockMeta(a_X, a_Y, a_Z);
a_World->SetBlockMeta(a_X, a_Y, a_Z, ChangeStateMetaData ( OldMetaData ) ); a_World->SetBlockMeta(a_X, a_Y, a_Z, ChangeStateMetaData ( OldMetaData ) );
@ -51,11 +51,11 @@ public:
a_World->SetBlockMeta(a_X, a_Y + 1, a_Z, ChangeStateMetaData ( TopMeta ) ); a_World->SetBlockMeta(a_X, a_Y + 1, a_Z, ChangeStateMetaData ( TopMeta ) );
} }
} }
} //tolua_export } // tolua_export
inline static bool IsDoor(char a_Block) inline static bool IsDoor(char a_Block)
{ {
return (a_Block == E_BLOCK_WOODEN_DOOR || a_Block == E_BLOCK_IRON_DOOR); return (a_Block == E_BLOCK_WOODEN_DOOR || a_Block == E_BLOCK_IRON_DOOR);
} }
}; //tolua_export }; // tolua_export

View File

@ -140,10 +140,10 @@ public:
void SetRoll (float a_Roll); void SetRoll (float a_Roll);
// tolua_end // tolua_end
inline int GetUniqueID(void) const { return m_UniqueID; } //tolua_export inline int GetUniqueID(void) const { return m_UniqueID; } // tolua_export
inline bool IsDestroyed(void) const { return m_bDestroyed; } //tolua_export inline bool IsDestroyed(void) const { return m_bDestroyed; } // tolua_export
void Destroy(); //tolua_export void Destroy(); // tolua_export
void RemoveFromChunk(void); // for internal use in cChunk void RemoveFromChunk(void); // for internal use in cChunk
virtual void Tick(float a_Dt, MTRand & a_TickRandom); // tolua_export virtual void Tick(float a_Dt, MTRand & a_TickRandom); // tolua_export
@ -199,7 +199,7 @@ protected:
float m_FireDamageInterval; float m_FireDamageInterval;
float m_BurnPeriod; float m_BurnPeriod;
}; //tolua_export }; // tolua_export
typedef std::list<cEntity *> cEntityList; typedef std::list<cEntity *> cEntityList;

View File

@ -138,8 +138,8 @@ bool cFurnaceEntity::Tick( float a_Dt )
m_Items[0].m_ItemCount--; m_Items[0].m_ItemCount--;
if( m_Items[0].IsEmpty() ) m_Items[0].Empty(); if( m_Items[0].IsEmpty() ) m_Items[0].Empty();
m_Items[2].m_ItemHealth = m_CookingItem->m_ItemHealth; m_Items[2].m_ItemDamage = m_CookingItem->m_ItemDamage;
m_Items[2].m_ItemID = m_CookingItem->m_ItemID; m_Items[2].m_ItemType = m_CookingItem->m_ItemType;
m_Items[2].m_ItemCount += m_CookingItem->m_ItemCount; m_Items[2].m_ItemCount += m_CookingItem->m_ItemCount;
delete m_CookingItem; delete m_CookingItem;
m_CookingItem = NULL; m_CookingItem = NULL;
@ -299,14 +299,14 @@ bool cFurnaceEntity::LoadFromFile(cFile & f)
for(unsigned int i = 0; i < NumSlots; i++) for(unsigned int i = 0; i < NumSlots; i++)
{ {
cItem & Item = m_Items[i]; cItem & Item = m_Items[i];
READ(f, Item.m_ItemID); READ(f, Item.m_ItemType);
READ(f, Item.m_ItemCount); READ(f, Item.m_ItemCount);
READ(f, Item.m_ItemHealth); READ(f, Item.m_ItemDamage);
} }
cItem CookingItem; cItem CookingItem;
READ(f, CookingItem.m_ItemID); READ(f, CookingItem.m_ItemType);
READ(f, CookingItem.m_ItemCount); READ(f, CookingItem.m_ItemCount);
READ(f, CookingItem.m_ItemHealth); READ(f, CookingItem.m_ItemDamage);
if (!CookingItem.IsEmpty()) if (!CookingItem.IsEmpty())
{ {
m_CookingItem = new cItem(CookingItem); m_CookingItem = new cItem(CookingItem);

View File

@ -204,7 +204,7 @@ const cFurnaceRecipe::Recipe* cFurnaceRecipe::GetRecipeFrom( const cItem & a_Ing
for( RecipeList::const_iterator itr = m_pState->Recipes.begin(); itr != m_pState->Recipes.end(); ++itr ) for( RecipeList::const_iterator itr = m_pState->Recipes.begin(); itr != m_pState->Recipes.end(); ++itr )
{ {
const Recipe & R = *itr; const Recipe & R = *itr;
if( (R.In->m_ItemID == a_Ingredient.m_ItemID) && (R.In->m_ItemCount <= a_Ingredient.m_ItemCount ) ) if( (R.In->m_ItemType == a_Ingredient.m_ItemType) && (R.In->m_ItemCount <= a_Ingredient.m_ItemCount ) )
{ {
if( BestRecipe && (BestRecipe->In->m_ItemCount > R.In->m_ItemCount) ) if( BestRecipe && (BestRecipe->In->m_ItemCount > R.In->m_ItemCount) )
{ {
@ -225,7 +225,7 @@ float cFurnaceRecipe::GetBurnTime( const cItem & a_Fuel ) const
for( FuelList::const_iterator itr = m_pState->Fuel.begin(); itr != m_pState->Fuel.end(); ++itr ) for( FuelList::const_iterator itr = m_pState->Fuel.begin(); itr != m_pState->Fuel.end(); ++itr )
{ {
const Fuel & F = *itr; const Fuel & F = *itr;
if( (F.In->m_ItemID == a_Fuel.m_ItemID) && (F.In->m_ItemCount <= a_Fuel.m_ItemCount ) ) if( (F.In->m_ItemType == a_Fuel.m_ItemType) && (F.In->m_ItemCount <= a_Fuel.m_ItemCount ) )
{ {
if( BestFuel > 0.f && (BestFuel > F.BurnTime ) ) if( BestFuel > 0.f && (BestFuel > F.BurnTime ) )
{ {

View File

@ -597,7 +597,7 @@ void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
true true
); );
cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_CHUNK_GENERATED, 3, m_World, a_ChunkX, a_ChunkZ); cRoot::Get()->GetPluginManager()->CallHookChunkGenerated(m_World, a_ChunkX, a_ChunkZ);
} }

View File

@ -5,20 +5,20 @@
class cGroup //tolua_export class cGroup // tolua_export
{ //tolua_export { // tolua_export
public: //tolua_export public: // tolua_export
cGroup() {} cGroup() {}
~cGroup() {} ~cGroup() {}
void SetName( std::string a_Name ) { m_Name = a_Name; } //tolua_export void SetName( std::string a_Name ) { m_Name = a_Name; } // tolua_export
const std::string & GetName() const { return m_Name; } //tolua_export const std::string & GetName() const { return m_Name; } // tolua_export
void SetColor( std::string a_Color ) { m_Color = a_Color; } //tolua_export void SetColor( std::string a_Color ) { m_Color = a_Color; } // tolua_export
void AddCommand( std::string a_Command ); //tolua_export void AddCommand( std::string a_Command ); // tolua_export
void AddPermission( std::string a_Permission ); //tolua_export void AddPermission( std::string a_Permission ); // tolua_export
void InheritFrom( cGroup* a_Group ); //tolua_export void InheritFrom( cGroup* a_Group ); // tolua_export
bool HasCommand( std::string a_Command ); //tolua_export bool HasCommand( std::string a_Command ); // tolua_export
typedef std::map< std::string, bool > PermissionMap; typedef std::map< std::string, bool > PermissionMap;
const PermissionMap & GetPermissions() const { return m_Permissions; } const PermissionMap & GetPermissions() const { return m_Permissions; }
@ -26,7 +26,7 @@ public: //tolua_export
typedef std::map< std::string, bool > CommandMap; typedef std::map< std::string, bool > CommandMap;
const CommandMap & GetCommands() const { return m_Commands; } const CommandMap & GetCommands() const { return m_Commands; }
const AString & GetColor() const { return m_Color; } //tolua_export const AString & GetColor() const { return m_Color; } // tolua_export
typedef std::list< cGroup* > GroupList; typedef std::list< cGroup* > GroupList;
const GroupList & GetInherits() const { return m_Inherits; } const GroupList & GetInherits() const { return m_Inherits; }
@ -37,4 +37,4 @@ private:
PermissionMap m_Permissions; PermissionMap m_Permissions;
CommandMap m_Commands; CommandMap m_Commands;
GroupList m_Inherits; GroupList m_Inherits;
};//tolua_export };// tolua_export

View File

@ -12,16 +12,19 @@
typedef std::map< AString, cGroup* > GroupMap; typedef std::map< AString, cGroup* > GroupMap;
struct cGroupManager::sGroupManagerState struct cGroupManager::sGroupManagerState
{ {
GroupMap Groups; GroupMap Groups;
}; };
cGroupManager* cGroupManager::GetGroupManager()
{
LOGWARN("WARNING: Using deprecated function cGroupManager::GetGroupManager() use cRoot::Get()->GetGroupManager() instead!");
return cRoot::Get()->GetGroupManager();
}
cGroupManager::~cGroupManager() cGroupManager::~cGroupManager()
{ {
@ -34,6 +37,10 @@ cGroupManager::~cGroupManager()
delete m_pState; delete m_pState;
} }
cGroupManager::cGroupManager() cGroupManager::cGroupManager()
: m_pState( new sGroupManagerState ) : m_pState( new sGroupManagerState )
{ {
@ -98,6 +105,10 @@ cGroupManager::cGroupManager()
LOG("-- Done Loading Groups --"); LOG("-- Done Loading Groups --");
} }
cGroup* cGroupManager::GetGroup( const AString & a_Name ) cGroup* cGroupManager::GetGroup( const AString & a_Name )
{ {
GroupMap::iterator itr = m_pState->Groups.find( a_Name ); GroupMap::iterator itr = m_pState->Groups.find( a_Name );
@ -110,5 +121,8 @@ cGroup* cGroupManager::GetGroup( const AString & a_Name )
m_pState->Groups[a_Name] = Group; m_pState->Groups[a_Name] = Group;
return Group; return Group;
} }

View File

@ -1,17 +1,30 @@
#pragma once #pragma once
class cGroup; class cGroup;
class cGroupManager class cGroupManager
{ {
public: public:
static cGroupManager * GetGroupManager(); //tolua_export cGroup * GetGroup(const AString & a_Name);
cGroup * GetGroup( const AString & a_Name );
private: private:
friend class cRoot; friend class cRoot;
cGroupManager(); cGroupManager();
~cGroupManager(); ~cGroupManager();
struct sGroupManagerState; struct sGroupManagerState;
sGroupManagerState* m_pState; sGroupManagerState * m_pState;
}; } ;

View File

@ -77,7 +77,7 @@ bool cInventory::AddItem( cItem & a_Item )
{ {
if (ChangedSlots[i]) if (ChangedSlots[i])
{ {
LOGD("cInventory::AddItem(): Item was added to %i ID:%i Count:%i", i, m_Slots[i].m_ItemID, m_Slots[i].m_ItemCount); LOGD("cInventory::AddItem(): Item was added to %i ID:%i Count:%i", i, m_Slots[i].m_ItemType, m_Slots[i].m_ItemCount);
SendSlot(i); SendSlot(i);
} }
} }
@ -107,7 +107,7 @@ bool cInventory::AddItemAnyAmount( cItem & a_Item )
{ {
if (ChangedSlots[i]) if (ChangedSlots[i])
{ {
LOGD("cInventory::AddItemAnyAmount(): Item was added to %i ID:%i Count:%i", i, m_Slots[i].m_ItemID, m_Slots[i].m_ItemCount); LOGD("cInventory::AddItemAnyAmount(): Item was added to %i ID:%i Count:%i", i, m_Slots[i].m_ItemType, m_Slots[i].m_ItemCount);
SendSlot(i); SendSlot(i);
} }
} }
@ -125,7 +125,7 @@ bool cInventory::RemoveItem( cItem & a_Item )
// First check equipped slot // First check equipped slot
if ((m_EquippedSlot >= 0) && (m_EquippedSlot < 9)) if ((m_EquippedSlot >= 0) && (m_EquippedSlot < 9))
{ {
if (m_HotSlots[m_EquippedSlot].m_ItemID == a_Item.m_ItemID) if (m_HotSlots[m_EquippedSlot].m_ItemType == a_Item.m_ItemType)
{ {
cItem & Item = m_HotSlots[m_EquippedSlot]; cItem & Item = m_HotSlots[m_EquippedSlot];
if(Item.m_ItemCount > a_Item.m_ItemCount) if(Item.m_ItemCount > a_Item.m_ItemCount)
@ -149,7 +149,7 @@ bool cInventory::RemoveItem( cItem & a_Item )
for(int i = 0; i < 36; i++) for(int i = 0; i < 36; i++)
{ {
cItem & Item = m_MainSlots[i]; cItem & Item = m_MainSlots[i];
if( Item.m_ItemID == a_Item.m_ItemID ) if( Item.m_ItemType == a_Item.m_ItemType )
{ {
if(Item.m_ItemCount > a_Item.m_ItemCount) if(Item.m_ItemCount > a_Item.m_ItemCount)
{ {
@ -323,7 +323,7 @@ int cInventory::HowManyCanFit(short a_ItemType, short a_ItemDamage, int a_BeginS
{ {
if ( if (
m_Slots[i].IsEmpty() || m_Slots[i].IsEmpty() ||
((m_Slots[i].m_ItemID == a_ItemType) && (m_Slots[i].m_ItemHealth == a_ItemDamage)) ((m_Slots[i].m_ItemType == a_ItemType) && (m_Slots[i].m_ItemDamage == a_ItemDamage))
) )
{ {
int MaxCount = ItemHandler(a_ItemType)->GetMaxStackSize(); int MaxCount = ItemHandler(a_ItemType)->GetMaxStackSize();
@ -345,15 +345,15 @@ int cInventory::MoveItem(short a_ItemType, short a_ItemDamage, int a_Count, int
{ {
if ( if (
m_Slots[i].IsEmpty() || m_Slots[i].IsEmpty() ||
((m_Slots[i].m_ItemID == a_ItemType) && (m_Slots[i].m_ItemHealth == a_ItemDamage)) ((m_Slots[i].m_ItemType == a_ItemType) && (m_Slots[i].m_ItemDamage == a_ItemDamage))
) )
{ {
int MaxCount = ItemHandler(a_ItemType)->GetMaxStackSize(); int MaxCount = ItemHandler(a_ItemType)->GetMaxStackSize();
ASSERT(m_Slots[i].m_ItemCount <= MaxCount); ASSERT(m_Slots[i].m_ItemCount <= MaxCount);
int NumToMove = std::min(a_Count, MaxCount - m_Slots[i].m_ItemCount); int NumToMove = std::min(a_Count, MaxCount - m_Slots[i].m_ItemCount);
m_Slots[i].m_ItemCount += NumToMove; m_Slots[i].m_ItemCount += NumToMove;
m_Slots[i].m_ItemHealth = a_ItemDamage; m_Slots[i].m_ItemDamage = a_ItemDamage;
m_Slots[i].m_ItemID = a_ItemType; m_Slots[i].m_ItemType = a_ItemType;
SendSlot(i); SendSlot(i);
res += NumToMove; res += NumToMove;
a_Count -= NumToMove; a_Count -= NumToMove;
@ -380,7 +380,7 @@ bool cInventory::AddToBar( cItem & a_Item, const int a_Offset, const int a_Size,
int MaxStackSize = cItemHandler::GetItemHandler(a_Item.m_ItemType)->GetMaxStackSize(); int MaxStackSize = cItemHandler::GetItemHandler(a_Item.m_ItemType)->GetMaxStackSize();
for(int i = 0; i < a_Size; i++) for(int i = 0; i < a_Size; i++)
{ {
if( m_Slots[i + a_Offset].m_ItemType == a_Item.m_ItemType && m_Slots[i + a_Offset].m_ItemCount < MaxStackSize && m_Slots[i + a_Offset].m_ItemHealth == a_Item.m_ItemHealth ) if( m_Slots[i + a_Offset].m_ItemType == a_Item.m_ItemType && m_Slots[i + a_Offset].m_ItemCount < MaxStackSize && m_Slots[i + a_Offset].m_ItemDamage == a_Item.m_ItemDamage )
{ {
int NumFree = MaxStackSize - m_Slots[i + a_Offset].m_ItemCount; int NumFree = MaxStackSize - m_Slots[i + a_Offset].m_ItemCount;
if( NumFree >= a_Item.m_ItemCount ) if( NumFree >= a_Item.m_ItemCount )

View File

@ -19,35 +19,35 @@ class cPlayer;
class cInventory //tolua_export class cInventory // tolua_export
{ //tolua_export { // tolua_export
public: public:
cInventory(cPlayer & a_Owner); cInventory(cPlayer & a_Owner);
~cInventory(); ~cInventory();
void Clear(); //tolua_export void Clear(); // tolua_export
cItem* GetSlotsForType( int a_Type ); cItem* GetSlotsForType( int a_Type );
int GetSlotCountForType( int a_Type ); int GetSlotCountForType( int a_Type );
bool AddItem( cItem & a_Item ); //tolua_export bool AddItem( cItem & a_Item ); // tolua_export
bool AddItemAnyAmount( cItem & a_Item ); //tolua_export bool AddItemAnyAmount( cItem & a_Item ); // tolua_export
bool RemoveItem( cItem & a_Item ); //tolua_export bool RemoveItem( cItem & a_Item ); // tolua_export
void SaveToJson(Json::Value & a_Value); void SaveToJson(Json::Value & a_Value);
bool LoadFromJson(Json::Value & a_Value); bool LoadFromJson(Json::Value & a_Value);
void SendWholeInventory(cClientHandle & a_Client); void SendWholeInventory(cClientHandle & a_Client);
cItem * GetSlot(int a_SlotNum ); //tolua_export cItem * GetSlot(int a_SlotNum ); // tolua_export
cItem * GetSlots(void) { return m_Slots; } cItem * GetSlots(void) { return m_Slots; }
const cItem * GetSlots(void) const { return m_Slots; } const cItem * GetSlots(void) const { return m_Slots; }
cItem * GetFromHotBar(int a_HotBarSlotNum); //tolua_export cItem * GetFromHotBar(int a_HotBarSlotNum); // tolua_export
cItem & GetEquippedItem(void); //tolua_export cItem & GetEquippedItem(void); // tolua_export
const cItem & GetEquippedItem(void) const; const cItem & GetEquippedItem(void) const;
void SetEquippedSlot(int a_SlotNum); //tolua_export void SetEquippedSlot(int a_SlotNum); // tolua_export
short GetEquippedSlot(void) { return m_EquippedSlot; } //tolua_export short GetEquippedSlot(void) { return m_EquippedSlot; } // tolua_export
// tolua_begin // tolua_begin
const cItem & GetEquippedHelmet (void) const { return m_Slots[c_ArmorOffset]; } const cItem & GetEquippedHelmet (void) const { return m_Slots[c_ArmorOffset]; }
@ -56,7 +56,7 @@ public:
const cItem & GetEquippedBoots (void) const { return m_Slots[c_ArmorOffset + 3]; } const cItem & GetEquippedBoots (void) const { return m_Slots[c_ArmorOffset + 3]; }
// tolua_end // tolua_end
void SendSlot( int a_SlotNum ); //tolua_export void SendSlot( int a_SlotNum ); // tolua_export
/// Returns how many items of the specified type would fit into the slot range specified /// Returns how many items of the specified type would fit into the slot range specified
int HowManyCanFit(short a_ItemType, short a_ItemDamage, int a_BeginSlot, int a_EndSlot); int HowManyCanFit(short a_ItemType, short a_ItemDamage, int a_BeginSlot, int a_EndSlot);
@ -89,7 +89,7 @@ protected:
short m_EquippedSlot; short m_EquippedSlot;
cPlayer & m_Owner; cPlayer & m_Owner;
}; //tolua_export }; // tolua_export

View File

@ -10,21 +10,21 @@
void cItem::GetJson( Json::Value & a_OutValue ) const void cItem::GetJson( Json::Value & a_OutValue ) const
{ {
a_OutValue["ID"] = m_ItemID; a_OutValue["ID"] = m_ItemType;
if( m_ItemID > 0 ) if( m_ItemType > 0 )
{ {
a_OutValue["Count"] = m_ItemCount; a_OutValue["Count"] = m_ItemCount;
a_OutValue["Health"] = m_ItemHealth; a_OutValue["Health"] = m_ItemDamage;
} }
} }
void cItem::FromJson( const Json::Value & a_Value ) void cItem::FromJson( const Json::Value & a_Value )
{ {
m_ItemID = (ENUM_ITEM_ID)a_Value.get("ID", -1 ).asInt(); m_ItemType = (ENUM_ITEM_ID)a_Value.get("ID", -1 ).asInt();
if( m_ItemID > 0 ) if( m_ItemType > 0 )
{ {
m_ItemCount = (char)a_Value.get("Count", -1 ).asInt(); m_ItemCount = (char)a_Value.get("Count", -1 ).asInt();
m_ItemHealth = (short)a_Value.get("Health", -1 ).asInt(); m_ItemDamage = (short)a_Value.get("Health", -1 ).asInt();
} }
} }

View File

@ -16,48 +16,51 @@ namespace Json
class cItem class cItem
{ {
public: public:
cItem(short a_ItemType = E_ITEM_EMPTY, char a_ItemCount = 0, short a_ItemHealth = 0) cItem(short a_ItemType = E_ITEM_EMPTY, char a_ItemCount = 0, short a_ItemDamage = 0)
: m_ItemType (a_ItemType) : m_ItemType (a_ItemType)
, m_ItemCount (a_ItemCount) , m_ItemCount (a_ItemCount)
, m_ItemHealth(a_ItemHealth) , m_ItemDamage(a_ItemDamage)
{ {
if (!IsValidItem( m_ItemID ) ) m_ItemID = E_ITEM_EMPTY; if (!IsValidItem(m_ItemType))
{
m_ItemType = E_ITEM_EMPTY;
}
} }
void Empty() void Empty()
{ {
m_ItemID = E_ITEM_EMPTY; m_ItemType = E_ITEM_EMPTY;
m_ItemCount = 0; m_ItemCount = 0;
m_ItemHealth = 0; m_ItemDamage = 0;
} }
void Clear(void) void Clear(void)
{ {
m_ItemID = E_ITEM_EMPTY; m_ItemType = E_ITEM_EMPTY;
m_ItemCount = 0; m_ItemCount = 0;
m_ItemHealth = 0; m_ItemDamage = 0;
} }
bool IsEmpty(void) const bool IsEmpty(void) const
{ {
return (m_ItemID <= 0 || m_ItemCount <= 0); return (m_ItemType <= 0 || m_ItemCount <= 0);
} }
bool IsEqual(const cItem & a_Item) const bool IsEqual(const cItem & a_Item) const
{ {
return (IsSameType(a_Item) && (m_ItemHealth == a_Item.m_ItemHealth)); return (IsSameType(a_Item) && (m_ItemDamage == a_Item.m_ItemDamage));
} }
bool IsSameType(const cItem & a_Item) const bool IsSameType(const cItem & a_Item) const
{ {
return (m_ItemID == a_Item.m_ItemID) || (IsEmpty() && a_Item.IsEmpty()); return (m_ItemType == a_Item.m_ItemType) || (IsEmpty() && a_Item.IsEmpty());
} }
// TODO Sorry for writing the functions in the header. But somehow it doesn´t worked when I put them into the cpp File :s // TODO Sorry for writing the functions in the header. But somehow it doesn´t worked when I put them into the cpp File :s
inline int GetMaxDuration(void) const inline int GetMaxDuration(void) const
{ {
switch(m_ItemID) switch (m_ItemType)
{ {
case 256: return 251; case 256: return 251;
case 257: return 251; case 257: return 251;
@ -90,13 +93,13 @@ public:
} }
} }
// Damages a weapon / tool. Returns true when destroyed /// Damages a weapon / tool. Returns true when destroyed
inline bool DamageItem() inline bool DamageItem()
{ {
if (HasDuration()) if (HasDuration())
{ {
m_ItemHealth++; m_ItemDamage++;
if(m_ItemHealth >= GetMaxDuration()) if (m_ItemDamage >= GetMaxDuration())
return true; return true;
} }
return false; return false;
@ -111,23 +114,9 @@ public:
static bool IsEnchantable(short a_ItemType); static bool IsEnchantable(short a_ItemType);
// tolua_end short m_ItemType;
union char m_ItemCount;
{ short m_ItemDamage;
// tolua_begin
short m_ItemID; // OBSOLETE, use m_ItemType instead
short m_ItemType;
// tolua_end
} ;
char m_ItemCount; // tolua_export
union
{
// tolua_begin
short m_ItemHealth; // OBSOLETE, use m_ItemDamage instead
short m_ItemDamage;
// tolua_end
} ;
// tolua_begin
}; };
// tolua_end // tolua_end

View File

@ -3,23 +3,54 @@
#include "ItemHandler.h" #include "ItemHandler.h"
#include "../World.h" #include "../World.h"
#include "../Blocks/BlockBed.h"
class cItemBedHandler : public cItemHandler
class cItemBedHandler :
public cItemHandler
{ {
public: public:
cItemBedHandler(int a_ItemType) cItemBedHandler(int a_ItemType) :
: cItemHandler(a_ItemType) cItemHandler(a_ItemType)
{ {
} }
virtual bool IsPlaceable() override
virtual bool IsPlaceable(void) override
{ {
return true; return true;
} }
virtual BLOCKTYPE GetBlockType() override virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
return E_BLOCK_BED; if (a_BlockFace != BLOCK_FACE_TOP)
{
// Can only be placed on the floor
return false;
}
a_BlockMeta = cBlockBedHandler::RotationToMetaData(a_Player->GetRotation());
// Check if there is empty space for the foot section:
Vector3i Direction = cBlockBedHandler::MetaDataToDirection(a_BlockMeta);
if (a_World->GetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z) != E_BLOCK_AIR)
{
return false;
}
a_BlockType = E_BLOCK_BED;
return true;
} }
}; } ;

View File

@ -3,23 +3,39 @@
#include "ItemHandler.h" #include "ItemHandler.h"
class cItemBrewingStandHandler : public cItemHandler
class cItemBrewingStandHandler :
public cItemHandler
{ {
public: public:
cItemBrewingStandHandler(int a_ItemType) cItemBrewingStandHandler(int a_ItemType) :
: cItemHandler(a_ItemType) cItemHandler(a_ItemType)
{ {
} }
virtual bool IsPlaceable() override
virtual bool IsPlaceable(void) override
{ {
return true; return true;
} }
virtual BLOCKTYPE GetBlockType() override
{
return E_BLOCK_BREWING_STAND;
}
}; virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
a_BlockType = E_BLOCK_BREWING_STAND;
a_BlockMeta = 0;
return true;
}
} ;

View File

@ -37,13 +37,13 @@ public:
bool ScoopUpFluid(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) bool ScoopUpFluid(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace)
{ {
if (a_Dir < 0) if (a_BlockFace < 0)
{ {
return false; return false;
} }
AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_Dir); AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
BLOCKTYPE ClickedBlock; BLOCKTYPE ClickedBlock;
NIBBLETYPE ClickedMeta; NIBBLETYPE ClickedMeta;
a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedMeta); a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedMeta);
@ -100,9 +100,9 @@ public:
} }
bool PlaceFluid(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir, BLOCKTYPE a_FluidBlock) bool PlaceFluid(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_FluidBlock)
{ {
if (a_Dir < 0) if (a_BlockFace < 0)
{ {
return false; return false;
} }
@ -112,7 +112,7 @@ public:
if (!CanWashAway) if (!CanWashAway)
{ {
// The block pointed at cannot be washed away, so put fluid on top of it / on its sides // The block pointed at cannot be washed away, so put fluid on top of it / on its sides
AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_Dir); AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
CurrentBlock = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); CurrentBlock = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
} }
if ( if (

View File

@ -3,23 +3,39 @@
#include "ItemHandler.h" #include "ItemHandler.h"
class cItemCauldronHandler : public cItemHandler
class cItemCauldronHandler :
public cItemHandler
{ {
public: public:
cItemCauldronHandler(int a_ItemType) cItemCauldronHandler(int a_ItemType) :
: cItemHandler(a_ItemType) cItemHandler(a_ItemType)
{ {
} }
virtual bool IsPlaceable() override
virtual bool IsPlaceable(void) override
{ {
return true; return true;
} }
virtual BLOCKTYPE GetBlockType() override
{
return E_BLOCK_CAULDRON;
}
}; virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
a_BlockType = E_BLOCK_CAULDRON;
a_BlockMeta = 0;
return true;
}
} ;

View File

@ -4,23 +4,42 @@
#include "ItemHandler.h" #include "ItemHandler.h"
#include "../World.h" #include "../World.h"
class cItemDoorHandler : public cItemHandler
class cItemDoorHandler :
public cItemHandler
{ {
public: public:
cItemDoorHandler(int a_ItemType) cItemDoorHandler(int a_ItemType) :
: cItemHandler(a_ItemType) cItemHandler(a_ItemType)
{ {
} }
virtual bool IsPlaceable() override virtual bool IsPlaceable(void) override
{ {
return true; return true;
} }
virtual BLOCKTYPE GetBlockType() override virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
return (m_ItemType == E_ITEM_WOODEN_DOOR) ? E_BLOCK_WOODEN_DOOR : E_BLOCK_IRON_DOOR; a_BlockType = (m_ItemType == E_ITEM_WOODEN_DOOR) ? E_BLOCK_WOODEN_DOOR : E_BLOCK_IRON_DOOR;
return BlockHandler(a_BlockType)->GetPlacementBlockTypeMeta(
a_World, a_Player,
a_BlockX, a_BlockY, a_BlockZ, a_BlockFace,
a_CursorX, a_CursorY, a_CursorZ,
a_BlockType, a_BlockMeta
);
} }
} ;
};

View File

@ -23,13 +23,13 @@ public:
{ {
// TODO: Handle coloring the sheep, too (OnItemUseOnEntity maybe) // TODO: Handle coloring the sheep, too (OnItemUseOnEntity maybe)
// Handle growing the plants: // Handle growing the plants:
if (a_Item->m_ItemHealth == E_META_DYE_WHITE) if (a_Item->m_ItemDamage == E_META_DYE_WHITE)
{ {
if (a_World->GrowRipePlant(a_BlockX, a_BlockY, a_BlockZ, true)) if (a_World->GrowRipePlant(a_BlockX, a_BlockY, a_BlockZ, true))
{ {
if (a_Player->GetGameMode() != eGameMode_Creative) if (a_Player->GetGameMode() != eGameMode_Creative)
{ {
cItem Item(a_Item->m_ItemType, 1, a_Item->m_ItemHealth); cItem Item(a_Item->m_ItemType, 1, a_Item->m_ItemDamage);
a_Player->GetInventory().RemoveItem(Item); a_Player->GetInventory().RemoveItem(Item);
return true; return true;
} }

View File

@ -3,23 +3,39 @@
#include "ItemHandler.h" #include "ItemHandler.h"
class cItemFlowerPotHandler : public cItemHandler
class cItemFlowerPotHandler :
public cItemHandler
{ {
public: public:
cItemFlowerPotHandler(int a_ItemType) cItemFlowerPotHandler(int a_ItemType) :
: cItemHandler(a_ItemType) cItemHandler(a_ItemType)
{ {
} }
virtual bool IsPlaceable() override
virtual bool IsPlaceable(void) override
{ {
return true; return true;
} }
virtual BLOCKTYPE GetBlockType() override
{
return E_BLOCK_FLOWER_POT;
}
}; virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
a_BlockType = E_BLOCK_FLOWER_POT;
a_BlockMeta = 0;
return true;
}
} ;

View File

@ -386,50 +386,38 @@ bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType)
BLOCKTYPE cItemHandler::GetBlockType() bool cItemHandler::GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
)
{ {
ASSERT(m_ItemType < 256); // Items with IDs above 255 should all be handled by specific handlers ASSERT(m_ItemType < 256); // Items with IDs above 255 should all be handled by specific handlers
#ifdef _DEBUG
if (m_ItemType > 256) if (m_ItemType > 256)
{ {
LOGERROR("Item %d has no valid block!", m_ItemType); LOGERROR("%s: Item %d has no valid block!", __FUNCTION__, m_ItemType);
return false;
} }
#endif // _DEBUG
return (BLOCKTYPE) m_ItemType; cBlockHandler * BlockH = BlockHandler(m_ItemType);
return BlockH->GetPlacementBlockTypeMeta(
a_World, a_Player,
a_BlockX, a_BlockY, a_BlockZ, a_BlockFace,
a_CursorX, a_CursorY, a_CursorZ,
a_BlockType, a_BlockMeta
);
a_BlockType = (BLOCKTYPE) m_ItemType;
a_BlockMeta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage & 0x0f); // This keeps most textures. The few other items have to override this
return true;
} }
NIBBLETYPE cItemHandler::GetBlockMeta(short a_ItemDamage) bool cItemHandler::EatItem(cPlayer * a_Player, cItem * a_Item)
{
return (NIBBLETYPE)a_ItemDamage & 0x0f; // This keeps most textures. The few other items have to override this
}
void cItemHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir)
{
BLOCKTYPE Block = GetBlockType();
cBlockHandler *Handler = cBlockHandler::GetBlockHandler(Block);
Handler->PlaceBlock(a_World, a_Player, GetBlockMeta(a_Item->m_ItemHealth), a_BlockX, a_BlockY, a_BlockZ, a_Dir);
if(a_Player->GetGameMode() == eGameMode_Survival)
{
cItem Item(a_Item->m_ItemType, 1);
a_Player->GetInventory().RemoveItem(Item);
}
}
bool cItemHandler::EatItem(cPlayer *a_Player, cItem *a_Item)
{ {
FoodInfo Info = GetFoodInfo(); FoodInfo Info = GetFoodInfo();

View File

@ -1,6 +1,8 @@
#pragma once #pragma once
#include "../Defines.h" #include "../Defines.h"
#include "../Item.h"
@ -18,13 +20,17 @@ class cItemHandler
{ {
public: public:
cItemHandler(int a_ItemType); cItemHandler(int a_ItemType);
// Called when the player tries to use the item. Return false to make the item unusable. DEFAULT: False
/// Called when the player tries to use the item. Return false to make the item unusable. DEFAULT: False
virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir); //eg for fishing or hoes virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir); //eg for fishing or hoes
// Called while the player diggs a block using this item
/// Called while the player diggs a block using this item
virtual bool OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, cItem * a_HeldItem, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace); virtual bool OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, cItem * a_HeldItem, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace);
// Called when the player destroys a block using this item. This also calls the drop function for the destroyed block
/// Called when the player destroys a block using this item. This also calls the drop function for the destroyed block
virtual void OnBlockDestroyed(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z); virtual void OnBlockDestroyed(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z);
// Called after the player has eaten this item.
/// Called after the player has eaten this item.
virtual void OnFoodEaten(cWorld *a_World, cPlayer *a_Player, cItem *a_Item); virtual void OnFoodEaten(cWorld *a_World, cPlayer *a_Player, cItem *a_Item);
/// Returns the maximum stack size for a given item /// Returns the maximum stack size for a given item
@ -43,34 +49,40 @@ public:
char PoisionChance; //0 - 100 char PoisionChance; //0 - 100
}; };
// Returns the FoodInfo for this item. (FoodRecovery, Saturation and PoisionChance) /// Returns the FoodInfo for this item. (FoodRecovery, Saturation and PoisionChance)
virtual FoodInfo GetFoodInfo(); virtual FoodInfo GetFoodInfo();
// Lets the player eat a selected item. Returns true if the player ate the item /// Lets the player eat a selected item. Returns true if the player ate the item
virtual bool EatItem(cPlayer *a_Player, cItem *a_Item); virtual bool EatItem(cPlayer *a_Player, cItem *a_Item);
// Places the current block and removes the item from the player inventory /// Indicates if this item is a tool
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir); virtual bool IsTool(void);
// Indicates if this item is a tool /// Indicates if this item is food
virtual bool IsTool(); virtual bool IsFood(void);
// Indicates if this item is food
virtual bool IsFood();
//Blocks simply get placed
virtual bool IsPlaceable();
// Returns the block type on placement /// Blocks simply get placed
virtual BLOCKTYPE GetBlockType(); virtual bool IsPlaceable(void);
//Returns the block meta on placement
virtual NIBBLETYPE GetBlockMeta(short a_ItemDamage); /** Called before a block is placed into a world.
// Returns whether this tool/item can harvest a specific block (e.g. wooden pickaxe can harvest stone, but wood can´t) DEFAULT: False The handler should return true to allow placement, false to refuse.
Also, the handler should set a_BlockType and a_BlockMeta to correct values for the newly placed block.
*/
virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
);
/// Returns whether this tool/item can harvest a specific block (e.g. wooden pickaxe can harvest stone, but wood can´t) DEFAULT: False
virtual bool CanHarvestBlock(BLOCKTYPE a_BlockType); virtual bool CanHarvestBlock(BLOCKTYPE a_BlockType);
static cItemHandler *GetItemHandler(int a_ItemType); static cItemHandler * GetItemHandler(int a_ItemType);
static cItemHandler * GetItemHandler(const cItem & a_Item) { return GetItemHandler(a_Item.m_ItemType); }
static void Deinit(); static void Deinit();
protected: protected:
int m_ItemType; int m_ItemType;
static cItemHandler *CreateItemHandler(int m_ItemType); static cItemHandler *CreateItemHandler(int m_ItemType);

View File

@ -10,15 +10,29 @@
class cItemLeavesHandler : class cItemLeavesHandler :
public cItemHandler public cItemHandler
{ {
typedef cItemHandler super;
public: public:
cItemLeavesHandler(int a_ItemType) cItemLeavesHandler(int a_ItemType)
: cItemHandler(a_ItemType) : cItemHandler(a_ItemType)
{ {
} }
virtual NIBBLETYPE GetBlockMeta(short a_ItemDamage) override virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
return (NIBBLETYPE)(a_ItemDamage & 0x0f) | 0x4; //0x4 bit set means this is a player-placed leaves block, not to be decayed bool res = super::GetPlacementBlockTypeMeta(
a_World, a_Player,
a_BlockX, a_BlockY, a_BlockZ, a_BlockFace,
a_CursorX, a_CursorY, a_CursorZ,
a_BlockType, a_BlockMeta
);
a_BlockMeta = a_BlockMeta | 0x4; //0x4 bit set means this is a player-placed leaves block, not to be decayed
return res;
} }
} ; } ;

View File

@ -1,32 +1,40 @@
#pragma once #pragma once
#include "ItemHandler.h" #include "ItemHandler.h"
#include "../World.h" #include "../World.h"
#include "../Player.h" #include "../Player.h"
class cItemLighterHandler : public cItemHandler
class cItemLighterHandler :
public cItemHandler
{ {
public: public:
cItemLighterHandler(int a_ItemType) cItemLighterHandler(int a_ItemType) :
: cItemHandler(a_ItemType) cItemHandler(a_ItemType)
{ {
} }
virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override
{ {
if (a_Dir < 0) if (a_BlockFace < 0)
{ {
return false; return false;
} }
a_Player->UseEquippedItem(); a_Player->UseEquippedItem();
AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_Dir); AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FIRE, 0); //0 -> new fire TODO: Make Firesimulator use this a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FIRE, 0); //0 -> new fire TODO: Make Firesimulator use this
return false; return false;
} }
} ;
};

View File

@ -15,19 +15,21 @@ public:
{ {
} }
virtual bool IsPlaceable() override virtual bool IsPlaceable(void) override
{ {
return true; return true;
} }
virtual BLOCKTYPE GetBlockType() override virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
return E_BLOCK_REDSTONE_WIRE; a_BlockType = E_BLOCK_REDSTONE_WIRE;
} a_BlockMeta = 0;
return true;
virtual NIBBLETYPE GetBlockMeta(short a_ItemDamage) override
{
return 0;
} }
} ; } ;

View File

@ -2,12 +2,14 @@
#pragma once #pragma once
#include "ItemHandler.h" #include "ItemHandler.h"
#include "../Simulator/RedstoneSimulator.h"
class cItemRedstoneRepeaterHandler : public cItemHandler class cItemRedstoneRepeaterHandler :
public cItemHandler
{ {
public: public:
cItemRedstoneRepeaterHandler(int a_ItemType) cItemRedstoneRepeaterHandler(int a_ItemType)
@ -20,14 +22,16 @@ public:
return true; return true;
} }
virtual BLOCKTYPE GetBlockType() override virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
return ::E_BLOCK_REDSTONE_REPEATER_OFF; a_BlockType = E_BLOCK_REDSTONE_REPEATER_OFF;
} a_BlockMeta = cRedstoneSimulator::RepeaterRotationToMetaData(a_Player->GetRotation());
return true;
virtual NIBBLETYPE GetBlockMeta(short a_ItemMeta) override
{
return 0;
} }
} ; } ;

View File

@ -9,6 +9,8 @@
class cItemSaplingHandler : public cItemHandler class cItemSaplingHandler : public cItemHandler
{ {
typedef cItemHandler super;
public: public:
cItemSaplingHandler(int a_ItemType) cItemSaplingHandler(int a_ItemType)
: cItemHandler(a_ItemType) : cItemHandler(a_ItemType)
@ -16,10 +18,22 @@ public:
} }
virtual NIBBLETYPE GetBlockMeta(short a_ItemDamage) override virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
bool res = super::GetPlacementBlockTypeMeta(
a_World, a_Player,
a_BlockX, a_BlockY, a_BlockZ, a_BlockFace,
a_CursorX, a_CursorY, a_CursorZ,
a_BlockType, a_BlockMeta
);
// Only the lowest 3 bits are important // Only the lowest 3 bits are important
return (NIBBLETYPE)(a_ItemDamage & 0x07); a_BlockMeta = a_BlockMeta & 0x7;
return res;
} }
} ; } ;

View File

@ -12,54 +12,49 @@ class cItemSeedsHandler :
public cItemHandler public cItemHandler
{ {
public: public:
cItemSeedsHandler(int a_ItemType) cItemSeedsHandler(int a_ItemType) :
: cItemHandler(a_ItemType) cItemHandler(a_ItemType)
{ {
} }
virtual bool IsPlaceable() override virtual bool IsPlaceable(void) override
{ {
return true; return true;
} }
virtual BLOCKTYPE GetBlockType() override virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
switch(m_ItemType) if (a_BlockFace != BLOCK_FACE_TOP)
{
case E_ITEM_SEEDS: return E_BLOCK_CROPS;
case E_ITEM_MELON_SEEDS: return E_BLOCK_MELON_STEM;
case E_ITEM_PUMPKIN_SEEDS: return E_BLOCK_PUMPKIN_STEM;
default: return E_BLOCK_AIR;
}
}
virtual NIBBLETYPE GetBlockMeta(short a_ItemDamage) override
{
return 0; //Not grown yet
}
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override
{
if (a_Dir != BLOCK_FACE_TOP)
{ {
// Only allow planting seeds from the top side of the block // Only allow planting seeds from the top side of the block
return; return false;
} }
// Only allow placement on farmland
int X = a_BlockX; int X = a_BlockX;
int Y = a_BlockY; int Y = a_BlockY;
int Z = a_BlockZ; int Z = a_BlockZ;
AddFaceDirection(X, Y, Z, a_BlockFace, true);
AddDirection(X, Y, Z, a_Dir, true);
if (a_World->GetBlock(X, Y, Z) != E_BLOCK_FARMLAND) if (a_World->GetBlock(X, Y, Z) != E_BLOCK_FARMLAND)
{ {
return; return false;
} }
return cItemHandler::PlaceBlock(a_World, a_Player, a_Item, a_BlockX, a_BlockY, a_BlockZ, a_Dir); a_BlockMeta = 0;
switch (m_ItemType)
{
case E_ITEM_SEEDS: a_BlockType = E_BLOCK_CROPS; return true;
case E_ITEM_MELON_SEEDS: a_BlockType = E_BLOCK_MELON_STEM; return true;
case E_ITEM_PUMPKIN_SEEDS: a_BlockType = E_BLOCK_PUMPKIN_STEM; return true;
default: a_BlockType = E_BLOCK_AIR; return true;
}
return false;
} }
} ; } ;

View File

@ -3,24 +3,49 @@
#include "ItemHandler.h" #include "ItemHandler.h"
#include "../World.h" #include "../World.h"
#include "../Sign.h"
class cItemSignHandler : public cItemHandler
class cItemSignHandler :
public cItemHandler
{ {
public: public:
cItemSignHandler(int a_ItemType) cItemSignHandler(int a_ItemType) :
: cItemHandler(a_ItemType) cItemHandler(a_ItemType)
{ {
} }
virtual bool IsPlaceable() override
virtual bool IsPlaceable(void) override
{ {
return true; return true;
} }
virtual BLOCKTYPE GetBlockType() override
{
return E_BLOCK_SIGN_POST;
}
}; virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
if (a_BlockFace == BLOCK_FACE_TOP)
{
a_BlockMeta = cSign::RotationToMetaData(a_Player->GetRotation());
a_BlockType = E_BLOCK_SIGN_POST;
}
else
{
a_BlockMeta = cSign::DirectionToMetaData(a_BlockFace);
a_BlockType = E_BLOCK_WALLSIGN;
}
return true;
}
} ;

View File

@ -27,9 +27,9 @@ public:
((a_Dir == 0) || (a_Dir == 1)) // Only when clicking on top or on bottom of the block ((a_Dir == 0) || (a_Dir == 1)) // Only when clicking on top or on bottom of the block
&& ((Block == E_BLOCK_WOODEN_SLAB) || (Block == E_BLOCK_STONE_SLAB)) // It is a slab && ((Block == E_BLOCK_WOODEN_SLAB) || (Block == E_BLOCK_STONE_SLAB)) // It is a slab
&& (Block == a_Item->m_ItemType) // Same slab && (Block == a_Item->m_ItemType) // Same slab
&& ((Meta & 0x7) == (a_Item->m_ItemHealth & 0x7))) // Same Texture && ((Meta & 0x7) == (a_Item->m_ItemDamage & 0x7))) // Same Texture
{ {
if(a_Player->GetGameMode() == eGameMode_Creative) if (a_Player->GetGameMode() == eGameMode_Creative)
{ {
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, Block - 1, Meta); // Block - 1 simple hack to save one if statement a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, Block - 1, Meta); // Block - 1 simple hack to save one if statement
return true; return true;

View File

@ -19,23 +19,23 @@ public:
} }
virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override
{ {
if (a_Dir < 0) if (a_BlockFace < 0)
{ {
return false; return false;
} }
AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_Dir); AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
if (a_Dir == BLOCK_FACE_BOTTOM) if (a_BlockFace == BLOCK_FACE_BOTTOM)
{ {
a_BlockY--; a_BlockY--;
} }
if (a_World->SpawnMob(a_BlockX + 0.5, a_BlockY, a_BlockZ + 0.5, a_Item->m_ItemDamage) >= 0) if (a_World->SpawnMob(a_BlockX + 0.5, a_BlockY, a_BlockZ + 0.5, a_Item->m_ItemDamage) >= 0)
{ {
if(a_Player->GetGameMode() != 1) if (a_Player->GetGameMode() != 1)
{ {
// The mob was spawned, "use" the item: // The mob was spawned, "use" the item:
a_Player->GetInventory().RemoveItem(a_Player->GetInventory().GetEquippedItem()); a_Player->GetInventory().RemoveItem(a_Player->GetInventory().GetEquippedItem());

View File

@ -2,7 +2,6 @@
#pragma once #pragma once
#include "ItemHandler.h" #include "ItemHandler.h"
#include "../World.h"
@ -12,25 +11,26 @@ class cItemSugarcaneHandler :
public cItemHandler public cItemHandler
{ {
public: public:
cItemSugarcaneHandler(int a_ItemType) cItemSugarcaneHandler(int a_ItemType) :
: cItemHandler(a_ItemType) cItemHandler(a_ItemType)
{ {
} }
virtual bool IsPlaceable() override virtual bool IsPlaceable(void) override
{ {
return true; return true;
} }
virtual BLOCKTYPE GetBlockType() override virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{ {
return E_BLOCK_SUGARCANE; a_BlockType = E_BLOCK_SUGARCANE;
} a_BlockMeta = 0;
return true;
virtual NIBBLETYPE GetBlockMeta(short a_ItemDamage) override
{
return 0; //Not grown yet
} }
} ; } ;

View File

@ -1,11 +1,11 @@
#pragma once #pragma once
class cLadder //tolua_export class cLadder // tolua_export
{ //tolua_export { // tolua_export
public: public:
static char DirectionToMetaData( char a_Direction ) //tolua_export static char DirectionToMetaData( char a_Direction ) // tolua_export
{ //tolua_export { // tolua_export
switch( a_Direction ) switch( a_Direction )
{ {
case 0x2: case 0x2:
@ -20,10 +20,10 @@ public:
break; break;
}; };
return 0x2; return 0x2;
} //tolua_export } // tolua_export
static char MetaDataToDirection( char a_MetaData ) //tolua_export static char MetaDataToDirection( char a_MetaData ) // tolua_export
{ //tolua_export { // tolua_export
switch( a_MetaData ) switch( a_MetaData )
{ {
case 0x2: case 0x2:
@ -38,6 +38,6 @@ public:
break; break;
}; };
return 0x2; return 0x2;
} //tolua_export } // tolua_export
}; //tolua_export }; // tolua_export

View File

@ -16,14 +16,14 @@ public:
~cLog(); ~cLog();
void Log(const char* a_Format, va_list argList ); void Log(const char* a_Format, va_list argList );
void Log(const char* a_Format, ...); void Log(const char* a_Format, ...);
//tolua_begin // tolua_begin
void SimpleLog(const char* a_String); void SimpleLog(const char* a_String);
void OpenLog( const char* a_FileName ); void OpenLog( const char* a_FileName );
void CloseLog(); void CloseLog();
void ClearLog(); void ClearLog();
static cLog* GetInstance(); static cLog* GetInstance();
}; };
//tolua_end // tolua_end

View File

@ -2,8 +2,8 @@
#include "ChunkDef.h" #include "ChunkDef.h"
class cLuaChunk //tolua_export class cLuaChunk // tolua_export
{ //tolua_export { // tolua_export
public: public:
cLuaChunk( cChunkDef::BlockTypes & a_BlockTypes cLuaChunk( cChunkDef::BlockTypes & a_BlockTypes
, cChunkDef::BlockNibbles & a_BlockNibbles , cChunkDef::BlockNibbles & a_BlockNibbles
@ -27,7 +27,7 @@ public:
~cLuaChunk() ~cLuaChunk()
{} {}
//tolua_begin // tolua_begin
// Block functions // Block functions
void FillBlocks( char a_BlockType, unsigned char a_BlockMeta ) void FillBlocks( char a_BlockType, unsigned char a_BlockMeta )
@ -124,7 +124,7 @@ public:
return m_bUseDefaultFinish; return m_bUseDefaultFinish;
} }
//tolua_end // tolua_end
private: private:
bool m_bUseDefaultBiomes; bool m_bUseDefaultBiomes;
@ -136,4 +136,4 @@ private:
cChunkDef::BlockTypes & m_BlockTypes; cChunkDef::BlockTypes & m_BlockTypes;
cChunkDef::BlockNibbles & m_BlockMeta; cChunkDef::BlockNibbles & m_BlockMeta;
cChunkDef::HeightMap & m_HeightMap; cChunkDef::HeightMap & m_HeightMap;
}; //tolua_export }; // tolua_export

View File

@ -11,32 +11,48 @@
bool report_errors(lua_State* lua, int status) bool report_errors(lua_State * lua, int status)
{ {
if ( status!=0 ) if (status == 0)
{ {
std::string s = lua_tostring(lua, -1); // No error to report
LOGERROR("-- %s", s.c_str() ); return false;
lua_pop(lua, 1);
return true;
} }
return false;
LOGERROR("LUA: %s", lua_tostring(lua, -1));
lua_pop(lua, 1);
return true;
} }
cLuaCommandBinder::cLuaCommandBinder() cLuaCommandBinder::cLuaCommandBinder()
{ {
} }
cLuaCommandBinder::~cLuaCommandBinder() cLuaCommandBinder::~cLuaCommandBinder()
{ {
} }
void cLuaCommandBinder::ClearBindings() void cLuaCommandBinder::ClearBindings()
{ {
m_BoundCommands.clear(); m_BoundCommands.clear();
} }
void cLuaCommandBinder::RemoveBindingsForPlugin( cPlugin* a_Plugin ) void cLuaCommandBinder::RemoveBindingsForPlugin( cPlugin* a_Plugin )
{ {
for( CommandMap::iterator itr = m_BoundCommands.begin(); itr != m_BoundCommands.end(); ) for( CommandMap::iterator itr = m_BoundCommands.begin(); itr != m_BoundCommands.end(); )
@ -54,6 +70,10 @@ void cLuaCommandBinder::RemoveBindingsForPlugin( cPlugin* a_Plugin )
} }
} }
bool cLuaCommandBinder::BindCommand( const std::string & a_Command, const std::string & a_Permission, cPlugin* a_Plugin, lua_State * a_LuaState, int a_FunctionReference ) bool cLuaCommandBinder::BindCommand( const std::string & a_Command, const std::string & a_Permission, cPlugin* a_Plugin, lua_State * a_LuaState, int a_FunctionReference )
{ {
if( !a_Plugin->CanBindCommands() ) if( !a_Plugin->CanBindCommands() )
@ -71,6 +91,10 @@ bool cLuaCommandBinder::BindCommand( const std::string & a_Command, const std::s
return true; return true;
} }
bool cLuaCommandBinder::HandleCommand( const std::string & a_Command, cPlayer* a_Player ) bool cLuaCommandBinder::HandleCommand( const std::string & a_Command, cPlayer* a_Player )
{ {
AStringVector Split = StringSplit(a_Command, " "); AStringVector Split = StringSplit(a_Command, " ");
@ -124,3 +148,7 @@ bool cLuaCommandBinder::HandleCommand( const std::string & a_Command, cPlayer* a
} }
return false; return false;
} }

View File

@ -10,19 +10,19 @@ class cLog;
class cMCLogger //tolua_export class cMCLogger // tolua_export
{ //tolua_export { // tolua_export
public: //tolua_export public: // tolua_export
cMCLogger(); cMCLogger();
cMCLogger( char* a_File ); //tolua_export cMCLogger( char* a_File ); // tolua_export
~cMCLogger(); //tolua_export ~cMCLogger(); // tolua_export
void Log(const char* a_Format, va_list a_ArgList); void Log(const char* a_Format, va_list a_ArgList);
void Info(const char* a_Format, va_list a_ArgList); void Info(const char* a_Format, va_list a_ArgList);
void Warn(const char* a_Format, va_list a_ArgList); void Warn(const char* a_Format, va_list a_ArgList);
void Error(const char* a_Format, va_list a_ArgList); void Error(const char* a_Format, va_list a_ArgList);
void LogSimple(const char* a_Text, int a_LogType = 0 ); //tolua_export void LogSimple(const char* a_Text, int a_LogType = 0 ); // tolua_export
static cMCLogger* GetInstance(); static cMCLogger* GetInstance();
private: private:
@ -31,7 +31,7 @@ private:
cCriticalSection m_CriticalSection; cCriticalSection m_CriticalSection;
cLog* m_Log; cLog* m_Log;
static cMCLogger* s_MCLogger; static cMCLogger* s_MCLogger;
}; //tolua_export }; // tolua_export
extern void LOG(const char* a_Format, ...); extern void LOG(const char* a_Format, ...);
extern void LOGINFO(const char* a_Format, ...); extern void LOGINFO(const char* a_Format, ...);

View File

@ -20,17 +20,8 @@
static bool report_errors(lua_State* lua, int status) // fwd: LuaCommandBinder.cpp
{ bool report_errors(lua_State* lua, int status);
if ( status!=0 )
{
std::string s = lua_tostring(lua, -1);
LOGERROR("-- %s", s.c_str() );
lua_pop(lua, 1);
return true;
}
return false;
}
@ -665,9 +656,9 @@ static int tolua_cPlugin_BindCommand(lua_State* tolua_S)
static int tolua_cPlugin_NewLua_AddWebTab(lua_State* tolua_S) static int tolua_cPlugin_NewLua_AddWebTab(lua_State * tolua_S)
{ {
cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); cPlugin_NewLua * self = (cPlugin_NewLua*)tolua_tousertype(tolua_S,1,0);
tolua_Error tolua_err; tolua_Error tolua_err;
tolua_err.array = 0; tolua_err.array = 0;

View File

@ -7,21 +7,21 @@
class cBlockingTCPLink //tolua_export class cBlockingTCPLink // tolua_export
{ //tolua_export { // tolua_export
public: //tolua_export public: // tolua_export
cBlockingTCPLink(void); //tolua_export cBlockingTCPLink(void); // tolua_export
~cBlockingTCPLink(); //tolua_export ~cBlockingTCPLink(); // tolua_export
bool Connect( const char* a_Address, unsigned int a_Port ); //tolua_export bool Connect( const char* a_Address, unsigned int a_Port ); // tolua_export
int Send( char* a_Data, unsigned int a_Size, int a_Flags = 0 ); //tolua_export int Send( char* a_Data, unsigned int a_Size, int a_Flags = 0 ); // tolua_export
int SendMessage( const char* a_Message, int a_Flags = 0 ); //tolua_export int SendMessage( const char* a_Message, int a_Flags = 0 ); // tolua_export
void CloseSocket(); //tolua_export void CloseSocket(); // tolua_export
void ReceiveData(AString & oData); //tolua_export void ReceiveData(AString & oData); // tolua_export
protected: protected:
cSocket m_Socket; cSocket m_Socket;
}; //tolua_export }; // tolua_export

View File

@ -2,21 +2,21 @@
#include "Socket.h" #include "Socket.h"
class cTCPLink //tolua_export class cTCPLink // tolua_export
{ //tolua_export { // tolua_export
public: //tolua_export public: // tolua_export
cTCPLink(); //tolua_export cTCPLink(); // tolua_export
~cTCPLink(); //tolua_export ~cTCPLink(); // tolua_export
bool Connect (const AString & a_Address, unsigned int a_Port ); //tolua_export bool Connect (const AString & a_Address, unsigned int a_Port ); // tolua_export
int Send (const char * a_Data, unsigned int a_Size, int a_Flags = 0 ); //tolua_export int Send (const char * a_Data, unsigned int a_Size, int a_Flags = 0 ); // tolua_export
int SendMessage(const char * a_Message, int a_Flags = 0 ); //tolua_export int SendMessage(const char * a_Message, int a_Flags = 0 ); // tolua_export
void CloseSocket(); //tolua_export void CloseSocket(); // tolua_export
protected: //tolua_export protected: // tolua_export
virtual void ReceivedData( char a_Data[256], int a_Size ) = 0; //tolua_export virtual void ReceivedData( char a_Data[256], int a_Size ) = 0; // tolua_export
static void ReceiveThread( void* a_Param ); static void ReceiveThread( void* a_Param );
cSocket m_Socket; cSocket m_Socket;
cEvent* m_StopEvent; cEvent* m_StopEvent;
}; //tolua_export }; // tolua_export

View File

@ -124,7 +124,7 @@ void cPawn::KilledBy(cPawn * a_Killer)
short OldHealth = m_Health; short OldHealth = m_Health;
m_Health = 0; m_Health = 0;
if (cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_KILLED, 2, this, a_Killer)) if (cRoot::Get()->GetPluginManager()->CallHookKilled(*this, a_Killer))
{ {
// Plugin wants to 'unkill' the pawn. Set health back and abort // Plugin wants to 'unkill' the pawn. Set health back and abort
m_Health = OldHealth; m_Health = OldHealth;

View File

@ -165,7 +165,7 @@ protected:
double m_LastPosX, m_LastPosY, m_LastPosZ; double m_LastPosX, m_LastPosY, m_LastPosZ;
Int64 m_TimeLastTeleportPacket; // In ticks Int64 m_TimeLastTeleportPacket; // In ticks
}; //tolua_export }; // tolua_export

View File

@ -24,16 +24,16 @@ class cPickup :
public: public:
CLASS_PROTODEF(cPickup); CLASS_PROTODEF(cPickup);
cPickup(int a_MicroPosX, int a_MicroPosY, int a_MicroPosZ, const cItem & a_Item, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f); //tolua_export cPickup(int a_MicroPosX, int a_MicroPosY, int a_MicroPosZ, const cItem & a_Item, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f); // tolua_export
virtual void Initialize(cWorld * a_World) override; virtual void Initialize(cWorld * a_World) override;
cItem & GetItem(void) {return m_Item; } //tolua_export cItem & GetItem(void) {return m_Item; } // tolua_export
const cItem & GetItem(void) const {return m_Item; } const cItem & GetItem(void) const {return m_Item; }
virtual void SpawnOn(cClientHandle & a_ClientHandle) override; virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
virtual bool CollectedBy(cPlayer * a_Dest); //tolua_export virtual bool CollectedBy(cPlayer * a_Dest); // tolua_export
virtual void Tick(float a_Dt, MTRand & a_TickRandom) override; virtual void Tick(float a_Dt, MTRand & a_TickRandom) override;
virtual void HandlePhysics(float a_Dt) override; virtual void HandlePhysics(float a_Dt) override;
@ -54,7 +54,7 @@ private:
cItem m_Item; cItem m_Item;
bool m_bCollected; bool m_bCollected;
}; //tolua_export }; // tolua_export

View File

@ -174,7 +174,7 @@ void cPlayer::Tick(float a_Dt, MTRand & a_TickRandom)
} }
else if (m_bDirtyPosition) else if (m_bDirtyPosition)
{ {
cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_PLAYER_MOVE, 1, this ); cRoot::Get()->GetPluginManager()->CallHookPlayerMoved(*this);
float DiffX = (float)(GetPosX() - m_LastPosX ); float DiffX = (float)(GetPosX() - m_LastPosX );
float DiffY = (float)(GetPosY() - m_LastPosY ); float DiffY = (float)(GetPosY() - m_LastPosY );
@ -1054,7 +1054,7 @@ void cPlayer::UseEquippedItem()
{ {
if (GetInventory().GetEquippedItem().DamageItem()) if (GetInventory().GetEquippedItem().DamageItem())
{ {
LOG("Player %s Broke ID: %i", GetClientHandle()->GetUsername().c_str(), GetInventory().GetEquippedItem().m_ItemID); LOG("Player %s Broke ID: %i", GetClientHandle()->GetUsername().c_str(), GetInventory().GetEquippedItem().m_ItemType);
GetInventory().RemoveItem( GetInventory().GetEquippedItem()); GetInventory().RemoveItem( GetInventory().GetEquippedItem());
} }
} }

View File

@ -35,7 +35,7 @@ public:
cPlayer(cClientHandle * a_Client, const AString & a_PlayerName); cPlayer(cClientHandle * a_Client, const AString & a_PlayerName);
virtual ~cPlayer(); virtual ~cPlayer();
virtual void Initialize( cWorld* a_World ); //tolua_export virtual void Initialize( cWorld* a_World ); // tolua_export
virtual void SpawnOn(cClientHandle & a_Client) override; virtual void SpawnOn(cClientHandle & a_Client) override;
@ -58,83 +58,84 @@ public:
void SetTouchGround( bool a_bTouchGround ); void SetTouchGround( bool a_bTouchGround );
inline void SetStance( const double a_Stance ) { m_Stance = a_Stance; } inline void SetStance( const double a_Stance ) { m_Stance = a_Stance; }
double GetEyeHeight(); //tolua_export double GetEyeHeight(); // tolua_export
Vector3d GetEyePosition(); //tolua_export Vector3d GetEyePosition(); // tolua_export
inline bool IsOnGround(void) const {return m_bTouchGround; } // tolua_export inline bool IsOnGround(void) const {return m_bTouchGround; } // tolua_export
inline const double GetStance(void) const { return m_Pos.y + 1.62; } //tolua_export // TODO: Proper stance when crouching etc. inline const double GetStance(void) const { return m_Pos.y + 1.62; } // tolua_export // TODO: Proper stance when crouching etc.
inline cInventory & GetInventory(void) { return m_Inventory; } //tolua_export inline cInventory & GetInventory(void) { return m_Inventory; } // tolua_export
inline const cInventory & GetInventory(void) const { return m_Inventory; } inline const cInventory & GetInventory(void) const { return m_Inventory; }
inline const cItem & GetEquippedItem(void) const {return GetInventory().GetEquippedItem(); } // tolua_export inline cItem & GetEquippedItem(void) { return GetInventory().GetEquippedItem(); } // tolua_export
inline const cItem & GetEquippedItem(void) const { return GetInventory().GetEquippedItem(); }
virtual void TeleportTo(double a_PosX, double a_PosY, double a_PosZ) override; virtual void TeleportTo(double a_PosX, double a_PosY, double a_PosZ) override;
eGameMode GetGameMode(void) const { return m_GameMode; } //tolua_export eGameMode GetGameMode(void) const { return m_GameMode; } // tolua_export
std::string GetIP() { return m_IP; } //tolua_export std::string GetIP() { return m_IP; } // tolua_export
float GetLastBlockActionTime() { return m_LastBlockActionTime; } //tolua_export float GetLastBlockActionTime() { return m_LastBlockActionTime; } // tolua_export
int GetLastBlockActionCnt() { return m_LastBlockActionCnt; } //tolua_export int GetLastBlockActionCnt() { return m_LastBlockActionCnt; } // tolua_export
void SetLastBlockActionCnt( int ); //tolua_export void SetLastBlockActionCnt( int ); // tolua_export
void SetLastBlockActionTime(); //tolua_export void SetLastBlockActionTime(); // tolua_export
void SetGameMode( eGameMode a_GameMode ); //tolua_export void SetGameMode( eGameMode a_GameMode ); // tolua_export
void LoginSetGameMode( eGameMode a_GameMode ); void LoginSetGameMode( eGameMode a_GameMode );
void SetIP(const AString & a_IP); void SetIP(const AString & a_IP);
// Tries to move to a new position, with collision checks and stuff // Tries to move to a new position, with collision checks and stuff
virtual void MoveTo( const Vector3d & a_NewPos ); //tolua_export virtual void MoveTo( const Vector3d & a_NewPos ); // tolua_export
cWindow* GetWindow() { return m_CurrentWindow; } cWindow* GetWindow() { return m_CurrentWindow; }
void OpenWindow( cWindow* a_Window ); void OpenWindow( cWindow* a_Window );
void CloseWindow(char a_WindowType); void CloseWindow(char a_WindowType);
cClientHandle * GetClientHandle(void) const { return m_ClientHandle; } //tolua_export cClientHandle * GetClientHandle(void) const { return m_ClientHandle; } // tolua_export
void SendMessage(const AString & a_Message); //tolua_export void SendMessage(const AString & a_Message); // tolua_export
const AString & GetName(void) const { return m_PlayerName; } //tolua_export const AString & GetName(void) const { return m_PlayerName; } // tolua_export
void SetName(const AString & a_Name) { m_PlayerName = a_Name; } //tolua_export void SetName(const AString & a_Name) { m_PlayerName = a_Name; } // tolua_export
typedef std::list< cGroup* > GroupList; typedef std::list< cGroup* > GroupList;
typedef std::list< std::string > StringList; typedef std::list< std::string > StringList;
/// Adds a player to existing group or creates a new group when it doesn't exist /// Adds a player to existing group or creates a new group when it doesn't exist
void AddToGroup( const AString & a_GroupName ); //tolua_export void AddToGroup( const AString & a_GroupName ); // tolua_export
/// Removes a player from the group, resolves permissions and group inheritance (case sensitive) /// Removes a player from the group, resolves permissions and group inheritance (case sensitive)
void RemoveFromGroup( const AString & a_GroupName ); //tolua_export void RemoveFromGroup( const AString & a_GroupName ); // tolua_export
bool CanUseCommand( const AString & a_Command ); //tolua_export bool CanUseCommand( const AString & a_Command ); // tolua_export
bool HasPermission( const AString & a_Permission ); //tolua_export bool HasPermission( const AString & a_Permission ); // tolua_export
const GroupList & GetGroups() { return m_Groups; } // >> EXPORTED IN MANUALBINDINGS << const GroupList & GetGroups() { return m_Groups; } // >> EXPORTED IN MANUALBINDINGS <<
StringList GetResolvedPermissions(); // >> EXPORTED IN MANUALBINDINGS << StringList GetResolvedPermissions(); // >> EXPORTED IN MANUALBINDINGS <<
bool IsInGroup( const AString & a_Group ); //tolua_export bool IsInGroup( const AString & a_Group ); // tolua_export
AString GetColor(void) const; //tolua_export AString GetColor(void) const; // tolua_export
void TossItem(bool a_bDraggingItem, char a_Amount = 1, short a_CreateType = 0, short a_CreateHealth = 0); //tolua_export void TossItem(bool a_bDraggingItem, char a_Amount = 1, short a_CreateType = 0, short a_CreateHealth = 0); // tolua_export
void Heal( int a_Health ); //tolua_export void Heal( int a_Health ); // tolua_export
/// Returns true if any food has been consumed, false if player "full" /// Returns true if any food has been consumed, false if player "full"
bool Feed(short a_Food, float a_Saturation); //tolua_export bool Feed(short a_Food, float a_Saturation); // tolua_export
short GetMaxFoodLevel() { return m_MaxFoodLevel; } //tolua_export short GetMaxFoodLevel() { return m_MaxFoodLevel; } // tolua_export
short GetFoodLevel() { return m_FoodLevel; } //tolua_export short GetFoodLevel() { return m_FoodLevel; } // tolua_export
float GetMaxFoodSaturationLevel() { return m_MaxFoodSaturationLevel; } //tolua_export float GetMaxFoodSaturationLevel() { return m_MaxFoodSaturationLevel; } // tolua_export
float GetFoodSaturationLevel() { return m_FoodSaturationLevel; } //tolua_export float GetFoodSaturationLevel() { return m_FoodSaturationLevel; } // tolua_export
void AddFoodExhaustion(float a_Exhaustion) { m_FoodExhaustionLevel += a_Exhaustion; } //tolua_export void AddFoodExhaustion(float a_Exhaustion) { m_FoodExhaustionLevel += a_Exhaustion; } // tolua_export
virtual void KilledBy(cPawn * a_Killer) override; virtual void KilledBy(cPawn * a_Killer) override;
void Respawn(void); //tolua_export void Respawn(void); // tolua_export
void SetVisible( bool a_bVisible ); //tolua_export void SetVisible( bool a_bVisible ); // tolua_export
bool IsVisible(void) const { return m_bVisible; } //tolua_export bool IsVisible(void) const { return m_bVisible; } // tolua_export
bool MoveToWorld(const char * a_WorldName ); //tolua_export bool MoveToWorld(const char * a_WorldName ); // tolua_export
bool SaveToDisk(void); bool SaveToDisk(void);
bool LoadFromDisk(void); bool LoadFromDisk(void);
void LoadPermissionsFromDisk(void); //tolua_export void LoadPermissionsFromDisk(void); // tolua_export
const AString & GetLoadedWorldName() { return m_LoadedWorldName; } const AString & GetLoadedWorldName() { return m_LoadedWorldName; }
@ -198,7 +199,7 @@ protected:
/// Filters out damage for creative mode /// Filters out damage for creative mode
virtual void DoTakeDamage(TakeDamageInfo & TDI) override; virtual void DoTakeDamage(TakeDamageInfo & TDI) override;
} ; //tolua_export } ; // tolua_export

View File

@ -3,6 +3,7 @@
#include "Plugin.h" #include "Plugin.h"
#include "Pawn.h" #include "Pawn.h"
#include "Player.h"
@ -16,16 +17,14 @@ cPlugin::cPlugin( const AString & a_PluginDirectory )
{ {
} }
cPlugin::~cPlugin() cPlugin::~cPlugin()
{ {
} }
// bool cPlugin::Initialize()
// {
// LOG("cPlugin::Initialize()");
// return false;
// }
@ -39,38 +38,8 @@ void cPlugin::Tick(float a_Dt)
bool cPlugin::OnBlockDig(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta) /*
{ // TODO
UNUSED(a_Player);
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_BlockFace);
UNUSED(a_Status);
UNUSED(a_OldBlock);
UNUSED(a_OldMeta);
return false;
}
bool cPlugin::OnBlockPlace(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem)
{
UNUSED(a_Player);
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_BlockFace);
UNUSED(a_HeldItem);
return false;
}
bool cPlugin::OnBlockToPickup(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups) bool cPlugin::OnBlockToPickup(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups)
{ {
UNUSED(a_BlockType); UNUSED(a_BlockType);
@ -80,6 +49,8 @@ bool cPlugin::OnBlockToPickup(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, con
UNUSED(a_Pickups); UNUSED(a_Pickups);
return false; return false;
} }
*/
@ -96,11 +67,12 @@ bool cPlugin::OnChat(cPlayer * a_Player, const AString & a_Message)
void cPlugin::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ) bool cPlugin::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ)
{ {
UNUSED(a_World); UNUSED(a_World);
UNUSED(a_ChunkX); UNUSED(a_ChunkX);
UNUSED(a_ChunkZ); UNUSED(a_ChunkZ);
return false;
} }
@ -154,7 +126,7 @@ bool cPlugin::OnDisconnect(cPlayer * a_Player, const AString & a_Reason)
bool cPlugin::OnKilled(cPawn * a_Killed, cEntity * a_Killer) bool cPlugin::OnKilled(cPawn & a_Killed, cEntity * a_Killer)
{ {
UNUSED(a_Killed); UNUSED(a_Killed);
UNUSED(a_Killer); UNUSED(a_Killer);
@ -177,7 +149,39 @@ bool cPlugin::OnLogin(cClientHandle * a_Client, int a_ProtocolVersion, const ASt
bool cPlugin::OnPlayerJoin(cPlayer * a_Player) bool cPlugin::OnPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
UNUSED(a_Player);
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_BlockFace);
UNUSED(a_BlockType);
UNUSED(a_BlockMeta);
return false;
}
bool cPlugin::OnPlayerBrokenBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
UNUSED(a_Player);
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_BlockFace);
UNUSED(a_BlockType);
UNUSED(a_BlockMeta);
return false;
}
bool cPlugin::OnPlayerEating(cPlayer & a_Player)
{ {
UNUSED(a_Player); UNUSED(a_Player);
return false; return false;
@ -187,18 +191,192 @@ bool cPlugin::OnPlayerJoin(cPlayer * a_Player)
void cPlugin::OnPlayerMove(cPlayer * a_Player) bool cPlugin::OnPlayerJoined(cPlayer & a_Player)
{ {
UNUSED(a_Player); UNUSED(a_Player);
return false;
} }
void cPlugin::OnPlayerSpawn(cPlayer * a_Player) bool cPlugin::OnPlayerLeftClick(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status)
{ {
UNUSED(a_Player); UNUSED(a_Player);
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_BlockFace);
UNUSED(a_Status);
return false;
}
bool cPlugin::OnPlayerMoved(cPlayer & a_Player)
{
UNUSED(a_Player);
return false;
}
bool cPlugin::OnPlayerPlacedBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
UNUSED(a_Player);
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_BlockFace);
UNUSED(a_CursorX);
UNUSED(a_CursorY);
UNUSED(a_CursorZ);
UNUSED(a_BlockType);
UNUSED(a_BlockMeta);
return false;
}
bool cPlugin::OnPlayerPlacingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
UNUSED(a_Player);
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_BlockFace);
UNUSED(a_CursorX);
UNUSED(a_CursorY);
UNUSED(a_CursorZ);
UNUSED(a_BlockType);
UNUSED(a_BlockMeta);
return false;
}
bool cPlugin::OnPlayerRightClick(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
{
UNUSED(a_Player);
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_BlockFace);
UNUSED(a_CursorX);
UNUSED(a_CursorY);
UNUSED(a_CursorZ);
return false;
}
bool cPlugin::OnPlayerShooting(cPlayer & a_Player)
{
UNUSED(a_Player);
return false;
}
bool cPlugin::OnPlayerSpawned(cPlayer & a_Player)
{
UNUSED(a_Player);
return false;
}
bool cPlugin::OnPlayerTossingItem(cPlayer & a_Player)
{
UNUSED(a_Player);
return false;
}
bool cPlugin::OnPlayerUsedBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
UNUSED(a_Player);
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_BlockFace);
UNUSED(a_CursorX);
UNUSED(a_CursorY);
UNUSED(a_CursorZ);
UNUSED(a_BlockType);
UNUSED(a_BlockMeta);
return false;
}
bool cPlugin::OnPlayerUsedItem(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
{
UNUSED(a_Player);
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_BlockFace);
UNUSED(a_CursorX);
UNUSED(a_CursorY);
UNUSED(a_CursorZ);
return false;
}
bool cPlugin::OnPlayerUsingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
UNUSED(a_Player);
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_BlockFace);
UNUSED(a_CursorX);
UNUSED(a_CursorY);
UNUSED(a_CursorZ);
UNUSED(a_BlockType);
UNUSED(a_BlockMeta);
return false;
}
bool cPlugin::OnPlayerUsingItem(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
{
UNUSED(a_Player);
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_BlockFace);
UNUSED(a_CursorX);
UNUSED(a_CursorY);
UNUSED(a_CursorZ);
return false;
} }

View File

@ -2,6 +2,11 @@
#pragma once #pragma once
#include "Item.h" #include "Item.h"
#include "PluginManager.h"
class cClientHandle; class cClientHandle;
class cPlayer; class cPlayer;
@ -28,50 +33,60 @@ class cCraftingRecipe;
class cPlugin class cPlugin
{ {
public: public:
// tolua_end
cPlugin( const AString & a_PluginDirectory ); cPlugin( const AString & a_PluginDirectory );
virtual ~cPlugin(); virtual ~cPlugin();
virtual void OnDisable() {} virtual void OnDisable(void) {}
virtual bool Initialize() = 0; virtual bool Initialize(void) = 0;
// Called each tick // Called each tick
virtual void Tick(float a_Dt); virtual void Tick(float a_Dt);
/** /**
* On all these functions, return true if you want to override default behavior * On all these functions, return true if you want to override default behavior and not call other plugins on that callback.
* You can also return false, so default behavior is used. * You can also return false, so default behavior is used.
**/ **/
virtual bool OnBlockDig (cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta); // TODO: virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups);
virtual bool OnBlockPlace (cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem); virtual bool OnChat (cPlayer * a_Player, const AString & a_Message);
virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups); virtual bool OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ);
virtual bool OnChat (cPlayer * a_Player, const AString & a_Message); virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk);
virtual void OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ); virtual bool OnCollectPickup (cPlayer * a_Player, cPickup * a_Pickup);
virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk); virtual bool OnCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
virtual bool OnCollectPickup (cPlayer * a_Player, cPickup * a_Pickup); virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason);
virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); virtual bool OnHandshake (cClientHandle * a_Client, const AString & a_Username);
virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason); virtual bool OnKilled (cPawn & a_Killed, cEntity * a_Killer);
virtual bool OnKilled (cPawn * a_Killed, cEntity* a_Killer ); virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username);
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username); virtual bool OnPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
virtual bool OnPlayerJoin (cPlayer* a_Player ); virtual bool OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
virtual void OnPlayerMove (cPlayer* a_Player ); virtual bool OnPlayerEating (cPlayer & a_Player);
virtual void OnPlayerSpawn (cPlayer* a_Player ); virtual bool OnPlayerJoined (cPlayer & a_Player);
virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status);
virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); virtual bool OnPlayerMoved (cPlayer & a_Player);
virtual bool OnTakeDamage (cPawn & a_Receiver, TakeDamageInfo & a_TakeDamageInfo); virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
virtual bool OnUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player); virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player); virtual bool OnPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ);
virtual bool OnWeatherChanged (cWorld * a_World); virtual bool OnPlayerShooting (cPlayer & a_Player);
virtual bool OnHandshake (cClientHandle * a_Client, const AString & a_Username); virtual bool OnPlayerSpawned (cPlayer & a_Player);
virtual bool OnPlayerTossingItem (cPlayer & a_Player);
virtual bool OnPlayerUsedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
virtual bool OnPlayerUsedItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ);
virtual bool OnPlayerUsingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
virtual bool OnPlayerUsingItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ);
virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
virtual bool OnTakeDamage (cPawn & a_Receiver, TakeDamageInfo & a_TakeDamageInfo);
virtual bool OnUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player);
virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player);
virtual bool OnWeatherChanged (cWorld * a_World);
// Accessors /** Called from cPluginManager::AddHook() to check if the hook can be added.
const AString & GetName() const { return m_Name; } Plugin API providers may check if the plugin is written correctly (has the hook handler function)
virtual void SetName( const AString & a_Name ) { m_Name = a_Name; } Returns true if the hook can be added (handler exists)
Descendants should also log the specific error message as a warning if they return false.
int GetVersion() const { return m_Version; } */
void SetVersion( int a_Version ) { m_Version = a_Version; } virtual bool CanAddHook(cPluginManager::PluginHook a_Hook) { return false; }
const AString & GetDirectory(void) const {return m_Directory; }
AString GetLocalDirectory(void) const; //tolua_export
struct CommandStruct struct CommandStruct
{ {
@ -80,6 +95,16 @@ public:
AString Permission; AString Permission;
}; };
// tolua_begin
const AString & GetName(void) const { return m_Name; }
void SetName(const AString & a_Name) { m_Name = a_Name; }
int GetVersion(void) const { return m_Version; }
void SetVersion(int a_Version) { m_Version = a_Version; }
const AString & GetDirectory(void) const {return m_Directory; }
AString GetLocalDirectory(void) const;
void AddCommand(const AString & a_Command, const AString & a_Description, const AString & a_Permission); void AddCommand(const AString & a_Command, const AString & a_Description, const AString & a_Permission);
// tolua_end // tolua_end
@ -109,7 +134,7 @@ private:
int m_Version; int m_Version;
AString m_Directory; AString m_Directory;
}; //tolua_export }; // tolua_export

View File

@ -199,7 +199,7 @@ void cPluginManager::Tick(float a_Dt)
ReloadPluginsNow(); ReloadPluginsNow();
} }
HookMap::iterator Plugins = m_Hooks.find( E_PLUGIN_TICK ); HookMap::iterator Plugins = m_Hooks.find(HOOK_TICK);
if( Plugins != m_Hooks.end() ) if( Plugins != m_Hooks.end() )
{ {
for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
@ -213,133 +213,33 @@ void cPluginManager::Tick(float a_Dt)
bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...) /*
bool cPluginManager::CallHookBlockToPickup(
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta,
const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups
)
{ {
HookMap::iterator Plugins = m_Hooks.find( a_Hook ); HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING);
if (Plugins == m_Hooks.end())
{
return false;
}
switch( a_Hook )
{
case HOOK_PLAYER_JOIN:
{
if( a_NumArgs != 1 ) break;
va_list argptr;
va_start( argptr, a_NumArgs);
cPlayer* Player = va_arg(argptr, cPlayer* );
va_end (argptr);
for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
{
if( (*itr)->OnPlayerJoin( Player ) )
return true;
}
break;
}
case HOOK_PLAYER_MOVE:
{
if( a_NumArgs != 1 ) break;
va_list argptr;
va_start( argptr, a_NumArgs);
cPlayer* Player = va_arg(argptr, cPlayer* );
va_end (argptr);
for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
{
(*itr)->OnPlayerMove( Player );
}
break;
}
case HOOK_KILLED:
{
if( a_NumArgs != 2 ) break;
va_list argptr;
va_start( argptr, a_NumArgs);
cPawn* Killed = va_arg(argptr, cPawn* );
cEntity* Killer = va_arg(argptr, cEntity* );
va_end (argptr);
for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
{
if( (*itr)->OnKilled( Killed, Killer ) )
return true;
}
break;
}
case HOOK_CHUNK_GENERATED:
{
if (a_NumArgs != 3)
{
break;
}
va_list argptr;
va_start( argptr, a_NumArgs);
cWorld * World = va_arg(argptr, cWorld *);
int ChunkX = va_arg(argptr, int);
int ChunkZ = va_arg(argptr, int);
va_end (argptr);
for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
{
(*itr)->OnChunkGenerated(World, ChunkX, ChunkZ);
}
break;
}
case HOOK_PLAYER_SPAWN:
{
if (a_NumArgs != 1)
{
break;
}
va_list argptr;
va_start( argptr, a_NumArgs);
cPlayer * Player = va_arg(argptr, cPlayer *);
va_end (argptr);
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
(*itr)->OnPlayerSpawn(Player);
}
break;
}
default:
{
LOGWARNING("cPluginManager: Calling Unknown hook: %i", a_Hook );
ASSERT(!"Calling an unknown hook");
break;
}
} // switch (a_Hook)
return false;
}
bool cPluginManager::CallHookLogin(cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_LOGIN);
if (Plugins == m_Hooks.end()) if (Plugins == m_Hooks.end())
{ {
return false; return false;
} }
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{ {
if ((*itr)->OnLogin(a_Client, a_ProtocolVersion, a_Username)) if ((*itr)->OnBlockToPickup(a_BlockType, a_BlockMeta, a_Player, a_EquippedItem, a_Pickups))
{ {
return true; return true;
} }
} }
return false; return false;
} }
*/
/*
bool cPluginManager::CallHookBlockDig(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta) bool cPluginManager::CallHookBlockDig(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta)
{ {
HookMap::iterator Plugins = m_Hooks.find(HOOK_BLOCK_DIG); HookMap::iterator Plugins = m_Hooks.find(HOOK_BLOCK_DIG);
@ -356,11 +256,13 @@ bool cPluginManager::CallHookBlockDig(cPlayer * a_Player, int a_BlockX, int a_Bl
} }
return false; return false;
} }
*/
/*
bool cPluginManager::CallHookBlockPlace(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem) bool cPluginManager::CallHookBlockPlace(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem)
{ {
HookMap::iterator Plugins = m_Hooks.find(HOOK_BLOCK_PLACE); HookMap::iterator Plugins = m_Hooks.find(HOOK_BLOCK_PLACE);
@ -377,6 +279,7 @@ bool cPluginManager::CallHookBlockPlace(cPlayer * a_Player, int a_BlockX, int a_
} }
return false; return false;
} }
*/
@ -396,7 +299,7 @@ bool cPluginManager::CallHookChat(cPlayer * a_Player, const AString & a_Message)
return true; return true;
} }
//Check if it was a standard command (starts with a slash) // Check if it was a standard command (starts with a slash)
if (a_Message[0] == '/') if (a_Message[0] == '/')
{ {
a_Player->SendMessage("Unknown Command"); a_Player->SendMessage("Unknown Command");
@ -425,6 +328,27 @@ bool cPluginManager::CallHookChat(cPlayer * a_Player, const AString & a_Message)
bool cPluginManager::CallHookChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_CHUNK_GENERATED);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnChunkGenerated(a_World, a_ChunkX, a_ChunkZ))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_LuaChunk) bool cPluginManager::CallHookChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_LuaChunk)
{ {
HookMap::iterator Plugins = m_Hooks.find(HOOK_CHUNK_GENERATING); HookMap::iterator Plugins = m_Hooks.find(HOOK_CHUNK_GENERATING);
@ -509,6 +433,405 @@ bool cPluginManager::CallHookDisconnect(cPlayer * a_Player, const AString & a_Re
bool cPluginManager::CallHookHandshake(cClientHandle * a_ClientHandle, const AString & a_Username)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_HANDSHAKE);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnHandshake(a_ClientHandle, a_Username))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookKilled(cPawn & a_Victim, cEntity * a_Killer)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_KILLED);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnKilled(a_Victim, a_Killer))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookLogin(cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_LOGIN);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnLogin(a_Client, a_ProtocolVersion, a_Username))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_BREAKING_BLOCK);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerBreakingBlock(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_BlockType, a_BlockMeta))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPlayerBrokenBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_BROKEN_BLOCK);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerBrokenBlock(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_BlockType, a_BlockMeta))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPlayerEating(cPlayer & a_Player)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_EATING);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerEating(a_Player))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPlayerJoined(cPlayer & a_Player)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_JOINED);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerJoined(a_Player))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPlayerLeftClick(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_LEFT_CLICK);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerLeftClick(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPlayerMoved(cPlayer & a_Player)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_MOVED);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerMoved(a_Player))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPlayerPlacedBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_PLACED_BLOCK);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerPlacedBlock(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPlayerPlacingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_PLACING_BLOCK);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerPlacingBlock(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPlayerRightClick(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_RIGHTCLICK);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerRightClick(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPlayerShooting(cPlayer & a_Player)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_SHOOTING);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerShooting(a_Player))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPlayerSpawned(cPlayer & a_Player)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_SPAWNED);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerSpawned(a_Player))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPlayerTossingItem(cPlayer & a_Player)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_TOSSING_ITEM);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerTossingItem(a_Player))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPlayerUsedBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_USED_BLOCK);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerUsedBlock(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPlayerUsedItem(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_USED_ITEM);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerUsedItem(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPlayerUsingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_USING_BLOCK);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerUsingBlock(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPlayerUsingItem(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_USING_ITEM);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerUsingItem(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) bool cPluginManager::CallHookPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
{ {
HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING); HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING);
@ -572,51 +895,6 @@ bool cPluginManager::CallHookTakeDamage(cPawn & a_Receiver, TakeDamageInfo & a_T
bool cPluginManager::CallHookBlockToPickup(
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta,
const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups
)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnBlockToPickup(a_BlockType, a_BlockMeta, a_Player, a_EquippedItem, a_Pickups))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookWeatherChanged(cWorld * a_World)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_WEATHER_CHANGED);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnWeatherChanged(a_World))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookUpdatingSign(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) bool cPluginManager::CallHookUpdatingSign(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player)
{ {
HookMap::iterator Plugins = m_Hooks.find(HOOK_UPDATING_SIGN); HookMap::iterator Plugins = m_Hooks.find(HOOK_UPDATING_SIGN);
@ -659,16 +937,16 @@ bool cPluginManager::CallHookUpdatedSign(cWorld * a_World, int a_BlockX, int a_B
bool cPluginManager::CallHookHandshake(cClientHandle * a_ClientHandle, const AString & a_Username) bool cPluginManager::CallHookWeatherChanged(cWorld * a_World)
{ {
HookMap::iterator Plugins = m_Hooks.find(HOOK_HANDSHAKE); HookMap::iterator Plugins = m_Hooks.find(HOOK_WEATHER_CHANGED);
if (Plugins == m_Hooks.end()) if (Plugins == m_Hooks.end())
{ {
return false; return false;
} }
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{ {
if ((*itr)->OnHandshake(a_ClientHandle, a_Username)) if ((*itr)->OnWeatherChanged(a_World))
{ {
return true; return true;
} }
@ -744,7 +1022,7 @@ bool cPluginManager::DisablePlugin( AString & a_PluginName )
bool cPluginManager::LoadPlugin( AString & a_PluginName ) bool cPluginManager::LoadPlugin( AString & a_PluginName )
{ {
cPlugin_NewLua* Plugin = new cPlugin_NewLua( a_PluginName.c_str() ); cPlugin_NewLua* Plugin = new cPlugin_NewLua( a_PluginName.c_str() );
if( !AddPlugin( Plugin ) ) if (!AddPlugin(Plugin))
{ {
delete Plugin; delete Plugin;
return false; return false;
@ -756,24 +1034,12 @@ bool cPluginManager::LoadPlugin( AString & a_PluginName )
void cPluginManager::RemoveHooks( cPlugin* a_Plugin ) void cPluginManager::RemoveHooks(cPlugin * a_Plugin)
{ {
m_Hooks[ E_PLUGIN_TICK].remove ( a_Plugin ); for (HookMap::iterator itr = m_Hooks.begin(), end = m_Hooks.end(); itr != end; ++itr)
m_Hooks[ E_PLUGIN_CHAT].remove ( a_Plugin ); {
m_Hooks[ E_PLUGIN_COLLECT_ITEM].remove ( a_Plugin ); itr->second.remove(a_Plugin);
m_Hooks[ E_PLUGIN_BLOCK_DIG].remove ( a_Plugin ); }
m_Hooks[ E_PLUGIN_BLOCK_PLACE].remove ( a_Plugin );
m_Hooks[ E_PLUGIN_DISCONNECT].remove ( a_Plugin );
m_Hooks[ E_PLUGIN_HANDSHAKE].remove ( a_Plugin );
m_Hooks[ E_PLUGIN_LOGIN].remove ( a_Plugin );
m_Hooks[ E_PLUGIN_PLAYER_SPAWN].remove ( a_Plugin );
m_Hooks[ E_PLUGIN_PLAYER_JOIN].remove ( a_Plugin );
m_Hooks[ E_PLUGIN_PLAYER_MOVE].remove ( a_Plugin );
m_Hooks[ E_PLUGIN_TAKE_DAMAGE].remove ( a_Plugin );
m_Hooks[ E_PLUGIN_KILLED].remove ( a_Plugin );
m_Hooks[ E_PLUGIN_CHUNK_GENERATED ].remove ( a_Plugin );
m_Hooks[ E_PLUGIN_CHUNK_GENERATING ].remove( a_Plugin );
m_Hooks[ E_PLUGIN_BLOCK_TO_DROPS ].remove ( a_Plugin );
} }
@ -828,16 +1094,20 @@ bool cPluginManager::AddPlugin( cPlugin* a_Plugin )
void cPluginManager::AddHook( cPlugin* a_Plugin, PluginHook a_Hook ) void cPluginManager::AddHook(cPlugin * a_Plugin, PluginHook a_Hook)
{ {
if( !a_Plugin ) if (!a_Plugin)
{ {
LOGWARN("Called cPluginManager::AddHook while a_Plugin is NULL"); LOGWARN("Called cPluginManager::AddHook() with a_Plugin == NULL");
return; return;
} }
PluginList & Plugins = m_Hooks[ a_Hook ]; if (!a_Plugin->CanAddHook(a_Hook))
Plugins.remove( a_Plugin ); {
Plugins.push_back( a_Plugin ); return;
}
PluginList & Plugins = m_Hooks[a_Hook];
Plugins.remove(a_Plugin);
Plugins.push_back(a_Plugin);
} }
@ -862,3 +1132,7 @@ bool cPluginManager::HasPlugin( cPlugin* a_Plugin ) const
} }
return false; return false;
} }

View File

@ -36,9 +36,9 @@ class cPawn;
class cPluginManager //tolua_export class cPluginManager // tolua_export
{ //tolua_export { // tolua_export
public: //tolua_export public: // tolua_export
// Called each tick // Called each tick
virtual void Tick(float a_Dt); virtual void Tick(float a_Dt);
@ -46,87 +46,92 @@ public: //tolua_export
// tolua_begin // tolua_begin
enum PluginHook enum PluginHook
{ {
HOOK_TICK,
HOOK_CHAT, HOOK_CHAT,
HOOK_COLLECT_PICKUP,
HOOK_COLLECT_ITEM = HOOK_COLLECT_PICKUP, // OBSOLETE, use HOOK_COLLECT_PICKUP instead
HOOK_BLOCK_DIG,
HOOK_BLOCK_PLACE,
HOOK_DISCONNECT,
HOOK_HANDSHAKE,
HOOK_LOGIN,
HOOK_PLAYER_SPAWN,
HOOK_PLAYER_JOIN,
HOOK_PLAYER_MOVE,
HOOK_TAKE_DAMAGE, // cPawn, TakeDamageInfo
HOOK_KILLED,
HOOK_CHUNK_GENERATED, HOOK_CHUNK_GENERATED,
HOOK_CHUNK_GENERATING, HOOK_CHUNK_GENERATING,
HOOK_BLOCK_TO_DROPS, HOOK_COLLECT_PICKUP,
HOOK_PRE_CRAFTING, /// cPlayer, cCraftingGrid, cCraftingRecipe HOOK_CRAFTING_NO_RECIPE,
HOOK_CRAFTING_NO_RECIPE, /// cPlayer, cCraftingGrid, cCraftingRecipe HOOK_DISCONNECT,
HOOK_POST_CRAFTING, /// cPlayer, cCraftingGrid, cCraftingRecipe HOOK_HANDSHAKE,
HOOK_BLOCK_TO_PICKUP, /// BlockType, BlockMeta, cPlayer, cItem, cItems HOOK_KILLED,
HOOK_WEATHER_CHANGED, /// cWorld HOOK_LOGIN,
HOOK_UPDATING_SIGN, /// cWorld, int, int, int, string, string, string, string HOOK_PLAYER_BREAKING_BLOCK,
HOOK_UPDATED_SIGN, /// cWorld, int, int, int, string, string, string, string HOOK_PLAYER_BROKEN_BLOCK,
HOOK_PLAYER_EATING,
HOOK_PLAYER_JOINED,
HOOK_PLAYER_LEFT_CLICK,
HOOK_PLAYER_MOVED,
HOOK_PLAYER_PLACED_BLOCK,
HOOK_PLAYER_PLACING_BLOCK,
HOOK_PLAYER_RIGHTCLICK,
HOOK_PLAYER_SHOOTING,
HOOK_PLAYER_SPAWNED,
HOOK_PLAYER_TOSSING_ITEM,
HOOK_PLAYER_USED_BLOCK,
HOOK_PLAYER_USED_ITEM,
HOOK_PLAYER_USING_BLOCK,
HOOK_PLAYER_USING_ITEM,
HOOK_POST_CRAFTING,
HOOK_PRE_CRAFTING,
HOOK_TAKE_DAMAGE,
HOOK_TICK,
HOOK_UPDATED_SIGN,
HOOK_UPDATING_SIGN,
HOOK_WEATHER_CHANGED,
// E_PLUGIN_ names are obsolete, but are kept for compatibility reasons // Note that if a hook type is added, it may need processing in cPlugin::CanAddHook() descendants!
E_PLUGIN_TICK = HOOK_TICK, } ;
E_PLUGIN_CHAT = HOOK_CHAT,
E_PLUGIN_COLLECT_ITEM = HOOK_COLLECT_ITEM,
E_PLUGIN_BLOCK_DIG = HOOK_BLOCK_DIG,
E_PLUGIN_BLOCK_PLACE = HOOK_BLOCK_PLACE,
E_PLUGIN_DISCONNECT = HOOK_DISCONNECT,
E_PLUGIN_HANDSHAKE = HOOK_HANDSHAKE,
E_PLUGIN_LOGIN = HOOK_LOGIN,
E_PLUGIN_PLAYER_SPAWN = HOOK_PLAYER_SPAWN,
E_PLUGIN_PLAYER_JOIN = HOOK_PLAYER_JOIN,
E_PLUGIN_PLAYER_MOVE = HOOK_PLAYER_MOVE,
E_PLUGIN_TAKE_DAMAGE = HOOK_TAKE_DAMAGE,
E_PLUGIN_KILLED = HOOK_KILLED,
E_PLUGIN_CHUNK_GENERATED = HOOK_CHUNK_GENERATED,
E_PLUGIN_CHUNK_GENERATING = HOOK_CHUNK_GENERATING,
E_PLUGIN_BLOCK_TO_DROPS = HOOK_BLOCK_TO_DROPS,
};
// tolua_end // tolua_end
static cPluginManager * GetPluginManager(); //tolua_export static cPluginManager * GetPluginManager(); // tolua_export
typedef std::map< AString, cPlugin * > PluginMap; typedef std::map< AString, cPlugin * > PluginMap;
typedef std::list< cPlugin * > PluginList; typedef std::list< cPlugin * > PluginList;
cPlugin * GetPlugin( const AString & a_Plugin ) const; //tolua_export cPlugin * GetPlugin( const AString & a_Plugin ) const; // tolua_export
const PluginMap & GetAllPlugins() const; // >> EXPORTED IN MANUALBINDINGS << const PluginMap & GetAllPlugins() const; // >> EXPORTED IN MANUALBINDINGS <<
void FindPlugins(); //tolua_export void FindPlugins(); // tolua_export
void ReloadPlugins(); //tolua_export void ReloadPlugins(); // tolua_export
bool AddPlugin( cPlugin* a_Plugin ); bool AddPlugin( cPlugin* a_Plugin );
void AddHook( cPlugin* a_Plugin, PluginHook a_Hook ); //tolua_export void AddHook( cPlugin* a_Plugin, PluginHook a_Hook ); // tolua_export
unsigned int GetNumPlugins() const; //tolua_export unsigned int GetNumPlugins() const; // tolua_export
// If the hook returns true, no further hook is called and the functions return false // TODO: bool CallHookBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups);
bool CallHook( PluginHook a_Hook, unsigned int a_NumArgs, ... ); bool CallHookChat (cPlayer * a_Player, const AString & a_Message);
bool CallHookChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ);
bool CallHookChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_Chunk);
bool CallHookCollectPickup (cPlayer * a_Player, cPickup & a_Pickup);
bool CallHookCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
bool CallHookDisconnect (cPlayer * a_Player, const AString & a_Reason);
bool CallHookHandshake (cClientHandle * a_ClientHandle, const AString & a_Username);
bool CallHookKilled (cPawn & a_Victim, cEntity * a_Killer);
bool CallHookLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username);
bool CallHookPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
bool CallHookPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
bool CallHookPlayerEating (cPlayer & a_Player);
bool CallHookPlayerJoined (cPlayer & a_Player);
bool CallHookPlayerMoved (cPlayer & a_Player);
bool CallHookPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status);
bool CallHookPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
bool CallHookPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
bool CallHookPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ);
bool CallHookPlayerShooting (cPlayer & a_Player);
bool CallHookPlayerSpawned (cPlayer & a_Player);
bool CallHookPlayerTossingItem (cPlayer & a_Player);
bool CallHookPlayerUsedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
bool CallHookPlayerUsedItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ);
bool CallHookPlayerUsingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
bool CallHookPlayerUsingItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ);
bool CallHookPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
bool CallHookTakeDamage (cPawn & a_Receiver, TakeDamageInfo & a_TDI);
bool CallHookUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player);
bool CallHookUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player);
bool CallHookWeatherChanged (cWorld * a_World);
bool CallHookBlockDig (cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status, BLOCKTYPE OldBlock, NIBBLETYPE OldMeta); bool DisablePlugin( AString & a_PluginName ); // tolua_export
bool CallHookBlockPlace (cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem); bool LoadPlugin( AString & a_PluginName ); // tolua_export
bool CallHookBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups);
bool CallHookChat (cPlayer * a_Player, const AString & a_Message);
bool CallHookChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_Chunk);
bool CallHookCollectPickup (cPlayer * a_Player, cPickup & a_Pickup);
bool CallHookCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
bool CallHookDisconnect (cPlayer * a_Player, const AString & a_Reason);
bool CallHookLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username);
bool CallHookPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
bool CallHookTakeDamage (cPawn & a_Receiver, TakeDamageInfo & a_TDI);
bool CallHookUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player);
bool CallHookUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player);
bool CallHookWeatherChanged (cWorld * a_World);
bool CallHookHandshake (cClientHandle * a_ClientHandle, const AString & a_Username);
bool DisablePlugin( AString & a_PluginName ); //tolua_export
bool LoadPlugin( AString & a_PluginName ); //tolua_export
void RemoveHooks( cPlugin * a_Plugin ); void RemoveHooks( cPlugin * a_Plugin );
void RemovePlugin( cPlugin * a_Plugin, bool a_bDelete = false ); void RemovePlugin( cPlugin * a_Plugin, bool a_bDelete = false );
@ -163,7 +168,7 @@ private:
#endif // USE_SQUIRREL #endif // USE_SQUIRREL
bool m_bReloadPlugins; bool m_bReloadPlugins;
}; //tolua_export }; // tolua_export

File diff suppressed because it is too large Load Diff

View File

@ -25,51 +25,69 @@ public:
cPlugin_NewLua( const AString & a_PluginDirectory ); cPlugin_NewLua( const AString & a_PluginDirectory );
~cPlugin_NewLua(); ~cPlugin_NewLua();
virtual void OnDisable(); //tolua_export virtual void OnDisable(void) override;
virtual bool Initialize(); //tolua_export virtual bool Initialize(void) override;
virtual void Tick(float a_Dt); //tolua_export virtual void Tick(float a_Dt) override;
virtual bool OnBlockDig (cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta) override; // TODO: virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups) override;
virtual bool OnBlockPlace (cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem) override; virtual bool OnChat (cPlayer * a_Player, const AString & a_Message) override;
virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups); virtual bool OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override;
virtual bool OnChat (cPlayer * a_Player, const AString & a_Message) override; virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) override;
virtual void OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; virtual bool OnCollectPickup (cPlayer * a_Player, cPickup * a_Pickup) override;
virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) override; virtual bool OnCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
virtual bool OnCollectPickup (cPlayer * a_Player, cPickup * a_Pickup) override; virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason) override;
virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnHandshake (cClientHandle * a_Client, const AString & a_Username) override;
virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason) override; virtual bool OnKilled (cPawn & a_Killed, cEntity * a_Killer) override;
virtual bool OnKilled (cPawn * a_Killed, cEntity* a_Killer ) override; virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override;
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override; virtual bool OnPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual bool OnPlayerJoin (cPlayer * a_Player ) override; virtual bool OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual void OnPlayerMove (cPlayer * a_Player ) override; virtual bool OnPlayerEating (cPlayer & a_Player) override;
virtual void OnPlayerSpawn (cPlayer * a_Player ) override; virtual bool OnPlayerJoined (cPlayer & a_Player) override;
virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnPlayerMoved (cPlayer & a_Player) override;
virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) override;
virtual bool OnTakeDamage (cPawn & a_Receiver, TakeDamageInfo & a_TakeDamageInfo) override; virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual bool OnUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) override; virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) override; virtual bool OnPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override;
virtual bool OnWeatherChanged (cWorld * a_World) override; virtual bool OnPlayerShooting (cPlayer & a_Player) override;
virtual bool OnHandshake (cClientHandle * a_Client, const AString & a_Username) override; virtual bool OnPlayerSpawned (cPlayer & a_Player) override;
virtual bool OnPlayerTossingItem (cPlayer & a_Player) override;
virtual bool OnPlayerUsedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual bool OnPlayerUsedItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override;
virtual bool OnPlayerUsingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual bool OnPlayerUsingItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override;
virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
virtual bool OnTakeDamage (cPawn & a_Receiver, TakeDamageInfo & a_TakeDamageInfo) override;
virtual bool OnUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) override;
virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) override;
virtual bool OnWeatherChanged (cWorld * a_World) override;
virtual void SetName( const AString & a_Name ) override { cPlugin::SetName(a_Name); } virtual bool CanAddHook(cPluginManager::PluginHook a_Hook) override;
// cWebPlugin override // cWebPlugin override
virtual const AString & GetName(void) const {return cPlugin::GetName(); } virtual const AString & GetWebTitle(void) const {return GetName(); }
// cWebPlugin and WebAdmin stuff // cWebPlugin and WebAdmin stuff
virtual AString HandleWebRequest( HTTPRequest * a_Request ) override; virtual AString HandleWebRequest( HTTPRequest * a_Request ) override;
bool AddWebTab( const AString & a_Title, lua_State * a_LuaState, int a_FunctionReference ); // >> EXPORTED IN MANUALBINDINGS << bool AddWebTab(const AString & a_Title, lua_State * a_LuaState, int a_FunctionReference); // >> EXPORTED IN MANUALBINDINGS <<
lua_State* GetLuaState() { return m_LuaState; } lua_State* GetLuaState() { return m_LuaState; }
cCriticalSection & GetCriticalSection() { return m_CriticalSection; } cCriticalSection & GetCriticalSection() { return m_CriticalSection; }
private: protected:
bool PushFunction( const char* a_FunctionName, bool a_bLogError = true ); bool PushFunction(const char * a_FunctionName, bool a_bLogError = true);
bool CallFunction( int a_NumArgs, int a_NumResults, const char* a_FunctionName ); // a_FunctionName is only used for error messages, nothing else bool CallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName ); // a_FunctionName is only used for error messages, nothing else
/// Returns the name of Lua function that should handle the specified hook
const char * GetHookFnName(cPluginManager::PluginHook a_Hook);
cCriticalSection m_CriticalSection; cCriticalSection m_CriticalSection;
lua_State * m_LuaState; lua_State * m_LuaState;
};//tolua_export } ; // tolua_export

View File

@ -978,8 +978,8 @@ int cProtocol125::ParseBlockDig(void)
HANDLE_PACKET_READ(ReadBEInt, int, PosX); HANDLE_PACKET_READ(ReadBEInt, int, PosX);
HANDLE_PACKET_READ(ReadByte, Byte, PosY); HANDLE_PACKET_READ(ReadByte, Byte, PosY);
HANDLE_PACKET_READ(ReadBEInt, int, PosZ); HANDLE_PACKET_READ(ReadBEInt, int, PosZ);
HANDLE_PACKET_READ(ReadChar, char, Direction); HANDLE_PACKET_READ(ReadChar, char, BlockFace);
m_Client->HandleBlockDig(PosX, PosY, PosZ, Direction, Status); m_Client->HandleLeftClick(PosX, PosY, PosZ, BlockFace, Status);
return PARSE_OK; return PARSE_OK;
} }
@ -992,7 +992,7 @@ int cProtocol125::ParseBlockPlace(void)
HANDLE_PACKET_READ(ReadBEInt, int, PosX); HANDLE_PACKET_READ(ReadBEInt, int, PosX);
HANDLE_PACKET_READ(ReadByte, Byte, PosY); HANDLE_PACKET_READ(ReadByte, Byte, PosY);
HANDLE_PACKET_READ(ReadBEInt, int, PosZ); HANDLE_PACKET_READ(ReadBEInt, int, PosZ);
HANDLE_PACKET_READ(ReadChar, char, Direction); HANDLE_PACKET_READ(ReadChar, char, BlockFace);
cItem HeldItem; cItem HeldItem;
int res = ParseItem(HeldItem); int res = ParseItem(HeldItem);
@ -1001,7 +1001,8 @@ int cProtocol125::ParseBlockPlace(void)
return res; return res;
} }
m_Client->HandleBlockPlace(PosX, PosY, PosZ, Direction, HeldItem); // 1.2.5 didn't have any cursor position, so use 8, 8, 8, so that halfslabs and stairs work correctly and the special value is recognizable.
m_Client->HandleRightClick(PosX, PosY, PosZ, BlockFace, 8, 8, 8, HeldItem);
return PARSE_OK; return PARSE_OK;
} }

View File

@ -484,7 +484,7 @@ int cProtocol132::ParseBlockPlace(void)
HANDLE_PACKET_READ(ReadBEInt, int, PosX); HANDLE_PACKET_READ(ReadBEInt, int, PosX);
HANDLE_PACKET_READ(ReadByte, Byte, PosY); HANDLE_PACKET_READ(ReadByte, Byte, PosY);
HANDLE_PACKET_READ(ReadBEInt, int, PosZ); HANDLE_PACKET_READ(ReadBEInt, int, PosZ);
HANDLE_PACKET_READ(ReadChar, char, Direction); HANDLE_PACKET_READ(ReadChar, char, BlockFace);
cItem HeldItem; cItem HeldItem;
int res = ParseItem(HeldItem); int res = ParseItem(HeldItem);
@ -497,7 +497,7 @@ int cProtocol132::ParseBlockPlace(void)
HANDLE_PACKET_READ(ReadChar, char, CursorY); HANDLE_PACKET_READ(ReadChar, char, CursorY);
HANDLE_PACKET_READ(ReadChar, char, CursorZ); HANDLE_PACKET_READ(ReadChar, char, CursorZ);
m_Client->HandleBlockPlace(PosX, PosY, PosZ, Direction, HeldItem); m_Client->HandleRightClick(PosX, PosY, PosZ, BlockFace, CursorX, CursorY, CursorZ, HeldItem);
return PARSE_OK; return PARSE_OK;
} }

View File

@ -27,22 +27,22 @@ typedef cItemCallback<cWorld> cWorldListCallback;
class cRoot //tolua_export class cRoot // tolua_export
{ //tolua_export { // tolua_export
public: public:
/// The version of the protocol that is primary for the server (reported in the server list). All versions are still supported. /// The version of the protocol that is primary for the server (reported in the server list). All versions are still supported.
int m_PrimaryServerVersion; // tolua_export int m_PrimaryServerVersion; // tolua_export
static cRoot* Get() { return s_Root; } //tolua_export static cRoot* Get() { return s_Root; } // tolua_export
cRoot(void); cRoot(void);
~cRoot(); ~cRoot();
void Start(void); void Start(void);
cServer * GetServer(void) { return m_Server; } //tolua_export cServer * GetServer(void) { return m_Server; } // tolua_export
cWorld * GetDefaultWorld(void); //tolua_export cWorld * GetDefaultWorld(void); // tolua_export
cWorld * GetWorld(const AString & a_WorldName); //tolua_export cWorld * GetWorld(const AString & a_WorldName); // tolua_export
/// Calls the callback for each world; returns true if the callback didn't abort (return true) /// Calls the callback for each world; returns true if the callback didn't abort (return true)
bool ForEachWorld(cWorldListCallback & a_Callback); // >> Exported in ManualBindings << bool ForEachWorld(cWorldListCallback & a_Callback); // >> Exported in ManualBindings <<
@ -62,7 +62,7 @@ public:
cPluginManager * GetPluginManager (void) { return m_PluginManager; } // tolua_export cPluginManager * GetPluginManager (void) { return m_PluginManager; } // tolua_export
cAuthenticator & GetAuthenticator (void) { return m_Authenticator; } cAuthenticator & GetAuthenticator (void) { return m_Authenticator; }
void ServerCommand(const AString & a_Cmd); //tolua_export void ServerCommand(const AString & a_Cmd); // tolua_export
void KickUser(int a_ClientID, const AString & a_Reason); // Kicks the user, no matter in what world they are. Used from cAuthenticator void KickUser(int a_ClientID, const AString & a_Reason); // Kicks the user, no matter in what world they are. Used from cAuthenticator
void AuthenticateUser(int a_ClientID); // Called by cAuthenticator to auth the specified user void AuthenticateUser(int a_ClientID); // Called by cAuthenticator to auth the specified user
@ -119,7 +119,7 @@ private:
static void InputThread(void* a_Params); static void InputThread(void* a_Params);
static cRoot* s_Root; static cRoot* s_Root;
}; //tolua_export }; // tolua_export

View File

@ -80,16 +80,6 @@ struct cServer::sServerState
cServer * cServer::GetServer()
{
LOGWARN("WARNING: Using deprecated function cServer::GetServer() use cRoot::Get()->GetServer() instead!");
return cRoot::Get()->GetServer();
}
void cServer::ServerListenThread( void *a_Args ) void cServer::ServerListenThread( void *a_Args )
{ {
LOG("ServerListenThread"); LOG("ServerListenThread");
@ -173,7 +163,8 @@ bool cServer::InitServer(cIniFile & a_SettingsIni)
printf("email: faketruth@gmail.com\n\n"); printf("email: faketruth@gmail.com\n\n");
LOG("Starting up server."); LOG("Starting up server.");
LOGINFO("Compatible clients: %s, protocol versions %s", MCS_CLIENT_VERSIONS, MCS_PROTOCOL_VERSIONS); LOGINFO("Compatible clients: %s", MCS_CLIENT_VERSIONS);
LOGINFO("Compatible protocol versions %s", MCS_PROTOCOL_VERSIONS);
if (cSocket::WSAStartup() != 0) // Only does anything on Windows, but whatever if (cSocket::WSAStartup() != 0) // Only does anything on Windows, but whatever
{ {

View File

@ -29,11 +29,9 @@ typedef std::list<cClientHandle *> cClientHandleList;
class cServer //tolua_export class cServer // tolua_export
{ //tolua_export { // tolua_export
public: //tolua_export public: // tolua_export
static cServer * GetServer(); //tolua_export
bool InitServer(cIniFile & a_SettingsIni); bool InitServer(cIniFile & a_SettingsIni);
int GetPort() { return m_iServerPort; } int GetPort() { return m_iServerPort; }
@ -47,7 +45,7 @@ public: //tolua_export
void StartListenThread(); void StartListenThread();
bool Command(cClientHandle & a_Client, const AString & a_Cmd); bool Command(cClientHandle & a_Client, const AString & a_Cmd);
void ServerCommand(const AString & a_Cmd); //tolua_export void ServerCommand(const AString & a_Cmd); // tolua_export
void Shutdown(); void Shutdown();
void SendMessage(const AString & a_Message, cPlayer * a_Player = NULL, bool a_bExclude = false ); // tolua_export void SendMessage(const AString & a_Message, cPlayer * a_Player = NULL, bool a_bExclude = false ); // tolua_export
@ -129,7 +127,7 @@ private:
/// Loads, or generates, if missing, RSA keys for protocol encryption /// Loads, or generates, if missing, RSA keys for protocol encryption
void PrepareKeys(void); void PrepareKeys(void);
}; //tolua_export }; // tolua_export

View File

@ -1,19 +1,19 @@
#pragma once #pragma once
class cSign //tolua_export class cSign // tolua_export
{ //tolua_export { // tolua_export
public: public:
static char RotationToMetaData( float a_Rotation ) //tolua_export static char RotationToMetaData( float a_Rotation ) // tolua_export
{ //tolua_export { // tolua_export
a_Rotation += 180 + (180/16); // So its not aligned with axis a_Rotation += 180 + (180/16); // So its not aligned with axis
if( a_Rotation > 360.f ) a_Rotation -= 360.f; if( a_Rotation > 360.f ) a_Rotation -= 360.f;
a_Rotation = (a_Rotation/360) * 16; a_Rotation = (a_Rotation/360) * 16;
return ((char)a_Rotation) % 16; return ((char)a_Rotation) % 16;
} //tolua_export } // tolua_export
static char DirectionToMetaData( char a_Direction ) //tolua_export static char DirectionToMetaData( char a_Direction ) // tolua_export
{ //tolua_export { // tolua_export
switch( a_Direction ) switch( a_Direction )
{ {
case 0x2: case 0x2:
@ -29,4 +29,4 @@ public:
}; };
return 0x2; return 0x2;
} }
}; //tolua_export }; // tolua_export

View File

@ -1,38 +1,41 @@
#pragma once #pragma once
class cStairs //tolua_export
{ //tolua_export
class cStairs // tolua_export
{ // tolua_export
public: public:
static NIBBLETYPE RotationToMetaData( float a_Rotation, char a_BlockFace) //tolua_export /// Converts player rotation to stair rotation metadata. To get upside-down stairs, OR with 0x4
{ //tolua_export static NIBBLETYPE RotationToMetaData(float a_Rotation) // tolua_export
{ // tolua_export
a_Rotation += 90 + 45; // So its not aligned with axis a_Rotation += 90 + 45; // So its not aligned with axis
NIBBLETYPE result = 0x0; NIBBLETYPE result = 0x0;
if (a_BlockFace == BLOCK_FACE_BOTTOM)
{
result = 0x4;
}
if (a_Rotation > 360.f) if (a_Rotation > 360.f)
{ {
a_Rotation -= 360.f; a_Rotation -= 360.f;
} }
if ((a_Rotation >= 0.f) && (a_Rotation < 90.f)) if ((a_Rotation >= 0.f) && (a_Rotation < 90.f))
{ {
return result; return 0x0;
} }
else if ((a_Rotation >= 180) && (a_Rotation < 270)) else if ((a_Rotation >= 180) && (a_Rotation < 270))
{ {
result += 0x1; return 0x1;
} }
else if ((a_Rotation >= 90) && (a_Rotation < 180)) else if ((a_Rotation >= 90) && (a_Rotation < 180))
{ {
result += 0x2; return 0x2;
} }
else else
{ {
result += 0x3; return 0x3;
} }
} // tolua_export
} ; // tolua_export
return result;
} //tolua_export
}; //tolua_export

View File

@ -17,7 +17,7 @@ public: // tolua_export
unsigned int size() const; // tolua_export unsigned int size() const; // tolua_export
std::string & get( const std::string & index ); //tolua_export std::string & get( const std::string & index ); // tolua_export
std::map< std::string, std::string >& GetStringMap() { return m_StringMap; } std::map< std::string, std::string >& GetStringMap() { return m_StringMap; }
private: private:

View File

@ -7,15 +7,15 @@
class cTorch //tolua_export class cTorch // tolua_export
{ //tolua_export { // tolua_export
public: public:
static char DirectionToMetaData( char a_Direction ) //tolua_export static char DirectionToMetaData( char a_Direction ) // tolua_export
{ //tolua_export { // tolua_export
switch (a_Direction) switch (a_Direction)
{ {
case BLOCK_FACE_BOTTOM: ASSERT(!"Shouldn't be getting this direction"); return 0; case BLOCK_FACE_BOTTOM: ASSERT(!"Shouldn't be getting this face"); return 0;
case BLOCK_FACE_TOP: return E_META_TORCH_FLOOR; case BLOCK_FACE_TOP: return E_META_TORCH_FLOOR;
case BLOCK_FACE_EAST: return E_META_TORCH_EAST; case BLOCK_FACE_EAST: return E_META_TORCH_EAST;
case BLOCK_FACE_WEST: return E_META_TORCH_WEST; case BLOCK_FACE_WEST: return E_META_TORCH_WEST;
@ -28,11 +28,11 @@ public:
} }
}; };
return 0x0; return 0x0;
} //tolua_export } // tolua_export
static char MetaDataToDirection(char a_MetaData) //tolua_export static char MetaDataToDirection(char a_MetaData) // tolua_export
{ //tolua_export { // tolua_export
switch (a_MetaData) switch (a_MetaData)
{ {
case 0: return BLOCK_FACE_TOP; // by default, the torches stand on the ground case 0: return BLOCK_FACE_TOP; // by default, the torches stand on the ground
@ -48,7 +48,7 @@ public:
} }
} }
return 0; return 0;
} //tolua_export } // tolua_export
static bool IsAttachedTo(const Vector3i & a_TorchPos, char a_TorchMeta, const Vector3i & a_BlockPos) static bool IsAttachedTo(const Vector3i & a_TorchPos, char a_TorchMeta, const Vector3i & a_BlockPos)
@ -70,7 +70,7 @@ public:
return false; return false;
} }
} ; //tolua_export } ; // tolua_export

View File

@ -5,18 +5,18 @@
class cWorld; class cWorld;
class cTracer //tolua_export class cTracer // tolua_export
{ //tolua_export { // tolua_export
public: //tolua_export public: // tolua_export
Vector3f DotPos; Vector3f DotPos;
Vector3f BoxOffset; Vector3f BoxOffset;
cTracer( cWorld* a_World); //tolua_export cTracer( cWorld* a_World); // tolua_export
~cTracer(); //tolua_export ~cTracer(); // tolua_export
int Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int a_Distance ); //tolua_export int Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int a_Distance ); // tolua_export
void SetValues( const Vector3f & a_Start, const Vector3f & a_Direction ); //tolua_export void SetValues( const Vector3f & a_Start, const Vector3f & a_Direction ); // tolua_export
Vector3f BlockHitPosition; //tolua_export Vector3f BlockHitPosition; // tolua_export
Vector3f HitNormal; //tolua_export Vector3f HitNormal; // tolua_export
Vector3f RealHit; //tolua_export Vector3f RealHit; // tolua_export
private: private:
int intersect3D_SegmentPlane( const Vector3f & a_Origin, const Vector3f & a_End, const Vector3f & a_PlanePos, const Vector3f & a_PlaneNormal ); int intersect3D_SegmentPlane( const Vector3f & a_Origin, const Vector3f & a_End, const Vector3f & a_PlanePos, const Vector3f & a_PlaneNormal );
int GetHitNormal( const Vector3f & start, const Vector3f & end, const Vector3i & a_BlockPos); int GetHitNormal( const Vector3f & start, const Vector3f & end, const Vector3i & a_BlockPos);
@ -31,4 +31,4 @@ private:
Vector3i end1; Vector3i end1;
Vector3i step; Vector3i step;
Vector3f tMax; Vector3f tMax;
}; //tolua_export }; // tolua_export

Some files were not shown because too many files have changed in this diff Show More