2013-09-07 19:14:57 -04:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "../Entities/Boat.h"
|
2013-12-16 12:01:33 -05:00
|
|
|
#include "../LineBlockTracer.h"
|
2013-09-07 19:14:57 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-04-13 12:38:06 -04:00
|
|
|
class cItemBoatHandler:
|
2013-09-07 19:14:57 -04:00
|
|
|
public cItemHandler
|
|
|
|
{
|
2020-04-13 12:38:06 -04:00
|
|
|
using Super = cItemHandler;
|
2016-02-05 16:45:45 -05:00
|
|
|
|
2013-09-07 19:14:57 -04:00
|
|
|
public:
|
2020-04-13 12:38:06 -04:00
|
|
|
|
|
|
|
cItemBoatHandler(int a_ItemType):
|
|
|
|
Super(a_ItemType)
|
2013-09-07 19:14:57 -04:00
|
|
|
{
|
|
|
|
}
|
2016-02-05 16:45:45 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
2020-04-21 16:19:22 -04:00
|
|
|
|
|
|
|
|
2015-04-14 04:49:01 -04:00
|
|
|
virtual bool OnItemUse(
|
2020-04-21 16:19:22 -04:00
|
|
|
cWorld * a_World,
|
|
|
|
cPlayer * a_Player,
|
|
|
|
cBlockPluginInterface & a_PluginInterface,
|
|
|
|
const cItem & a_HeldItem,
|
|
|
|
const Vector3i a_ClickedBlockPos,
|
|
|
|
eBlockFace a_ClickedBlockFace
|
2015-04-14 04:49:01 -04:00
|
|
|
) override
|
2013-09-07 19:14:57 -04:00
|
|
|
{
|
2020-04-21 16:19:22 -04:00
|
|
|
// Only allow placing blocks on top of blocks, or when not in range of dest block:
|
|
|
|
if ((a_ClickedBlockFace != BLOCK_FACE_YM) && (a_ClickedBlockFace != BLOCK_FACE_NONE))
|
2013-09-07 19:14:57 -04:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2013-12-16 12:01:33 -05:00
|
|
|
|
2020-04-21 16:19:22 -04:00
|
|
|
// Find the actual placement position by tracing line of sight until non-air block:
|
|
|
|
class cCallbacks:
|
2013-12-16 12:01:33 -05:00
|
|
|
public cBlockTracer::cCallbacks
|
|
|
|
{
|
|
|
|
public:
|
2014-04-02 10:40:13 -04:00
|
|
|
Vector3d m_Pos;
|
|
|
|
bool m_HasFound;
|
2016-02-05 16:45:45 -05:00
|
|
|
|
2020-04-21 16:19:22 -04:00
|
|
|
cCallbacks():
|
2014-04-02 10:40:13 -04:00
|
|
|
m_HasFound(false)
|
2013-12-16 12:01:33 -05:00
|
|
|
{
|
2014-04-02 10:40:13 -04:00
|
|
|
}
|
2016-02-05 16:45:45 -05:00
|
|
|
|
2020-05-08 05:04:07 -04:00
|
|
|
virtual bool OnNextBlock(Vector3i a_CBBlockPos, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, eBlockFace a_CBEntryFace) override
|
2014-04-02 10:40:13 -04:00
|
|
|
{
|
|
|
|
if (a_CBBlockType != E_BLOCK_AIR)
|
2013-12-16 12:01:33 -05:00
|
|
|
{
|
2020-05-08 05:04:07 -04:00
|
|
|
m_Pos = a_CBBlockPos;
|
2014-04-02 10:40:13 -04:00
|
|
|
m_HasFound = true;
|
2013-12-16 12:01:33 -05:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} Callbacks;
|
2020-04-21 16:19:22 -04:00
|
|
|
auto Start = a_Player->GetEyePosition() + a_Player->GetLookVector();
|
|
|
|
auto End = a_Player->GetEyePosition() + a_Player->GetLookVector() * 5;
|
|
|
|
cLineBlockTracer::Trace(*a_World, Callbacks, Start, End);
|
2014-04-02 10:40:13 -04:00
|
|
|
if (!Callbacks.m_HasFound)
|
2013-12-16 12:01:33 -05:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2013-09-07 19:14:57 -04:00
|
|
|
|
2016-07-18 16:10:00 -04:00
|
|
|
// Block above must be air to spawn a boat (prevents spawning a boat underwater)
|
2020-04-21 16:19:22 -04:00
|
|
|
auto PosAbove = Callbacks.m_Pos.Floor().addedY(1);
|
|
|
|
if (!cChunkDef::IsValidHeight(PosAbove.y))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
BLOCKTYPE BlockAbove = a_World->GetBlock(PosAbove);
|
2016-07-18 16:10:00 -04:00
|
|
|
if (BlockAbove != E_BLOCK_AIR)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Spawn block at water level
|
2020-03-05 09:05:30 -05:00
|
|
|
if (a_World->SpawnBoat(Callbacks.m_Pos + Vector3d(0.5, 1, 0.5), cBoat::ItemToMaterial(a_Player->GetEquippedItem())) == cEntity::INVALID_ID)
|
2017-05-02 07:16:59 -04:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2013-09-07 19:14:57 -04:00
|
|
|
|
2017-03-17 14:33:18 -04:00
|
|
|
// Remove boat from players hand
|
|
|
|
if (!a_Player->IsGameModeCreative())
|
|
|
|
{
|
|
|
|
a_Player->GetInventory().RemoveOneEquippedItem();
|
|
|
|
}
|
|
|
|
|
2013-09-07 19:14:57 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} ;
|