commit
c30b7b8735
|
@ -70,6 +70,8 @@ void cMobHeadEntity::SetOwner(const AString & a_Owner)
|
||||||
|
|
||||||
void cMobHeadEntity::SendTo(cClientHandle & a_Client)
|
void cMobHeadEntity::SendTo(cClientHandle & a_Client)
|
||||||
{
|
{
|
||||||
|
cWorld * World = a_Client.GetPlayer()->GetWorld();
|
||||||
|
a_Client.SendBlockChange(m_PosX, m_PosY, m_PosZ, m_BlockType, World->GetBlockMeta(m_PosX, m_PosY, m_PosZ));
|
||||||
a_Client.SendUpdateBlockEntity(*this);
|
a_Client.SendUpdateBlockEntity(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,8 @@ public:
|
||||||
- Loop through boundary variables, and fill with portal blocks based on Dir with meta from Dir
|
- Loop through boundary variables, and fill with portal blocks based on Dir with meta from Dir
|
||||||
*/
|
*/
|
||||||
|
|
||||||
a_BlockY--; // Because we want the block below the fire
|
// a_BlockY - 1: Because we want the block below the fire
|
||||||
FindAndSetPortalFrame(a_BlockX, a_BlockY, a_BlockZ, a_ChunkInterface, a_WorldInterface);
|
FindAndSetPortalFrame(a_BlockX, a_BlockY - 1, a_BlockZ, a_ChunkInterface, a_WorldInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnDigging(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
|
virtual void OnDigging(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "BlockGlass.h"
|
#include "BlockGlass.h"
|
||||||
#include "BlockGlowstone.h"
|
#include "BlockGlowstone.h"
|
||||||
#include "BlockGravel.h"
|
#include "BlockGravel.h"
|
||||||
|
#include "BlockHayBale.h"
|
||||||
#include "BlockMobHead.h"
|
#include "BlockMobHead.h"
|
||||||
#include "BlockHopper.h"
|
#include "BlockHopper.h"
|
||||||
#include "BlockIce.h"
|
#include "BlockIce.h"
|
||||||
|
@ -134,7 +135,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
|
||||||
case E_BLOCK_GLASS_PANE: return new cBlockGlassHandler (a_BlockType);
|
case E_BLOCK_GLASS_PANE: return new cBlockGlassHandler (a_BlockType);
|
||||||
case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType);
|
case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType);
|
||||||
case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType);
|
case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType);
|
||||||
case E_BLOCK_HAY_BALE: return new cBlockSidewaysHandler (a_BlockType);
|
case E_BLOCK_HAY_BALE: return new cBlockHayBaleHandler (a_BlockType);
|
||||||
case E_BLOCK_HEAD: return new cBlockMobHeadHandler (a_BlockType);
|
case E_BLOCK_HEAD: return new cBlockMobHeadHandler (a_BlockType);
|
||||||
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType);
|
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType);
|
||||||
case E_BLOCK_HOPPER: return new cBlockHopperHandler (a_BlockType);
|
case E_BLOCK_HOPPER: return new cBlockHopperHandler (a_BlockType);
|
||||||
|
|
29
src/Blocks/BlockHayBale.h
Normal file
29
src/Blocks/BlockHayBale.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "BlockHandler.h"
|
||||||
|
#include "BlockSideways.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class cBlockHayBaleHandler :
|
||||||
|
public cBlockSidewaysHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cBlockHayBaleHandler(BLOCKTYPE a_BlockType)
|
||||||
|
: cBlockSidewaysHandler(a_BlockType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual const char * GetStepSound(void) override
|
||||||
|
{
|
||||||
|
return "step.grass";
|
||||||
|
}
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,24 +19,69 @@ public:
|
||||||
|
|
||||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||||
{
|
{
|
||||||
a_Pickups.push_back(cItem(E_ITEM_HEAD, 1, 0));
|
// The drop spawn is in OnDestroyed method
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
|
||||||
|
{
|
||||||
|
if (a_Player->IsGameModeCreative())
|
||||||
|
{
|
||||||
|
// No drops in creative mode
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
class cCallback : public cBlockEntityCallback
|
||||||
|
{
|
||||||
|
virtual bool Item(cBlockEntity * a_BlockEntity)
|
||||||
|
{
|
||||||
|
if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity);
|
||||||
|
|
||||||
|
cItems Pickups;
|
||||||
|
Pickups.Add(E_ITEM_HEAD, 1, (short) MobHeadEntity->GetType());
|
||||||
|
MTRand r1;
|
||||||
|
|
||||||
|
// Mid-block position first
|
||||||
|
double MicroX, MicroY, MicroZ;
|
||||||
|
MicroX = MobHeadEntity->GetPosX() + 0.5;
|
||||||
|
MicroY = MobHeadEntity->GetPosY() + 0.5;
|
||||||
|
MicroZ = MobHeadEntity->GetPosZ() + 0.5;
|
||||||
|
|
||||||
|
// Add random offset second
|
||||||
|
MicroX += r1.rand(1) - 0.5;
|
||||||
|
MicroZ += r1.rand(1) - 0.5;
|
||||||
|
|
||||||
|
MobHeadEntity->GetWorld()->SpawnItemPickups(Pickups, MicroX, MicroY, MicroZ);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} Callback;
|
||||||
|
|
||||||
|
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
|
bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
{
|
{
|
||||||
if (a_BlockY < 2)
|
if (a_BlockY < 2)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
class cCallback : public cMobHeadCallback
|
class cCallback : public cBlockEntityCallback
|
||||||
{
|
{
|
||||||
bool m_IsWither;
|
bool m_IsWither;
|
||||||
|
|
||||||
virtual bool Item (cMobHeadEntity * a_MobHeadEntity)
|
virtual bool Item(cBlockEntity * a_BlockEntity)
|
||||||
{
|
{
|
||||||
m_IsWither = (a_MobHeadEntity->GetType() == SKULL_TYPE_WITHER);
|
if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity);
|
||||||
|
|
||||||
|
m_IsWither = (MobHeadEntity->GetType() == SKULL_TYPE_WITHER);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +115,7 @@ public:
|
||||||
|
|
||||||
} PlayerCallback(Vector3f((float)a_BlockX, (float)a_BlockY, (float)a_BlockZ));
|
} PlayerCallback(Vector3f((float)a_BlockX, (float)a_BlockY, (float)a_BlockZ));
|
||||||
|
|
||||||
a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA);
|
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA);
|
||||||
|
|
||||||
if (!CallbackA.IsWither())
|
if (!CallbackA.IsWither())
|
||||||
{
|
{
|
||||||
|
@ -87,8 +132,8 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
a_World->DoWithMobHeadAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA);
|
a_WorldInterface.DoWithBlockEntityAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA);
|
||||||
a_World->DoWithMobHeadAt(a_BlockX + 1, a_BlockY, a_BlockZ, CallbackB);
|
a_WorldInterface.DoWithBlockEntityAt(a_BlockX + 1, a_BlockY, a_BlockZ, CallbackB);
|
||||||
|
|
||||||
BLOCKTYPE Block1 = a_ChunkInterface.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ);
|
BLOCKTYPE Block1 = a_ChunkInterface.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ);
|
||||||
BLOCKTYPE Block2 = a_ChunkInterface.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ);
|
BLOCKTYPE Block2 = a_ChunkInterface.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ);
|
||||||
|
@ -101,15 +146,15 @@ public:
|
||||||
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
|
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
|
||||||
|
|
||||||
// Block entities
|
// Block entities
|
||||||
a_World->SetBlock(a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||||
a_World->SetBlock(a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||||
|
|
||||||
// Spawn the wither:
|
// Spawn the wither:
|
||||||
a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
|
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
|
||||||
|
|
||||||
// Award Achievement
|
// Award Achievement
|
||||||
a_World->ForEachPlayer(PlayerCallback);
|
a_WorldInterface.ForEachPlayer(PlayerCallback);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -117,8 +162,8 @@ public:
|
||||||
CallbackA.Reset();
|
CallbackA.Reset();
|
||||||
CallbackB.Reset();
|
CallbackB.Reset();
|
||||||
|
|
||||||
a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ - 1, CallbackA);
|
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ - 1, CallbackA);
|
||||||
a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ + 1, CallbackB);
|
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ + 1, CallbackB);
|
||||||
|
|
||||||
Block1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1);
|
Block1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1);
|
||||||
Block2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1);
|
Block2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1);
|
||||||
|
@ -131,15 +176,15 @@ public:
|
||||||
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
|
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
|
||||||
|
|
||||||
// Block entities
|
// Block entities
|
||||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0);
|
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0);
|
||||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0);
|
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0);
|
||||||
|
|
||||||
// Spawn the wither:
|
// Spawn the wither:
|
||||||
a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
|
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
|
||||||
|
|
||||||
// Award Achievement
|
// Award Achievement
|
||||||
a_World->ForEachPlayer(PlayerCallback);
|
a_WorldInterface.ForEachPlayer(PlayerCallback);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -154,23 +199,29 @@ public:
|
||||||
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
|
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
|
||||||
) override
|
) override
|
||||||
{
|
{
|
||||||
class cCallback : public cMobHeadCallback
|
class cCallback : public cBlockEntityCallback
|
||||||
{
|
{
|
||||||
cPlayer * m_Player;
|
cPlayer * m_Player;
|
||||||
NIBBLETYPE m_OldBlockMeta;
|
NIBBLETYPE m_OldBlockMeta;
|
||||||
NIBBLETYPE m_NewBlockMeta;
|
NIBBLETYPE m_NewBlockMeta;
|
||||||
|
|
||||||
virtual bool Item (cMobHeadEntity * a_MobHeadEntity)
|
virtual bool Item(cBlockEntity * a_BlockEntity)
|
||||||
{
|
{
|
||||||
|
if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity);
|
||||||
|
|
||||||
int Rotation = 0;
|
int Rotation = 0;
|
||||||
if (m_NewBlockMeta == 1)
|
if (m_NewBlockMeta == 1)
|
||||||
{
|
{
|
||||||
Rotation = (int) floor(m_Player->GetYaw() * 16.0F / 360.0F + 0.5) & 0xF;
|
Rotation = (int) floor(m_Player->GetYaw() * 16.0F / 360.0F + 0.5) & 0xF;
|
||||||
}
|
}
|
||||||
|
|
||||||
a_MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta));
|
MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta));
|
||||||
a_MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation));
|
MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation));
|
||||||
a_MobHeadEntity->GetWorld()->BroadcastBlockEntity(a_MobHeadEntity->GetPosX(), a_MobHeadEntity->GetPosY(), a_MobHeadEntity->GetPosZ(), m_Player->GetClientHandle());
|
MobHeadEntity->GetWorld()->BroadcastBlockEntity(MobHeadEntity->GetPosX(), MobHeadEntity->GetPosY(), MobHeadEntity->GetPosZ());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,8 +235,7 @@ public:
|
||||||
cCallback Callback(a_Player, a_BlockMeta, static_cast<NIBBLETYPE>(a_BlockFace));
|
cCallback Callback(a_Player, a_BlockMeta, static_cast<NIBBLETYPE>(a_BlockFace));
|
||||||
|
|
||||||
a_BlockMeta = (NIBBLETYPE)a_BlockFace;
|
a_BlockMeta = (NIBBLETYPE)a_BlockFace;
|
||||||
cWorld * World = (cWorld *) &a_WorldInterface;
|
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
|
||||||
World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
|
|
||||||
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta);
|
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta);
|
||||||
|
|
||||||
if (a_BlockMeta == SKULL_TYPE_WITHER)
|
if (a_BlockMeta == SKULL_TYPE_WITHER)
|
||||||
|
@ -200,7 +250,7 @@ public:
|
||||||
};
|
};
|
||||||
for (size_t i = 0; i < ARRAYCOUNT(Coords); ++i)
|
for (size_t i = 0; i < ARRAYCOUNT(Coords); ++i)
|
||||||
{
|
{
|
||||||
if (TrySpawnWither(a_ChunkInterface, World, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z))
|
if (TrySpawnWither(a_ChunkInterface, a_WorldInterface, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,12 @@
|
||||||
|
|
||||||
class cItems;
|
class cItems;
|
||||||
|
|
||||||
|
typedef cItemCallback<cBlockEntity> cBlockEntityCallback;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cWorldInterface
|
class cWorldInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -29,6 +35,9 @@ public:
|
||||||
/** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */
|
/** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */
|
||||||
virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0;
|
virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0;
|
||||||
|
|
||||||
|
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
|
||||||
|
virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) = 0;
|
||||||
|
|
||||||
/** Sends the block on those coords to the player */
|
/** Sends the block on those coords to the player */
|
||||||
virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer * a_Player) = 0;
|
virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer * a_Player) = 0;
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,8 @@ class cBlockArea;
|
||||||
class cMobCensus;
|
class cMobCensus;
|
||||||
class cMobSpawner;
|
class cMobSpawner;
|
||||||
|
|
||||||
typedef std::list<cClientHandle *> cClientHandleList;
|
typedef std::list<cClientHandle *> cClientHandleList;
|
||||||
typedef cChunk * cChunkPtr;
|
typedef cChunk * cChunkPtr;
|
||||||
typedef cItemCallback<cEntity> cEntityCallback;
|
typedef cItemCallback<cEntity> cEntityCallback;
|
||||||
typedef cItemCallback<cBlockEntity> cBlockEntityCallback;
|
typedef cItemCallback<cBlockEntity> cBlockEntityCallback;
|
||||||
typedef cItemCallback<cChestEntity> cChestCallback;
|
typedef cItemCallback<cChestEntity> cChestCallback;
|
||||||
|
|
|
@ -953,6 +953,26 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
|
||||||
m_LastDigBlockY = a_BlockY;
|
m_LastDigBlockY = a_BlockY;
|
||||||
m_LastDigBlockZ = a_BlockZ;
|
m_LastDigBlockZ = a_BlockZ;
|
||||||
|
|
||||||
|
// Check for clickthrough-blocks:
|
||||||
|
/* When the user breaks a fire block, the client send the wrong block location.
|
||||||
|
We must find the right block with the face direction. */
|
||||||
|
if (a_BlockFace != BLOCK_FACE_NONE)
|
||||||
|
{
|
||||||
|
int pX = a_BlockX;
|
||||||
|
int pY = a_BlockY;
|
||||||
|
int pZ = a_BlockZ;
|
||||||
|
|
||||||
|
AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false)
|
||||||
|
cBlockHandler * Handler = cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(pX, pY, pZ));
|
||||||
|
|
||||||
|
if (Handler->IsClickedThrough())
|
||||||
|
{
|
||||||
|
cChunkInterface ChunkInterface(m_Player->GetWorld()->GetChunkMap());
|
||||||
|
Handler->OnDigging(ChunkInterface, *m_Player->GetWorld(), m_Player, pX, pY, pZ);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(m_Player->IsGameModeCreative()) || // In creative mode, digging is done immediately
|
(m_Player->IsGameModeCreative()) || // In creative mode, digging is done immediately
|
||||||
cBlockInfo::IsOneHitDig(a_OldBlock) // One-hit blocks get destroyed immediately, too
|
cBlockInfo::IsOneHitDig(a_OldBlock) // One-hit blocks get destroyed immediately, too
|
||||||
|
@ -979,22 +999,6 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
|
||||||
|
|
||||||
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
|
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
|
||||||
ItemHandler->OnDiggingBlock(World, m_Player, m_Player->GetEquippedItem(), a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
|
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); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false)
|
|
||||||
Handler = cBlockInfo::GetHandler(World->GetBlock(pX, pY, pZ));
|
|
||||||
|
|
||||||
if (Handler->IsClickedThrough())
|
|
||||||
{
|
|
||||||
Handler->OnDigging(ChunkInterface, *World, m_Player, pX, pY, pZ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,10 +36,6 @@ void cThrownSnowballEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d &
|
||||||
{
|
{
|
||||||
TotalDamage = 3;
|
TotalDamage = 3;
|
||||||
}
|
}
|
||||||
else if (MobType == cMonster::mtEnderDragon)
|
|
||||||
{
|
|
||||||
TotalDamage = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// TODO: If entity is Ender Crystal, destroy it
|
// TODO: If entity is Ender Crystal, destroy it
|
||||||
a_EntityHit.TakeDamage(dtRangedAttack, this, TotalDamage, 1);
|
a_EntityHit.TakeDamage(dtRangedAttack, this, TotalDamage, 1);
|
||||||
|
|
|
@ -31,6 +31,17 @@ public:
|
||||||
Vector3d Pos = a_Player->GetThrowStartPos();
|
Vector3d Pos = a_Player->GetThrowStartPos();
|
||||||
Vector3d Speed = a_Player->GetLookVector() * m_SpeedCoeff;
|
Vector3d Speed = a_Player->GetLookVector() * m_SpeedCoeff;
|
||||||
|
|
||||||
|
// Play sound
|
||||||
|
cFastRandom Random;
|
||||||
|
a_World->BroadcastSoundEffect(
|
||||||
|
"random.bow",
|
||||||
|
(int)std::floor(a_Player->GetPosX() * 8.0),
|
||||||
|
(int)std::floor((a_Player->GetPosY() - a_Player->GetHeight()) * 8.0),
|
||||||
|
(int)std::floor(a_Player->GetPosZ() * 8.0),
|
||||||
|
0.5F,
|
||||||
|
0.4F / (Random.NextFloat(1.0F) * 0.4F + 0.8F)
|
||||||
|
);
|
||||||
|
|
||||||
if (a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, a_Player->GetEquippedItem(), &Speed) < 0)
|
if (a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, a_Player->GetEquippedItem(), &Speed) < 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -532,7 +532,7 @@ public:
|
||||||
virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData) override; // tolua_export
|
virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData) override; // tolua_export
|
||||||
|
|
||||||
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
|
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
|
||||||
bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) override; // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found */
|
/** Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found */
|
||||||
bool DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
|
@ -608,17 +608,12 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile)
|
||||||
case cProjectileEntity::pkGhastFireball:
|
case cProjectileEntity::pkGhastFireball:
|
||||||
{
|
{
|
||||||
m_Writer.AddInt("ExplosionPower", 1);
|
m_Writer.AddInt("ExplosionPower", 1);
|
||||||
// fall-through:
|
break;
|
||||||
}
|
}
|
||||||
case cProjectileEntity::pkFireCharge:
|
case cProjectileEntity::pkFireCharge:
|
||||||
case cProjectileEntity::pkWitherSkull:
|
case cProjectileEntity::pkWitherSkull:
|
||||||
case cProjectileEntity::pkEnderPearl:
|
case cProjectileEntity::pkEnderPearl:
|
||||||
{
|
{
|
||||||
m_Writer.BeginList("Motion", TAG_Double);
|
|
||||||
m_Writer.AddDouble("", a_Projectile->GetSpeedX());
|
|
||||||
m_Writer.AddDouble("", a_Projectile->GetSpeedY());
|
|
||||||
m_Writer.AddDouble("", a_Projectile->GetSpeedZ());
|
|
||||||
m_Writer.EndList();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user