diff options
Diffstat (limited to 'src/BlockEntities/DispenserEntity.cpp')
-rw-r--r-- | src/BlockEntities/DispenserEntity.cpp | 100 |
1 files changed, 46 insertions, 54 deletions
diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index 249952c7a..9d8267c38 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -13,8 +13,8 @@ -cDispenserEntity::cDispenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): - Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World) +cDispenserEntity::cDispenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World): + super(a_BlockType, a_BlockMeta, a_Pos, a_World) { ASSERT(a_BlockType == E_BLOCK_DISPENSER); } @@ -25,27 +25,24 @@ cDispenserEntity::cDispenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) { - int DispX = m_RelX; - int DispY = m_PosY; - int DispZ = m_RelZ; - NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ); - AddDropSpenserDir(DispX, DispY, DispZ, Meta); - cChunk * DispChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(DispX, DispZ); - if (DispChunk == nullptr) + Vector3i dispRelCoord(GetRelPos()); + auto meta = a_Chunk.GetMeta(dispRelCoord); + AddDropSpenserDir(dispRelCoord, meta); + auto dispChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(dispRelCoord.x, dispRelCoord.z); + if (dispChunk == nullptr) { // 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); + BLOCKTYPE dispBlock = dispChunk->GetBlock(dispRelCoord); + auto dispAbsCoord = dispChunk->RelativeToAbsolute(dispRelCoord); // Dispense the item: 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 (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) + if (m_World->SpawnMinecart(dispAbsCoord.x + 0.5, dispAbsCoord.y + 0.5, dispAbsCoord.z + 0.5, SlotItem.m_ItemType) != cEntity::INVALID_ID) { m_Contents.ChangeSlotCount(a_SlotNum, -1); } @@ -55,15 +52,15 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) { case E_ITEM_BUCKET: { - LOGD("Dispensing empty bucket in slot %d; DispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(DispBlock).c_str(), DispBlock); - switch (DispBlock) + LOGD("Dispensing empty bucket in slot %d; dispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(dispBlock).c_str(), dispBlock); + switch (dispBlock) { case E_BLOCK_STATIONARY_WATER: case E_BLOCK_WATER: { if (ScoopUpLiquid(a_SlotNum, E_ITEM_WATER_BUCKET)) { - DispChunk->SetBlock(DispX, DispY, DispZ, E_BLOCK_AIR, 0); + dispChunk->SetBlock(dispRelCoord, E_BLOCK_AIR, 0); } break; } @@ -72,7 +69,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) { if (ScoopUpLiquid(a_SlotNum, E_ITEM_LAVA_BUCKET)) { - DispChunk->SetBlock(DispX, DispY, DispZ, E_BLOCK_AIR, 0); + dispChunk->SetBlock(dispRelCoord, E_BLOCK_AIR, 0); } break; } @@ -87,10 +84,10 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_WATER_BUCKET: { - LOGD("Dispensing water bucket in slot %d; DispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(DispBlock).c_str(), DispBlock); - if (EmptyLiquidBucket(DispBlock, a_SlotNum)) + LOGD("Dispensing water bucket in slot %d; dispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(dispBlock).c_str(), dispBlock); + if (EmptyLiquidBucket(dispBlock, a_SlotNum)) { - DispChunk->SetBlock(DispX, DispY, DispZ, E_BLOCK_WATER, 0); + dispChunk->SetBlock(dispRelCoord, E_BLOCK_WATER, 0); } else { @@ -101,10 +98,10 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_LAVA_BUCKET: { - LOGD("Dispensing lava bucket in slot %d; DispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(DispBlock).c_str(), DispBlock); - if (EmptyLiquidBucket(DispBlock, a_SlotNum)) + LOGD("Dispensing lava bucket in slot %d; dispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(dispBlock).c_str(), dispBlock); + if (EmptyLiquidBucket(dispBlock, a_SlotNum)) { - DispChunk->SetBlock(DispX, DispY, DispZ, E_BLOCK_LAVA, 0); + dispChunk->SetBlock(dispRelCoord, E_BLOCK_LAVA, 0); } else { @@ -115,9 +112,9 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_SPAWN_EGG: { - double MobX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); - double MobZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); - if (m_World->SpawnMob(MobX, DispY, MobZ, static_cast<eMonsterType>(m_Contents.GetSlot(a_SlotNum).m_ItemDamage), false) != cEntity::INVALID_ID) + double MobX = 0.5 + dispAbsCoord.x; + double MobZ = 0.5 + dispAbsCoord.z; + if (m_World->SpawnMob(MobX, dispAbsCoord.y, MobZ, static_cast<eMonsterType>(m_Contents.GetSlot(a_SlotNum).m_ItemDamage), false) != cEntity::INVALID_ID) { m_Contents.ChangeSlotCount(a_SlotNum, -1); } @@ -127,11 +124,9 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_BLOCK_TNT: { // Spawn a primed TNT entity, if space allows: - if (!cBlockInfo::IsSolid(DispBlock)) + if (!cBlockInfo::IsSolid(dispBlock)) { - double TNTX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); - double TNTZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); - m_World->SpawnPrimedTNT({TNTX, DispY + 0.5, TNTZ}, 80, 0); // 80 ticks fuse, no initial velocity + m_World->SpawnPrimedTNT(Vector3d(0.5, 0.5, 0.5) + dispAbsCoord, 80, 0); // 80 ticks fuse, no initial velocity m_Contents.ChangeSlotCount(a_SlotNum, -1); } break; @@ -140,9 +135,9 @@ 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 (DispBlock == E_BLOCK_AIR) + if (dispBlock == E_BLOCK_AIR) { - DispChunk->SetBlock(DispX, DispY, DispZ, E_BLOCK_FIRE, 0); + dispChunk->SetBlock(dispRelCoord, E_BLOCK_FIRE, 0); bool ItemBroke = m_Contents.DamageItem(a_SlotNum, 1); @@ -156,7 +151,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_FIRE_CHARGE: { - if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkFireCharge, GetShootVector(Meta) * 20) != cEntity::INVALID_ID) + if (SpawnProjectileFromDispenser(dispAbsCoord, cProjectileEntity::pkFireCharge, GetShootVector(meta) * 20) != cEntity::INVALID_ID) { m_Contents.ChangeSlotCount(a_SlotNum, -1); } @@ -165,7 +160,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_ARROW: { - if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkArrow, GetShootVector(Meta) * 30 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID) + if (SpawnProjectileFromDispenser(dispAbsCoord, cProjectileEntity::pkArrow, GetShootVector(meta) * 30 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID) { m_Contents.ChangeSlotCount(a_SlotNum, -1); } @@ -174,7 +169,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_SNOWBALL: { - if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkSnowball, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID) + if (SpawnProjectileFromDispenser(dispAbsCoord, cProjectileEntity::pkSnowball, GetShootVector(meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID) { m_Contents.ChangeSlotCount(a_SlotNum, -1); } @@ -183,7 +178,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_EGG: { - if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkEgg, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID) + if (SpawnProjectileFromDispenser(dispAbsCoord, cProjectileEntity::pkEgg, GetShootVector(meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID) { m_Contents.ChangeSlotCount(a_SlotNum, -1); } @@ -192,7 +187,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_BOTTLE_O_ENCHANTING: { - if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkExpBottle, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID) + if (SpawnProjectileFromDispenser(dispAbsCoord, cProjectileEntity::pkExpBottle, GetShootVector(meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID) { m_Contents.ChangeSlotCount(a_SlotNum, -1); } @@ -201,7 +196,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_POTION: { - if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkSplashPotion, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0), &SlotItem) != cEntity::INVALID_ID) + if (SpawnProjectileFromDispenser(dispAbsCoord, cProjectileEntity::pkSplashPotion, GetShootVector(meta) * 20 + Vector3d(0, 1, 0), &SlotItem) != cEntity::INVALID_ID) { m_Contents.ChangeSlotCount(a_SlotNum, -1); } @@ -215,7 +210,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) DropFromSlot(a_Chunk, a_SlotNum); break; } - if (m_World->GrowRipePlant(BlockX, DispY, BlockZ, true)) + if (m_World->GrowRipePlant(dispAbsCoord.x, dispAbsCoord.y, dispAbsCoord.z, true)) { m_Contents.ChangeSlotCount(a_SlotNum, -1); } @@ -229,16 +224,16 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_ACACIA_BOAT: case E_ITEM_DARK_OAK_BOAT: { - Vector3d SpawnPos; - if (IsBlockWater(DispBlock)) + Vector3d spawnPos = dispAbsCoord; + if (IsBlockWater(dispBlock)) { // Water next to the dispenser, spawn a boat above the water block - SpawnPos.Set(BlockX, DispY + 1, BlockZ); + spawnPos.y += 1; } - else if (IsBlockWater(DispChunk->GetBlock(DispX, DispY - 1, DispZ))) + else if (IsBlockWater(dispChunk->GetBlock(dispRelCoord.addedY(-1)))) { // Water one block below the dispenser, spawn a boat at the dispenser's Y level - SpawnPos.Set(BlockX, DispY, BlockZ); + // No adjustment needed } else { @@ -247,10 +242,10 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int 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); + 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, cBoat::ItemToMaterial(SlotItem))) + if (m_World->SpawnBoat(spawnPos, cBoat::ItemToMaterial(SlotItem))) { m_Contents.ChangeSlotCount(a_SlotNum, -1); } @@ -259,7 +254,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_FIREWORK_ROCKET: { - if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkFirework, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0), &SlotItem) != cEntity::INVALID_ID) + if (SpawnProjectileFromDispenser(dispAbsCoord, cProjectileEntity::pkFirework, GetShootVector(meta) * 20 + Vector3d(0, 1, 0), &SlotItem) != cEntity::INVALID_ID) { m_Contents.ChangeSlotCount(a_SlotNum, -1); } @@ -278,12 +273,9 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) -UInt32 cDispenserEntity::SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY, int a_BlockZ, cProjectileEntity::eKind a_Kind, const Vector3d & a_ShootVector, const cItem * a_Item) +UInt32 cDispenserEntity::SpawnProjectileFromDispenser(Vector3i a_BlockPos, 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), + return m_World->CreateProjectile(Vector3d(0.5, 0.5, 0.5) + a_BlockPos, a_Kind, nullptr, a_Item, &a_ShootVector ); } |