2013-07-29 07:13:03 -04:00
# include "Globals.h"
# include "BlockBed.h"
void cBlockBedHandler : : OnPlacedByPlayer (
2014-02-01 08:06:32 -05:00
cChunkInterface & a_ChunkInterface , cWorldInterface & a_WorldInterface , cPlayer * a_Player ,
2014-02-04 13:59:05 -05:00
int a_BlockX , int a_BlockY , int a_BlockZ , eBlockFace a_BlockFace ,
2013-07-29 07:13:03 -04:00
int a_CursorX , int a_CursorY , int a_CursorZ ,
BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta
)
{
if ( a_BlockMeta < 8 )
{
Vector3i Direction = MetaDataToDirection ( a_BlockMeta ) ;
2014-02-01 08:06:32 -05:00
a_ChunkInterface . SetBlock ( a_WorldInterface , a_BlockX + Direction . x , a_BlockY , a_BlockZ + Direction . z , E_BLOCK_BED , a_BlockMeta | 0x8 ) ;
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
Vector3i ThisPos ( a_BlockX , a_BlockY , a_BlockZ ) ;
Vector3i Direction = MetaDataToDirection ( OldMeta & 0x7 ) ;
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 :
cPlayerBedStateUnsetter ( Vector3i a_Position , cWorldInterface & a_WorldInterface ) :
m_Position ( a_Position ) , m_WorldInterface ( a_WorldInterface )
{
}
virtual bool Item ( cPlayer * a_Player ) override
{
a_Player - > SetIsInBed ( false ) ;
m_WorldInterface . GetBroadcastManager ( ) . BroadcastEntityAnimation ( * a_Player , 2 ) ;
return false ;
}
private :
Vector3i m_Position ;
cWorldInterface & m_WorldInterface ;
} ;
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 ) ;
2014-02-20 11:31:38 -05:00
if ( Meta & 0x4 )
2013-07-29 07:13:03 -04:00
{
2014-02-20 10:26:50 -05: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 ) ;
2014-02-20 10:26:50 -05:00
if ( Meta & 0x8 )
2013-07-29 07:13:03 -04:00
{
2014-02-20 10:26:50 -05:00
// Is pillow
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-03-09 11:53:03 -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
PillowDirection = MetaDataToDirection ( Meta & 0x7 ) ;
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
a_ChunkInterface . SetBlockMeta ( a_BlockX , a_BlockY , a_BlockZ , Meta | 0x4 ) ; // Where 0x4 = occupied bit
a_Player - > SetIsInBed ( true ) ;
cTimeFastForwardTester Tester ;
if ( a_WorldInterface . ForEachPlayer ( Tester ) )
{
cPlayerBedStateUnsetter Unsetter ( Vector3i ( a_BlockX + PillowDirection . x , a_BlockY , a_BlockZ + PillowDirection . z ) , a_WorldInterface ) ;
a_WorldInterface . ForEachPlayer ( Unsetter ) ;
a_WorldInterface . SetTimeOfDay ( 0 ) ;
a_ChunkInterface . SetBlockMeta ( a_BlockX , a_BlockY , a_BlockZ , Meta & 0xB ) ; // Where 0xB = 1011, and zero is to make sure 'occupied' bit is always unset
}
}
}
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