1
0
Fork 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
** 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 */

View File

@ -255,7 +255,7 @@ AString ItemTypeToString(short a_ItemType)
AString ItemToFullString(const cItem & a_Item)
{
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;
}

View File

@ -1,6 +1,6 @@
#pragma once
//tolua_begin
// tolua_begin
enum ENUM_BLOCK_ID
{
E_BLOCK_AIR = 0,
@ -161,10 +161,15 @@ enum ENUM_BLOCK_ID
E_BLOCK_POTATOES = 142,
E_BLOCK_WOODEN_BUTTON = 143,
E_BLOCK_HEAD = 144,
// 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_end
//tolua_begin
// tolua_begin
enum ENUM_ITEM_ID
{
E_ITEM_EMPTY = -1,
@ -303,6 +308,8 @@ enum ENUM_ITEM_ID
E_ITEM_TRIPWIRE = 132,
E_ITEM_EMERALD_BLOCK = 133,
E_ITEM_FIRST = 256, // First true item type
E_ITEM_IRON_SHOVEL = 256,
E_ITEM_IRON_PICKAXE = 257,
E_ITEM_IRON_AXE = 258,
@ -445,7 +452,13 @@ enum ENUM_ITEM_ID
E_ITEM_FIREWORK_ROCKET = 401,
E_ITEM_FIREWORK_STAR = 402,
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_CAT_DISC = 2257,
E_ITEM_BLOCKS_DISC = 2258,
@ -457,7 +470,12 @@ enum ENUM_ITEM_ID
E_ITEM_STRAD_DISC = 2264,
E_ITEM_WARD_DISC = 2265,
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_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);
if (Meta & 0x8)
{
// 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
{
@ -72,9 +65,8 @@ void cBlockBedHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, i
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
{
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 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

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:
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();
// 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;
}
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()));
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
float rot = a_Player->GetRotation();
// 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:
cBlockDispenserHandler(BLOCKTYPE a_BlockType)
: cBlockEntityHandler(a_BlockType)
cBlockDispenserHandler(BLOCKTYPE 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));
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
a_BlockType = m_BlockType;
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)
{
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)
{
@ -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);
}
@ -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());
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_TopBlockMeta = 9;
}
a_World->SetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, a_TopBlockMeta);
}

View File

@ -3,6 +3,8 @@
#include "BlockHandler.h"
#include "../World.h"
#include "../Doors.h"
#include "../Player.h"
@ -13,32 +15,89 @@ class cBlockDoorHandler :
{
public:
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 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 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
{
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;
}
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
{
return false;
}
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);
}
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);
}

View File

@ -12,41 +12,44 @@ class cBlockFenceGateHandler :
public cBlockHandler
{
public:
cBlockFenceGateHandler(BLOCKTYPE a_BlockType)
: cBlockHandler(a_BlockType)
cBlockFenceGateHandler(BLOCKTYPE a_BlockType) :
cBlockHandler(a_BlockType)
{
}
void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir)
{
}
void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir)
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 = cDoors::RotationToMetaData(a_Player->GetRotation() + 270);
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);
return true;
}
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);
char NewMetaData = cDoors::RotationToMetaData(a_Player->GetRotation() + 270);
NIBBLETYPE OldMetaData = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
NIBBLETYPE NewMetaData = cDoors::RotationToMetaData(a_Player->GetRotation() + 270);
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));
}
else
{
//Standing aside - use last direction
// Standing aside - use last direction
a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, OldMetaData);
}
}
virtual bool IsUseable() override
virtual bool IsUseable(void) override
{
return true;
}

View File

@ -11,17 +11,21 @@ class cBlockFlowerPotHandler :
public cBlockHandler
{
public:
cBlockFlowerPotHandler(BLOCKTYPE a_BlockType)
: cBlockHandler(a_BlockType)
cBlockFlowerPotHandler(BLOCKTYPE a_BlockType) :
cBlockHandler(a_BlockType)
{
}
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
a_Pickups.push_back(cItem(E_ITEM_FLOWER_POT, 1, 0));
if( a_BlockMeta == 0 ) return;
if (a_BlockMeta == 0)
{
return;
}
cItem Plant;
switch( a_BlockMeta )
switch (a_BlockMeta)
{
case 1: Plant = cItem(E_ITEM_RED_ROSE, 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 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;
default: return;
}
a_Pickups.push_back(Plant);
}
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 );
if( Meta ) return;
switch( a_Player->GetEquippedItem().m_ItemType )
NIBBLETYPE Meta = a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ );
if (Meta != 0)
{
// Already filled
return;
}
switch (a_Player->GetEquippedItem().m_ItemType)
{
case E_ITEM_RED_ROSE: Meta = 1; break;
case E_ITEM_YELLOW_FLOWER: Meta = 2; break;
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_CONIFER: Meta = 4; break;
@ -62,17 +73,29 @@ public:
case E_ITEM_CACTUS: Meta = 9; break;
case E_BLOCK_DEAD_BUSH: Meta = 10; break;
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);
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;
}

View File

