@@ -774,8 +774,8 @@ class GameGlobalShaderConstantSetterFactory : public IShaderConstantSetterFactor
774774};
775775
776776
777- bool nodePlacementPrediction (Client &client,
778- const ItemDefinition &playeritem_def , v3s16 nodepos, v3s16 neighbourpos)
777+ bool nodePlacementPrediction (Client &client, const ItemDefinition &playeritem_def,
778+ const ItemStack &playeritem , v3s16 nodepos, v3s16 neighbourpos)
779779{
780780 std::string prediction = playeritem_def.node_placement_prediction ;
781781 INodeDefManager *nodedef = client.ndef ();
@@ -818,11 +818,13 @@ bool nodePlacementPrediction(Client &client,
818818 return false ;
819819 }
820820
821+ const ContentFeatures &predicted_f = nodedef->get (id);
822+
821823 // Predict param2 for facedir and wallmounted nodes
822824 u8 param2 = 0 ;
823825
824- if (nodedef-> get (id) .param_type_2 == CPT2_WALLMOUNTED ||
825- nodedef-> get (id) .param_type_2 == CPT2_COLORED_WALLMOUNTED) {
826+ if (predicted_f .param_type_2 == CPT2_WALLMOUNTED ||
827+ predicted_f .param_type_2 == CPT2_COLORED_WALLMOUNTED) {
826828 v3s16 dir = nodepos - neighbourpos;
827829
828830 if (abs (dir.Y ) > MYMAX (abs (dir.X ), abs (dir.Z ))) {
@@ -834,8 +836,8 @@ bool nodePlacementPrediction(Client &client,
834836 }
835837 }
836838
837- if (nodedef-> get (id) .param_type_2 == CPT2_FACEDIR ||
838- nodedef-> get (id) .param_type_2 == CPT2_COLORED_FACEDIR) {
839+ if (predicted_f .param_type_2 == CPT2_FACEDIR ||
840+ predicted_f .param_type_2 == CPT2_COLORED_FACEDIR) {
839841 v3s16 dir = nodepos - floatToInt (client.getEnv ().getLocalPlayer ()->getPosition (), BS);
840842
841843 if (abs (dir.X ) > abs (dir.Z )) {
@@ -848,7 +850,7 @@ bool nodePlacementPrediction(Client &client,
848850 assert (param2 <= 5 );
849851
850852 // Check attachment if node is in group attached_node
851- if (((ItemGroupList) nodedef-> get (id) .groups )[" attached_node" ] != 0 ) {
853+ if (((ItemGroupList) predicted_f .groups )[" attached_node" ] != 0 ) {
852854 static v3s16 wallmounted_dirs[8 ] = {
853855 v3s16 (0 , 1 , 0 ),
854856 v3s16 (0 , -1 , 0 ),
@@ -859,8 +861,8 @@ bool nodePlacementPrediction(Client &client,
859861 };
860862 v3s16 pp;
861863
862- if (nodedef-> get (id) .param_type_2 == CPT2_WALLMOUNTED ||
863- nodedef-> get (id) .param_type_2 == CPT2_COLORED_WALLMOUNTED)
864+ if (predicted_f .param_type_2 == CPT2_WALLMOUNTED ||
865+ predicted_f .param_type_2 == CPT2_COLORED_WALLMOUNTED)
864866 pp = p + wallmounted_dirs[param2];
865867 else
866868 pp = p + v3s16 (0 , -1 , 0 );
@@ -869,6 +871,28 @@ bool nodePlacementPrediction(Client &client,
869871 return false ;
870872 }
871873
874+ // Apply color
875+ if ((predicted_f.param_type_2 == CPT2_COLOR
876+ || predicted_f.param_type_2 == CPT2_COLORED_FACEDIR
877+ || predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED)) {
878+ const std::string &indexstr = playeritem.metadata .getString (
879+ " palette_index" , 0 );
880+ if (!indexstr.empty ()) {
881+ s32 index = mystoi (indexstr);
882+ if (predicted_f.param_type_2 == CPT2_COLOR) {
883+ param2 = index;
884+ } else if (predicted_f.param_type_2
885+ == CPT2_COLORED_WALLMOUNTED) {
886+ // param2 = pure palette index + other
887+ param2 = (index & 0xf8 ) | (param2 & 0x07 );
888+ } else if (predicted_f.param_type_2
889+ == CPT2_COLORED_FACEDIR) {
890+ // param2 = pure palette index + other
891+ param2 = (index & 0xe0 ) | (param2 & 0x1f );
892+ }
893+ }
894+ }
895+
872896 // Add node to client map
873897 MapNode n (id, 0 , param2);
874898
@@ -1277,8 +1301,9 @@ class Game {
12771301 const core::line3d<f32 > &shootline, bool liquids_pointable,
12781302 bool look_for_object, const v3s16 &camera_offset);
12791303 void handlePointingAtNothing (const ItemStack &playerItem);
1280- void handlePointingAtNode (const PointedThing &pointed, const ItemDefinition &playeritem_def,
1281- const ToolCapabilities &playeritem_toolcap, f32 dtime);
1304+ void handlePointingAtNode (const PointedThing &pointed,
1305+ const ItemDefinition &playeritem_def, const ItemStack &playeritem,
1306+ const ToolCapabilities &playeritem_toolcap, f32 dtime);
12821307 void handlePointingAtObject (const PointedThing &pointed, const ItemStack &playeritem,
12831308 const v3f &player_position, bool show_debug);
12841309 void handleDigging (const PointedThing &pointed, const v3s16 &nodepos,
@@ -3599,7 +3624,8 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
35993624 if (playeritem.name .empty () && hand_def.tool_capabilities != NULL ) {
36003625 playeritem_toolcap = *hand_def.tool_capabilities ;
36013626 }
3602- handlePointingAtNode (pointed, playeritem_def, playeritem_toolcap, dtime);
3627+ handlePointingAtNode (pointed, playeritem_def, playeritem,
3628+ playeritem_toolcap, dtime);
36033629 } else if (pointed.type == POINTEDTHING_OBJECT) {
36043630 handlePointingAtObject (pointed, playeritem, player_position, show_debug);
36053631 } else if (isLeftPressed ()) {
@@ -3734,8 +3760,9 @@ void Game::handlePointingAtNothing(const ItemStack &playerItem)
37343760}
37353761
37363762
3737- void Game::handlePointingAtNode (const PointedThing &pointed, const ItemDefinition &playeritem_def,
3738- const ToolCapabilities &playeritem_toolcap, f32 dtime)
3763+ void Game::handlePointingAtNode (const PointedThing &pointed,
3764+ const ItemDefinition &playeritem_def, const ItemStack &playeritem,
3765+ const ToolCapabilities &playeritem_toolcap, f32 dtime)
37393766{
37403767 v3s16 nodepos = pointed.node_undersurface ;
37413768 v3s16 neighbourpos = pointed.node_abovesurface ;
@@ -3795,7 +3822,7 @@ void Game::handlePointingAtNode(const PointedThing &pointed, const ItemDefinitio
37953822 // If the wielded item has node placement prediction,
37963823 // make that happen
37973824 bool placed = nodePlacementPrediction (*client,
3798- playeritem_def,
3825+ playeritem_def, playeritem,
37993826 nodepos, neighbourpos);
38003827
38013828 if (placed) {
0 commit comments