summaryrefslogtreecommitdiffstats
path: root/src/BlockEntities
diff options
context:
space:
mode:
authorQUSpilPrgm <QUSpilPrgm@users.noreply.github.com>2016-05-29 10:30:47 +0200
committerQUSpilPrgm <QUSpilPrgm@users.noreply.github.com>2016-06-03 15:45:49 +0200
commit706257f8fbd897dc6087fa93269dd964d633d0f8 (patch)
tree6dd9d70ac993c04993580345b246f5d0c52f1ccc /src/BlockEntities
parentDebuggers: Added the forgotten Inject.lua file. (diff)
downloadcuberite-706257f8fbd897dc6087fa93269dd964d633d0f8.tar
cuberite-706257f8fbd897dc6087fa93269dd964d633d0f8.tar.gz
cuberite-706257f8fbd897dc6087fa93269dd964d633d0f8.tar.bz2
cuberite-706257f8fbd897dc6087fa93269dd964d633d0f8.tar.lz
cuberite-706257f8fbd897dc6087fa93269dd964d633d0f8.tar.xz
cuberite-706257f8fbd897dc6087fa93269dd964d633d0f8.tar.zst
cuberite-706257f8fbd897dc6087fa93269dd964d633d0f8.zip
Diffstat (limited to 'src/BlockEntities')
-rw-r--r--src/BlockEntities/DispenserEntity.cpp89
-rw-r--r--src/BlockEntities/DispenserEntity.h2
2 files changed, 81 insertions, 10 deletions
diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp
index 297d5273e..e03644a0f 100644
--- a/src/BlockEntities/DispenserEntity.cpp
+++ b/src/BlockEntities/DispenserEntity.cpp
@@ -3,8 +3,10 @@
#include "DispenserEntity.h"
#include "../Simulator/FluidSimulator.h"
+#include "../Entities/Boat.h"
#include "../Chunk.h"
+#include "../Defines.h"
#include "../World.h"
#include "../Entities/ProjectileEntity.h"
@@ -39,7 +41,16 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
int BlockZ = (DispZ + DispChunk->GetPosZ() * cChunkDef::Width);
// Dispense the item:
- switch (m_Contents.GetSlot(a_SlotNum).m_ItemType)
+ const cItem & SlotItem = m_Contents.GetSlot(a_SlotNum);
+ if (ItemCategory::IsMinecart(SlotItem.m_ItemType) && IsBlockRail(DispBlock)) // only actually place the minecart if there are rails!
+ {
+ if (m_World->SpawnMinecart(BlockX + 0.5, DispY + 0.5, BlockZ + 0.5, SlotItem.m_ItemType) != cEntity::INVALID_ID)
+ {
+ m_Contents.ChangeSlotCount(a_SlotNum, -1);
+ }
+ return;
+ }
+ switch (SlotItem.m_ItemType)
{
case E_ITEM_BUCKET:
{
@@ -115,7 +126,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_BLOCK_TNT:
{
// Spawn a primed TNT entity, if space allows:
- if (DispChunk->GetBlock(DispX, DispY, DispZ) == E_BLOCK_AIR)
+ if (!cBlockInfo::IsSolid(DispBlock))
{
double TNTX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width);
double TNTZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width);
@@ -128,7 +139,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_FLINT_AND_STEEL:
{
// Spawn fire if the block in front is air.
- if (DispChunk->GetBlock(DispX, DispY, DispZ) == E_BLOCK_AIR)
+ if (DispBlock == E_BLOCK_AIR)
{
DispChunk->SetBlock(DispX, DispY, DispZ, E_BLOCK_FIRE, 0);
@@ -153,7 +164,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_ARROW:
{
- if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkArrow, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID)
+ if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkArrow, GetShootVector(Meta) * 30 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID)
{
m_Contents.ChangeSlotCount(a_SlotNum, -1);
}
@@ -178,6 +189,68 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
break;
}
+ case E_ITEM_BOTTLE_O_ENCHANTING:
+ {
+ if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkExpBottle, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID)
+ {
+ m_Contents.ChangeSlotCount(a_SlotNum, -1);
+ }
+ break;
+ }
+
+ case E_ITEM_POTION:
+ {
+ if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkSplashPotion, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0), &SlotItem) != cEntity::INVALID_ID)
+ {
+ m_Contents.ChangeSlotCount(a_SlotNum, -1);
+ }
+ break;
+ }
+
+ case E_ITEM_DYE:
+ {
+ if (SlotItem.m_ItemDamage != E_META_DYE_WHITE)
+ {
+ DropFromSlot(a_Chunk, a_SlotNum);
+ break;
+ }
+ if (m_World->GrowRipePlant(BlockX, DispY, BlockZ, true))
+ {
+ m_Contents.ChangeSlotCount(a_SlotNum, -1);
+ }
+ break;
+ }
+
+ case E_ITEM_BOAT:
+ {
+ Vector3d SpawnPos;
+ if (IsBlockWater(DispBlock))
+ {
+ // Water next to the dispenser, spawn a boat above the water block
+ SpawnPos.Set(BlockX, DispY + 1, BlockZ);
+ }
+ else if (IsBlockWater(DispChunk->GetBlock(DispX, DispY - 1, DispZ)))
+ {
+ // Water one block below the dispenser, spawn a boat at the dispenser's Y level
+ SpawnPos.Set(BlockX, DispY, BlockZ);
+ }
+ else
+ {
+ // There's no eligible water block, drop the boat as a pickup
+ DropFromSlot(a_Chunk, a_SlotNum);
+ break;
+ }
+
+ SpawnPos += GetShootVector(Meta) * 0.8; // A boat is bigger than one block. Add the shoot vector to put it outside the dispenser.
+ SpawnPos += Vector3d(0.5, 0.5, 0.5);
+
+ if (m_World->SpawnBoat(SpawnPos.x, SpawnPos.y, SpawnPos.z))
+ {
+ m_Contents.ChangeSlotCount(a_SlotNum, -1);
+ }
+ break;
+ }
+
case E_ITEM_FIREWORK_ROCKET:
{
// TODO: Add the fireworks entity
@@ -189,27 +262,25 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
DropFromSlot(a_Chunk, a_SlotNum);
break;
}
- } // switch (ItemType)
+ } // switch (SlotItem.m_ItemType)
}
-UInt32 cDispenserEntity::SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY, int a_BlockZ, cProjectileEntity::eKind a_Kind, const Vector3d & a_ShootVector)
+UInt32 cDispenserEntity::SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY, int a_BlockZ, cProjectileEntity::eKind a_Kind, const Vector3d & a_ShootVector, const cItem * a_Item)
{
return m_World->CreateProjectile(
static_cast<double>(a_BlockX + 0.5),
static_cast<double>(a_BlockY + 0.5),
static_cast<double>(a_BlockZ + 0.5),
- a_Kind, nullptr, nullptr, &a_ShootVector
+ a_Kind, nullptr, a_Item, &a_ShootVector
);
}
-
-
Vector3d cDispenserEntity::GetShootVector(NIBBLETYPE a_Meta)
{
switch (a_Meta & 0x7)
diff --git a/src/BlockEntities/DispenserEntity.h b/src/BlockEntities/DispenserEntity.h
index c9b553017..03ce3ad69 100644
--- a/src/BlockEntities/DispenserEntity.h
+++ b/src/BlockEntities/DispenserEntity.h
@@ -26,7 +26,7 @@ public:
/** Spawns a projectile of the given kind in front of the dispenser with the specified speed.
Returns the UniqueID of the spawned projectile, or 0 on failure. */
- UInt32 SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY, int a_BlockZ, cProjectileEntity::eKind a_Kind, const Vector3d & a_Speed);
+ UInt32 SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY, int a_BlockZ, cProjectileEntity::eKind a_Kind, const Vector3d & a_Speed, const cItem * a_Item = nullptr);
/** Returns a unit vector in the cardinal direction of where the dispenser is facing. */
Vector3d GetShootVector(NIBBLETYPE a_Meta);