2026-03-01 12:16:08 +08:00
# include "stdafx.h"
# include "net.minecraft.world.level.h"
# include "net.minecraft.world.level.tile.h"
# include "net.minecraft.world.entity.h"
# include "net.minecraft.world.entity.boss.enderdragon.h"
# include "EnderCrystal.h"
# include "DamageSource.h"
void EnderCrystal : : _init ( Level * level )
2026-03-02 17:37:16 +07:00
{
2026-03-01 12:16:08 +08:00
// 4J Stu - This function call had to be moved here from the Entity ctor to ensure that
// the derived version of the function is called
this - > defineSynchedData ( ) ;
blocksBuilding = true ;
setSize ( 2.0f , 2.0f ) ;
heightOffset = bbHeight / 2.0f ;
life = MAX_LIFE ;
time = random - > nextInt ( 100000 ) ;
}
EnderCrystal : : EnderCrystal ( Level * level ) : Entity ( level )
{
_init ( level ) ;
}
EnderCrystal : : EnderCrystal ( Level * level , double x , double y , double z ) : Entity ( level )
{
_init ( level ) ;
setPos ( x , y , z ) ;
}
bool EnderCrystal : : makeStepSound ( )
{
return false ;
}
void EnderCrystal : : defineSynchedData ( )
{
entityData - > define ( DATA_REMAINING_LIFE , life ) ;
}
void EnderCrystal : : tick ( )
{
xo = x ;
yo = y ;
zo = z ;
time + + ;
entityData - > set ( DATA_REMAINING_LIFE , life ) ;
// Don't set the tile directly on the client, as this can end up in the updatesToReset queue in the MultiPlayerLevel, and the perpetually end up removing/adding these fire tiles causing timing
// glitches from the lighting changes requried.
if ( ! level - > isClientSide )
{
int xt = Mth : : floor ( x ) ;
int yt = Mth : : floor ( y ) ;
int zt = Mth : : floor ( z ) ;
if ( level - > getTile ( xt , yt , zt ) ! = Tile : : fire_Id )
{
2026-03-03 03:04:10 +08:00
level - > setTileAndUpdate ( xt , yt , zt , Tile : : fire_Id ) ;
2026-03-01 12:16:08 +08:00
}
}
}
void EnderCrystal : : addAdditonalSaveData ( CompoundTag * tag )
{
}
void EnderCrystal : : readAdditionalSaveData ( CompoundTag * tag )
{
}
float EnderCrystal : : getShadowHeightOffs ( )
{
return 0 ;
}
bool EnderCrystal : : isPickable ( )
{
return true ;
}
2026-03-03 03:04:10 +08:00
bool EnderCrystal : : hurt ( DamageSource * source , float damage )
2026-03-01 12:16:08 +08:00
{
2026-03-03 03:04:10 +08:00
if ( isInvulnerable ( ) ) return false ;
2026-03-01 12:16:08 +08:00
2026-03-03 03:04:10 +08:00
// 4J-PB - if the owner of the source is the enderdragon, then ignore it (where the dragon's fireball hits an endercrystal)
if ( source - > getEntity ( ) ! = NULL & & source - > getEntity ( ) - > instanceof ( eTYPE_ENDERDRAGON ) )
2026-03-01 12:16:08 +08:00
{
return false ;
}
if ( ! removed & & ! level - > isClientSide )
{
life = 0 ;
if ( life < = 0 )
{
remove ( ) ;
if ( ! level - > isClientSide )
{
level - > explode ( nullptr , x , y , z , 6 , true ) ;
2026-03-02 17:37:16 +07:00
vector < shared_ptr < Entity > > entities = level - > getAllEntities ( ) ;
shared_ptr < EnderDragon > dragon = nullptr ;
2026-03-01 12:16:08 +08:00
AUTO_VAR ( itEnd , entities . end ( ) ) ;
for ( AUTO_VAR ( it , entities . begin ( ) ) ; it ! = itEnd ; it + + )
{
2026-03-02 17:37:16 +07:00
shared_ptr < Entity > e = * it ; //entities->at(i);
2026-03-02 17:36:56 +07:00
dragon = dynamic_pointer_cast < EnderDragon > ( e ) ;
2026-03-01 12:16:08 +08:00
if ( dragon ! = NULL )
{
dragon - > handleCrystalDestroyed ( source ) ;
break ;
}
}
}
}
}
return true ;
}