diff options
author | madmaxoft <github@xoft.cz> | 2014-06-11 19:38:14 +0200 |
---|---|---|
committer | madmaxoft <github@xoft.cz> | 2014-06-11 19:38:14 +0200 |
commit | d6b2660f3643cf1c2a24732cb62caed340a2afd9 (patch) | |
tree | 6e16fcaf2f0fdf80a3b5edfd8fea3ff68a97971f | |
parent | Changed the teleport permissions to the new ones. (diff) | |
parent | - Fixed a lot of alignment (diff) | |
download | cuberite-d6b2660f3643cf1c2a24732cb62caed340a2afd9.tar cuberite-d6b2660f3643cf1c2a24732cb62caed340a2afd9.tar.gz cuberite-d6b2660f3643cf1c2a24732cb62caed340a2afd9.tar.bz2 cuberite-d6b2660f3643cf1c2a24732cb62caed340a2afd9.tar.lz cuberite-d6b2660f3643cf1c2a24732cb62caed340a2afd9.tar.xz cuberite-d6b2660f3643cf1c2a24732cb62caed340a2afd9.tar.zst cuberite-d6b2660f3643cf1c2a24732cb62caed340a2afd9.zip |
-rw-r--r-- | src/BlockEntities/DispenserEntity.cpp | 95 | ||||
-rw-r--r-- | src/BlockEntities/DispenserEntity.h | 15 |
2 files changed, 91 insertions, 19 deletions
diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index 2a32f69d9..97e25ca6d 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -6,6 +6,10 @@ #include "../Simulator/FluidSimulator.h" #include "../Chunk.h" +#include "../World.h" +#include "../Entities/ArrowEntity.h" +#include "../Entities/FireChargeEntity.h" +#include "../Entities/ProjectileEntity.h" @@ -33,7 +37,10 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) // Would dispense into / interact with a non-loaded chunk, ignore the tick return; } + BLOCKTYPE DispBlock = DispChunk->GetBlock(DispX, DispY, DispZ); + int BlockX = (DispX + DispChunk->GetPosX() * cChunkDef::Width); + int BlockZ = (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); // Dispense the item: switch (m_Contents.GetSlot(a_SlotNum).m_ItemType) @@ -69,7 +76,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) } break; } // E_ITEM_BUCKET - + case E_ITEM_WATER_BUCKET: { LOGD("Dispensing water bucket in slot %d; DispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(DispBlock).c_str(), DispBlock); @@ -83,7 +90,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) } break; } - + case E_ITEM_LAVA_BUCKET: { LOGD("Dispensing lava bucket in slot %d; DispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(DispBlock).c_str(), DispBlock); @@ -97,7 +104,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) } break; } - + case E_ITEM_SPAWN_EGG: { double MobX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); @@ -108,7 +115,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) } break; } - + case E_BLOCK_TNT: { // Spawn a primed TNT entity, if space allows: @@ -128,7 +135,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) if (DispChunk->GetBlock(DispX, DispY, DispZ) == E_BLOCK_AIR) { DispChunk->SetBlock(DispX, DispY, DispZ, E_BLOCK_FIRE, 0); - + bool ItemBroke = m_Contents.DamageItem(a_SlotNum, 1); if (ItemBroke) @@ -138,13 +145,45 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) } break; } - + case E_ITEM_FIRE_CHARGE: { - // TODO: Spawn fireball entity + SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkFireCharge, GetShootVector(Meta) * 20); + m_Contents.ChangeSlotCount(a_SlotNum, -1); + + break; + } + + case E_ITEM_ARROW: + { + SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkArrow, GetShootVector(Meta) * 20); + m_Contents.ChangeSlotCount(a_SlotNum, -1); + + break; + } + + case E_ITEM_SNOWBALL: + { + SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkSnowball, GetShootVector(Meta) * 20); + m_Contents.ChangeSlotCount(a_SlotNum, -1); + + break; + } + + case E_ITEM_EGG: + { + SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkEgg, GetShootVector(Meta) * 20); + m_Contents.ChangeSlotCount(a_SlotNum, -1); + + break; + } + + case E_ITEM_FIREWORK_ROCKET: + { + // TODO: Add the fireworks entity break; } - + default: { DropFromSlot(a_Chunk, a_SlotNum); @@ -155,6 +194,35 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) +void cDispenserEntity::SpawnProjectileFromDispenser(int & a_BlockX, int & a_BlockY, int & a_BlockZ, cProjectileEntity::eKind a_Kind, Vector3d a_ShootVector) +{ + if (a_Kind != cProjectileEntity::pkFireCharge) + { + a_ShootVector.y = a_ShootVector.y + 1; + } + + m_World->CreateProjectile((double) a_BlockX + 0.5, (double) a_BlockY + 0.5, (double) a_BlockZ + 0.5, a_Kind, NULL, NULL, &a_ShootVector); +} + + +Vector3d cDispenserEntity::GetShootVector(NIBBLETYPE & a_Meta) +{ + switch(a_Meta) + { + case E_META_DROPSPENSER_FACING_YP: return Vector3d( 0, 1, 0); // UP + case E_META_DROPSPENSER_FACING_YM: return Vector3d( 0, -1, 0); // DOWN + + case E_META_DROPSPENSER_FACING_XM: return Vector3d(-1, 0, 0); // WEST + case E_META_DROPSPENSER_FACING_XP: return Vector3d( 1, 0, 0); // EAST + + case E_META_DROPSPENSER_FACING_ZM: return Vector3d( 0, 0, -1); + case E_META_DROPSPENSER_FACING_ZP: return Vector3d( 0, 0, 1); + } + + return Vector3d(0, 1, 0); +} + + @@ -167,14 +235,14 @@ bool cDispenserEntity::ScoopUpLiquid(int a_SlotNum, short a_BucketItemType) m_Contents.SetSlot(a_SlotNum, LiquidBucket); return true; } - + // There are stacked buckets at the selected slot, see if a full bucket will fit somewhere else if (m_Contents.HowManyCanFit(LiquidBucket) < 1) { // Cannot fit into m_Contents return false; } - + m_Contents.ChangeSlotCount(a_SlotNum, -1); m_Contents.AddItem(LiquidBucket); return true; @@ -195,7 +263,7 @@ bool cDispenserEntity::EmptyLiquidBucket(BLOCKTYPE a_BlockInFront, int a_SlotNum // Not a suitable block in front return false; } - + cItem EmptyBucket(E_ITEM_BUCKET, 1); if (m_Contents.GetSlot(a_SlotNum).m_ItemCount == 1) { @@ -203,14 +271,14 @@ bool cDispenserEntity::EmptyLiquidBucket(BLOCKTYPE a_BlockInFront, int a_SlotNum m_Contents.SetSlot(a_SlotNum, EmptyBucket); return true; } - + // There are full buckets stacked at this slot, check if we can fit in the empty bucket if (m_Contents.HowManyCanFit(EmptyBucket) < 1) { // The empty bucket wouldn't fit into m_Contents return false; } - + // The empty bucket fits in, remove one full bucket and add the empty one m_Contents.ChangeSlotCount(a_SlotNum, -1); m_Contents.AddItem(EmptyBucket); @@ -219,4 +287,3 @@ bool cDispenserEntity::EmptyLiquidBucket(BLOCKTYPE a_BlockInFront, int a_SlotNum - diff --git a/src/BlockEntities/DispenserEntity.h b/src/BlockEntities/DispenserEntity.h index fdfe4e5b4..9410a1129 100644 --- a/src/BlockEntities/DispenserEntity.h +++ b/src/BlockEntities/DispenserEntity.h @@ -12,27 +12,32 @@ class cDispenserEntity : public cDropSpenserEntity { typedef cDropSpenserEntity super; - + public: // tolua_end - + /// Constructor used for normal operation cDispenserEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); static const char * GetClassStatic(void) { return "cDispenserEntity"; } + /** Spawns a projectile of the given kind in front of the dispenser */ + void SpawnProjectileFromDispenser(int & a_BlockX, int & a_BlockY, int & a_BlockZ, cProjectileEntity::eKind a_Kind, Vector3d a_ShootVector); + + /** Returns how to aim the projectile */ + Vector3d GetShootVector(NIBBLETYPE & a_Meta); + private: // cDropSpenser overrides: virtual void DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) override; - + /// If such a bucket can fit, adds it to m_Contents and returns true bool ScoopUpLiquid(int a_SlotNum, short a_BucketItemType); - + /// If the a_BlockInFront is liquidable and the empty bucket can fit, does the m_Contents processing and returns true bool EmptyLiquidBucket(BLOCKTYPE a_BlockInFront, int a_SlotNum); } ; // tolua_export - |