@ -14,8 +14,8 @@ class cBlockFurnaceHandler :
public cBlockEntityHandler
{
public:
cBlockFurnaceHandler(BLOCKTYPE a_BlockType)
: cBlockEntityHandler(a_BlockType)
cBlockFurnaceHandler(BLOCKTYPE 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));
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
a_BlockType = m_BlockType;
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)
{
}
@ -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, 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)
{
//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, 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)
{
// 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:
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);
/// Called by cBlockHandler::PlaceBlock after the player has placed a new block
virtual void OnPlacedByPlayer(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir);
/** Called before a block is placed into a world.
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
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
virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ);
@ -46,11 +63,8 @@ public:
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
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.
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));
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
a_BlockType = m_BlockType;
a_BlockMeta = cLadder::DirectionToMetaData(a_BlockFace);
return true;
}
/// 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;
}
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;
}
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 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
{
char Dir = cLadder::MetaDataToDirection(a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ));
return CanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Dir);
char BlockFace = cLadder::MetaDataToDirection(a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ));
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
}
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.
// 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);
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);
}
@ -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)
{
OnUse(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ);
}
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);
OnUse(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NONE, 8, 8, 8);
}

View File

@ -2,6 +2,9 @@
#include "BlockHandler.h"
#include "../World.h"
#include "../Simulator/RedstoneSimulator.h"
@ -10,11 +13,9 @@ class cBlockLeverHandler :
{
public:
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 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
@ -30,16 +31,31 @@ 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
{
return false;
}
virtual const char * GetStepSound(void) override
{
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)
{
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_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cPiston::RotationPitchToMetaData(a_Player->GetRotation(), a_Player->GetPitch()));
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
a_BlockType = E_BLOCK_REDSTONE_REPEATER_OFF;
a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), a_Player->GetPitch());
return true;
}

View File

@ -1,15 +1,28 @@
#pragma once
#include "BlockHandler.h"
class cBlockPistonHandler : public cBlockHandler
class cBlockPistonHandler :
public cBlockHandler
{
public:
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 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;
} ;

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));
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
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);
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);
a_BlockType = m_BlockType;
a_BlockMeta = FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ);
return true;
}
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);
if(IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ) && Meta != FindMeta(a_World, 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)))
{
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
{
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;
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:
{
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;
}
break;
}
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;
}
break;
}
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;
}
break;
}
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;
}
break;
}
}
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;
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));
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;
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;
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;
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;
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))
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++)
for (int i = 0; i < 8; i++)
{
if(Neighbors[i])
if (Neighbors[i])
{
RailsCnt++;
}
}
if(RailsCnt == 1)
if (RailsCnt == 1)
{
if(Neighbors[7]) Meta = E_RAIL_ASCEND_SOUTH;
else if(Neighbors[6]) Meta = E_RAIL_ASCEND_NORTH;
else if(Neighbors[5]) Meta = E_RAIL_ASCEND_WEST;
else if(Neighbors[4]) Meta = E_RAIL_ASCEND_EAST;
else if(Neighbors[0] || Neighbors[1]) Meta = E_RAIL_EAST_WEST;
else if(Neighbors[2] || Neighbors[3]) Meta = E_RAIL_NORTH_SOUTH;
if (Neighbors[7]) return E_RAIL_ASCEND_SOUTH;
else if (Neighbors[6]) return E_RAIL_ASCEND_NORTH;
else if (Neighbors[5]) return E_RAIL_ASCEND_WEST;
else if (Neighbors[4]) return E_RAIL_ASCEND_EAST;
else if (Neighbors[0] || Neighbors[1]) return E_RAIL_EAST_WEST;
else if (Neighbors[2] || Neighbors[3]) return E_RAIL_NORTH_SOUTH;
ASSERT(!"Weird neighbor count");
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;
}
}
if(RailsCnt > 1)
if (RailsCnt > 1)
{
if(Neighbors[3] && Neighbors[0]) Meta = E_RAIL_CURVED_SOUTH_EAST;
else if(Neighbors[3] && Neighbors[1]) Meta = E_RAIL_CURVED_SOUTH_WEST;
else if(Neighbors[2] && Neighbors[0]) Meta = E_RAIL_CURVED_NORTH_EAST;
else if(Neighbors[2] && Neighbors[1]) Meta = E_RAIL_CURVED_NORTH_WEST;
else if(Neighbors[7] && Neighbors[2]) Meta = E_RAIL_ASCEND_SOUTH;
else if(Neighbors[3] && Neighbors[6]) Meta = E_RAIL_ASCEND_NORTH;
else if(Neighbors[5] && Neighbors[0]) Meta = E_RAIL_ASCEND_WEST;
else if(Neighbors[4] && Neighbors[1]) Meta = E_RAIL_ASCEND_EAST;
else if(Neighbors[0] && Neighbors[1]) Meta = E_RAIL_EAST_WEST;
else if(Neighbors[2] && Neighbors[3]) Meta = E_RAIL_NORTH_SOUTH;
if (Neighbors[3] && Neighbors[0]) return E_RAIL_CURVED_SOUTH_EAST;
else if(Neighbors[3] && Neighbors[1]) return E_RAIL_CURVED_SOUTH_WEST;
else if(Neighbors[2] && Neighbors[0]) return E_RAIL_CURVED_NORTH_EAST;
else if(Neighbors[2] && Neighbors[1]) return E_RAIL_CURVED_NORTH_WEST;
else if(Neighbors[7] && Neighbors[2]) return E_RAIL_ASCEND_SOUTH;
else if(Neighbors[3] && Neighbors[6]) return E_RAIL_ASCEND_NORTH;
else if(Neighbors[5] && Neighbors[0]) return E_RAIL_ASCEND_WEST;
else if(Neighbors[4] && Neighbors[1]) return E_RAIL_ASCEND_EAST;
else if(Neighbors[0] && Neighbors[1]) return E_RAIL_EAST_WEST;
else if(Neighbors[2] && Neighbors[3]) return E_RAIL_NORTH_SOUTH;
ASSERT(!"Weird neighbor count");
}
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;
char Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
switch(Meta)
if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL) return false;
NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
switch (Meta)
{
case E_RAIL_NORTH_SOUTH:
{
@ -238,15 +245,16 @@ public:
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);
char Meta;
if(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL)
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false);
NIBBLETYPE Meta;
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;
}
@ -264,46 +272,65 @@ public:
{
Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
}
switch(a_Direction)
switch (a_BlockFace)
{
case BLOCK_FACE_NORTH:
{
if(Meta == E_RAIL_NORTH_SOUTH ||
Meta == E_RAIL_ASCEND_NORTH ||
Meta == E_RAIL_ASCEND_SOUTH ||
Meta == E_RAIL_CURVED_SOUTH_EAST ||
Meta == E_RAIL_CURVED_SOUTH_WEST)
return false;
if (
(Meta == E_RAIL_NORTH_SOUTH) ||
(Meta == E_RAIL_ASCEND_NORTH) ||
(Meta == E_RAIL_ASCEND_SOUTH) ||
(Meta == E_RAIL_CURVED_SOUTH_EAST) ||
(Meta == E_RAIL_CURVED_SOUTH_WEST)
)
{
return false;
}
break;
}
case BLOCK_FACE_SOUTH:
{
if(Meta == E_RAIL_NORTH_SOUTH ||
Meta == E_RAIL_ASCEND_NORTH ||
Meta == E_RAIL_ASCEND_SOUTH ||
Meta == E_RAIL_CURVED_NORTH_EAST ||
Meta == E_RAIL_CURVED_NORTH_WEST)
return false;
if (
(Meta == E_RAIL_NORTH_SOUTH) ||
(Meta == E_RAIL_ASCEND_NORTH) ||
(Meta == E_RAIL_ASCEND_SOUTH) ||
(Meta == E_RAIL_CURVED_NORTH_EAST) ||
(Meta == E_RAIL_CURVED_NORTH_WEST)
)
{
return false;
}
break;
}
case BLOCK_FACE_EAST:
{
if(Meta == E_RAIL_EAST_WEST ||
Meta == E_RAIL_ASCEND_EAST ||
Meta == E_RAIL_ASCEND_WEST ||
Meta == E_RAIL_CURVED_SOUTH_WEST ||
Meta == E_RAIL_CURVED_NORTH_WEST)
return false;
if (
(Meta == E_RAIL_EAST_WEST) ||
(Meta == E_RAIL_ASCEND_EAST) ||
(Meta == E_RAIL_ASCEND_WEST) ||
(Meta == E_RAIL_CURVED_SOUTH_WEST) ||
(Meta == E_RAIL_CURVED_NORTH_WEST)
)
{
return false;
}
break;
}
case BLOCK_FACE_WEST:
{
if(Meta == E_RAIL_EAST_WEST ||
Meta == E_RAIL_ASCEND_EAST ||
Meta == E_RAIL_ASCEND_WEST ||
Meta == E_RAIL_CURVED_SOUTH_EAST ||
Meta == E_RAIL_CURVED_NORTH_EAST)
return false;
if (
(Meta == E_RAIL_EAST_WEST) ||
(Meta == E_RAIL_ASCEND_EAST) ||
(Meta == E_RAIL_ASCEND_WEST) ||
(Meta == E_RAIL_CURVED_SOUTH_EAST) ||
(Meta == E_RAIL_CURVED_NORTH_EAST)
)
{
return false;
}
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)
{
// 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:
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 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
{
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)
{
// 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));
}
@ -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)
{
OnUse(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ);
}
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);
OnUse(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NONE, 8, 8, 8);
}

View File

@ -13,11 +13,10 @@ class cBlockRedstoneRepeaterHandler :
{
public:
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 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
@ -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
{
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
{
a_Pickups.push_back(cItem(E_ITEM_SIGN, 1, 0));

View File

@ -24,24 +24,41 @@ 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 ));
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
}
static char DirectionToMetaData( char a_Direction, NIBBLETYPE Meta )
{
char result = Meta;
if( a_Direction == 0)
a_BlockType = m_BlockType;
NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage & 0x07);
switch (a_BlockFace)
{
result |= 0x8;
}
return result;
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
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;
}
virtual const char * GetStepSound(void) override
{
return ((m_BlockType == E_BLOCK_WOODEN_SLAB) || (m_BlockType == E_BLOCK_DOUBLE_WOODEN_SLAB)) ? "step.wood" : "step.stone";

View File

@ -1,22 +1,56 @@
#pragma once
#include "BlockHandler.h"
#include "../Stairs.h"
class cBlockStairsHandler : public cBlockHandler
class cBlockStairsHandler :
public cBlockHandler
{
public:
cBlockStairsHandler(BLOCKTYPE a_BlockType)
: cBlockHandler(a_BlockType)
cBlockStairsHandler(BLOCKTYPE 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));
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
a_BlockType = m_BlockType;
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,23 +19,29 @@ 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_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cTorch::DirectionToMetaData(a_Dir));
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
a_BlockType = m_BlockType;
a_BlockMeta = cTorch::DirectionToMetaData(a_BlockFace);
return true;
}
virtual bool DoesAllowBlockOnTop(void) override
{
return false;
@ -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
// How to propagate that change up?
// 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;
}
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
static char FindSuitableDirection(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
/// Finds a suitable Face for the Torch. Returns BLOCK_FACE_BOTTOM on failure
static char FindSuitableFace(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
{
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 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
{
char Dir = cTorch::MetaDataToDirection(a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ));
return TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Dir);
char Face = cTorch::MetaDataToDirection(a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ));
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));
OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
a_BlockType = m_BlockType;
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 (
(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;
@ -38,18 +44,18 @@ public:
BLOCKTYPE TopBlock = a_World->GetBlock( a_BlockX, a_BlockY + 1, a_BlockZ);
if (g_BlockIsSolid[TopBlock] || (TopBlock == E_BLOCK_LEAVES))
{
AddDirection( a_BlockX, a_BlockY, a_BlockZ, a_Dir, true );
BLOCKTYPE BaseBlock = a_World->GetBlock( a_BlockX, a_BlockY, a_BlockZ);
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true);
BLOCKTYPE BaseBlock = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
if (!g_BlockIsSolid[BaseBlock] && (BaseBlock != E_BLOCK_LEAVES))
{
AddDirection( a_BlockX, a_BlockY, a_BlockZ, a_Dir, false );
a_World->SetBlock( a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_VINES, 0);
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false);
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_VINES, 0);
}
return true;
}
AddDirection( a_BlockX, a_BlockY, a_BlockZ, a_Dir, true );
BLOCKTYPE BaseBlock = a_World->GetBlock( a_BlockX, a_BlockY, a_BlockZ);
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true);
BLOCKTYPE BaseBlock = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
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);
a_Player->OpenWindow(Window);

View File

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

View File

@ -128,8 +128,6 @@ public:
int GetPosZ() { return m_PosZ; }
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 );
// 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 ); }

View File

@ -89,8 +89,8 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance)
, m_LastStreamedChunkZ(0x7fffffff)
, m_ShouldCheckDownloaded(false)
, m_UniqueID(0)
, m_BlockDigAnim(-1)
, m_LastDigStatus(-1)
, m_BlockDigAnimStage(-1)
, m_HasStartedDigging(false)
{
m_Protocol = new cProtocolRecognizer(this);
@ -231,7 +231,7 @@ void cClientHandle::Authenticate(void)
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();
@ -260,7 +260,7 @@ void cClientHandle::Authenticate(void)
// Broadcast this player's spawning to all other players in the same chunk
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())
{
// Too many interactions per second, simply ignore. Probably a hacked client, so don't even send bak the block
return;
}
LOGD("OnBlockDig: {%i, %i, %i}; Face: %i; Stat: %i LastStat: %i",
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
switch (a_Status)
{
m_Player->TossItem(false);
return;
}
if (a_Status == DIG_STATUS_SHOOT_EAT)
{
LOGINFO("BlockDig: Status SHOOT/EAT not implemented");
return;
}
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))
{
// The plugin doesn't agree with the digging, replace the block on the client and quit:
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
return;
}
bool bBroken = (
((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;
m_LastDigX = a_BlockX;
m_LastDigY = a_BlockY;
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)
case DIG_STATUS_DROP_HELD: // Drop held item
{
ItemHandler->OnBlockDestroyed(World, m_Player, &Equipped, a_BlockX, a_BlockY, a_BlockZ);
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())
if (PlgMgr->CallHookPlayerTossingItem(*m_Player))
{
Handler->OnDigging(World, m_Player, pX, pY, pZ);
// 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;
}
if (cRoot::Get()->GetPluginManager()->CallHookPlayerBreakingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_OldBlock, a_OldMeta))
{
// 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;
}
// 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();
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)
{
int pX = a_BlockX;
int pY = a_BlockY;
int pZ = a_BlockZ;
AddFaceDirection(pX, pY, pZ, a_BlockFace);
Handler = cBlockHandler::GetBlockHandler(World->GetBlock(pX, pY, pZ));
// 2013_01_05 _X: This looks weird
// Why do we ask the block "behind" the one being clicked if it is clicked through? Shouldn't we ask the primary block instead?
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()
);
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())
{
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
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);
}
return;
@ -648,104 +755,133 @@ void cClientHandle::HandleBlockPlace(int a_BlockX, int a_BlockY, int a_BlockZ, c
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())
{
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
{
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemID);
if (ItemHandler->OnItemUse(World, m_Player, &Equipped, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace))
if (PlgMgr->CallHookPlayerUsingItem(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ))
{
// 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))
{
if (a_BlockFace > -1)
{
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;
}
// 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;
}
else if (ItemHandler->IsFood())
BLOCKTYPE PlaceBlock = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
if (!BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision())
{
cItem Item;
Item.m_ItemID = Equipped.m_ItemID;
Item.m_ItemCount = 1;
if (ItemHandler->EatItem(m_Player, &Item))
{
ItemHandler->OnFoodEaten(World, m_Player, &Item);
m_Player->GetInventory().RemoveItem(Item);
return;
}
// Tried to place a block *into* another?
return; // Happens when you place a block aiming at side of block like torch or stem
}
}
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;
}
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:
if ((m_Player != NULL) && (m_BlockDigAnim > -1))
if ((m_Player != NULL) && (m_BlockDigAnimStage > -1))
{
int lastAnimVal = m_BlockDigAnim;
m_BlockDigAnim += (int)(m_BlockDigAnimSpeed * a_Dt);
if (m_BlockDigAnim > 9000)
int lastAnimVal = m_BlockDigAnimStage;
m_BlockDigAnimStage += (int)(m_BlockDigAnimSpeed * a_Dt);
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;
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~
cRoot::Get()->GetServer()->BroadcastChat(m_Username + " joined the game!", this);

View File

@ -31,6 +31,7 @@ class cProtocol;
class cRedstone;
class cWindow;
class cFallingBlock;
class cItemHandler;
@ -63,7 +64,7 @@ public:
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 StreamChunks(void);
@ -125,15 +126,15 @@ public:
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 );
const AString & GetUsername(void) const; //tolua_export
void SetUsername( const AString & a_Username ); //tolua_export
const AString & GetUsername(void) const; // 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
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)
bool WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
@ -150,8 +151,8 @@ public:
void HandlePing (void);
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 HandleBlockDig (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 HandleLeftClick (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status);
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 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)
@ -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)
// 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_BlockDigX;
int m_BlockDigY;
int m_BlockDigZ;
int m_BlockDigAnimX;
int m_BlockDigAnimY;
int m_BlockDigAnimZ;
char m_LastDigStatus;
int m_LastDigX;
int m_LastDigY;
int m_LastDigZ;
// 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:
bool m_HasStartedDigging;
int m_LastDigBlockX;
int m_LastDigBlockY;
int m_LastDigBlockZ;
enum eState
{
@ -264,6 +266,15 @@ private:
/// Adds a single chunk to be streamed to the client; used by StreamChunks()
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:
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

View File

@ -148,10 +148,10 @@ void cCraftingGrid::ConsumeGrid(const cCraftingGrid & a_Grid)
continue;
}
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.",
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;
}
@ -159,7 +159,7 @@ void cCraftingGrid::ConsumeGrid(const cCraftingGrid & a_Grid)
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.",
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;
@ -194,7 +194,7 @@ void cCraftingGrid::Dump(void)
{
int idx = x + m_Width * y;
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:");
m_Ingredients.Dump();
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)
{
AString Damage = TrimString(Split[1]);
a_Item.m_ItemHealth = atoi(Damage.c_str());
if ((a_Item.m_ItemHealth == 0) && (Damage.compare("0") != 0))
a_Item.m_ItemDamage = atoi(Damage.c_str());
if ((a_Item.m_ItemDamage == 0) && (Damage.compare("0") != 0))
{
// Parsing the number failed
return false;
@ -662,11 +662,11 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti
if (
(itrS->x >= a_GridWidth) ||
(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_ItemHealth > 0) && // should compare damage values?
(itrS->m_Item.m_ItemHealth != a_CraftingGrid[GridID].m_ItemHealth)
(itrS->m_Item.m_ItemDamage > 0) && // should compare damage values?
(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;
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_ItemHealth == a_CraftingGrid[GridIdx].m_ItemHealth) // the damage matches
(itrS->m_Item.m_ItemDamage < 0) || // doesn't want damage comparison
(itrS->m_Item.m_ItemDamage == a_CraftingGrid[GridIdx].m_ItemDamage) // the damage matches
)
)
{

View File

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

View File

@ -5,17 +5,19 @@
typedef unsigned char Byte;
//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[];
// tolua_begin
//--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_SHOOT_EAT = 5,
} ;
//tolua_end
// tolua_end
inline bool IsValidBlock( int a_BlockType ) //tolua_export
{ //tolua_export
if( a_BlockType > -1 &&
a_BlockType <= 145 && //items to 109 are valid for Beta1.8.1.. 1.2.5 is up to 126
//a_BlockType != 29 && allow pistons
//a_BlockType != 33 && allow pistons
a_BlockType != 34 &&
a_BlockType != 36 )
inline bool IsValidBlock(int a_BlockType) // tolua_export
{ // tolua_export
if (
(a_BlockType > -1) &&
(a_BlockType <= E_BLOCK_MAX_TYPE_ID) &&
(a_BlockType != 34) && // Piston extension
(a_BlockType != 36) // Piston moved block
)
{
return true;
}
return false;
} //tolua_export
} // tolua_export
// Was old :o
// Changed to fit the style ;)
inline bool IsValidItem( int a_ItemID ) //tolua_export
{ //tolua_export
if( (a_ItemID >= 256 && a_ItemID <= 400)
|| (a_ItemID >= 2256 && a_ItemID <= 2267) )
inline bool IsValidItem(int a_ItemType) // tolua_export
{ // tolua_export
if (
((a_ItemType >= E_ITEM_FIRST) && (a_ItemType <= E_ITEM_MAX_CONSECUTIVE_TYPE_ID)) || // Basic items range
((a_ItemType >= E_ITEM_FIRST_DISC) && (a_ItemType <= E_ITEM_LAST_DISC)) // Music discs' special range
)
{
return true;
}
if( a_ItemID == 0 )
if (a_ItemType == 0)
{
return false;
}
return IsValidBlock( a_ItemID );
} //tolua_export
return IsValidBlock(a_ItemType);
} // tolua_export
@ -87,7 +91,7 @@ inline bool IsValidItem( int a_ItemID ) //tolua_export
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)
{
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)
{
return IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType);
}
inline bool IsBlockTypeOfDirt(BLOCKTYPE a_BlockType)
{
switch (a_BlockType)
@ -112,7 +123,9 @@ inline bool IsBlockTypeOfDirt(BLOCKTYPE a_BlockType)
case E_BLOCK_DIRT:
case E_BLOCK_GRASS:
case E_BLOCK_FARMLAND:
{
return true;
}
}
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)
{
switch (a_Direction)
switch (a_BlockFace)
{
case BLOCK_FACE_BOTTOM: a_Y--; break;
case BLOCK_FACE_TOP: a_Y++; break;
case BLOCK_FACE_EAST: a_X++; break;
case BLOCK_FACE_WEST: a_X--; break;
case BLOCK_FACE_NORTH: a_Z--; break;
case BLOCK_FACE_SOUTH: a_Z++; break;
case BLOCK_FACE_BOTTOM: a_BlockY--; break;
case BLOCK_FACE_TOP: a_BlockY++; break;
case BLOCK_FACE_EAST: a_BlockX++; break;
case BLOCK_FACE_WEST: a_BlockX--; break;
case BLOCK_FACE_NORTH: a_BlockZ--; break;
case BLOCK_FACE_SOUTH: a_BlockZ++; break;
default:
{
LOGWARNING("AddDirection(): Unknown direction: %d", a_Direction);
ASSERT(!"AddDirection(): Unknown direction");
LOGWARNING("%s: Unknown face: %d", __FUNCTION__, a_BlockFace);
ASSERT(!"AddFaceDirection(): Unknown face");
break;
}
}
}
else
{
switch( a_Direction ) // other way around
switch (a_BlockFace)
{
case BLOCK_FACE_BOTTOM: a_Y++; break;
case BLOCK_FACE_TOP: a_Y--; break;
case BLOCK_FACE_EAST: a_X--; break;
case BLOCK_FACE_WEST: a_X++; break;
case BLOCK_FACE_NORTH: a_Z++; break;
case BLOCK_FACE_SOUTH: a_Z--; break;
case BLOCK_FACE_BOTTOM: a_BlockY++; break;
case BLOCK_FACE_TOP: a_BlockY--; break;
case BLOCK_FACE_EAST: a_BlockX--; break;
case BLOCK_FACE_WEST: a_BlockX++; break;
case BLOCK_FACE_NORTH: a_BlockZ++; break;
case BLOCK_FACE_SOUTH: a_BlockZ--; break;
default:
{
LOGWARNING("AddDirection(): Unknown inv direction: %d", a_Direction);
ASSERT(!"AddDirection(): Unknown direction");
LOGWARNING("%s: Unknown inv face: %d", __FUNCTION__, a_BlockFace);
ASSERT(!"AddFaceDirection(): Unknown face");
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>
#define PI 3.14159265358979323846264338327950288419716939937510582097494459072381640628620899862803482534211706798f
#define MIN(a,b) (((a)>(b))?(b):(a))
@ -225,7 +247,7 @@ inline float GetSpecialSignf( float a_Val )
//tolua_begin
// tolua_begin
namespace ItemCategory
{
inline bool IsPickaxe(short a_ItemID)
@ -344,7 +366,7 @@ namespace ItemCategory
);
}
}
//tolua_end
// tolua_end
inline bool BlockRequiresSpecialTool(BLOCKTYPE a_BlockType)
@ -354,7 +376,7 @@ inline bool BlockRequiresSpecialTool(BLOCKTYPE a_BlockType)
}
//tolua_begin
// tolua_begin
enum eGameMode
{
eGameMode_NotSet = -1,
@ -377,7 +399,7 @@ enum eWeather
//tolua_end
// tolua_end

View File

@ -121,7 +121,7 @@ void cDispenserEntity::Dispense()
else
{
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_Items[OccupiedSlots[RandomSlot]].m_ItemCount--;
}
@ -138,7 +138,7 @@ void cDispenserEntity::Dispense()
else
{
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_Items[OccupiedSlots[RandomSlot]].m_ItemCount--;
}
@ -155,7 +155,7 @@ void cDispenserEntity::Dispense()
else
{
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_Items[OccupiedSlots[RandomSlot]].m_ItemCount--;
}
@ -172,7 +172,7 @@ void cDispenserEntity::Dispense()
default:
{
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_Items[OccupiedSlots[RandomSlot]].m_ItemCount--;
break;
@ -280,9 +280,9 @@ bool cDispenserEntity::LoadFromFile(cFile & f)
for(unsigned int i = 0; i < NumSlots; 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_ItemHealth);
READ(f, Item.m_ItemDamage);
}
return true;

View File

@ -1,11 +1,11 @@
#pragma once
class cDoors //tolua_export
{ //tolua_export
class cDoors // tolua_export
{ // tolua_export
public:
static char RotationToMetaData( float a_Rotation ) //tolua_export
{ //tolua_export
static char RotationToMetaData( float a_Rotation ) // tolua_export
{ // tolua_export
a_Rotation += 90 + 45; // So its not aligned with axis
if( a_Rotation > 360.f ) a_Rotation -= 360.f;
if( a_Rotation >= 0.f && a_Rotation < 90.f )
@ -16,18 +16,18 @@ public:
return 0x1;
else
return 0x3;
} //tolua_export
} // tolua_export
static char ChangeStateMetaData( char a_MetaData ) //tolua_export
{ //tolua_export
static char ChangeStateMetaData( char a_MetaData ) // tolua_export
{ // tolua_export
a_MetaData ^= 4; //XOR bit 2 aka 3. bit (Door open state)
return a_MetaData;
} //tolua_export
} // tolua_export
static void ChangeDoor(cWorld *a_World, int a_X, int a_Y, int a_Z) //tolua_export
{ //tolua_export
static void ChangeDoor(cWorld *a_World, int a_X, int a_Y, int a_Z) // tolua_export
{ // tolua_export
char OldMetaData = a_World->GetBlockMeta(a_X, a_Y, a_Z);
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 ) );
}
}
} //tolua_export
} // tolua_export
inline static bool IsDoor(char a_Block)
{
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);
// tolua_end
inline int GetUniqueID(void) const { return m_UniqueID; } //tolua_export
inline bool IsDestroyed(void) const { return m_bDestroyed; } //tolua_export
inline int GetUniqueID(void) const { return m_UniqueID; } // 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
virtual void Tick(float a_Dt, MTRand & a_TickRandom); // tolua_export
@ -199,7 +199,7 @@ protected:
float m_FireDamageInterval;
float m_BurnPeriod;
}; //tolua_export
}; // tolua_export
typedef std::list<cEntity *> cEntityList;

View File

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

View File

@ -597,7 +597,7 @@ void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
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
{ //tolua_export
public: //tolua_export
class cGroup // tolua_export
{ // tolua_export
public: // tolua_export
cGroup() {}
~cGroup() {}
void SetName( std::string a_Name ) { m_Name = a_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 AddCommand( std::string a_Command ); //tolua_export
void AddPermission( std::string a_Permission ); //tolua_export
void InheritFrom( cGroup* a_Group ); //tolua_export
void SetName( std::string a_Name ) { m_Name = a_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 AddCommand( std::string a_Command ); // tolua_export
void AddPermission( std::string a_Permission ); // 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;
const PermissionMap & GetPermissions() const { return m_Permissions; }
@ -26,7 +26,7 @@ public: //tolua_export
typedef std::map< std::string, bool > CommandMap;
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;
const GroupList & GetInherits() const { return m_Inherits; }
@ -37,4 +37,4 @@ private:
PermissionMap m_Permissions;
CommandMap m_Commands;
GroupList m_Inherits;
};//tolua_export
};// tolua_export

View File

@ -12,16 +12,19 @@
typedef std::map< AString, cGroup* > GroupMap;
struct cGroupManager::sGroupManagerState
{
GroupMap Groups;
};
cGroupManager* cGroupManager::GetGroupManager()
{
LOGWARN("WARNING: Using deprecated function cGroupManager::GetGroupManager() use cRoot::Get()->GetGroupManager() instead!");
return cRoot::Get()->GetGroupManager();
}
cGroupManager::~cGroupManager()
{
@ -34,6 +37,10 @@ cGroupManager::~cGroupManager()
delete m_pState;
}
cGroupManager::cGroupManager()
: m_pState( new sGroupManagerState )
{
@ -98,6 +105,10 @@ cGroupManager::cGroupManager()
LOG("-- Done Loading Groups --");
}
cGroup* cGroupManager::GetGroup( const AString & 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;
return Group;
}
}

View File

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

View File

@ -77,7 +77,7 @@ bool cInventory::AddItem( cItem & a_Item )
{
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);
}
}
@ -107,7 +107,7 @@ bool cInventory::AddItemAnyAmount( cItem & a_Item )
{
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);
}
}
@ -125,7 +125,7 @@ bool cInventory::RemoveItem( cItem & a_Item )
// First check equipped slot
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];
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++)
{
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)
{
@ -323,7 +323,7 @@ int cInventory::HowManyCanFit(short a_ItemType, short a_ItemDamage, int a_BeginS
{
if (
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();
@ -345,15 +345,15 @@ int cInventory::MoveItem(short a_ItemType, short a_ItemDamage, int a_Count, int
{
if (
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();
ASSERT(m_Slots[i].m_ItemCount <= MaxCount);
int NumToMove = std::min(a_Count, MaxCount - m_Slots[i].m_ItemCount);
m_Slots[i].m_ItemCount += NumToMove;
m_Slots[i].m_ItemHealth = a_ItemDamage;
m_Slots[i].m_ItemID = a_ItemType;
m_Slots[i].m_ItemDamage = a_ItemDamage;
m_Slots[i].m_ItemType = a_ItemType;
SendSlot(i);
res += 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();
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;
if( NumFree >= a_Item.m_ItemCount )

View File

@ -19,35 +19,35 @@ class cPlayer;
class cInventory //tolua_export
{ //tolua_export
class cInventory // tolua_export
{ // tolua_export
public:
cInventory(cPlayer & a_Owner);
~cInventory();
void Clear(); //tolua_export
void Clear(); // tolua_export
cItem* GetSlotsForType( int a_Type );
int GetSlotCountForType( int a_Type );
bool AddItem( cItem & a_Item ); //tolua_export
bool AddItemAnyAmount( cItem & a_Item ); //tolua_export
bool RemoveItem( cItem & a_Item ); //tolua_export
bool AddItem( cItem & a_Item ); // tolua_export
bool AddItemAnyAmount( cItem & a_Item ); // tolua_export
bool RemoveItem( cItem & a_Item ); // tolua_export
void SaveToJson(Json::Value & a_Value);
bool LoadFromJson(Json::Value & a_Value);
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; }
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;
void SetEquippedSlot(int a_SlotNum); //tolua_export
short GetEquippedSlot(void) { return m_EquippedSlot; } //tolua_export
void SetEquippedSlot(int a_SlotNum); // tolua_export
short GetEquippedSlot(void) { return m_EquippedSlot; } // tolua_export
// tolua_begin
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]; }
// 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
int HowManyCanFit(short a_ItemType, short a_ItemDamage, int a_BeginSlot, int a_EndSlot);
@ -89,7 +89,7 @@ protected:
short m_EquippedSlot;
cPlayer & m_Owner;
}; //tolua_export
}; // tolua_export

View File

@ -10,21 +10,21 @@
void cItem::GetJson( Json::Value & a_OutValue ) const
{
a_OutValue["ID"] = m_ItemID;
if( m_ItemID > 0 )
a_OutValue["ID"] = m_ItemType;
if( m_ItemType > 0 )
{
a_OutValue["Count"] = m_ItemCount;
a_OutValue["Health"] = m_ItemHealth;
a_OutValue["Health"] = m_ItemDamage;
}
}
void cItem::FromJson( const Json::Value & a_Value )
{
m_ItemID = (ENUM_ITEM_ID)a_Value.get("ID", -1 ).asInt();
if( m_ItemID > 0 )
m_ItemType = (ENUM_ITEM_ID)a_Value.get("ID", -1 ).asInt();
if( m_ItemType > 0 )
{
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
{
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_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()
{
m_ItemID = E_ITEM_EMPTY;
m_ItemType = E_ITEM_EMPTY;
m_ItemCount = 0;
m_ItemHealth = 0;
m_ItemDamage = 0;
}
void Clear(void)
{
m_ItemID = E_ITEM_EMPTY;
m_ItemType = E_ITEM_EMPTY;
m_ItemCount = 0;
m_ItemHealth = 0;
m_ItemDamage = 0;
}
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
{
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
{
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
inline int GetMaxDuration(void) const
{
switch(m_ItemID)
switch (m_ItemType)
{
case 256: 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()
{
if (HasDuration())
{
m_ItemHealth++;
if(m_ItemHealth >= GetMaxDuration())
m_ItemDamage++;
if (m_ItemDamage >= GetMaxDuration())
return true;
}
return false;
@ -111,23 +114,9 @@ public:
static bool IsEnchantable(short a_ItemType);
// tolua_end
union
{
// 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
short m_ItemType;
char m_ItemCount;
short m_ItemDamage;
};
// tolua_end

View File

@ -3,23 +3,54 @@
#include "ItemHandler.h"
#include "../World.h"
#include "../Blocks/BlockBed.h"
class cItemBedHandler : public cItemHandler
class cItemBedHandler :
public cItemHandler
{
public:
cItemBedHandler(int a_ItemType)
: cItemHandler(a_ItemType)
cItemBedHandler(int a_ItemType) :
cItemHandler(a_ItemType)
{
}
virtual bool IsPlaceable() override
virtual bool IsPlaceable(void) override
{
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"
class cItemBrewingStandHandler : public cItemHandler
class cItemBrewingStandHandler :
public cItemHandler
{
public:
cItemBrewingStandHandler(int a_ItemType)
: cItemHandler(a_ItemType)
cItemBrewingStandHandler(int a_ItemType) :
cItemHandler(a_ItemType)
{
}
virtual bool IsPlaceable() override
virtual bool IsPlaceable(void) override
{
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;
}
AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_Dir);
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
BLOCKTYPE ClickedBlock;
NIBBLETYPE 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;
}
@ -112,7 +112,7 @@ public:
if (!CanWashAway)
{
// 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);
}
if (

View File

@ -3,23 +3,39 @@
#include "ItemHandler.h"
class cItemCauldronHandler : public cItemHandler
class cItemCauldronHandler :
public cItemHandler
{
public:
cItemCauldronHandler(int a_ItemType)
: cItemHandler(a_ItemType)
cItemCauldronHandler(int a_ItemType) :
cItemHandler(a_ItemType)
{
}
virtual bool IsPlaceable() override
virtual bool IsPlaceable(void) override
{
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 "../World.h"
class cItemDoorHandler : public cItemHandler
class cItemDoorHandler :
public cItemHandler
{
public:
cItemDoorHandler(int a_ItemType)
: cItemHandler(a_ItemType)
cItemDoorHandler(int a_ItemType) :
cItemHandler(a_ItemType)
{
}
virtual bool IsPlaceable() override
virtual bool IsPlaceable(void) override
{
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)
// 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_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);
return true;
}

View File

@ -3,23 +3,39 @@
#include "ItemHandler.h"
class cItemFlowerPotHandler : public cItemHandler
class cItemFlowerPotHandler :
public cItemHandler
{
public:
cItemFlowerPotHandler(int a_ItemType)
: cItemHandler(a_ItemType)
cItemFlowerPotHandler(int a_ItemType) :
cItemHandler(a_ItemType)
{
}
virtual bool IsPlaceable() override
virtual bool IsPlaceable(void) override
{
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
#ifdef _DEBUG
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)
{
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)
bool cItemHandler::EatItem(cPlayer * a_Player, cItem * a_Item)
{
FoodInfo Info = GetFoodInfo();

View File

@ -1,6 +1,8 @@
#pragma once
#include "../Defines.h"
#include "../Item.h"
@ -18,13 +20,17 @@ class cItemHandler
{
public:
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
// 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);
// 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);
// 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);
/// Returns the maximum stack size for a given item
@ -43,33 +49,39 @@ public:
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();
// 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);
// Places the current block and removes the item from the player inventory
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir);
/// Indicates if this item is a tool
virtual bool IsTool(void);
// Indicates if this item is a tool
virtual bool IsTool();
// Indicates if this item is food
virtual bool IsFood();
//Blocks simply get placed
virtual bool IsPlaceable();
/// Indicates if this item is food
virtual bool IsFood(void);
/// Blocks simply get placed
virtual bool IsPlaceable(void);
// Returns the block type on placement
virtual BLOCKTYPE GetBlockType();
//Returns the block meta on placement
virtual NIBBLETYPE GetBlockMeta(short a_ItemDamage);
// Returns whether this tool/item can harvest a specific block (e.g. wooden pickaxe can harvest stone, but wood can´t) DEFAULT: False
/** Called before a block is placed into a world.
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);
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();
protected:
int m_ItemType;

View File

@ -10,15 +10,29 @@
class cItemLeavesHandler :
public cItemHandler
{
typedef cItemHandler super;
public:
cItemLeavesHandler(int 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
#include "ItemHandler.h"
#include "../World.h"
#include "../Player.h"
class cItemLighterHandler : public cItemHandler
class cItemLighterHandler :
public cItemHandler
{
public:
cItemLighterHandler(int a_ItemType)
: cItemHandler(a_ItemType)
cItemLighterHandler(int 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;
}
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
return false;
}
} ;
};

View File

@ -15,19 +15,21 @@ public:
{
}
virtual bool IsPlaceable() override
virtual bool IsPlaceable(void) override
{
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;
}
virtual NIBBLETYPE GetBlockMeta(short a_ItemDamage) override
{
return 0;
a_BlockType = E_BLOCK_REDSTONE_WIRE;
a_BlockMeta = 0;
return true;
}
} ;

View File

@ -2,12 +2,14 @@
#pragma once
#include "ItemHandler.h"
#include "../Simulator/RedstoneSimulator.h"
class cItemRedstoneRepeaterHandler : public cItemHandler
class cItemRedstoneRepeaterHandler :
public cItemHandler
{
public:
cItemRedstoneRepeaterHandler(int a_ItemType)
@ -20,14 +22,16 @@ public:
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;
}
virtual NIBBLETYPE GetBlockMeta(short a_ItemMeta) override
{
return 0;
a_BlockType = E_BLOCK_REDSTONE_REPEATER_OFF;
a_BlockMeta = cRedstoneSimulator::RepeaterRotationToMetaData(a_Player->GetRotation());
return true;
}
} ;

View File

@ -9,6 +9,8 @@
class cItemSaplingHandler : public cItemHandler
{
typedef cItemHandler super;
public:
cItemSaplingHandler(int 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
return (NIBBLETYPE)(a_ItemDamage & 0x07);
a_BlockMeta = a_BlockMeta & 0x7;
return res;
}
} ;

View File

@ -12,54 +12,49 @@ class cItemSeedsHandler :
public cItemHandler
{
public:
cItemSeedsHandler(int a_ItemType)
: cItemHandler(a_ItemType)
cItemSeedsHandler(int a_ItemType) :
cItemHandler(a_ItemType)
{
}
virtual bool IsPlaceable() override
virtual bool IsPlaceable(void) override
{
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)
{
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)
if (a_BlockFace != BLOCK_FACE_TOP)
{
// Only allow planting seeds from the top side of the block
return;
return false;
}
// Only allow placement on farmland
int X = a_BlockX;
int Y = a_BlockY;
int Z = a_BlockZ;
AddDirection(X, Y, Z, a_Dir, true);
AddFaceDirection(X, Y, Z, a_BlockFace, true);
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 "../World.h"
#include "../Sign.h"
class cItemSignHandler : public cItemHandler
class cItemSignHandler :
public cItemHandler
{
public:
cItemSignHandler(int a_ItemType)
: cItemHandler(a_ItemType)
cItemSignHandler(int a_ItemType) :
cItemHandler(a_ItemType)
{
}
virtual bool IsPlaceable() override
virtual bool IsPlaceable(void) override
{
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_SIGN_POST;
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
&& ((Block == E_BLOCK_WOODEN_SLAB) || (Block == E_BLOCK_STONE_SLAB)) // It is a 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
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;
}
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--;
}
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:
a_Player->GetInventory().RemoveItem(a_Player->GetInventory().GetEquippedItem());

View File

@ -2,7 +2,6 @@
#pragma once
#include "ItemHandler.h"
#include "../World.h"
@ -12,25 +11,26 @@ class cItemSugarcaneHandler :
public cItemHandler
{
public:
cItemSugarcaneHandler(int a_ItemType)
: cItemHandler(a_ItemType)
cItemSugarcaneHandler(int a_ItemType) :
cItemHandler(a_ItemType)
{
}
virtual bool IsPlaceable() override
virtual bool IsPlaceable(void) override
{
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;
}
virtual NIBBLETYPE GetBlockMeta(short a_ItemDamage) override
{
return 0; //Not grown yet
a_BlockType = E_BLOCK_SUGARCANE;
a_BlockMeta = 0;
return true;
}
} ;

View File

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

View File

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

View File

@ -2,8 +2,8 @@
#include "ChunkDef.h"
class cLuaChunk //tolua_export
{ //tolua_export
class cLuaChunk // tolua_export
{ // tolua_export
public:
cLuaChunk( cChunkDef::BlockTypes & a_BlockTypes
, cChunkDef::BlockNibbles & a_BlockNibbles
@ -27,7 +27,7 @@ public:
~cLuaChunk()
{}
//tolua_begin
// tolua_begin
// Block functions
void FillBlocks( char a_BlockType, unsigned char a_BlockMeta )
@ -124,7 +124,7 @@ public:
return m_bUseDefaultFinish;
}
//tolua_end
// tolua_end
private:
bool m_bUseDefaultBiomes;
@ -136,4 +136,4 @@ private:
cChunkDef::BlockTypes & m_BlockTypes;
cChunkDef::BlockNibbles & m_BlockMeta;
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);
LOGERROR("-- %s", s.c_str() );
lua_pop(lua, 1);
return true;
// No error to report
return false;
}
return false;
LOGERROR("LUA: %s", lua_tostring(lua, -1));
lua_pop(lua, 1);
return true;
}
cLuaCommandBinder::cLuaCommandBinder()
{
}
cLuaCommandBinder::~cLuaCommandBinder()
{
}
void cLuaCommandBinder::ClearBindings()
{
m_BoundCommands.clear();
}
void cLuaCommandBinder::RemoveBindingsForPlugin( cPlugin* a_Plugin )
{
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 )
{
if( !a_Plugin->CanBindCommands() )
@ -71,6 +91,10 @@ bool cLuaCommandBinder::BindCommand( const std::string & a_Command, const std::s
return true;
}
bool cLuaCommandBinder::HandleCommand( const std::string & a_Command, cPlayer* a_Player )
{
AStringVector Split = StringSplit(a_Command, " ");
@ -124,3 +148,7 @@ bool cLuaCommandBinder::HandleCommand( const std::string & a_Command, cPlayer* a
}
return false;
}

View File

@ -10,19 +10,19 @@ class cLog;
class cMCLogger //tolua_export
{ //tolua_export
public: //tolua_export
class cMCLogger // tolua_export
{ // tolua_export
public: // tolua_export
cMCLogger();
cMCLogger( char* a_File ); //tolua_export
~cMCLogger(); //tolua_export
cMCLogger( char* a_File ); // tolua_export
~cMCLogger(); // tolua_export
void Log(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 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();
private:
@ -31,7 +31,7 @@ private:
cCriticalSection m_CriticalSection;
cLog* m_Log;
static cMCLogger* s_MCLogger;
}; //tolua_export
}; // tolua_export
extern void LOG(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)
{
if ( status!=0 )
{
std::string s = lua_tostring(lua, -1);
LOGERROR("-- %s", s.c_str() );
lua_pop(lua, 1);
return true;
}
return false;
}
// fwd: LuaCommandBinder.cpp
bool report_errors(lua_State* lua, int status);
@ -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_err.array = 0;

View File

@ -7,21 +7,21 @@
class cBlockingTCPLink //tolua_export
{ //tolua_export
public: //tolua_export
cBlockingTCPLink(void); //tolua_export
~cBlockingTCPLink(); //tolua_export
class cBlockingTCPLink // tolua_export
{ // tolua_export
public: // tolua_export
cBlockingTCPLink(void); // tolua_export
~cBlockingTCPLink(); // 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 SendMessage( const char* a_Message, int a_Flags = 0 ); //tolua_export
void CloseSocket(); //tolua_export
void ReceiveData(AString & oData); //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 SendMessage( const char* a_Message, int a_Flags = 0 ); // tolua_export
void CloseSocket(); // tolua_export
void ReceiveData(AString & oData); // tolua_export
protected:
cSocket m_Socket;
}; //tolua_export
}; // tolua_export

View File

@ -2,21 +2,21 @@
#include "Socket.h"
class cTCPLink //tolua_export
{ //tolua_export
public: //tolua_export
cTCPLink(); //tolua_export
~cTCPLink(); //tolua_export
class cTCPLink // tolua_export
{ // tolua_export
public: // tolua_export
cTCPLink(); // tolua_export
~cTCPLink(); // 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 SendMessage(const char * a_Message, int a_Flags = 0 ); //tolua_export
void CloseSocket(); //tolua_export
protected: //tolua_export
virtual void ReceivedData( char a_Data[256], int a_Size ) = 0; //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 SendMessage(const char * a_Message, int a_Flags = 0 ); // tolua_export
void CloseSocket(); // tolua_export
protected: // tolua_export
virtual void ReceivedData( char a_Data[256], int a_Size ) = 0; // tolua_export
static void ReceiveThread( void* a_Param );
cSocket m_Socket;
cEvent* m_StopEvent;
}; //tolua_export
}; // tolua_export

View File

@ -124,7 +124,7 @@ void cPawn::KilledBy(cPawn * a_Killer)
short OldHealth = m_Health;
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
m_Health = OldHealth;

View File

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

View File

@ -24,16 +24,16 @@ class cPickup :
public:
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;
cItem & GetItem(void) {return m_Item; } //tolua_export
cItem & GetItem(void) {return m_Item; } // tolua_export
const cItem & GetItem(void) const {return m_Item; }
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 HandlePhysics(float a_Dt) override;
@ -54,7 +54,7 @@ private:
cItem m_Item;
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)
{
cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_PLAYER_MOVE, 1, this );
cRoot::Get()->GetPluginManager()->CallHookPlayerMoved(*this);
float DiffX = (float)(GetPosX() - m_LastPosX );
float DiffY = (float)(GetPosY() - m_LastPosY );
@ -1054,7 +1054,7 @@ void cPlayer::UseEquippedItem()
{
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());
}
}

View File

@ -35,7 +35,7 @@ public:
cPlayer(cClientHandle * a_Client, const AString & a_PlayerName);
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;
@ -58,83 +58,84 @@ public:
void SetTouchGround( bool a_bTouchGround );
inline void SetStance( const double a_Stance ) { m_Stance = a_Stance; }
double GetEyeHeight(); //tolua_export
Vector3d GetEyePosition(); //tolua_export
double GetEyeHeight(); // tolua_export
Vector3d GetEyePosition(); // 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 cInventory & GetInventory(void) { return m_Inventory; } //tolua_export
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 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;
eGameMode GetGameMode(void) const { return m_GameMode; } //tolua_export
std::string GetIP() { return m_IP; } //tolua_export
float GetLastBlockActionTime() { return m_LastBlockActionTime; } //tolua_export
int GetLastBlockActionCnt() { return m_LastBlockActionCnt; } //tolua_export
void SetLastBlockActionCnt( int ); //tolua_export
void SetLastBlockActionTime(); //tolua_export
void SetGameMode( eGameMode a_GameMode ); //tolua_export
eGameMode GetGameMode(void) const { return m_GameMode; } // tolua_export
std::string GetIP() { return m_IP; } // tolua_export
float GetLastBlockActionTime() { return m_LastBlockActionTime; } // tolua_export
int GetLastBlockActionCnt() { return m_LastBlockActionCnt; } // tolua_export
void SetLastBlockActionCnt( int ); // tolua_export
void SetLastBlockActionTime(); // tolua_export
void SetGameMode( eGameMode a_GameMode ); // tolua_export
void LoginSetGameMode( eGameMode a_GameMode );
void SetIP(const AString & a_IP);
// 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; }
void OpenWindow( cWindow* a_Window );
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
void SetName(const AString & a_Name) { m_PlayerName = a_Name; } //tolua_export
const AString & GetName(void) const { return m_PlayerName; } // tolua_export
void SetName(const AString & a_Name) { m_PlayerName = a_Name; } // tolua_export
typedef std::list< cGroup* > GroupList;
typedef std::list< std::string > StringList;
/// 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)
void RemoveFromGroup( const AString & a_GroupName ); //tolua_export
bool CanUseCommand( const AString & a_Command ); //tolua_export
bool HasPermission( const AString & a_Permission ); //tolua_export
void RemoveFromGroup( const AString & a_GroupName ); // tolua_export
bool CanUseCommand( const AString & a_Command ); // tolua_export
bool HasPermission( const AString & a_Permission ); // tolua_export
const GroupList & GetGroups() { return m_Groups; } // >> 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"
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 GetFoodLevel() { return m_FoodLevel; } //tolua_export
short GetMaxFoodLevel() { return m_MaxFoodLevel; } // tolua_export
short GetFoodLevel() { return m_FoodLevel; } // tolua_export
float GetMaxFoodSaturationLevel() { return m_MaxFoodSaturationLevel; } //tolua_export
float GetFoodSaturationLevel() { return m_FoodSaturationLevel; } //tolua_export
float GetMaxFoodSaturationLevel() { return m_MaxFoodSaturationLevel; } // 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;
void Respawn(void); //tolua_export
void Respawn(void); // tolua_export
void SetVisible( bool a_bVisible ); //tolua_export
bool IsVisible(void) const { return m_bVisible; } //tolua_export
void SetVisible( bool a_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 LoadFromDisk(void);
void LoadPermissionsFromDisk(void); //tolua_export
void LoadPermissionsFromDisk(void); // tolua_export
const AString & GetLoadedWorldName() { return m_LoadedWorldName; }
@ -198,7 +199,7 @@ protected:
/// Filters out damage for creative mode
virtual void DoTakeDamage(TakeDamageInfo & TDI) override;
} ; //tolua_export
} ; // tolua_export

View File

@ -3,6 +3,7 @@
#include "Plugin.h"
#include "Pawn.h"
#include "Player.h"
@ -16,16 +17,14 @@ cPlugin::cPlugin( const AString & a_PluginDirectory )
{
}
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)
{
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;
}
/*
// TODO
bool cPlugin::OnBlockToPickup(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups)
{
UNUSED(a_BlockType);
@ -80,6 +49,8 @@ bool cPlugin::OnBlockToPickup(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, con
UNUSED(a_Pickups);
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_ChunkX);
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_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);
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);
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_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
#include "Item.h"
#include "PluginManager.h"
class cClientHandle;
class cPlayer;
@ -28,51 +33,61 @@ class cCraftingRecipe;
class cPlugin
{
public:
// tolua_end
cPlugin( const AString & a_PluginDirectory );
virtual ~cPlugin();
virtual void OnDisable() {}
virtual bool Initialize() = 0;
virtual void OnDisable(void) {}
virtual bool Initialize(void) = 0;
// Called each tick
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.
**/
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);
virtual bool OnBlockPlace (cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem);
virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups);
virtual bool OnChat (cPlayer * a_Player, const AString & a_Message);
virtual void OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ);
virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk);
virtual bool OnCollectPickup (cPlayer * a_Player, cPickup * a_Pickup);
virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason);
virtual bool OnKilled (cPawn * a_Killed, cEntity* a_Killer );
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username);
virtual bool OnPlayerJoin (cPlayer* a_Player );
virtual void OnPlayerMove (cPlayer* a_Player );
virtual void OnPlayerSpawn (cPlayer* a_Player );
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);
virtual bool OnHandshake (cClientHandle * a_Client, const AString & a_Username);
// TODO: virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups);
virtual bool OnChat (cPlayer * a_Player, const AString & a_Message);
virtual bool OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ);
virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk);
virtual bool OnCollectPickup (cPlayer * a_Player, cPickup * a_Pickup);
virtual bool OnCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason);
virtual bool OnHandshake (cClientHandle * a_Client, const AString & a_Username);
virtual bool OnKilled (cPawn & a_Killed, cEntity * a_Killer);
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 OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
virtual bool OnPlayerEating (cPlayer & a_Player);
virtual bool OnPlayerJoined (cPlayer & a_Player);
virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status);
virtual bool OnPlayerMoved (cPlayer & a_Player);
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 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 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 OnPlayerShooting (cPlayer & a_Player);
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);
/** Called from cPluginManager::AddHook() to check if the hook can be added.
Plugin API providers may check if the plugin is written correctly (has the hook handler function)
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.
*/
virtual bool CanAddHook(cPluginManager::PluginHook a_Hook) { return false; }
// Accessors
const AString & GetName() const { return m_Name; }
virtual void SetName( const AString & a_Name ) { m_Name = a_Name; }
int GetVersion() 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; //tolua_export
struct CommandStruct
{
AString Command;
@ -80,6 +95,16 @@ public:
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);
// tolua_end
@ -109,7 +134,7 @@ private:
int m_Version;
AString m_Directory;
}; //tolua_export
}; // tolua_export

