+ // Calculate direction for wall mounted stuff
+ if(m_nodedef->get(n).wall_mounted)
+ n.param2 = packDir(p_under - p_above);
+
+ // Calculate the direction for furnaces and chests and stuff
+ if(m_nodedef->get(n).param_type == CPT_FACEDIR_SIMPLE)
+ {
+ v3f playerpos = player->getPosition();
+ v3f blockpos = intToFloat(p_above, BS) - playerpos;
+ blockpos = blockpos.normalize();
+ n.param1 = 0;
+ if (fabs(blockpos.X) > fabs(blockpos.Z)) {
+ if (blockpos.X < 0)
+ n.param1 = 3;
+ else
+ n.param1 = 1;
+ } else {
+ if (blockpos.Z < 0)
+ n.param1 = 2;
+ else
+ n.param1 = 0;
+ }
+ }
+
+ /*
+ Send to all close-by players
+ */
+ core::list<u16> far_players;
+ sendAddNode(p_above, n, 0, &far_players, 30);
+
+ /*
+ Handle inventory
+ */
+ InventoryList *ilist = player->inventory.getList("main");
+ if(g_settings->getBool("creative_mode") == false && ilist)
+ {
+ // Remove from inventory and send inventory
+ if(mitem->getCount() <= 1)
+ ilist->deleteItem(item_i);
+ else
+ mitem->remove(1);
+ srp->m_inventory_not_sent = true;
+ }
+
+ /*
+ Add node.
+
+ This takes some time so it is done after the quick stuff
+ */
+ core::map<v3s16, MapBlock*> modified_blocks;
+ {
+ MapEditEventIgnorer ign(&m_ignore_map_edit_events);
+
+ std::string p_name = std::string(player->getName());
+ m_env->getMap().addNodeAndUpdate(p_above, n, modified_blocks, p_name);
+ }
+ /*
+ Set blocks not sent to far players
+ */
+ for(core::list<u16>::Iterator
+ i = far_players.begin();
+ i != far_players.end(); i++)
+ {
+ u16 peer_id = *i;
+ RemoteClient *client = getClient(peer_id);
+ if(client==NULL)
+ continue;
+ client->SetBlocksNotSent(modified_blocks);
+ }
+
+ /*
+ Run script hook
+ */
+ scriptapi_environment_on_placenode(m_lua, p_above, n, srp);
+
+ /*
+ Calculate special events
+ */
+
+ /*if(n.d == LEGN(m_nodedef, "CONTENT_MESE"))
+ {
+ u32 count = 0;
+ for(s16 z=-1; z<=1; z++)
+ for(s16 y=-1; y<=1; y++)
+ for(s16 x=-1; x<=1; x++)
+ {
+
+ }
+ }*/
+ }
+ /*
+ Place other item (not a block)
+ */
+ else
+ {
+ if(!build_priv)
+ {
+ infostream<<"Not allowing player to place item: "
+ "no build privileges"<<std::endl;
+ return;
+ }
+
+ // Calculate a position for it
+ v3f pos = player_pos;
+ if(pointed.type == POINTEDTHING_NOTHING)
+ {
+ infostream<<"Not allowing player to place item: "
+ "pointing to nothing"<<std::endl;
+ return;
+ }
+ else if(pointed.type == POINTEDTHING_NODE)
+ {
+ pos = intToFloat(p_above, BS);
+ }
+ else if(pointed.type == POINTEDTHING_OBJECT)
+ {
+ pos = pointed_object->getBasePosition();
+
+ // Randomize a bit
+ pos.X += BS*0.2*(float)myrand_range(-1000,1000)/1000.0;
+ pos.Z += BS*0.2*(float)myrand_range(-1000,1000)/1000.0;
+ }
+
+ //pos.Y -= BS*0.45;
+ //pos.Y -= BS*0.25; // let it drop a bit
+
+ /*
+ Check that the block is loaded so that the item
+ can properly be added to the static list too
+ */
+ v3s16 blockpos = getNodeBlockPos(floatToInt(pos, BS));
+ MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos);
+ if(block==NULL)
+ {
+ infostream<<"Error while placing item: "
+ "block not found"<<std::endl;
+ return;
+ }
+
+ actionstream<<player->getName()<<" places "<<item->getName()
+ <<" at "<<PP(pos)<<std::endl;
+
+ /*
+ Place the item
+ */
+ bool remove = item->dropOrPlace(m_env, srp, pos, true, -1);
+ if(remove && g_settings->getBool("creative_mode") == false)
+ {
+ InventoryList *ilist = player->inventory.getList("main");
+ if(ilist){
+ // Remove from inventory and send inventory
+ ilist->deleteItem(item_i);
+ srp->m_inventory_not_sent = true;
+ }
+ }
+ }