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/../World.h"
# include "Entities/Player.h"
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
2014-07-21 09:19:48 -04:00
Vector3i ThisPos ( a_BlockX , a_BlockY , a_BlockZ ) ;
2015-05-15 19:47:58 -04:00
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
{
2014-02-01 08:06:32 -05:00
a_ChunkInterface . FastSetBlock ( ThisPos - Direction , 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
{
2014-02-01 08:06:32 -05:00
a_ChunkInterface . FastSetBlock ( ThisPos + Direction , E_BLOCK_AIR , 0 ) ;
2013-07-29 07:13:03 -04:00
}
}
}
2014-03-08 19:17:23 -05:00
class cTimeFastForwardTester :
public cPlayerListCallback
{
virtual bool Item ( cPlayer * a_Player ) override
{
if ( ! a_Player - > IsInBed ( ) )
{
return true ;
}
return false ;
}
} ;
class cPlayerBedStateUnsetter :
public cPlayerListCallback
{
public :
2015-02-08 16:21:48 -05:00
cPlayerBedStateUnsetter ( Vector3i a_Position , cChunkInterface & a_ChunkInterface ) :
m_Position ( a_Position ) ,
m_ChunkInterface ( a_ChunkInterface )
2014-03-08 19:17:23 -05:00
{
}
virtual bool Item ( cPlayer * a_Player ) override
{
2015-02-08 16:21:48 -05:00
cBlockBedHandler : : SetBedOccupationState ( m_ChunkInterface , a_Player - > GetLastBedPos ( ) , false ) ;
2014-03-08 19:17:23 -05:00
a_Player - > SetIsInBed ( false ) ;
return false ;
}
private :
Vector3i m_Position ;
2015-02-08 16:21:48 -05:00
cChunkInterface & m_ChunkInterface ;
2014-03-08 19:17:23 -05:00
} ;
2014-02-04 13:59:05 -05:00
void 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
}
else
2013-07-29 07:13:03 -04:00
{
2014-02-01 08:06:32 -05:00
if ( a_WorldInterface . GetTimeOfDay ( ) > 13000 )
2013-07-29 07:13:03 -04:00
{
2014-02-01 08:06:32 -05:00
NIBBLETYPE Meta = a_ChunkInterface . GetBlockMeta ( a_BlockX , a_BlockY , a_BlockZ ) ;
2015-02-08 16:21:48 -05:00
if ( ( Meta & 0x4 ) = = 0x4 )
2013-07-29 07:13:03 -04:00
{
2014-05-29 11:58:55 -04:00
a_Player - > SendMessageFailure ( " This bed is occupied " ) ;
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
2014-02-20 10:26:50 -05: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
{
2014-03-08 19:17:23 -05: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
2014-06-01 13:46:59 -04:00
a_Player - > SetBedPos ( Vector3i ( a_BlockX , a_BlockY , a_BlockZ ) ) ;
2015-02-08 16:21:48 -05:00
SetBedOccupationState ( a_ChunkInterface , a_Player - > GetLastBedPos ( ) , true ) ;
a_Player - > SetIsInBed ( true ) ;
2014-06-01 13:46:59 -04:00
a_Player - > SendMessageSuccess ( " Home position set successfully " ) ;
2014-03-08 19:17:23 -05:00
2015-03-05 16:21:39 -05:00
cTimeFastForwardTester Tester ;
if ( a_WorldInterface . ForEachPlayer ( Tester ) )
{
cPlayerBedStateUnsetter Unsetter ( Vector3i ( a_BlockX + PillowDirection . x , a_BlockY , a_BlockZ + PillowDirection . z ) , a_ChunkInterface ) ;
a_WorldInterface . ForEachPlayer ( Unsetter ) ;
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
}
else
{
2014-02-05 18:24:16 -05:00
a_Player - > SendMessageFailure ( " You can only sleep at night " ) ;
2013-07-29 07:13:03 -04:00
}
}
}
2014-02-20 10:26:50 -05:00