summaryrefslogtreecommitdiffstats
path: root/src/Blocks/BlockMobHead.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Blocks/BlockMobHead.h')
-rw-r--r--src/Blocks/BlockMobHead.h108
1 files changed, 79 insertions, 29 deletions
diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h
index 9855574ad..301386568 100644
--- a/src/Blocks/BlockMobHead.h
+++ b/src/Blocks/BlockMobHead.h
@@ -19,24 +19,69 @@ public:
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;
- bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
+ 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, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
if (a_BlockY < 2)
{
return false;
}
- class cCallback : public cMobHeadCallback
+ class cCallback : public cBlockEntityCallback
{
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;
}
@@ -70,7 +115,7 @@ public:
} 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())
{
@@ -87,8 +132,8 @@ public:
return false;
}
- a_World->DoWithMobHeadAt(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, CallbackA);
+ 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 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);
// Block entities
- a_World->SetBlock(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_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_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, 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:
- 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
- a_World->ForEachPlayer(PlayerCallback);
+ a_WorldInterface.ForEachPlayer(PlayerCallback);
return true;
}
@@ -117,8 +162,8 @@ public:
CallbackA.Reset();
CallbackB.Reset();
- a_World->DoWithMobHeadAt(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, CallbackA);
+ a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ + 1, CallbackB);
Block1 = 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);
// Block entities
- a_World->SetBlock(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_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_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0);
// 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
- a_World->ForEachPlayer(PlayerCallback);
+ a_WorldInterface.ForEachPlayer(PlayerCallback);
return true;
}
@@ -154,23 +199,29 @@ public:
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
) override
{
- class cCallback : public cMobHeadCallback
+ class cCallback : public cBlockEntityCallback
{
cPlayer * m_Player;
NIBBLETYPE m_OldBlockMeta;
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;
if (m_NewBlockMeta == 1)
{
Rotation = (int) floor(m_Player->GetYaw() * 16.0F / 360.0F + 0.5) & 0xF;
}
-
- a_MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta));
- a_MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation));
- a_MobHeadEntity->GetWorld()->BroadcastBlockEntity(a_MobHeadEntity->GetPosX(), a_MobHeadEntity->GetPosY(), a_MobHeadEntity->GetPosZ(), m_Player->GetClientHandle());
+
+ MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta));
+ MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation));
+ MobHeadEntity->GetWorld()->BroadcastBlockEntity(MobHeadEntity->GetPosX(), MobHeadEntity->GetPosY(), MobHeadEntity->GetPosZ());
return false;
}
@@ -184,8 +235,7 @@ public:
cCallback Callback(a_Player, a_BlockMeta, static_cast<NIBBLETYPE>(a_BlockFace));
a_BlockMeta = (NIBBLETYPE)a_BlockFace;
- cWorld * World = (cWorld *) &a_WorldInterface;
- World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
+ a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta);
if (a_BlockMeta == SKULL_TYPE_WITHER)
@@ -200,7 +250,7 @@ public:
};
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;
}