View File

@ -199,7 +199,7 @@ void cPluginManager::Tick(float a_Dt)
ReloadPluginsNow();
}
HookMap::iterator Plugins = m_Hooks.find( E_PLUGIN_TICK );
HookMap::iterator Plugins = m_Hooks.find(HOOK_TICK);
if( Plugins != m_Hooks.end() )
{
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 );
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);
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)->OnLogin(a_Client, a_ProtocolVersion, a_Username))
if ((*itr)->OnBlockToPickup(a_BlockType, a_BlockMeta, a_Player, a_EquippedItem, a_Pickups))
{
return true;
}
}
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)
{
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;
}
*/
/*
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);
@ -377,6 +279,7 @@ bool cPluginManager::CallHookBlockPlace(cPlayer * a_Player, int a_BlockX, int a_
}
return false;
}
*/
@ -396,7 +299,7 @@ bool cPluginManager::CallHookChat(cPlayer * a_Player, const AString & a_Message)
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] == '/')
{
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)
{
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)
{
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)
{
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())
{
return false;
}
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;
}
@ -744,7 +1022,7 @@ bool cPluginManager::DisablePlugin( AString & a_PluginName )
bool cPluginManager::LoadPlugin( AString & a_PluginName )
{
cPlugin_NewLua* Plugin = new cPlugin_NewLua( a_PluginName.c_str() );
if( !AddPlugin( Plugin ) )
if (!AddPlugin(Plugin))
{
delete Plugin;
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 );
m_Hooks[ E_PLUGIN_CHAT].remove ( a_Plugin );
m_Hooks[ E_PLUGIN_COLLECT_ITEM].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 );
for (HookMap::iterator itr = m_Hooks.begin(), end = m_Hooks.end(); itr != end; ++itr)
{
itr->second.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;
}
PluginList & Plugins = m_Hooks[ a_Hook ];
Plugins.remove( a_Plugin );
Plugins.push_back( a_Plugin );
if (!a_Plugin->CanAddHook(a_Hook))
{
return;
}
PluginList & Plugins = m_Hooks[a_Hook];
Plugins.remove(a_Plugin);
Plugins.push_back(a_Plugin);
}
@ -861,4 +1131,8 @@ bool cPluginManager::HasPlugin( cPlugin* a_Plugin ) const
return true;
}
return false;
}
}

