2026-03-01 12:16:08 +08:00
# include "stdafx.h"
# include "PlayerRenderer.h"
# include "SkullTileRenderer.h"
2026-03-03 03:04:10 +08:00
# include "HumanoidMobRenderer.h"
2026-03-01 12:16:08 +08:00
# include "HumanoidModel.h"
# include "ModelPart.h"
# include "LocalPlayer.h"
# include "MultiPlayerLocalPlayer.h"
# include "entityRenderDispatcher.h"
# include "..\Minecraft.World\net.minecraft.world.entity.h"
# include "..\Minecraft.World\net.minecraft.world.entity.player.h"
# include "..\Minecraft.World\net.minecraft.world.item.h"
# include "..\Minecraft.World\net.minecraft.world.level.tile.h"
# include "..\Minecraft.World\net.minecraft.h"
# include "..\Minecraft.World\StringHelpers.h"
2026-03-06 19:23:32 -06:00
static unsigned int nametagColorForIndex ( int index )
2026-03-01 12:16:08 +08:00
{
2026-03-06 19:23:32 -06:00
static const unsigned int s_firstColors [ ] = {
0xff000000 , // WHITE (represents the "white" player, but using black as the colour)
0xff33cc33 , // GREEN
0xffcc3333 , // RED
0xff3333cc , // BLUE
0xffcc33cc , // PINK
0xffcc6633 , // ORANGE
0xffcccc33 , // YELLOW
0xff33dccc // TURQUOISE
} ;
# ifndef __PSVITA__
if ( index > = 0 & & index < 8 ) // Use original colors for the first 8 players
return s_firstColors [ index ] ;
if ( index > = 8 & & index < MINECRAFT_NET_MAX_PLAYERS )
{
float h = ( float ) ( ( index * 137 ) % 360 ) / 60.f ;
int i = ( int ) h ;
float f = h - i ;
float q = 1.f - f ;
float t = 1.f - ( 1.f - f ) ;
float r = 0.f , g = 0.f , b = 0.f ;
switch ( i % 6 )
{
case 0 : r = 1.f ; g = t ; b = 0.f ; break ;
case 1 : r = q ; g = 1.f ; b = 0.f ; break ;
case 2 : r = 0.f ; g = 1.f ; b = t ; break ;
case 3 : r = 0.f ; g = q ; b = 1.f ; break ;
case 4 : r = t ; g = 0.f ; b = 1.f ; break ;
default : r = 1.f ; g = 0.f ; b = q ; break ;
}
int ri = ( int ) ( r * 255.f ) & 0xff , gi = ( int ) ( g * 255.f ) & 0xff , bi = ( int ) ( b * 255.f ) & 0xff ;
return 0xff000000u | ( ri < < 16 ) | ( gi < < 8 ) | bi ;
}
2026-03-01 12:16:08 +08:00
# endif
2026-03-06 19:23:32 -06:00
return 0xFF000000 ; //Fallback if exceeds 256 somehow
}
2026-03-01 12:16:08 +08:00
2026-03-03 03:04:10 +08:00
ResourceLocation PlayerRenderer : : DEFAULT_LOCATION = ResourceLocation ( TN_MOB_CHAR ) ;
2026-03-01 12:16:08 +08:00
2026-03-03 03:04:10 +08:00
PlayerRenderer : : PlayerRenderer ( ) : LivingEntityRenderer ( new HumanoidModel ( 0 ) , 0.5f )
2026-03-01 12:16:08 +08:00
{
2026-03-08 19:08:36 -04:00
humanoidModel = static_cast < HumanoidModel * > ( model ) ;
2026-03-01 12:16:08 +08:00
armorParts1 = new HumanoidModel ( 1.0f ) ;
armorParts2 = new HumanoidModel ( 0.5f ) ;
}
unsigned int PlayerRenderer : : getNametagColour ( int index )
{
if ( index > = 0 & & index < MINECRAFT_NET_MAX_PLAYERS )
2026-03-06 19:23:32 -06:00
return nametagColorForIndex ( index ) ;
2026-03-01 12:16:08 +08:00
return 0xFF000000 ;
}
2026-03-03 03:04:10 +08:00
int PlayerRenderer : : prepareArmor ( shared_ptr < LivingEntity > _player , int layer , float a )
2026-03-01 12:16:08 +08:00
{
// 4J - dynamic cast required because we aren't using templates/generics in our version
2026-03-02 17:37:16 +07:00
shared_ptr < Player > player = dynamic_pointer_cast < Player > ( _player ) ;
2026-03-01 12:16:08 +08:00
// 4J-PB - need to disable rendering armour for some special skins (Daleks)
unsigned int uiAnimOverrideBitmask = player - > getAnimOverrideBitmask ( ) ;
if ( uiAnimOverrideBitmask & ( 1 < < HumanoidModel : : eAnim_DontRenderArmour ) )
{
return - 1 ;
}
2026-03-02 17:37:16 +07:00
shared_ptr < ItemInstance > itemInstance = player - > inventory - > getArmor ( 3 - layer ) ;
2026-03-08 19:08:36 -04:00
if ( itemInstance ! = nullptr )
2026-03-01 12:16:08 +08:00
{
Item * item = itemInstance - > getItem ( ) ;
if ( dynamic_cast < ArmorItem * > ( item ) )
{
ArmorItem * armorItem = dynamic_cast < ArmorItem * > ( item ) ;
2026-03-03 03:04:10 +08:00
bindTexture ( HumanoidMobRenderer : : getArmorLocation ( armorItem , layer ) ) ;
2026-03-01 12:16:08 +08:00
HumanoidModel * armor = layer = = 2 ? armorParts2 : armorParts1 ;
armor - > head - > visible = layer = = 0 ;
armor - > hair - > visible = layer = = 0 ;
armor - > body - > visible = layer = = 1 | | layer = = 2 ;
armor - > arm0 - > visible = layer = = 1 ;
armor - > arm1 - > visible = layer = = 1 ;
armor - > leg0 - > visible = layer = = 2 | | layer = = 3 ;
armor - > leg1 - > visible = layer = = 2 | | layer = = 3 ;
setArmor ( armor ) ;
2026-03-08 19:08:36 -04:00
if ( armor ! = nullptr ) armor - > attackTime = model - > attackTime ;
if ( armor ! = nullptr ) armor - > riding = model - > riding ;
if ( armor ! = nullptr ) armor - > young = model - > young ;
2026-03-01 12:16:08 +08:00
float brightness = SharedConstants : : TEXTURE_LIGHTING ? 1 : player - > getBrightness ( a ) ;
if ( armorItem - > getMaterial ( ) = = ArmorItem : : ArmorMaterial : : CLOTH )
{
int color = armorItem - > getColor ( itemInstance ) ;
2026-03-08 19:08:36 -04:00
float red = static_cast < float > ( ( color > > 16 ) & 0xFF ) / 0xFF ;
float green = static_cast < float > ( ( color > > 8 ) & 0xFF ) / 0xFF ;
float blue = static_cast < float > ( color & 0xFF ) / 0xFF ;
2026-03-01 12:16:08 +08:00
glColor3f ( brightness * red , brightness * green , brightness * blue ) ;
if ( itemInstance - > isEnchanted ( ) ) return 0x1f ;
return 0x10 ;
}
else
{
glColor3f ( brightness , brightness , brightness ) ;
}
if ( itemInstance - > isEnchanted ( ) ) return 0xf ;
return 1 ;
}
}
return - 1 ;
}
2026-03-03 03:04:10 +08:00
void PlayerRenderer : : prepareSecondPassArmor ( shared_ptr < LivingEntity > _player , int layer , float a )
2026-03-01 12:16:08 +08:00
{
// 4J - dynamic cast required because we aren't using templates/generics in our version
2026-03-02 17:37:16 +07:00
shared_ptr < Player > player = dynamic_pointer_cast < Player > ( _player ) ;
shared_ptr < ItemInstance > itemInstance = player - > inventory - > getArmor ( 3 - layer ) ;
2026-03-08 19:08:36 -04:00
if ( itemInstance ! = nullptr )
2026-03-01 12:16:08 +08:00
{
Item * item = itemInstance - > getItem ( ) ;
if ( dynamic_cast < ArmorItem * > ( item ) )
{
ArmorItem * armorItem = dynamic_cast < ArmorItem * > ( item ) ;
2026-03-08 19:08:36 -04:00
bindTexture ( HumanoidMobRenderer : : getArmorLocation ( static_cast < ArmorItem * > ( item ) , layer , true ) ) ;
2026-03-01 12:16:08 +08:00
float brightness = SharedConstants : : TEXTURE_LIGHTING ? 1 : player - > getBrightness ( a ) ;
glColor3f ( brightness , brightness , brightness ) ;
}
}
}
2026-03-02 17:37:16 +07:00
void PlayerRenderer : : render ( shared_ptr < Entity > _mob , double x , double y , double z , float rot , float a )
2026-03-01 12:16:08 +08:00
{
2026-03-08 19:08:36 -04:00
if ( _mob = = nullptr )
{
return ;
}
2026-03-01 12:16:08 +08:00
// 4J - dynamic cast required because we aren't using templates/generics in our version
2026-03-02 17:37:16 +07:00
shared_ptr < Player > mob = dynamic_pointer_cast < Player > ( _mob ) ;
2026-03-01 12:16:08 +08:00
2026-03-08 19:08:36 -04:00
if ( mob = = nullptr ) return ;
2026-03-01 12:16:08 +08:00
if ( mob - > hasInvisiblePrivilege ( ) ) return ;
2026-03-02 17:37:16 +07:00
shared_ptr < ItemInstance > item = mob - > inventory - > getSelected ( ) ;
2026-03-08 19:08:36 -04:00
armorParts1 - > holdingRightHand = armorParts2 - > holdingRightHand = humanoidModel - > holdingRightHand = item ! = nullptr ? 1 : 0 ;
if ( item ! = nullptr )
2026-03-01 12:16:08 +08:00
{
if ( mob - > getUseItemDuration ( ) > 0 )
{
UseAnim anim = item - > getUseAnimation ( ) ;
if ( anim = = UseAnim_block )
{
armorParts1 - > holdingRightHand = armorParts2 - > holdingRightHand = humanoidModel - > holdingRightHand = 3 ;
}
else if ( anim = = UseAnim_bow )
{
armorParts1 - > bowAndArrow = armorParts2 - > bowAndArrow = humanoidModel - > bowAndArrow = true ;
}
}
}
// 4J added, for 3rd person view of eating
2026-03-08 19:08:36 -04:00
if ( item ! = nullptr & & mob - > getUseItemDuration ( ) > 0 & & item - > getUseAnimation ( ) = = UseAnim_eat )
2026-03-01 12:16:08 +08:00
{
// These factors are largely lifted from ItemInHandRenderer to try and keep the 3rd person eating animation as similar as possible
float t = ( mob - > getUseItemDuration ( ) - a + 1 ) ;
float swing = 1 - ( t / item - > getUseDuration ( ) ) ;
armorParts1 - > eating = armorParts2 - > eating = humanoidModel - > eating = true ;
armorParts1 - > eating_t = armorParts2 - > eating_t = humanoidModel - > eating_t = t ;
armorParts1 - > eating_swing = armorParts2 - > eating_swing = humanoidModel - > eating_swing = swing ;
}
else
{
armorParts1 - > eating = armorParts2 - > eating = humanoidModel - > eating = false ;
}
armorParts1 - > sneaking = armorParts2 - > sneaking = humanoidModel - > sneaking = mob - > isSneaking ( ) ;
double yp = y - mob - > heightOffset ;
2026-04-02 17:16:31 -05:00
if ( mob - > isSneaking ( ) )
2026-03-01 12:16:08 +08:00
{
yp - = 2 / 16.0f ;
}
2026-04-02 17:16:31 -05:00
if ( mob - > getAnimOverrideBitmask ( ) & ( 1 < < HumanoidModel : : eAnim_SmallModel ) )
{
if ( mob - > isRiding ( ) )
{
std : : shared_ptr < Entity > ridingEntity = mob - > riding ;
if ( ridingEntity ! = nullptr ) // Safety check;
{
if ( ridingEntity - > instanceof ( eTYPE_BOAT ) )
{
yp + = 0.25f ; // reverts the change in Boat.cpp for smaller models.
}
}
}
}
2026-03-01 12:16:08 +08:00
// Check if an idle animation is needed
if ( mob - > getAnimOverrideBitmask ( ) & ( 1 < < HumanoidModel : : eAnim_HasIdle ) )
{
if ( mob - > isIdle ( ) )
{
humanoidModel - > idle = true ;
armorParts1 - > idle = true ;
armorParts2 - > idle = true ;
}
else
{
humanoidModel - > idle = false ;
armorParts1 - > idle = false ;
armorParts2 - > idle = false ;
}
}
else
{
humanoidModel - > idle = false ;
armorParts1 - > idle = false ;
armorParts2 - > idle = false ;
}
// 4J-PB - any additional parts to turn on for this player (skin dependent)
vector < ModelPart * > * pAdditionalModelParts = mob - > GetAdditionalModelParts ( ) ;
//turn them on
2026-03-06 02:11:18 +07:00
if ( pAdditionalModelParts ! = nullptr )
2026-03-01 12:16:08 +08:00
{
2026-03-06 02:11:18 +07:00
for ( ModelPart * pModelPart : * pAdditionalModelParts )
2026-03-01 12:16:08 +08:00
{
pModelPart - > visible = true ;
}
}
2026-03-03 03:04:10 +08:00
LivingEntityRenderer : : render ( mob , x , yp , z , rot , a ) ;
2026-03-01 12:16:08 +08:00
// turn them off again
if ( pAdditionalModelParts & & pAdditionalModelParts - > size ( ) ! = 0 )
{
2026-03-06 02:11:18 +07:00
for ( ModelPart * pModelPart : * pAdditionalModelParts )
2026-03-01 12:16:08 +08:00
{
pModelPart - > visible = false ;
}
}
armorParts1 - > bowAndArrow = armorParts2 - > bowAndArrow = humanoidModel - > bowAndArrow = false ;
armorParts1 - > sneaking = armorParts2 - > sneaking = humanoidModel - > sneaking = false ;
armorParts1 - > holdingRightHand = armorParts2 - > holdingRightHand = humanoidModel - > holdingRightHand = 0 ;
}
2026-03-03 03:04:10 +08:00
void PlayerRenderer : : additionalRendering ( shared_ptr < LivingEntity > _mob , float a )
2026-03-01 12:16:08 +08:00
{
2026-03-03 03:04:10 +08:00
float brightness = SharedConstants : : TEXTURE_LIGHTING ? 1 : _mob - > getBrightness ( a ) ;
glColor3f ( brightness , brightness , brightness ) ;
2026-03-01 12:16:08 +08:00
2026-03-03 03:04:10 +08:00
LivingEntityRenderer : : additionalRendering ( _mob , a ) ;
LivingEntityRenderer : : renderArrows ( _mob , a ) ;
2026-03-01 12:16:08 +08:00
// 4J - dynamic cast required because we aren't using templates/generics in our version
2026-03-02 17:37:16 +07:00
shared_ptr < Player > mob = dynamic_pointer_cast < Player > ( _mob ) ;
2026-03-01 12:16:08 +08:00
2026-03-02 17:37:16 +07:00
shared_ptr < ItemInstance > headGear = mob - > inventory - > getArmor ( 3 ) ;
2026-03-08 19:08:36 -04:00
if ( headGear ! = nullptr )
2026-03-01 12:16:08 +08:00
{
// don't render the pumpkin for the skins
unsigned int uiAnimOverrideBitmask = mob - > getSkinAnimOverrideBitmask ( mob - > getCustomSkin ( ) ) ;
if ( ( uiAnimOverrideBitmask & ( 1 < < HumanoidModel : : eAnim_DontRenderArmour ) ) = = 0 )
{
glPushMatrix ( ) ;
humanoidModel - > head - > translateTo ( 1 / 16.0f ) ;
if ( headGear - > getItem ( ) - > id < 256 )
{
if ( TileRenderer : : canRender ( Tile : : tiles [ headGear - > id ] - > getRenderShape ( ) ) )
{
float s = 10 / 16.0f ;
glTranslatef ( - 0 / 16.0f , - 4 / 16.0f , 0 / 16.0f ) ;
glRotatef ( 90 , 0 , 1 , 0 ) ;
glScalef ( s , - s , s ) ;
}
2026-03-03 03:04:10 +08:00
entityRenderDispatcher - > itemInHandRenderer - > renderItem ( mob , headGear , 0 ) ;
2026-03-01 12:16:08 +08:00
}
else if ( headGear - > getItem ( ) - > id = = Item : : skull_Id )
{
float s = 17 / 16.0f ;
glScalef ( s , - s , - s ) ;
wstring extra = L " " ;
if ( headGear - > hasTag ( ) & & headGear - > getTag ( ) - > contains ( L " SkullOwner " ) )
{
extra = headGear - > getTag ( ) - > getString ( L " SkullOwner " ) ;
}
SkullTileRenderer : : instance - > renderSkull ( - 0.5f , 0 , - 0.5f , Facing : : UP , 180 , headGear - > getAuxValue ( ) , extra ) ;
}
glPopMatrix ( ) ;
}
}
// need to add a custom texture for deadmau5
2026-03-08 19:08:36 -04:00
if ( mob ! = nullptr & & app . isXuidDeadmau5 ( mob - > getXuid ( ) ) & & bindTexture ( mob - > customTextureUrl , L " " ) )
2026-03-01 12:16:08 +08:00
{
for ( int i = 0 ; i < 2 ; i + + )
{
float yr = ( mob - > yRotO + ( mob - > yRot - mob - > yRotO ) * a ) - ( mob - > yBodyRotO + ( mob - > yBodyRot - mob - > yBodyRotO ) * a ) ;
float xr = mob - > xRotO + ( mob - > xRot - mob - > xRotO ) * a ;
glPushMatrix ( ) ;
glRotatef ( yr , 0 , 1 , 0 ) ;
glRotatef ( xr , 1 , 0 , 0 ) ;
glTranslatef ( ( 6 / 16.0f ) * ( i * 2 - 1 ) , 0 , 0 ) ;
glTranslatef ( 0 , - 6 / 16.0f , 0 ) ;
glRotatef ( - xr , 1 , 0 , 0 ) ;
glRotatef ( - yr , 0 , 1 , 0 ) ;
float s = 8 / 6.0f ;
glScalef ( s , s , s ) ;
humanoidModel - > renderEars ( 1 / 16.0f , true ) ;
glPopMatrix ( ) ;
}
}
2026-03-03 03:04:10 +08:00
// 4J: removed
/*boolean loaded = mob->getCloakTexture()->isLoaded();
boolean b1 = ! mob - > isInvisible ( ) ;
boolean b2 = ! mob - > isCapeHidden ( ) ; */
if ( bindTexture ( mob - > customTextureUrl2 , L " " ) & & ! mob - > isInvisible ( ) )
2026-03-01 12:16:08 +08:00
{
glPushMatrix ( ) ;
glTranslatef ( 0 , 0 , 2 / 16.0f ) ;
double xd = ( mob - > xCloakO + ( mob - > xCloak - mob - > xCloakO ) * a ) - ( mob - > xo + ( mob - > x - mob - > xo ) * a ) ;
double yd = ( mob - > yCloakO + ( mob - > yCloak - mob - > yCloakO ) * a ) - ( mob - > yo + ( mob - > y - mob - > yo ) * a ) ;
double zd = ( mob - > zCloakO + ( mob - > zCloak - mob - > zCloakO ) * a ) - ( mob - > zo + ( mob - > z - mob - > zo ) * a ) ;
float yr = mob - > yBodyRotO + ( mob - > yBodyRot - mob - > yBodyRotO ) * a ;
double xa = Mth : : sin ( yr * PI / 180 ) ;
double za = - Mth : : cos ( yr * PI / 180 ) ;
2026-03-08 19:08:36 -04:00
float flap = static_cast < float > ( yd ) * 10 ;
2026-03-01 12:16:08 +08:00
if ( flap < - 6 ) flap = - 6 ;
if ( flap > 32 ) flap = 32 ;
2026-03-08 19:08:36 -04:00
float lean = static_cast < float > ( xd * xa + zd * za ) * 100 ;
float lean2 = static_cast < float > ( xd * za - zd * xa ) * 100 ;
2026-03-01 12:16:08 +08:00
if ( lean < 0 ) lean = 0 ;
float pow = mob - > oBob + ( mob - > bob - mob - > oBob ) * a ;
flap + = sin ( ( mob - > walkDistO + ( mob - > walkDist - mob - > walkDistO ) * a ) * 6 ) * 32 * pow ;
if ( mob - > isSneaking ( ) )
{
flap + = 25 ;
}
// 4J Stu - Fix for sprint-flying causing the cape to rotate up by 180 degrees or more
float xRot = 6.0f + lean / 2 + flap ;
if ( xRot > 64.0f ) xRot = 64.0f ;
glRotatef ( xRot , 1 , 0 , 0 ) ;
glRotatef ( lean2 / 2 , 0 , 0 , 1 ) ;
glRotatef ( - lean2 / 2 , 0 , 1 , 0 ) ;
glRotatef ( 180 , 0 , 1 , 0 ) ;
humanoidModel - > renderCloak ( 1 / 16.0f , true ) ;
glPopMatrix ( ) ;
}
2026-03-06 02:11:18 +07:00
2026-03-02 17:37:16 +07:00
shared_ptr < ItemInstance > item = mob - > inventory - > getSelected ( ) ;
2026-03-01 12:16:08 +08:00
2026-03-08 19:08:36 -04:00
if ( item ! = nullptr )
2026-03-01 12:16:08 +08:00
{
glPushMatrix ( ) ;
humanoidModel - > arm0 - > translateTo ( 1 / 16.0f ) ;
glTranslatef ( - 1 / 16.0f , 7 / 16.0f , 1 / 16.0f ) ;
2026-03-08 19:08:36 -04:00
if ( mob - > fishing ! = nullptr )
2026-03-01 12:16:08 +08:00
{
2026-03-08 19:08:36 -04:00
item = std : : make_shared < ItemInstance > ( Item : : stick ) ;
2026-03-01 12:16:08 +08:00
}
UseAnim anim = UseAnim_none ; //null;
if ( mob - > getUseItemDuration ( ) > 0 )
{
anim = item - > getUseAnimation ( ) ;
}
if ( item - > id < 256 & & TileRenderer : : canRender ( Tile : : tiles [ item - > id ] - > getRenderShape ( ) ) )
{
float s = 8 / 16.0f ;
glTranslatef ( - 0 / 16.0f , 3 / 16.0f , - 5 / 16.0f ) ;
s * = 0.75f ;
glRotatef ( 20 , 1 , 0 , 0 ) ;
glRotatef ( 45 , 0 , 1 , 0 ) ;
2026-03-03 03:04:10 +08:00
glScalef ( - s , - s , s ) ;
2026-03-01 12:16:08 +08:00
}
else if ( item - > id = = Item : : bow - > id )
{
float s = 10 / 16.0f ;
glTranslatef ( 0 / 16.0f , 2 / 16.0f , 5 / 16.0f ) ;
glRotatef ( - 20 , 0 , 1 , 0 ) ;
glScalef ( s , - s , s ) ;
glRotatef ( - 100 , 1 , 0 , 0 ) ;
glRotatef ( 45 , 0 , 1 , 0 ) ;
}
else if ( Item : : items [ item - > id ] - > isHandEquipped ( ) )
{
float s = 10 / 16.0f ;
if ( Item : : items [ item - > id ] - > isMirroredArt ( ) )
{
glRotatef ( 180 , 0 , 0 , 1 ) ;
glTranslatef ( 0 , - 2 / 16.0f , 0 ) ;
}
if ( mob - > getUseItemDuration ( ) > 0 )
{
if ( anim = = UseAnim_block )
{
glTranslatef ( 0.05f , 0 , - 0.1f ) ;
glRotatef ( - 50 , 0 , 1 , 0 ) ;
glRotatef ( - 10 , 1 , 0 , 0 ) ;
glRotatef ( - 60 , 0 , 0 , 1 ) ;
}
}
glTranslatef ( 0 , 3 / 16.0f , 0 ) ;
glScalef ( s , - s , s ) ;
glRotatef ( - 100 , 1 , 0 , 0 ) ;
glRotatef ( 45 , 0 , 1 , 0 ) ;
}
else
{
float s = 6 / 16.0f ;
glTranslatef ( + 4 / 16.0f , + 3 / 16.0f , - 3 / 16.0f ) ;
glScalef ( s , s , s ) ;
glRotatef ( 60 , 0 , 0 , 1 ) ;
glRotatef ( - 90 , 1 , 0 , 0 ) ;
glRotatef ( 20 , 0 , 0 , 1 ) ;
}
if ( item - > getItem ( ) - > hasMultipleSpriteLayers ( ) )
{
for ( int layer = 0 ; layer < = 1 ; layer + + )
{
int col = item - > getItem ( ) - > getColor ( item , layer ) ;
float red = ( ( col > > 16 ) & 0xff ) / 255.0f ;
float g = ( ( col > > 8 ) & 0xff ) / 255.0f ;
float b = ( ( col ) & 0xff ) / 255.0f ;
glColor4f ( red , g , b , 1 ) ;
this - > entityRenderDispatcher - > itemInHandRenderer - > renderItem ( mob , item , layer , false ) ;
}
}
else
{
2026-03-03 03:04:10 +08:00
int col = item - > getItem ( ) - > getColor ( item , 0 ) ;
float red = ( ( col > > 16 ) & 0xff ) / 255.0f ;
float g = ( ( col > > 8 ) & 0xff ) / 255.0f ;
float b = ( ( col ) & 0xff ) / 255.0f ;
glColor4f ( red , g , b , 1 ) ;
2026-03-01 12:16:08 +08:00
this - > entityRenderDispatcher - > itemInHandRenderer - > renderItem ( mob , item , 0 ) ;
}
glPopMatrix ( ) ;
2026-03-03 03:04:10 +08:00
}
}
void PlayerRenderer : : renderNameTags ( shared_ptr < LivingEntity > player , double x , double y , double z , wstring msg , float scale , double dist )
{
#if 0
if ( dist < 10 * 10 )
{
Scoreboard * scoreboard = player - > getScoreboard ( ) ;
Objective * objective = scoreboard - > getDisplayObjective ( Scoreboard : : DISPLAY_SLOT_BELOW_NAME ) ;
2026-03-08 19:08:36 -04:00
if ( objective ! = nullptr )
2026-03-03 03:04:10 +08:00
{
Score * score = scoreboard - > getPlayerScore ( player - > getAName ( ) , objective ) ;
if ( player - > isSleeping ( ) )
{
renderNameTag ( player , score - > getScore ( ) + " " + objective - > getDisplayName ( ) , x , y - 1.5f , z , 64 ) ;
}
else
{
renderNameTag ( player , score - > getScore ( ) + " " + objective - > getDisplayName ( ) , x , y , z , 64 ) ;
}
y + = getFont ( ) - > lineHeight * 1.15f * scale ;
}
2026-03-01 12:16:08 +08:00
}
2026-03-03 03:04:10 +08:00
# endif
2026-03-01 12:16:08 +08:00
2026-03-03 03:04:10 +08:00
LivingEntityRenderer : : renderNameTags ( player , x , y , z , msg , scale , dist ) ;
2026-03-01 12:16:08 +08:00
}
2026-03-03 03:04:10 +08:00
void PlayerRenderer : : scale ( shared_ptr < LivingEntity > player , float a )
2026-03-01 12:16:08 +08:00
{
float s = 15 / 16.0f ;
glScalef ( s , s , s ) ;
}
void PlayerRenderer : : renderHand ( )
{
2026-03-03 03:04:10 +08:00
float brightness = 1 ;
glColor3f ( brightness , brightness , brightness ) ;
2026-03-01 12:16:08 +08:00
humanoidModel - > m_uiAnimOverrideBitmask = Minecraft : : GetInstance ( ) - > player - > getAnimOverrideBitmask ( ) ;
armorParts1 - > eating = armorParts2 - > eating = humanoidModel - > eating = humanoidModel - > idle = false ;
humanoidModel - > attackTime = 0 ;
2026-03-03 03:04:10 +08:00
humanoidModel - > setupAnim ( 0 , 0 , 0 , 0 , 0 , 1 / 16.0f , Minecraft : : GetInstance ( ) - > player ) ;
2026-03-01 12:16:08 +08:00
// 4J-PB - does this skin have its arm0 disabled? (Dalek, etc)
if ( ( humanoidModel - > m_uiAnimOverrideBitmask & ( 1 < < HumanoidModel : : eAnim_DisableRenderArm0 ) ) = = 0 )
{
humanoidModel - > arm0 - > render ( 1 / 16.0f , true ) ;
}
2026-03-28 13:44:27 -06:00
//Render custom skin boxes on viewmodel - Botch
vector < ModelPart * > * additionalModelParts = Minecraft : : GetInstance ( ) - > player - > GetAdditionalModelParts ( ) ;
if ( ! additionalModelParts ) return ; //If there are no custom boxes, return. This fixes bug where the game will crash if you select a skin with no additional boxes.
vector < ModelPart * > armchildren = humanoidModel - > arm0 - > children ;
std : : unordered_set < ModelPart * > additionalModelPartSet ( additionalModelParts - > begin ( ) , additionalModelParts - > end ( ) ) ;
for ( const auto & x : armchildren ) {
if ( x ) {
if ( additionalModelPartSet . find ( x ) ! = additionalModelPartSet . end ( ) ) { //This is to verify box is still actually on current skin - Botch
glPushMatrix ( ) ;
//We need to transform to match offset of arm - Botch
glTranslatef ( - 5 * 0.0625f , 2 * 0.0625f , 0 ) ;
glRotatef ( 0.1 * ( 180.0f / PI ) , 0 , 0 , 1 ) ;
x - > visible = true ;
x - > render ( 1.0f / 16.0f , true ) ;
x - > visible = false ;
glPopMatrix ( ) ;
}
}
}
2026-03-01 12:16:08 +08:00
}
2026-03-03 03:04:10 +08:00
void PlayerRenderer : : setupPosition ( shared_ptr < LivingEntity > _mob , double x , double y , double z )
2026-03-01 12:16:08 +08:00
{
// 4J - dynamic cast required because we aren't using templates/generics in our version
2026-03-02 17:37:16 +07:00
shared_ptr < Player > mob = dynamic_pointer_cast < Player > ( _mob ) ;
2026-03-01 12:16:08 +08:00
if ( mob - > isAlive ( ) & & mob - > isSleeping ( ) )
{
2026-03-03 03:04:10 +08:00
LivingEntityRenderer : : setupPosition ( mob , x + mob - > bedOffsetX , y + mob - > bedOffsetY , z + mob - > bedOffsetZ ) ;
2026-03-01 12:16:08 +08:00
}
else
{
2026-03-03 03:04:10 +08:00
if ( mob - > isRiding ( ) & & ( mob - > getAnimOverrideBitmask ( ) & ( 1 < < HumanoidModel : : eAnim_SmallModel ) ) ! = 0 )
{
y + = 0.5f ;
}
LivingEntityRenderer : : setupPosition ( mob , x , y , z ) ;
2026-03-01 12:16:08 +08:00
}
}
2026-03-03 03:04:10 +08:00
void PlayerRenderer : : setupRotations ( shared_ptr < LivingEntity > _mob , float bob , float bodyRot , float a )
2026-03-01 12:16:08 +08:00
{
// 4J - dynamic cast required because we aren't using templates/generics in our version
2026-03-02 17:37:16 +07:00
shared_ptr < Player > mob = dynamic_pointer_cast < Player > ( _mob ) ;
2026-03-01 12:16:08 +08:00
if ( mob - > isAlive ( ) & & mob - > isSleeping ( ) )
{
glRotatef ( mob - > getSleepRotation ( ) , 0 , 1 , 0 ) ;
glRotatef ( getFlipDegrees ( mob ) , 0 , 0 , 1 ) ;
glRotatef ( 270 , 0 , 1 , 0 ) ;
}
else
{
2026-03-03 03:04:10 +08:00
LivingEntityRenderer : : setupRotations ( mob , bob , bodyRot , a ) ;
2026-03-01 12:16:08 +08:00
}
}
// 4J Added override to stop rendering shadow if player is invisible
2026-03-02 17:37:16 +07:00
void PlayerRenderer : : renderShadow ( shared_ptr < Entity > e , double x , double y , double z , float pow , float a )
2026-03-01 12:16:08 +08:00
{
if ( app . GetGameHostOption ( eGameHostOption_HostCanBeInvisible ) > 0 )
{
2026-03-02 17:37:16 +07:00
shared_ptr < Player > player = dynamic_pointer_cast < Player > ( e ) ;
2026-03-08 19:08:36 -04:00
if ( player ! = nullptr & & player - > hasInvisiblePrivilege ( ) ) return ;
2026-03-01 12:16:08 +08:00
}
EntityRenderer : : renderShadow ( e , x , y , z , pow , a ) ;
}
2026-03-03 03:04:10 +08:00
// 4J Added override
void PlayerRenderer : : bindTexture ( shared_ptr < Entity > entity )
{
shared_ptr < Player > player = dynamic_pointer_cast < Player > ( entity ) ;
bindTexture ( player - > customTextureUrl , player - > getTexture ( ) ) ;
}
ResourceLocation * PlayerRenderer : : getTextureLocation ( shared_ptr < Entity > entity )
{
shared_ptr < Player > player = dynamic_pointer_cast < Player > ( entity ) ;
2026-03-08 19:08:36 -04:00
return new ResourceLocation ( static_cast < _TEXTURE_NAME > ( player - > getTexture ( ) ) ) ;
2026-03-28 13:44:27 -06:00
}