2017-09-19 08:34:08 +00:00
2017-07-07 07:31:45 +00:00
// BlockBed.cpp
2013-07-29 11:13:03 +00:00
# include "Globals.h"
# include "BlockBed.h"
2014-09-26 17:13:19 +00:00
# include "BroadcastInterface.h"
# include "Entities/Player.h"
2017-09-11 21:20:49 +00:00
# include "../World.h"
2017-07-01 13:59:26 +00:00
# include "../BoundingBox.h"
# include "../Mobs/Monster.h"
2017-07-07 07:31:45 +00:00
# include "../BlockEntities/BedEntity.h"
2014-09-26 17:13:19 +00:00
2013-07-29 11:13:03 +00:00
2014-02-01 13:06:32 +00:00
void cBlockBedHandler : : OnDestroyed ( cChunkInterface & a_ChunkInterface , cWorldInterface & a_WorldInterface , int a_BlockX , int a_BlockY , int a_BlockZ )
2013-07-29 11:13:03 +00:00
{
2014-02-01 13:06:32 +00:00
NIBBLETYPE OldMeta = a_ChunkInterface . GetBlockMeta ( a_BlockX , a_BlockY , a_BlockZ ) ;
2013-07-29 11:13:03 +00:00
2017-07-07 07:31:45 +00:00
Vector3i ThisPos ( a_BlockX , a_BlockY , a_BlockZ ) ;
Vector3i Direction = MetaDataToDirection ( OldMeta & 0x3 ) ;
2013-07-29 11:13:03 +00:00
if ( OldMeta & 0x8 )
{
// Was pillow
2014-02-01 13:06:32 +00:00
if ( a_ChunkInterface . GetBlock ( ThisPos - Direction ) = = E_BLOCK_BED )
2013-07-29 11:13:03 +00:00
{
2017-07-07 07:31:45 +00:00
// First replace the bed with air
2014-02-01 13:06:32 +00:00
a_ChunkInterface . FastSetBlock ( ThisPos - Direction , E_BLOCK_AIR , 0 ) ;
2017-07-07 07:31:45 +00:00
// Then destroy the bed entity
Vector3i PillowPos ( ThisPos - Direction ) ;
a_ChunkInterface . SetBlock ( PillowPos . x , PillowPos . y , PillowPos . z , E_BLOCK_AIR , 0 ) ;
2013-07-29 11:13:03 +00:00
}
}
else
{
// Was foot end
2014-02-01 13:06:32 +00:00
if ( a_ChunkInterface . GetBlock ( ThisPos + Direction ) = = E_BLOCK_BED )
2013-07-29 11:13:03 +00:00
{
2017-07-07 07:31:45 +00:00
// First replace the bed with air
2014-02-01 13:06:32 +00:00
a_ChunkInterface . FastSetBlock ( ThisPos + Direction , E_BLOCK_AIR , 0 ) ;
2017-07-07 07:31:45 +00:00
// Then destroy the bed entity
Vector3i FootPos ( ThisPos + Direction ) ;
a_ChunkInterface . SetBlock ( FootPos . x , FootPos . y , FootPos . z , E_BLOCK_AIR , 0 ) ;
2013-07-29 11:13:03 +00:00
}
}
}
2017-07-31 20:17:52 +00:00
bool cBlockBedHandler : : OnUse ( cChunkInterface & a_ChunkInterface , cWorldInterface & a_WorldInterface , cPlayer & a_Player , int a_BlockX , int a_BlockY , int a_BlockZ , eBlockFace a_BlockFace , int a_CursorX , int a_CursorY , int a_CursorZ )
2013-07-29 11:13:03 +00:00
{
2014-02-01 13:06:32 +00:00
if ( a_WorldInterface . GetDimension ( ) ! = dimOverworld )
Added OnExploding() and OnExploded() hooks.
As requested in FS 413, with extra parameters:
World, BlockX, BlockY, BlockZ, Size, CanCauseFire, Source, SourceData
OnExploding() can return 3 values:
StopHook, CanCauseFire, ExplosionSize
2013-08-09 12:58:43 +00:00
{
Vector3i Coords ( a_BlockX , a_BlockY , a_BlockZ ) ;
2014-02-01 13:06:32 +00:00
a_WorldInterface . DoExplosionAt ( 5 , a_BlockX , a_BlockY , a_BlockZ , true , esBed , & Coords ) ;
Added OnExploding() and OnExploded() hooks.
As requested in FS 413, with extra parameters:
World, BlockX, BlockY, BlockZ, Size, CanCauseFire, Source, SourceData
OnExploding() can return 3 values:
StopHook, CanCauseFire, ExplosionSize
2013-08-09 12:58:43 +00:00
}
2017-08-24 09:19:40 +00:00
else if ( ! ( ( a_WorldInterface . GetTimeOfDay ( ) > 12541 ) & & ( a_WorldInterface . GetTimeOfDay ( ) < 23458 ) ) ) // Source: https://minecraft.gamepedia.com/Bed#Sleeping
2017-07-01 13:59:26 +00:00
{
2017-07-31 20:17:52 +00:00
a_Player . SendMessageFailure ( " You can only sleep at night " ) ;
2017-07-01 13:59:26 +00:00
}
Added OnExploding() and OnExploded() hooks.
As requested in FS 413, with extra parameters:
World, BlockX, BlockY, BlockZ, Size, CanCauseFire, Source, SourceData
OnExploding() can return 3 values:
StopHook, CanCauseFire, ExplosionSize
2013-08-09 12:58:43 +00:00
else
2013-07-29 11:13:03 +00:00
{
2017-07-01 13:59:26 +00:00
NIBBLETYPE Meta = a_ChunkInterface . GetBlockMeta ( a_BlockX , a_BlockY , a_BlockZ ) ;
if ( ( Meta & 0x4 ) = = 0x4 )
{
2017-07-31 20:17:52 +00:00
a_Player . SendMessageFailure ( " This bed is occupied " ) ;
2017-07-01 13:59:26 +00:00
}
else
2013-07-29 11:13:03 +00:00
{
2017-09-11 21:20:49 +00:00
auto FindMobs = [ ] ( cEntity & a_Entity )
{
return (
( a_Entity . GetEntityType ( ) = = cEntity : : etMonster ) & &
( static_cast < cMonster & > ( a_Entity ) . GetMobFamily ( ) = = cMonster : : mfHostile )
) ;
} ;
2017-07-31 20:17:52 +00:00
if ( ! a_Player . GetWorld ( ) - > ForEachEntityInBox ( cBoundingBox ( a_Player . GetPosition ( ) - Vector3i ( 0 , 5 , 0 ) , 8 , 10 ) , FindMobs ) )
2013-07-29 11:13:03 +00:00
{
2017-07-31 20:17:52 +00:00
a_Player . SendMessageFailure ( " You may not rest now, there are monsters nearby " ) ;
2013-07-29 11:13:03 +00:00
}
else
{
2014-03-09 00:17:23 +00:00
Vector3i PillowDirection ( 0 , 0 , 0 ) ;
2015-02-08 21:21:48 +00:00
if ( ( Meta & 0x8 ) = = 0x8 )
2013-07-29 11:13:03 +00:00
{
2014-07-17 20:50:58 +00:00
// Is pillow
2017-07-31 20:17:52 +00:00
a_WorldInterface . GetBroadcastManager ( ) . BroadcastUseBed ( a_Player , a_BlockX , a_BlockY , a_BlockZ ) ;
2013-07-29 11:13:03 +00:00
}
2014-02-20 15:26:50 +00:00
else
{
// Is foot end
2014-07-17 20:15:34 +00:00
VERIFY ( ( Meta & 0x4 ) ! = 0x4 ) ; // Occupied flag should never be set, else our compilator (intended) is broken
2014-03-09 00:17:23 +00:00
2015-05-15 23:47:58 +00:00
PillowDirection = MetaDataToDirection ( Meta & 0x3 ) ;
2014-07-17 20:15:34 +00:00
if ( a_ChunkInterface . GetBlock ( a_BlockX + PillowDirection . x , a_BlockY , a_BlockZ + PillowDirection . z ) = = E_BLOCK_BED ) // Must always use pillow location for sleeping
2014-02-20 15:26:50 +00:00
{
2017-07-31 20:17:52 +00:00
a_WorldInterface . GetBroadcastManager ( ) . BroadcastUseBed ( a_Player , a_BlockX + PillowDirection . x , a_BlockY , a_BlockZ + PillowDirection . z ) ;
2014-02-20 15:26:50 +00:00
}
}
2014-03-09 00:17:23 +00:00
2017-07-31 20:17:52 +00:00
a_Player . SetBedPos ( Vector3i ( a_BlockX , a_BlockY , a_BlockZ ) ) ;
SetBedOccupationState ( a_ChunkInterface , a_Player . GetLastBedPos ( ) , true ) ;
a_Player . SetIsInBed ( true ) ;
a_Player . SendMessageSuccess ( " Home position set successfully " ) ;
2014-03-09 00:17:23 +00:00
2017-09-11 21:20:49 +00:00
auto TimeFastForwardTester = [ ] ( cPlayer & a_OtherPlayer )
2015-03-05 21:21:39 +00:00
{
2017-09-11 21:20:49 +00:00
if ( ! a_OtherPlayer . IsInBed ( ) )
{
return true ;
}
return false ;
} ;
if ( a_WorldInterface . ForEachPlayer ( TimeFastForwardTester ) )
{
a_WorldInterface . ForEachPlayer ( [ & ] ( cPlayer & a_OtherPlayer )
{
cBlockBedHandler : : SetBedOccupationState ( a_ChunkInterface , a_OtherPlayer . GetLastBedPos ( ) , false ) ;
a_OtherPlayer . SetIsInBed ( false ) ;
return false ;
}
) ;
2015-03-05 21:21:39 +00:00
a_WorldInterface . SetTimeOfDay ( 0 ) ;
a_ChunkInterface . SetBlockMeta ( a_BlockX , a_BlockY , a_BlockZ , Meta & 0x0b ) ; // Clear the "occupied" bit of the bed's block
}
2014-07-17 20:50:58 +00:00
}
2014-03-09 00:17:23 +00:00
}
2013-07-29 11:13:03 +00:00
}
2015-12-01 22:12:44 +00:00
return true ;
2013-07-29 11:13:03 +00:00
}
2014-02-20 15:26:50 +00:00
2017-07-31 20:17:52 +00:00
void cBlockBedHandler : : OnPlacedByPlayer ( cChunkInterface & a_ChunkInterface , cWorldInterface & a_WorldInterface , cPlayer & a_Player , const sSetBlock & a_BlockChange )
2017-07-07 07:31:45 +00:00
{
2017-09-11 21:20:49 +00:00
a_Player . GetWorld ( ) - > DoWithBedAt ( a_BlockChange . GetX ( ) , a_BlockChange . GetY ( ) , a_BlockChange . GetZ ( ) , [ & ] ( cBedEntity & a_Bed )
2017-07-07 07:31:45 +00:00
{
2017-09-11 21:20:49 +00:00
a_Bed . SetColor ( a_Player . GetEquippedItem ( ) . m_ItemDamage ) ;
2017-07-07 07:31:45 +00:00
return true ;
}
2017-09-11 21:20:49 +00:00
) ;
2017-07-07 07:31:45 +00:00
}
2017-08-25 09:56:01 +00:00
void cBlockBedHandler : : ConvertToPickups ( cWorldInterface & a_WorldInterface , cItems & a_Pickups , NIBBLETYPE a_BlockMeta , int a_BlockX , int a_BlockY , int a_BlockZ )
2017-07-07 07:31:45 +00:00
{
2017-09-11 21:20:49 +00:00
short Color = E_META_WOOL_RED ;
a_WorldInterface . DoWithBedAt ( a_BlockX , a_BlockY , a_BlockZ , [ & ] ( cBedEntity & a_Bed )
2017-07-07 07:31:45 +00:00
{
2017-09-11 21:20:49 +00:00
Color = a_Bed . GetColor ( ) ;
2017-07-07 07:31:45 +00:00
return true ;
}
2017-09-11 21:20:49 +00:00
) ;
a_Pickups . Add ( cItem ( E_ITEM_BED , 1 , Color ) ) ;
2017-07-07 07:31:45 +00:00
}