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
BIN
data/cobble.png
Normal file
After Width: | Height: | Size: 830 B |
BIN
data/steel_block.png
Normal file
After Width: | Height: | Size: 219 B |
BIN
data/steel_ingot.png
Normal file
After Width: | Height: | Size: 207 B |
BIN
data/stone.png
Before Width: | Height: | Size: 846 B After Width: | Height: | Size: 806 B |
BIN
data/tool_steelaxe.png
Normal file
After Width: | Height: | Size: 207 B |
BIN
data/tool_steelpick.png
Normal file
After Width: | Height: | Size: 272 B |
BIN
data/tool_steelshovel.png
Normal file
After Width: | Height: | Size: 235 B |
BIN
data/tool_stoneaxe.png
Normal file
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
After Width: | Height: | Size: 206 B |
BIN
data/tool_woodaxe.png
Normal file
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
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";
|
||||||
|
|
||||||
|
98
src/map.cpp
@ -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;
|
||||||
};
|
};
|
||||||
|
214
src/server.cpp
@ -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,
|
||||||
|