End crystal placement (#5112)
* End crystal placement * End crystal placement - fixed error and added some comments * Removed unused includes * Update src/Items/ItemEndCrystal.h Co-authored-by: Alexander Harkness <me@bearbin.net> * End Crystal placement, early-return pattern enforcement * End crystal Item finish? * Small changes Fixed a crashbug in ender crystal destruction. According to vanilla 1.16 testing, end crystals don't place if any entity intersects the box, not just other end crystals. Check return value of SpawnEnderCrystal. Add header in SeeMake. Cafe Stile Redux. * The stylechecker relies on CMakeLists * There is another Co-authored-by: Alexander Harkness <me@bearbin.net> Co-authored-by: Tiger Wang <ziwei.tiger@outlook.com>
This commit is contained in:
parent
59e906ec6c
commit
4f3b699b27
@ -89,13 +89,14 @@ void cEnderCrystal::KilledBy(TakeDamageInfo & a_TDI)
|
|||||||
{
|
{
|
||||||
Super::KilledBy(a_TDI);
|
Super::KilledBy(a_TDI);
|
||||||
|
|
||||||
m_World->DoExplosionAt(6.0, GetPosX(), GetPosY() + (GetHeight() / 2.0), GetPosZ(), true, esEnderCrystal, this);
|
// Destroy first so the Explodinator doesn't find us (when iterating through entities):
|
||||||
|
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
m_World->SetBlock(POS_TOINT, E_BLOCK_FIRE, 0);
|
m_World->DoExplosionAt(6.0, GetPosX(), GetPosY() + (GetHeight() / 2.0), GetPosZ(), true, esEnderCrystal, this);
|
||||||
|
|
||||||
|
const auto Position = GetPosition().Floor();
|
||||||
|
if (cChunkDef::IsValidHeight(Position.y))
|
||||||
|
{
|
||||||
|
m_World->SetBlock(Position, E_BLOCK_FIRE, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ target_sources(
|
|||||||
ItemDye.h
|
ItemDye.h
|
||||||
ItemEmptyMap.h
|
ItemEmptyMap.h
|
||||||
ItemEnchantingTable.h
|
ItemEnchantingTable.h
|
||||||
|
ItemEndCrystal.h
|
||||||
ItemEyeOfEnder.h
|
ItemEyeOfEnder.h
|
||||||
ItemFishingRod.h
|
ItemFishingRod.h
|
||||||
ItemFood.h
|
ItemFood.h
|
||||||
|
81
src/Items/ItemEndCrystal.h
Normal file
81
src/Items/ItemEndCrystal.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ItemHandler.h"
|
||||||
|
#include "../World.h"
|
||||||
|
#include "../Entities/Player.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class cItemEndCrystalHandler :
|
||||||
|
public cItemHandler
|
||||||
|
{
|
||||||
|
using Super = cItemHandler;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
cItemEndCrystalHandler(int a_ItemType) :
|
||||||
|
Super(a_ItemType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool OnItemUse(
|
||||||
|
cWorld * a_World, cPlayer * a_Player,
|
||||||
|
cBlockPluginInterface & a_PluginInterface, const cItem & a_HeldItem,
|
||||||
|
const Vector3i a_BlockPos,
|
||||||
|
eBlockFace a_ClickedBlockFace) override
|
||||||
|
{
|
||||||
|
// Must click a valid block:
|
||||||
|
if (a_ClickedBlockFace < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
const auto BlockType = a_World->GetBlock(a_BlockPos);
|
||||||
|
|
||||||
|
// Don't place if placement block is not obsidian or bedrock:
|
||||||
|
(BlockType != E_BLOCK_OBSIDIAN) && (BlockType != E_BLOCK_BEDROCK)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The position of the block above the placement block.
|
||||||
|
const auto Above = a_BlockPos.addedY(1);
|
||||||
|
|
||||||
|
if (
|
||||||
|
// Don't place if two blocks above placement block aren't air:
|
||||||
|
((Above.y != cChunkDef::Height) && (a_World->GetBlock(Above) != E_BLOCK_AIR)) ||
|
||||||
|
((Above.y < (cChunkDef::Height - 1)) && (a_World->GetBlock(Above.addedY(1)) != E_BLOCK_AIR)) ||
|
||||||
|
|
||||||
|
// Refuse placement if there are any entities in a (1 by 2 by 1) bounding box with base at the block above:
|
||||||
|
!a_World->ForEachEntityInBox(
|
||||||
|
{ Above, Above + Vector3i(1, 2, 1) },
|
||||||
|
[](cEntity & a_Entity)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spawns ender crystal entity, aborts if plugin cancelled:
|
||||||
|
if (a_World->SpawnEnderCrystal(Vector3d(0.5, 0, 0.5) + Above, false) == cEntity::INVALID_ID)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!a_Player->IsGameModeCreative())
|
||||||
|
{
|
||||||
|
a_Player->GetInventory().RemoveOneEquippedItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
@ -24,6 +24,7 @@
|
|||||||
#include "ItemDye.h"
|
#include "ItemDye.h"
|
||||||
#include "ItemEmptyMap.h"
|
#include "ItemEmptyMap.h"
|
||||||
#include "ItemEnchantingTable.h"
|
#include "ItemEnchantingTable.h"
|
||||||
|
#include "ItemEndCrystal.h"
|
||||||
#include "ItemEyeOfEnder.h"
|
#include "ItemEyeOfEnder.h"
|
||||||
#include "ItemFishingRod.h"
|
#include "ItemFishingRod.h"
|
||||||
#include "ItemFood.h"
|
#include "ItemFood.h"
|
||||||
@ -137,6 +138,7 @@ cItemHandler * cItemHandler::CreateItemHandler(int a_ItemType)
|
|||||||
case E_ITEM_EGG: return new cItemEggHandler();
|
case E_ITEM_EGG: return new cItemEggHandler();
|
||||||
case E_ITEM_EMPTY_MAP: return new cItemEmptyMapHandler();
|
case E_ITEM_EMPTY_MAP: return new cItemEmptyMapHandler();
|
||||||
case E_ITEM_ENDER_PEARL: return new cItemEnderPearlHandler();
|
case E_ITEM_ENDER_PEARL: return new cItemEnderPearlHandler();
|
||||||
|
case E_ITEM_END_CRYSTAL: return new cItemEndCrystalHandler(a_ItemType);
|
||||||
case E_ITEM_EYE_OF_ENDER: return new cItemEyeOfEnderHandler();
|
case E_ITEM_EYE_OF_ENDER: return new cItemEyeOfEnderHandler();
|
||||||
case E_ITEM_FIRE_CHARGE: return new cItemLighterHandler(a_ItemType);
|
case E_ITEM_FIRE_CHARGE: return new cItemLighterHandler(a_ItemType);
|
||||||
case E_ITEM_FIREWORK_ROCKET: return new cItemFireworkHandler();
|
case E_ITEM_FIREWORK_ROCKET: return new cItemFireworkHandler();
|
||||||
|
Loading…
Reference in New Issue
Block a user