Furnace is now usable. Added more tools.

--HG--
rename : data/tool_stpick.png => data/tool_stonepick.png
rename : data/tool_wpick.png => data/tool_woodpick.png
This commit is contained in:
Perttu Ahola 2011-04-05 18:23:30 +03:00
parent 5b4928e07c
commit 89aa8b9be1
22 changed files with 421 additions and 101 deletions

BIN
data/cobble.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 830 B

BIN
data/steel_block.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

BIN
data/steel_ingot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 846 B

After

Width:  |  Height:  |  Size: 806 B

BIN
data/tool_steelaxe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

BIN
data/tool_steelpick.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

BIN
data/tool_steelshovel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

BIN
data/tool_stoneaxe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Before

Width:  |  Height:  |  Size: 990 B

After

Width:  |  Height:  |  Size: 990 B

BIN
data/tool_stoneshovel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

BIN
data/tool_woodaxe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Before

Width:  |  Height:  |  Size: 989 B

After

Width:  |  Height:  |  Size: 989 B

BIN
data/tool_woodshovel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

@ -94,12 +94,51 @@ InventoryItem* InventoryItem::deSerialize(std::istream &is)
MaterialItem MaterialItem
*/ */
bool MaterialItem::isCookable()
{
if(m_content == CONTENT_TREE)
{
return true;
}
else if(m_content == CONTENT_COBBLE)
{
return true;
}
return false;
}
InventoryItem *MaterialItem::createCookResult() InventoryItem *MaterialItem::createCookResult()
{ {
if(m_content == CONTENT_TREE) if(m_content == CONTENT_TREE)
{ {
return new CraftItem("lump_of_coal", 1); return new CraftItem("lump_of_coal", 1);
} }
else if(m_content == CONTENT_COBBLE)
{
return new MaterialItem(CONTENT_STONE, 1);
}
return NULL;
}
/*
CraftItem
*/
bool CraftItem::isCookable()
{
if(m_subname == "lump_of_iron")
{
return true;
}
return false;
}
InventoryItem *CraftItem::createCookResult()
{
if(m_subname == "lump_of_iron")
{
return new CraftItem("steel_ingot", 1);
}
return NULL; return NULL;
} }
@ -357,6 +396,9 @@ void InventoryList::deleteItem(u32 i)
InventoryItem * InventoryList::addItem(InventoryItem *newitem) InventoryItem * InventoryList::addItem(InventoryItem *newitem)
{ {
if(newitem == NULL)
return NULL;
/* /*
First try to find if it could be added to some existing items First try to find if it could be added to some existing items
*/ */
@ -391,6 +433,9 @@ InventoryItem * InventoryList::addItem(InventoryItem *newitem)
InventoryItem * InventoryList::addItem(u32 i, InventoryItem *newitem) InventoryItem * InventoryList::addItem(u32 i, InventoryItem *newitem)
{ {
if(newitem == NULL)
return NULL;
// If it is an empty position, it's an easy job. // If it is an empty position, it's an easy job.
InventoryItem *to_item = m_items[i]; InventoryItem *to_item = m_items[i];
if(to_item == NULL) if(to_item == NULL)

@ -91,6 +91,8 @@ public:
/* /*
Other properties Other properties
*/ */
// Whether it can be cooked
virtual bool isCookable(){return false;}
// Time of cooking // Time of cooking
virtual float getCookTime(){return 3.0;} virtual float getCookTime(){return 3.0;}
// Result of cooking // Result of cooking
@ -160,6 +162,7 @@ public:
/* /*
Other properties Other properties
*/ */
bool isCookable();
InventoryItem *createCookResult(); InventoryItem *createCookResult();
/* /*
Special methods Special methods
@ -272,6 +275,8 @@ public:
name = "lump_of_coal.png"; name = "lump_of_coal.png";
else if(m_subname == "lump_of_iron") else if(m_subname == "lump_of_iron")
name = "lump_of_iron.png"; name = "lump_of_iron.png";
else if(m_subname == "steel_ingot")
name = "steel_ingot.png";
else else
name = "cloud.png"; name = "cloud.png";
@ -301,6 +306,11 @@ public:
return 0; return 0;
return QUANTITY_ITEM_MAX_COUNT - m_count; return QUANTITY_ITEM_MAX_COUNT - m_count;
} }
/*
Other properties
*/
bool isCookable();
InventoryItem *createCookResult();
/* /*
Special methods Special methods
*/ */
@ -348,11 +358,25 @@ public:
std::string basename; std::string basename;
if(m_toolname == "WPick") if(m_toolname == "WPick")
basename = "tool_wpick.png"; basename = "tool_woodpick.png";
else if(m_toolname == "STPick") else if(m_toolname == "STPick")
basename = "tool_stpick.png"; basename = "tool_stonepick.png";
else if(m_toolname == "SteelPick")
basename = "tool_steelpick.png";
else if(m_toolname == "MesePick") else if(m_toolname == "MesePick")
basename = "tool_mesepick.png"; basename = "tool_mesepick.png";
else if(m_toolname == "WShovel")
basename = "tool_woodshovel.png";
else if(m_toolname == "STShovel")
basename = "tool_stoneshovel.png";
else if(m_toolname == "SteelShovel")
basename = "tool_steelshovel.png";
else if(m_toolname == "WAxe")
basename = "tool_woodaxe.png";
else if(m_toolname == "STAxe")
basename = "tool_stoneaxe.png";
else if(m_toolname == "SteelAxe")
basename = "tool_steelaxe.png";
else else
basename = "cloud.png"; basename = "cloud.png";

@ -2252,7 +2252,7 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos,
TimeTaker timer_generate("generateChunkRaw() generate"); TimeTaker timer_generate("generateChunkRaw() generate");
// Maximum height of the stone surface and obstacles. // Maximum height of the stone surface and obstacles.
// This is used to disable dungeon generation from going too high. // This is used to disable cave generation from going too high.
s16 stone_surface_max_y = 0; s16 stone_surface_max_y = 0;
/* /*
@ -2320,12 +2320,12 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos,
Randomize some parameters Randomize some parameters
*/ */
s32 stone_obstacle_count = 0; //s32 stone_obstacle_count = 0;
/*s32 stone_obstacle_count = /*s32 stone_obstacle_count =
rangelim((1.0+noise2d(m_seed+897, rangelim((1.0+noise2d(m_seed+897,
sectorpos_base.X, sectorpos_base.Y))/2.0 * 30, 0, 100000);*/ sectorpos_base.X, sectorpos_base.Y))/2.0 * 30, 0, 100000);*/
s16 stone_obstacle_max_height = 0; //s16 stone_obstacle_max_height = 0;
/*s16 stone_obstacle_max_height = /*s16 stone_obstacle_max_height =
rangelim((1.0+noise2d(m_seed+5902, rangelim((1.0+noise2d(m_seed+5902,
sectorpos_base.X, sectorpos_base.Y))/2.0 * 30, 0, 100000);*/ sectorpos_base.X, sectorpos_base.Y))/2.0 * 30, 0, 100000);*/
@ -2336,7 +2336,11 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos,
//for(u32 i_age=0; i_age<1; i_age++) //for(u32 i_age=0; i_age<1; i_age++)
for(u32 i_age=0; i_age<2; i_age++) for(u32 i_age=0; i_age<2; i_age++)
{ // Aging loop { // Aging loop
/******************************
BEGINNING OF AGING LOOP
******************************/
#if 0
{ {
// 8ms @cs=8 // 8ms @cs=8
//TimeTaker timer1("stone obstacles"); //TimeTaker timer1("stone obstacles");
@ -2461,26 +2465,30 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos,
} }
}//timer1 }//timer1
#endif
{ {
// 24ms @cs=8 // 24ms @cs=8
//TimeTaker timer1("dungeons"); //TimeTaker timer1("caves");
/* /*
Make dungeons Make caves
*/ */
u32 dungeons_count = relative_volume / 600000; u32 caves_count = relative_volume / 400000;
u32 bruises_count = relative_volume * stone_surface_max_y / 40000000; u32 bruises_count = relative_volume * stone_surface_max_y / 40000000;
if(stone_surface_max_y < WATER_LEVEL) if(stone_surface_max_y < WATER_LEVEL)
bruises_count = 0; bruises_count = 0;
/*u32 dungeons_count = 0; /*u32 caves_count = 0;
u32 bruises_count = 0;*/ u32 bruises_count = 0;*/
for(u32 jj=0; jj<dungeons_count+bruises_count; jj++) for(u32 jj=0; jj<caves_count+bruises_count; jj++)
{ {
s16 min_tunnel_diameter = 2; s16 min_tunnel_diameter = 3;
s16 max_tunnel_diameter = 6; s16 max_tunnel_diameter = 5;
u16 tunnel_routepoints = 25; u16 tunnel_routepoints = 20;
bool bruise_surface = (jj < bruises_count); v3f main_direction(0,0,0);
bool bruise_surface = (jj > caves_count);
if(bruise_surface) if(bruise_surface)
{ {
@ -2494,6 +2502,9 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos,
tunnel_routepoints = 5; tunnel_routepoints = 5;
} }
else
{
}
// Allowed route area size in nodes // Allowed route area size in nodes
v3s16 ar( v3s16 ar(
@ -2521,7 +2532,7 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos,
// Allow half a diameter + 7 over stone surface // Allow half a diameter + 7 over stone surface
s16 route_y_max = -of.Y + stone_surface_max_y + max_tunnel_diameter/2 + 7; s16 route_y_max = -of.Y + stone_surface_max_y + max_tunnel_diameter/2 + 7;
/*// If dungeons, don't go through surface too often /*// If caves, don't go through surface too often
if(bruise_surface == false) if(bruise_surface == false)
route_y_max -= myrand_range(0, max_tunnel_diameter*2);*/ route_y_max -= myrand_range(0, max_tunnel_diameter*2);*/
@ -2546,16 +2557,16 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos,
s16 route_start_y_min = route_y_min; s16 route_start_y_min = route_y_min;
s16 route_start_y_max = route_y_max; s16 route_start_y_max = route_y_max;
// Start every 2nd dungeon from surface // Start every 2nd cave from surface
bool coming_from_surface = (jj % 2 == 0 && bruise_surface == false); bool coming_from_surface = (jj % 2 == 0 && bruise_surface == false);
if(coming_from_surface) if(coming_from_surface)
{ {
route_start_y_min = -of.Y + stone_surface_max_y + 5; route_start_y_min = -of.Y + stone_surface_max_y + 10;
} }
route_start_y_min = rangelim(route_start_y_min, 0, ar.Y-1); route_start_y_min = rangelim(route_start_y_min, 0, ar.Y-1);
route_start_y_max = rangelim(route_start_y_max, 0, ar.Y-1); route_start_y_max = rangelim(route_start_y_max, route_start_y_min, ar.Y-1);
// Randomize starting position // Randomize starting position
v3f orp( v3f orp(
@ -2572,6 +2583,16 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos,
for(u16 j=0; j<tunnel_routepoints; j++) for(u16 j=0; j<tunnel_routepoints; j++)
{ {
if(j%7==0 && bruise_surface == false)
{
main_direction = v3f(
((float)(myrand()%20)-(float)10)/10,
((float)(myrand()%20)-(float)10)/30,
((float)(myrand()%20)-(float)10)/10
);
main_direction *= (float)myrand_range(1, 3);
}
// Randomize size // Randomize size
s16 min_d = min_tunnel_diameter; s16 min_d = min_tunnel_diameter;
s16 max_d = max_tunnel_diameter; s16 max_d = max_tunnel_diameter;
@ -2584,7 +2605,7 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos,
} }
else else
{ {
maxlen = v3s16(15, myrand_range(1, 20), 15); maxlen = v3s16(rs*4, myrand_range(1, rs*3), rs*4);
} }
v3f vec; v3f vec;
@ -2606,6 +2627,8 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos,
); );
} }
vec += main_direction;
v3f rp = orp + vec; v3f rp = orp + vec;
if(rp.X < 0) if(rp.X < 0)
rp.X = 0; rp.X = 0;
@ -3095,7 +3118,7 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos,
break; break;
} }
// Make water only not in dungeons // Make water only not in caves
if(!(vmanip.m_flags[i]&VMANIP_FLAG_DUNGEON)) if(!(vmanip.m_flags[i]&VMANIP_FLAG_DUNGEON))
{ {
n->d = CONTENT_WATERSOURCE; n->d = CONTENT_WATERSOURCE;
@ -3119,6 +3142,9 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos,
}//timer1 }//timer1
} // Aging loop } // Aging loop
/***********************
END OF AGING LOOP
************************/
{ {
//TimeTaker timer1("convert mud to sand"); //TimeTaker timer1("convert mud to sand");
@ -3953,7 +3979,7 @@ MapBlock * ServerMap::generateBlock(
else else
n.d = CONTENT_AIR; n.d = CONTENT_AIR;
} }
// Else it's ground or dungeons (air) // Else it's ground or caves (air)
else else
{ {
// If it's surface_depth under ground, it's stone // If it's surface_depth under ground, it's stone
@ -4034,7 +4060,7 @@ MapBlock * ServerMap::generateBlock(
//dstream<<"generateBlock(): Done"<<std::endl; //dstream<<"generateBlock(): Done"<<std::endl;
/* /*
Generate dungeons Generate caves
*/ */
// Initialize temporary table // Initialize temporary table
@ -4172,36 +4198,36 @@ MapBlock * ServerMap::generateBlock(
continue_generating: continue_generating:
/* /*
Choose whether to actually generate dungeon Choose whether to actually generate cave
*/ */
bool do_generate_dungeons = true; bool do_generate_caves = true;
// Don't generate if no part is underground // Don't generate if no part is underground
if(!some_part_underground) if(!some_part_underground)
{ {
do_generate_dungeons = false; do_generate_caves = false;
} }
// Don't generate if mostly underwater surface // Don't generate if mostly underwater surface
/*else if(mostly_underwater_surface) /*else if(mostly_underwater_surface)
{ {
do_generate_dungeons = false; do_generate_caves = false;
}*/ }*/
// Partly underground = cave // Partly underground = cave
else if(!completely_underground) else if(!completely_underground)
{ {
do_generate_dungeons = (rand() % 100 <= (s32)(caves_amount*100)); do_generate_caves = (rand() % 100 <= (s32)(caves_amount*100));
} }
// Found existing dungeon underground // Found existing cave underground
else if(found_existing && completely_underground) else if(found_existing && completely_underground)
{ {
do_generate_dungeons = (rand() % 100 <= (s32)(caves_amount*100)); do_generate_caves = (rand() % 100 <= (s32)(caves_amount*100));
} }
// Underground and no dungeons found // Underground and no caves found
else else
{ {
do_generate_dungeons = (rand() % 300 <= (s32)(caves_amount*100)); do_generate_caves = (rand() % 300 <= (s32)(caves_amount*100));
} }
if(do_generate_dungeons) if(do_generate_caves)
{ {
/* /*
Generate some tunnel starting from orp and ors Generate some tunnel starting from orp and ors
@ -4253,7 +4279,7 @@ continue_generating:
// Set to true if has caves. // Set to true if has caves.
// Set when some non-air is changed to air when making caves. // Set when some non-air is changed to air when making caves.
bool has_dungeons = false; bool has_caves = false;
/* /*
Apply temporary cave data to block Apply temporary cave data to block
@ -4266,7 +4292,7 @@ continue_generating:
{ {
MapNode n = block->getNode(v3s16(x0,y0,z0)); MapNode n = block->getNode(v3s16(x0,y0,z0));
// Create dungeons // Create caves
if(underground_emptiness[ if(underground_emptiness[
ued*ued*(z0*ued/MAP_BLOCKSIZE) ued*ued*(z0*ued/MAP_BLOCKSIZE)
+ued*(y0*ued/MAP_BLOCKSIZE) +ued*(y0*ued/MAP_BLOCKSIZE)
@ -4275,7 +4301,7 @@ continue_generating:
if(content_features(n.d).walkable/*is_ground_content(n.d)*/) if(content_features(n.d).walkable/*is_ground_content(n.d)*/)
{ {
// Has now caves // Has now caves
has_dungeons = true; has_caves = true;
// Set air to node // Set air to node
n.d = CONTENT_AIR; n.d = CONTENT_AIR;
} }
@ -4295,7 +4321,7 @@ continue_generating:
Force lighting update if some part of block is partly Force lighting update if some part of block is partly
underground and has caves. underground and has caves.
*/ */
/*if(some_part_underground && !completely_underground && has_dungeons) /*if(some_part_underground && !completely_underground && has_caves)
{ {
//dstream<<"Half-ground caves"<<std::endl; //dstream<<"Half-ground caves"<<std::endl;
lighting_invalidated_blocks[block->getPos()] = block; lighting_invalidated_blocks[block->getPos()] = block;
@ -4440,11 +4466,11 @@ continue_generating:
*/ */
dstream dstream
<<"lighting_invalidated_blocks.size()" <<"lighting_invalidated_blocks.size()"
<<", has_dungeons" <<", has_caves"
<<", completely_ug" <<", completely_ug"
<<", some_part_ug" <<", some_part_ug"
<<" "<<lighting_invalidated_blocks.size() <<" "<<lighting_invalidated_blocks.size()
<<", "<<has_dungeons <<", "<<has_caves
<<", "<<completely_underground <<", "<<completely_underground
<<", "<<some_part_underground <<", "<<some_part_underground
<<std::endl; <<std::endl;

@ -141,7 +141,7 @@ void init_mapnode()
f->setInventoryTextureCube("stone.png", "stone.png", "stone.png"); f->setInventoryTextureCube("stone.png", "stone.png", "stone.png");
f->param_type = CPT_MINERAL; f->param_type = CPT_MINERAL;
f->is_ground_content = true; f->is_ground_content = true;
f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; f->dug_item = std::string("MaterialItem ")+itos(CONTENT_COBBLE)+" 1";
i = CONTENT_GRASS; i = CONTENT_GRASS;
f = &g_content_features[i]; f = &g_content_features[i];
@ -284,6 +284,7 @@ void init_mapnode()
f->setInventoryTexture("torch_on_floor.png"); f->setInventoryTexture("torch_on_floor.png");
f->param_type = CPT_LIGHT; f->param_type = CPT_LIGHT;
f->light_propagates = true; f->light_propagates = true;
f->sunlight_propagates = true;
f->solidness = 0; // drawn separately, makes no faces f->solidness = 0; // drawn separately, makes no faces
f->walkable = false; f->walkable = false;
f->wall_mounted = true; f->wall_mounted = true;
@ -321,10 +322,28 @@ void init_mapnode()
f->setAllTextures("furnace_side.png"); f->setAllTextures("furnace_side.png");
f->setTexture(5, "furnace_front.png"); // Z- f->setTexture(5, "furnace_front.png"); // Z-
f->setInventoryTexture("furnace_front.png"); f->setInventoryTexture("furnace_front.png");
f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; //f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
f->dug_item = std::string("MaterialItem ")+itos(CONTENT_COBBLE)+" 6";
if(f->initial_metadata == NULL) if(f->initial_metadata == NULL)
f->initial_metadata = new FurnaceNodeMetadata(); f->initial_metadata = new FurnaceNodeMetadata();
i = CONTENT_COBBLE;
f = &g_content_features[i];
f->setAllTextures("cobble.png");
f->setInventoryTextureCube("cobble.png", "cobble.png", "cobble.png");
f->param_type = CPT_NONE;
f->is_ground_content = true;
f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
i = CONTENT_STEEL;
f = &g_content_features[i];
f->setAllTextures("steel_block.png");
f->setInventoryTextureCube("steel_block.png", "steel_block.png",
"steel_block.png");
f->param_type = CPT_NONE;
f->is_ground_content = true;
f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
} }
v3s16 facedir_rotate(u8 facedir, v3s16 dir) v3s16 facedir_rotate(u8 facedir, v3s16 dir)

@ -98,6 +98,8 @@ void init_content_inventory_texture_paths();
#define CONTENT_CHEST 15 #define CONTENT_CHEST 15
#define CONTENT_FURNACE 16 #define CONTENT_FURNACE 16
//#define CONTENT_WORKBENCH 17 //#define CONTENT_WORKBENCH 17
#define CONTENT_COBBLE 18
#define CONTENT_STEEL 19
/* /*
Content feature list Content feature list

@ -15,12 +15,40 @@ void setStoneLikeDiggingProperties(u8 material, float toughness)
g_material_properties[material].setDiggingProperties("WPick", g_material_properties[material].setDiggingProperties("WPick",
DiggingProperties(true, 1.3*toughness, 65535./30.*toughness)); DiggingProperties(true, 1.3*toughness, 65535./30.*toughness));
g_material_properties[material].setDiggingProperties("STPick", g_material_properties[material].setDiggingProperties("STPick",
DiggingProperties(true, 0.65*toughness, 65535./100.*toughness)); DiggingProperties(true, 0.75*toughness, 65535./100.*toughness));
g_material_properties[material].setDiggingProperties("SteelPick",
DiggingProperties(true, 0.50*toughness, 65535./333.*toughness));
/*g_material_properties[material].setDiggingProperties("MesePick", /*g_material_properties[material].setDiggingProperties("MesePick",
DiggingProperties(true, 0.0*toughness, 65535./20.*toughness));*/ DiggingProperties(true, 0.0*toughness, 65535./20.*toughness));*/
} }
void setDirtLikeDiggingProperties(u8 material, float toughness)
{
g_material_properties[material].setDiggingProperties("",
DiggingProperties(true, 0.75*toughness, 0));
g_material_properties[material].setDiggingProperties("WShovel",
DiggingProperties(true, 0.4*toughness, 65535./50.*toughness));
g_material_properties[material].setDiggingProperties("STShovel",
DiggingProperties(true, 0.2*toughness, 65535./150.*toughness));
g_material_properties[material].setDiggingProperties("SteelShovel",
DiggingProperties(true, 0.15*toughness, 65535./400.*toughness));
}
void setWoodLikeDiggingProperties(u8 material, float toughness)
{
g_material_properties[material].setDiggingProperties("",
DiggingProperties(true, 3.0*toughness, 0));
g_material_properties[material].setDiggingProperties("WAxe",
DiggingProperties(true, 1.5*toughness, 65535./30.*toughness));
g_material_properties[material].setDiggingProperties("STAxe",
DiggingProperties(true, 0.75*toughness, 65535./100.*toughness));
g_material_properties[material].setDiggingProperties("SteelAxe",
DiggingProperties(true, 0.5*toughness, 65535./333.*toughness));
}
void initializeMaterialProperties() void initializeMaterialProperties()
{ {
/* /*
@ -31,41 +59,25 @@ void initializeMaterialProperties()
*/ */
setStoneLikeDiggingProperties(CONTENT_STONE, 1.0); setStoneLikeDiggingProperties(CONTENT_STONE, 1.0);
g_material_properties[CONTENT_GRASS].setDiggingProperties("",
DiggingProperties(true, 0.4, 0));
g_material_properties[CONTENT_TORCH].setDiggingProperties("",
DiggingProperties(true, 0.0, 0));
g_material_properties[CONTENT_TREE].setDiggingProperties("",
DiggingProperties(true, 1.5, 0));
g_material_properties[CONTENT_LEAVES].setDiggingProperties("",
DiggingProperties(true, 0.35, 0));
g_material_properties[CONTENT_GRASS_FOOTSTEPS].setDiggingProperties("",
DiggingProperties(true, 0.5, 0));
setStoneLikeDiggingProperties(CONTENT_MESE, 0.5); setStoneLikeDiggingProperties(CONTENT_MESE, 0.5);
g_material_properties[CONTENT_MUD].setDiggingProperties("",
DiggingProperties(true, 0.4, 0));
setStoneLikeDiggingProperties(CONTENT_COALSTONE, 1.5); setStoneLikeDiggingProperties(CONTENT_COALSTONE, 1.5);
setStoneLikeDiggingProperties(CONTENT_FURNACE, 3.0);
setStoneLikeDiggingProperties(CONTENT_COBBLE, 1.0);
setStoneLikeDiggingProperties(CONTENT_STEEL, 5.0);
g_material_properties[CONTENT_WOOD].setDiggingProperties("", setDirtLikeDiggingProperties(CONTENT_MUD, 1.0);
DiggingProperties(true, 1.0, 0)); setDirtLikeDiggingProperties(CONTENT_GRASS, 1.0);
setDirtLikeDiggingProperties(CONTENT_GRASS_FOOTSTEPS, 1.0);
setDirtLikeDiggingProperties(CONTENT_SAND, 1.0);
g_material_properties[CONTENT_SAND].setDiggingProperties("", setWoodLikeDiggingProperties(CONTENT_TREE, 1.0);
DiggingProperties(true, 0.4, 0)); setWoodLikeDiggingProperties(CONTENT_LEAVES, 0.15);
setWoodLikeDiggingProperties(CONTENT_WOOD, 0.75);
g_material_properties[CONTENT_CHEST].setDiggingProperties("", setWoodLikeDiggingProperties(CONTENT_CHEST, 1.0);
DiggingProperties(true, 1.0, 0));
setStoneLikeDiggingProperties(CONTENT_FURNACE, 1.0);
g_material_properties[CONTENT_SIGN_WALL].setDiggingProperties("", g_material_properties[CONTENT_SIGN_WALL].setDiggingProperties("",
DiggingProperties(true, 0.5, 0));
g_material_properties[CONTENT_TORCH].setDiggingProperties("",
DiggingProperties(true, 0.0, 0)); DiggingProperties(true, 0.0, 0));
/* /*

@ -165,6 +165,18 @@ std::string ChestNodeMetadata::infoText()
{ {
return "Chest"; return "Chest";
} }
bool ChestNodeMetadata::nodeRemovalDisabled()
{
/*
Disable removal if chest contains something
*/
InventoryList *list = m_inventory->getList("0");
if(list == NULL)
return true;
if(list->getUsedSlots() == 0)
return true;
return false;
}
/* /*
FurnaceNodeMetadata FurnaceNodeMetadata
@ -266,7 +278,7 @@ bool FurnaceNodeMetadata::step(float dtime)
// Start only if there are free slots in dst, so that it can // Start only if there are free slots in dst, so that it can
// accomodate any result item // accomodate any result item
if(dst_list->getFreeSlots() > 0) if(dst_list->getFreeSlots() > 0 && src_item && src_item->isCookable())
{ {
m_src_totaltime = 3; m_src_totaltime = 3;
} }
@ -281,11 +293,12 @@ bool FurnaceNodeMetadata::step(float dtime)
//dstream<<"Furnace is active"<<std::endl; //dstream<<"Furnace is active"<<std::endl;
m_fuel_time += dtime; m_fuel_time += dtime;
m_src_time += dtime; m_src_time += dtime;
if(m_src_time >= m_src_totaltime && m_src_totaltime > 0.001) if(m_src_time >= m_src_totaltime && m_src_totaltime > 0.001
&& src_item)
{ {
src_list->decrementMaterials(1);
InventoryItem *cookresult = src_item->createCookResult(); InventoryItem *cookresult = src_item->createCookResult();
dst_list->addItem(cookresult); dst_list->addItem(cookresult);
src_list->decrementMaterials(1);
m_src_time = 0; m_src_time = 0;
m_src_totaltime = 0; m_src_totaltime = 0;
} }

@ -61,6 +61,7 @@ public:
virtual void inventoryModified(){} virtual void inventoryModified(){}
// A step in time. Returns true if metadata changed. // A step in time. Returns true if metadata changed.
virtual bool step(float dtime) {return false;} virtual bool step(float dtime) {return false;}
virtual bool nodeRemovalDisabled(){return false;}
protected: protected:
static void registerType(u16 id, Factory f); static void registerType(u16 id, Factory f);
@ -100,6 +101,8 @@ public:
virtual std::string infoText(); virtual std::string infoText();
virtual Inventory* getInventory() {return m_inventory;} virtual Inventory* getInventory() {return m_inventory;}
virtual bool nodeRemovalDisabled();
private: private:
Inventory *m_inventory; Inventory *m_inventory;
}; };

@ -2033,31 +2033,40 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
u8 material; u8 material;
u8 mineral = MINERAL_NONE; u8 mineral = MINERAL_NONE;
bool cannot_remove_node = false;
try try
{ {
MapNode n = m_env.getMap().getNode(p_under); MapNode n = m_env.getMap().getNode(p_under);
// Get mineral
mineral = n.getMineral();
// Get material at position // Get material at position
material = n.d; material = n.d;
// If not yet cancelled
if(cannot_remove_node == false)
{
// If it's not diggable, do nothing // If it's not diggable, do nothing
if(content_diggable(material) == false) if(content_diggable(material) == false)
{ {
derr_server<<"Server: Not finishing digging: Node not diggable" derr_server<<"Server: Not finishing digging: "
<<"Node not diggable"
<<std::endl; <<std::endl;
cannot_remove_node = true;
// Client probably has wrong data. }
// Set block not sent, so that client will get }
// a valid one. // If not yet cancelled
dstream<<"Client "<<peer_id<<" tried to dig " if(cannot_remove_node == false)
<<"node from invalid position; setting" {
<<" MapBlock not sent."<<std::endl; // Get node metadata
RemoteClient *client = getClient(peer_id); NodeMetadata *meta = m_env.getMap().getNodeMetadata(p_under);
v3s16 blockpos = getNodeBlockPos(p_under); if(meta && meta->nodeRemovalDisabled() == true)
client->SetBlockNotSent(blockpos); {
derr_server<<"Server: Not finishing digging: "
return; <<"Node metadata disables removal"
<<std::endl;
cannot_remove_node = true;
}
} }
// Get mineral
mineral = n.getMineral();
} }
catch(InvalidPositionException &e) catch(InvalidPositionException &e)
{ {
@ -2066,6 +2075,27 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
<<std::endl; <<std::endl;
m_emerge_queue.addBlock(peer_id, m_emerge_queue.addBlock(peer_id,
getNodeBlockPos(p_over), BLOCK_EMERGE_FLAG_FROMDISK); getNodeBlockPos(p_over), BLOCK_EMERGE_FLAG_FROMDISK);
cannot_remove_node = true;
}
/*
If node can't be removed, set block to be re-sent to
client and quit.
*/
if(cannot_remove_node)
{
derr_server<<"Server: Not finishing digging."<<std::endl;
// Client probably has wrong data.
// Set block not sent, so that client will get
// a valid one.
dstream<<"Client "<<peer_id<<" tried to dig "
<<"node; but node cannot be removed."
<<" setting MapBlock not sent."<<std::endl;
RemoteClient *client = getClient(peer_id);
v3s16 blockpos = getNodeBlockPos(p_under);
client->SetBlockNotSent(blockpos);
return; return;
} }
@ -3016,9 +3046,9 @@ void Server::SendInventory(u16 peer_id)
if(!found) if(!found)
{ {
ItemSpec specs[9]; ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_STONE); specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE);
specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_STONE); specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE);
specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_STONE); specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE);
specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
if(checkItemCombination(items, specs)) if(checkItemCombination(items, specs))
@ -3028,6 +3058,22 @@ void Server::SendInventory(u16 peer_id)
} }
} }
// Steel pick
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[1] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[2] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
if(checkItemCombination(items, specs))
{
rlist->addItem(new ToolItem("SteelPick", 0));
found = true;
}
}
// Mese pick // Mese pick
if(!found) if(!found)
{ {
@ -3044,7 +3090,97 @@ void Server::SendInventory(u16 peer_id)
} }
} }
// Chest1 // Wooden showel
if(!found)
{
ItemSpec specs[9];
specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
if(checkItemCombination(items, specs))
{
rlist->addItem(new ToolItem("WShovel", 0));
found = true;
}
}
// Stone showel
if(!found)
{
ItemSpec specs[9];
specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_STONE);
specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
if(checkItemCombination(items, specs))
{
rlist->addItem(new ToolItem("STShovel", 0));
found = true;
}
}
// Steel showel
if(!found)
{
ItemSpec specs[9];
specs[1] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
if(checkItemCombination(items, specs))
{
rlist->addItem(new ToolItem("SteelShovel", 0));
found = true;
}
}
// Wooden axe
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
if(checkItemCombination(items, specs))
{
rlist->addItem(new ToolItem("WAxe", 0));
found = true;
}
}
// Stone axe
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE);
specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE);
specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE);
specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
if(checkItemCombination(items, specs))
{
rlist->addItem(new ToolItem("STAxe", 0));
found = true;
}
}
// Steel axe
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[1] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[3] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
if(checkItemCombination(items, specs))
{
rlist->addItem(new ToolItem("SteelAxe", 0));
found = true;
}
}
// Chest
if(!found) if(!found)
{ {
ItemSpec specs[9]; ItemSpec specs[9];
@ -3063,6 +3199,45 @@ void Server::SendInventory(u16 peer_id)
} }
} }
// Furnace
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE);
specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE);
specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE);
specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE);
specs[5] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE);
specs[6] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE);
specs[7] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE);
specs[8] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE);
if(checkItemCombination(items, specs))
{
rlist->addItem(new MaterialItem(CONTENT_FURNACE, 1));
found = true;
}
}
// Steel block
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[1] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[2] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[3] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[4] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[5] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[6] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[7] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[8] = ItemSpec(ITEM_CRAFT, "steel_ingot");
if(checkItemCombination(items, specs))
{
rlist->addItem(new MaterialItem(CONTENT_STEEL, 1));
found = true;
}
}
} }
} // if creative_mode == false } // if creative_mode == false
@ -3350,6 +3525,7 @@ void setCreativeInventory(Player *player)
// CONTENT_IGNORE-terminated list // CONTENT_IGNORE-terminated list
u8 material_items[] = { u8 material_items[] = {
CONTENT_TORCH, CONTENT_TORCH,
CONTENT_COBBLE,
CONTENT_MUD, CONTENT_MUD,
CONTENT_STONE, CONTENT_STONE,
CONTENT_SAND, CONTENT_SAND,