2017-09-19 04:34:08 -04:00
2017-07-07 03:31:45 -04:00
// BlockBed.cpp
2013-07-29 07:13:03 -04:00
# include "Globals.h"
# include "BlockBed.h"
2014-09-26 13:13:19 -04:00
# include "BroadcastInterface.h"
# include "Entities/Player.h"
2017-09-11 17:20:49 -04:00
# include "../World.h"
2017-07-01 09:59:26 -04:00
# include "../BoundingBox.h"
# include "../Mobs/Monster.h"
2017-07-07 03:31:45 -04:00
# include "../BlockEntities/BedEntity.h"
2014-09-26 13:13:19 -04:00
2013-07-29 07:13:03 -04:00
2014-02-01 08:06:32 -05:00
void cBlockBedHandler : : OnDestroyed ( cChunkInterface & a_ChunkInterface , cWorldInterface & a_WorldInterface , int a_BlockX , int a_BlockY , int a_BlockZ )
2013-07-29 07:13:03 -04:00
{
2014-02-01 08:06:32 -05:00
NIBBLETYPE OldMeta = a_ChunkInterface . GetBlockMeta ( a_BlockX , a_BlockY , a_BlockZ ) ;
2013-07-29 07:13:03 -04:00
2017-07-07 03:31:45 -04:00
Vector3i ThisPos ( a_BlockX , a_BlockY , a_BlockZ ) ;
Vector3i Direction = MetaDataToDirection ( OldMeta & 0x3 ) ;
2013-07-29 07:13:03 -04:00
if ( OldMeta & 0x8 )
{
// Was pillow
2014-02-01 08:06:32 -05:00
if ( a_ChunkInterface . GetBlock ( ThisPos - Direction ) = = E_BLOCK_BED )
2013-07-29 07:13:03 -04:00
{
2017-07-07 03:31:45 -04:00
// First replace the bed with air
2014-02-01 08:06:32 -05:00
a_ChunkInterface . FastSetBlock ( ThisPos - Direction , E_BLOCK_AIR , 0 ) ;
2017-07-07 03:31:45 -04: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 07:13:03 -04:00
}
}
else
{
// Was foot end
2014-02-01 08:06:32 -05:00
if ( a_ChunkInterface . GetBlock ( ThisPos + Direction ) = = E_BLOCK_BED )
2013-07-29 07:13:03 -04:00
{
2017-07-07 03:31:45 -04:00
// First replace the bed with air
2014-02-01 08:06:32 -05:00
a_ChunkInterface . FastSetBlock ( ThisPos + Direction , E_BLOCK_AIR , 0 ) ;
2017-07-07 03:31:45 -04: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 07:13:03 -04:00
}
}
}
2017-07-31 16:17:52 -04: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 07:13:03 -04:00
{
2014-02-01 08:06:32 -05: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 08:58:43 -04:00
{
Vector3i Coords ( a_BlockX , a_BlockY , a_BlockZ ) ;
2014-02-01 08:06:32 -05: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 08:58:43 -04:00
}
2017-08-24 05:19:40 -04:00
else if ( ! ( ( a_WorldInterface . GetTimeOfDay ( ) > 12541 ) & & ( a_WorldInterface . GetTimeOfDay ( ) < 23458 ) ) ) // Source: https://minecraft.gamepedia.com/Bed#Sleeping
2017-07-01 09:59:26 -04:00
{
2017-07-31 16:17:52 -04:00
a_Player . SendMessageFailure ( " You can only sleep at night " ) ;
2017-07-01 09:59:26 -04: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 08:58:43 -04:00
else
2013-07-29 07:13:03 -04:00
{
2017-07-01 09:59:26 -04:00
NIBBLETYPE Meta = a_ChunkInterface . GetBlockMeta ( a_BlockX , a_BlockY , a_BlockZ ) ;
if ( ( Meta & 0x4 ) = = 0x4 )
{
2017-07-31 16:17:52 -04:00
a_Player . SendMessageFailure ( " This bed is occupied " ) ;
2017-07-01 09:59:26 -04:00
}
else
2013-07-29 07:13:03 -04:00
{
2017-09-11 17:20:49 -04:00
auto FindMobs = [ ] ( cEntity & a_Entity )
{
return (
( a_Entity . GetEntityType ( ) = = cEntity : : etMonster ) & &
( static_cast < cMonster & > ( a_Entity ) . GetMobFamily ( ) = = cMonster : : mfHostile )
) ;
} ;
2017-07-31 16:17:52 -04:00
if ( ! a_Player . GetWorld ( ) - > ForEachEntityInBox ( cBoundingBox ( a_Player . GetPosition ( ) - Vector3i ( 0 , 5 , 0 ) , 8 , 10 ) , FindMobs ) )
2013-07-29 07:13:03 -04:00
{
2017-07-31 16:17:52 -04:00
a_Player . SendMessageFailure ( " You may not rest now, there are monsters nearby " ) ;
2013-07-29 07:13:03 -04:00
}
else
{
2014-03-08 19:17:23 -05:00
Vector3i PillowDirection ( 0 , 0 , 0 ) ;
2015-02-08 16:21:48 -05:00
if ( ( Meta & 0x8 ) = = 0x8 )
2013-07-29 07:13:03 -04:00
{
2014-07-17 16:50:58 -04:00
// Is pillow
2017-07-31 16:17:52 -04:00
a_WorldInterface . GetBroadcastManager ( ) . BroadcastUseBed ( a_Player , a_BlockX , a_BlockY , a_BlockZ ) ;
2013-07-29 07:13:03 -04:00
}
2014-02-20 10:26:50 -05:00
else
{
// Is foot end
2014-07-17 16:15:34 -04:00
VERIFY ( ( Meta & 0x4 ) ! = 0x4 ) ; // Occupied flag should never be set, else our compilator (intended) is broken
2014-03-08 19:17:23 -05:00
2015-05-15 19:47:58 -04:00
PillowDirection = MetaDataToDirection ( Meta & 0x3 ) ;
2014-07-17 16:15:34 -04: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 10:26:50 -05:00
{
2017-07-31 16:17:52 -04:00
a_WorldInterface . GetBroadcastManager ( ) . BroadcastUseBed ( a_Player , a_BlockX + PillowDirection . x , a_BlockY , a_BlockZ + PillowDirection . z ) ;
2014-02-20 10:26:50 -05:00
}
}
2014-03-08 19:17:23 -05:00
2017-07-31 16:17:52 -04: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-08 19:17:23 -05:00
2017-09-11 17:20:49 -04:00
auto TimeFastForwardTester = [ ] ( cPlayer & a_OtherPlayer )
2015-03-05 16:21:39 -05:00
{
2017-09-11 17:20:49 -04: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 16:21:39 -05: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 16:50:58 -04:00
}
2014-03-08 19:17:23 -05:00
}
2013-07-29 07:13:03 -04:00
}
2015-12-01 17:12:44 -05:00
return true ;
2013-07-29 07:13:03 -04:00
}
2014-02-20 10:26:50 -05:00
2017-07-31 16:17:52 -04:00
void cBlockBedHandler : : OnPlacedByPlayer ( cChunkInterface & a_ChunkInterface , cWorldInterface & a_WorldInterface , cPlayer & a_Player , const sSetBlock & a_BlockChange )
2017-07-07 03:31:45 -04:00
{
2017-09-11 17:20:49 -04:00
a_Player . GetWorld ( ) - > DoWithBedAt ( a_BlockChange . GetX ( ) , a_BlockChange . GetY ( ) , a_BlockChange . GetZ ( ) , [ & ] ( cBedEntity & a_Bed )
2017-07-07 03:31:45 -04:00
{
2017-09-11 17:20:49 -04:00
a_Bed . SetColor ( a_Player . GetEquippedItem ( ) . m_ItemDamage ) ;
2017-07-07 03:31:45 -04:00
return true ;
}
2017-09-11 17:20:49 -04:00
) ;
2017-07-07 03:31:45 -04:00
}
2017-08-25 05:56:01 -04: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 03:31:45 -04:00
{
2017-09-11 17:20:49 -04:00
short Color = E_META_WOOL_RED ;
a_WorldInterface . DoWithBedAt ( a_BlockX , a_BlockY , a_BlockZ , [ & ] ( cBedEntity & a_Bed )
2017-07-07 03:31:45 -04:00
{
2017-09-11 17:20:49 -04:00
Color = a_Bed . GetColor ( ) ;
2017-07-07 03:31:45 -04:00
return true ;
}
2017-09-11 17:20:49 -04:00
) ;
a_Pickups . Add ( cItem ( E_ITEM_BED , 1 , Color ) ) ;
2017-07-07 03:31:45 -04:00
}