Predict wallmounted param2 during node placement prediction.

Also clean up the_game a bit: move node placement prediction to a
separate function.
This commit is contained in:
Kahrl 2013-04-27 03:47:52 +02:00 committed by PilzAdam
parent be4cc306a5
commit 777ac58f85
1 changed files with 68 additions and 44 deletions

View File

@ -789,6 +789,65 @@ public:
} }
}; };
void nodePlacementPrediction(Client &client,
const ItemDefinition &playeritem_def,
v3s16 nodepos, v3s16 neighbourpos)
{
std::string prediction = playeritem_def.node_placement_prediction;
INodeDefManager *nodedef = client.ndef();
ClientMap &map = client.getEnv().getClientMap();
if(prediction != "" && !nodedef->get(map.getNode(nodepos)).rightclickable)
{
verbosestream<<"Node placement prediction for "
<<playeritem_def.name<<" is "
<<prediction<<std::endl;
v3s16 p = neighbourpos;
// Place inside node itself if buildable_to
try{
MapNode n_under = map.getNode(nodepos);
if(nodedef->get(n_under).buildable_to)
p = nodepos;
}catch(InvalidPositionException &e){}
// Find id of predicted node
content_t id;
bool found = nodedef->getId(prediction, id);
if(!found){
errorstream<<"Node placement prediction failed for "
<<playeritem_def.name<<" (places "
<<prediction
<<") - Name not known"<<std::endl;
return;
}
// Predict param2
u8 param2 = 0;
if(nodedef->get(id).param_type_2 == CPT2_WALLMOUNTED){
v3s16 dir = nodepos - neighbourpos;
if(abs(dir.Y) > MYMAX(abs(dir.X), abs(dir.Z))){
param2 = dir.Y < 0 ? 1 : 0;
} else if(abs(dir.X) > abs(dir.Z)){
param2 = dir.X < 0 ? 3 : 2;
} else {
param2 = dir.Z < 0 ? 5 : 4;
}
}
// TODO: Facedir prediction
// TODO: If predicted node is in attached_node group, check attachment
// Add node to client map
MapNode n(id, 0, param2);
try{
// This triggers the required mesh update too
client.addNode(p, n);
}catch(InvalidPositionException &e){
errorstream<<"Node placement prediction failed for "
<<playeritem_def.name<<" (places "
<<prediction
<<") - Position not loaded"<<std::endl;
}
}
}
void the_game( void the_game(
bool &kill, bool &kill,
bool random_input, bool random_input,
@ -2198,17 +2257,15 @@ void the_game(
- Can it point to liquids? - Can it point to liquids?
*/ */
ItemStack playeritem; ItemStack playeritem;
bool playeritem_usable = false;
bool playeritem_liquids_pointable = false;
{ {
InventoryList *mlist = local_inventory.getList("main"); InventoryList *mlist = local_inventory.getList("main");
if(mlist != NULL) if(mlist != NULL)
{ {
playeritem = mlist->getItem(client.getPlayerItem()); playeritem = mlist->getItem(client.getPlayerItem());
playeritem_usable = playeritem.getDefinition(itemdef).usable;
playeritem_liquids_pointable = playeritem.getDefinition(itemdef).liquids_pointable;
} }
} }
const ItemDefinition &playeritem_def =
playeritem.getDefinition(itemdef);
ToolCapabilities playeritem_toolcap = ToolCapabilities playeritem_toolcap =
playeritem.getToolCapabilities(itemdef); playeritem.getToolCapabilities(itemdef);
@ -2267,7 +2324,7 @@ void the_game(
// input // input
&client, player_position, camera_direction, &client, player_position, camera_direction,
camera_position, shootline, d, camera_position, shootline, d,
playeritem_liquids_pointable, !ldown_for_dig, playeritem_def.liquids_pointable, !ldown_for_dig,
// output // output
hilightboxes, hilightboxes,
selected_object); selected_object);
@ -2327,7 +2384,7 @@ void the_game(
else else
repeat_rightclick_timer = 0; repeat_rightclick_timer = 0;
if(playeritem_usable && input->getLeftState()) if(playeritem_def.usable && input->getLeftState())
{ {
if(input->getLeftClicked()) if(input->getLeftClicked())
client.interact(4, pointed); client.interact(4, pointed);
@ -2534,46 +2591,13 @@ void the_game(
// If the wielded item has node placement prediction, // If the wielded item has node placement prediction,
// make that happen // make that happen
const ItemDefinition &def = nodePlacementPrediction(client,
playeritem.getDefinition(itemdef); playeritem_def,
if(def.node_placement_prediction != "" nodepos, neighbourpos);
&& !nodedef->get(map.getNode(nodepos)).rightclickable)
do{ // breakable
verbosestream<<"Node placement prediction for "
<<playeritem.name<<" is "
<<def.node_placement_prediction<<std::endl;
v3s16 p = neighbourpos;
// Place inside node itself if buildable_to
try{
MapNode n_under = map.getNode(nodepos);
if(nodedef->get(n_under).buildable_to)
p = nodepos;
}catch(InvalidPositionException &e){}
// Find id of predicted node
content_t id;
bool found =
nodedef->getId(def.node_placement_prediction, id);
if(!found){
errorstream<<"Node placement prediction failed for "
<<playeritem.name<<" (places "
<<def.node_placement_prediction
<<") - Name not known"<<std::endl;
break;
}
MapNode n(id);
try{
// This triggers the required mesh update too
client.addNode(p, n);
}catch(InvalidPositionException &e){
errorstream<<"Node placement prediction failed for "
<<playeritem.name<<" (places "
<<def.node_placement_prediction
<<") - Position not loaded"<<std::endl;
}
}while(0);
// Read the sound // Read the sound
soundmaker.m_player_rightpunch_sound = def.sound_place; soundmaker.m_player_rightpunch_sound =
playeritem_def.sound_place;
} }
} }
} }