View File

@ -36,9 +36,9 @@ class cPawn;
class cPluginManager //tolua_export
{ //tolua_export
public: //tolua_export
class cPluginManager // tolua_export
{ // tolua_export
public: // tolua_export
// Called each tick
virtual void Tick(float a_Dt);
@ -46,87 +46,92 @@ public: //tolua_export
// tolua_begin
enum PluginHook
{
HOOK_TICK,
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_GENERATING,
HOOK_BLOCK_TO_DROPS,
HOOK_PRE_CRAFTING, /// cPlayer, cCraftingGrid, cCraftingRecipe
HOOK_CRAFTING_NO_RECIPE, /// cPlayer, cCraftingGrid, cCraftingRecipe
HOOK_POST_CRAFTING, /// cPlayer, cCraftingGrid, cCraftingRecipe
HOOK_BLOCK_TO_PICKUP, /// BlockType, BlockMeta, cPlayer, cItem, cItems
HOOK_WEATHER_CHANGED, /// cWorld
HOOK_UPDATING_SIGN, /// cWorld, int, int, int, string, string, string, string
HOOK_UPDATED_SIGN, /// cWorld, int, int, int, string, string, string, string
HOOK_COLLECT_PICKUP,
HOOK_CRAFTING_NO_RECIPE,
HOOK_DISCONNECT,
HOOK_HANDSHAKE,
HOOK_KILLED,
HOOK_LOGIN,
HOOK_PLAYER_BREAKING_BLOCK,
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
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,
};
// Note that if a hook type is added, it may need processing in cPlugin::CanAddHook() descendants!
} ;
// tolua_end
static cPluginManager * GetPluginManager(); //tolua_export
static cPluginManager * GetPluginManager(); // tolua_export
typedef std::map< AString, cPlugin * > PluginMap;
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 <<
void FindPlugins(); //tolua_export
void ReloadPlugins(); //tolua_export
void FindPlugins(); // tolua_export
void ReloadPlugins(); // tolua_export
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
bool CallHook( PluginHook a_Hook, unsigned int a_NumArgs, ... );
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 CallHookBlockPlace (cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem);
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);
// TODO: 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 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 DisablePlugin( AString & a_PluginName ); //tolua_export
bool LoadPlugin( AString & a_PluginName ); //tolua_export
bool DisablePlugin( AString & a_PluginName ); // tolua_export
bool LoadPlugin( AString & a_PluginName ); // tolua_export
void RemoveHooks( cPlugin * a_Plugin );
void RemovePlugin( cPlugin * a_Plugin, bool a_bDelete = false );
@ -163,7 +168,7 @@ private:
#endif // USE_SQUIRREL
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();
virtual void OnDisable(); //tolua_export
virtual bool Initialize(); //tolua_export
virtual void OnDisable(void) override;
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;
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 OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups);
virtual bool OnChat (cPlayer * a_Player, const AString & a_Message) override;
virtual void OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override;
virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) override;
virtual bool OnCollectPickup (cPlayer * a_Player, cPickup * a_Pickup) override;
virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason) 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 OnPlayerJoin (cPlayer * a_Player ) override;
virtual void OnPlayerMove (cPlayer * a_Player ) override;
virtual void OnPlayerSpawn (cPlayer * a_Player ) 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 bool OnHandshake (cClientHandle * a_Client, const AString & a_Username) 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 OnChat (cPlayer * a_Player, const AString & a_Message) override;
virtual bool OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override;
virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) override;
virtual bool OnCollectPickup (cPlayer * a_Player, cPickup * a_Pickup) override;
virtual bool OnCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason) override;
virtual bool OnHandshake (cClientHandle * a_Client, const AString & a_Username) 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 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 OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual bool OnPlayerEating (cPlayer & a_Player) override;
virtual bool OnPlayerJoined (cPlayer & a_Player) override;
virtual bool OnPlayerMoved (cPlayer & a_Player) 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 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 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 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 OnPlayerShooting (cPlayer & a_Player) 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
virtual const AString & GetName(void) const {return cPlugin::GetName(); }
virtual const AString & GetWebTitle(void) const {return GetName(); }
// cWebPlugin and WebAdmin stuff
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; }
cCriticalSection & GetCriticalSection() { return m_CriticalSection; }
private:
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
protected:
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
/// Returns the name of Lua function that should handle the specified hook
const char * GetHookFnName(cPluginManager::PluginHook a_Hook);
cCriticalSection m_CriticalSection;
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(ReadByte, Byte, PosY);
HANDLE_PACKET_READ(ReadBEInt, int, PosZ);
HANDLE_PACKET_READ(ReadChar, char, Direction);
m_Client->HandleBlockDig(PosX, PosY, PosZ, Direction, Status);
HANDLE_PACKET_READ(ReadChar, char, BlockFace);
m_Client->HandleLeftClick(PosX, PosY, PosZ, BlockFace, Status);
return PARSE_OK;
}
@ -992,7 +992,7 @@ int cProtocol125::ParseBlockPlace(void)
HANDLE_PACKET_READ(ReadBEInt, int, PosX);
HANDLE_PACKET_READ(ReadByte, Byte, PosY);
HANDLE_PACKET_READ(ReadBEInt, int, PosZ);
HANDLE_PACKET_READ(ReadChar, char, Direction);
HANDLE_PACKET_READ(ReadChar, char, BlockFace);
cItem HeldItem;
int res = ParseItem(HeldItem);
@ -1001,7 +1001,8 @@ int cProtocol125::ParseBlockPlace(void)
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;
}

