- /*
- Handle material items
- */
- if(std::string("MaterialItem") == item->getName())
- {
- bool cannot_place_node = !build_priv;
-
- try{
- // Don't add a node if this is not a free space
- MapNode n2 = m_env->getMap().getNode(p_above);
- if(m_nodedef->get(n2).buildable_to == false)
- {
- infostream<<"Client "<<peer_id<<" tried to place"
- <<" node in invalid position."<<std::endl;
- cannot_place_node = true;
- }
- }
- catch(InvalidPositionException &e)
- {
- infostream<<"Server: Ignoring ADDNODE: Node not found"
- <<" Adding block to emerge queue."
- <<std::endl;
- m_emerge_queue.addBlock(peer_id,
- getNodeBlockPos(p_above), BLOCK_EMERGE_FLAG_FROMDISK);
- cannot_place_node = true;
- }
-
- if(cannot_place_node)
- {
- // Client probably has wrong data.
- // Set block not sent, so that client will get
- // a valid one.
- RemoteClient *client = getClient(peer_id);
- v3s16 blockpos = getNodeBlockPos(p_above);
- client->SetBlockNotSent(blockpos);
- return;
- }
-
- // Reset build time counter
- getClient(peer_id)->m_time_from_building = 0.0;
-
- // Create node data
- MaterialItem *mitem = (MaterialItem*)item;
- MapNode n;
- n.setContent(mitem->getMaterial());
-
- actionstream<<player->getName()<<" places material "
- <<(int)mitem->getMaterial()
- <<" at "<<PP(p_under)<<std::endl;
-
- // 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;
- }
- }
- }
- }
- else if(pointed.type == POINTEDTHING_OBJECT)