View File

@ -484,7 +484,7 @@ int cProtocol132::ParseBlockPlace(void)
HANDLE_PACKET_READ(ReadBEInt, int, PosX);
HANDLE_PACKET_READ(ReadByte, Byte, PosY);
HANDLE_PACKET_READ(ReadBEInt, int, PosZ);
HANDLE_PACKET_READ(ReadChar, char, Direction);
HANDLE_PACKET_READ(ReadChar, char, BlockFace);
cItem HeldItem;
int res = ParseItem(HeldItem);
@ -497,7 +497,7 @@ int cProtocol132::ParseBlockPlace(void)
HANDLE_PACKET_READ(ReadChar, char, CursorY);
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;
}

View File

@ -27,22 +27,22 @@ typedef cItemCallback<cWorld> cWorldListCallback;
class cRoot //tolua_export
{ //tolua_export
class cRoot // tolua_export
{ // tolua_export
public:
/// 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
static cRoot* Get() { return s_Root; } //tolua_export
static cRoot* Get() { return s_Root; } // tolua_export
cRoot(void);
~cRoot();
void Start(void);
cServer * GetServer(void) { return m_Server; } //tolua_export
cWorld * GetDefaultWorld(void); //tolua_export
cWorld * GetWorld(const AString & a_WorldName); //tolua_export
cServer * GetServer(void) { return m_Server; } // tolua_export
cWorld * GetDefaultWorld(void); // 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)
bool ForEachWorld(cWorldListCallback & a_Callback); // >> Exported in ManualBindings <<
@ -62,7 +62,7 @@ public:
cPluginManager * GetPluginManager (void) { return m_PluginManager; } // tolua_export
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 AuthenticateUser(int a_ClientID); // Called by cAuthenticator to auth the specified user
@ -119,7 +119,7 @@ private:
static void InputThread(void* a_Params);
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 )
{
LOG("ServerListenThread");
@ -173,7 +163,8 @@ bool cServer::InitServer(cIniFile & a_SettingsIni)
printf("email: faketruth@gmail.com\n\n");
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
{

View File

@ -29,11 +29,9 @@ typedef std::list<cClientHandle *> cClientHandleList;
class cServer //tolua_export
{ //tolua_export
public: //tolua_export
static cServer * GetServer(); //tolua_export
class cServer // tolua_export
{ // tolua_export
public: // tolua_export
bool InitServer(cIniFile & a_SettingsIni);
int GetPort() { return m_iServerPort; }
@ -47,7 +45,7 @@ public: //tolua_export
void StartListenThread();
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 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
void PrepareKeys(void);
}; //tolua_export
}; // tolua_export

View File

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

View File

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

View File

@ -7,15 +7,15 @@
class cTorch //tolua_export
{ //tolua_export
class cTorch // tolua_export
{ // tolua_export
public:
static char DirectionToMetaData( char a_Direction ) //tolua_export
{ //tolua_export
static char DirectionToMetaData( char a_Direction ) // tolua_export
{ // tolua_export
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_EAST: return E_META_TORCH_EAST;
case BLOCK_FACE_WEST: return E_META_TORCH_WEST;
@ -28,11 +28,11 @@ public:
}
};
return 0x0;
} //tolua_export
} // tolua_export
static char MetaDataToDirection(char a_MetaData) //tolua_export
{ //tolua_export
static char MetaDataToDirection(char a_MetaData) // tolua_export
{ // tolua_export
switch (a_MetaData)
{
case 0: return BLOCK_FACE_TOP; // by default, the torches stand on the ground
@ -48,7 +48,7 @@ public:
}
}
return 0;
} //tolua_export
} // tolua_export
static bool IsAttachedTo(const Vector3i & a_TorchPos, char a_TorchMeta, const Vector3i & a_BlockPos)
@ -70,7 +70,7 @@ public:
return false;
}
} ; //tolua_export
} ; // tolua_export

View File

@ -5,18 +5,18 @@
class cWorld;
class cTracer //tolua_export
{ //tolua_export
public: //tolua_export
class cTracer // tolua_export
{ // tolua_export
public: // tolua_export
Vector3f DotPos;
Vector3f BoxOffset;
cTracer( cWorld* a_World); //tolua_export
~cTracer(); //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
Vector3f BlockHitPosition; //tolua_export
Vector3f HitNormal; //tolua_export
Vector3f RealHit; //tolua_export
cTracer( cWorld* a_World); // tolua_export
~cTracer(); // 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
Vector3f BlockHitPosition; // tolua_export
Vector3f HitNormal; // tolua_export
Vector3f RealHit; // tolua_export
private:
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);
@ -31,4 +31,4 @@ private:
Vector3i end1;
Vector3i step;
Vector3f tMax;
}; //tolua_export
}; // tolua_export

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