better caves

This commit is contained in:
Perttu Ahola 2010-12-25 16:04:51 +02:00
parent c37eb9b139
commit 07a759fdb8
9 changed files with 404 additions and 157 deletions

@ -93,19 +93,35 @@ GUIInventoryMenu::GUIInventoryMenu(gui::IGUIEnvironment* env,
GUIInventoryMenu::~GUIInventoryMenu() GUIInventoryMenu::~GUIInventoryMenu()
{ {
removeChildren();
if(m_selected_item) if(m_selected_item)
delete m_selected_item; delete m_selected_item;
} }
void GUIInventoryMenu::removeChildren()
{
{
gui::IGUIElement *e = getElementFromId(256);
if(e != NULL)
e->remove();
}
}
void GUIInventoryMenu::regenerateGui(v2u32 screensize) void GUIInventoryMenu::regenerateGui(v2u32 screensize)
{ {
// Remove children
removeChildren();
padding = v2s32(24,24); padding = v2s32(24,24);
spacing = v2s32(60,56); spacing = v2s32(60,56);
imgsize = v2s32(48,48); imgsize = v2s32(48,48);
s32 helptext_h = 15;
v2s32 size( v2s32 size(
padding.X*2+spacing.X*(8-1)+imgsize.X, padding.X*2+spacing.X*(8-1)+imgsize.X,
padding.Y*2+spacing.Y*(7-1)+imgsize.Y padding.Y*2+spacing.Y*(7-1)+imgsize.Y + helptext_h
); );
core::rect<s32> rect( core::rect<s32> rect(
@ -127,6 +143,16 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize)
basepos + v2s32(spacing.X*3, spacing.Y*0), v2s32(3, 3))); basepos + v2s32(spacing.X*3, spacing.Y*0), v2s32(3, 3)));
m_draw_positions.push_back(ListDrawSpec("craftresult", m_draw_positions.push_back(ListDrawSpec("craftresult",
basepos + v2s32(spacing.X*7, spacing.Y*1), v2s32(1, 1))); basepos + v2s32(spacing.X*7, spacing.Y*1), v2s32(1, 1)));
// Add children
{
core::rect<s32> rect(0, 0, size.X-padding.X*2, helptext_h);
rect = rect + v2s32(size.X/2 - rect.getWidth()/2,
size.Y-rect.getHeight()-15);
const wchar_t *text =
L"Left click: Move all items, Right click: Move single item";
Environment->addStaticText(text, rect, false, true, this, 256);
}
} }
GUIInventoryMenu::ItemSpec GUIInventoryMenu::getItemAtPos(v2s32 p) const GUIInventoryMenu::ItemSpec GUIInventoryMenu::getItemAtPos(v2s32 p) const
@ -244,22 +270,25 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
m_inventory->getList(m_selected_item->listname); m_inventory->getList(m_selected_item->listname);
InventoryList *list_to = InventoryList *list_to =
m_inventory->getList(s.listname); m_inventory->getList(s.listname);
// Indicates whether source slot completely empties
bool source_empties = false;
if(list_from && list_to if(list_from && list_to
&& list_from->getItem(m_selected_item->i) != NULL) && list_from->getItem(m_selected_item->i) != NULL)
{ {
dstream<<"Queueing IACTION_MOVE"<<std::endl; dstream<<"Queueing IACTION_MOVE"<<std::endl;
IMoveAction *a = IMoveAction *a = new IMoveAction();
new IMoveAction();
a->count = right ? 1 : 0; a->count = right ? 1 : 0;
a->from_name = m_selected_item->listname; a->from_name = m_selected_item->listname;
a->from_i = m_selected_item->i; a->from_i = m_selected_item->i;
a->to_name = s.listname; a->to_name = s.listname;
a->to_i = s.i; a->to_i = s.i;
m_actions->push_back(a); m_actions->push_back(a);
if(list_from->getItem(m_selected_item->i)->getCount()==1)
source_empties = true;
} }
bool source_empties = false; // Remove selection if target was left-clicked or source
if(list_from && list_from->getItem(m_selected_item->i)->getCount()==1) // slot was emptied
source_empties = true;
if(right == false || source_empties) if(right == false || source_empties)
{ {
delete m_selected_item; delete m_selected_item;

@ -77,6 +77,7 @@ public:
int *active_menu_count); int *active_menu_count);
~GUIInventoryMenu(); ~GUIInventoryMenu();
void removeChildren();
/* /*
Remove and re-add (or reposition) stuff Remove and re-add (or reposition) stuff
*/ */

@ -114,11 +114,21 @@ void GUIPauseMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 180, 220); core::rect<s32> rect(0, 0, 180, 220);
rect = rect + v2s32(size.X/2 - 90 - rect.getWidth(), size.Y/2-rect.getHeight()/2); rect = rect + v2s32(size.X/2 - 90 - rect.getWidth(), size.Y/2-rect.getHeight()/2);
v2u32 max_texture_size;
{
video::IVideoDriver* driver = Environment->getVideoDriver();
max_texture_size = driver->getMaxTextureSize();
}
wchar_t text[200]; wchar_t text[200];
swprintf(text, 200, swprintf(text, 200,
L"Minetest-c55\n" L"Minetest-c55\n"
L"SER_FMT_VER_HIGHEST=%i", L"SER_FMT_VER_HIGHEST=%i\n"
(int)SER_FMT_VER_HIGHEST L"max_texture_size=\n(%i,%i)\n",
(int)SER_FMT_VER_HIGHEST,
max_texture_size.X,
max_texture_size.Y
); );
Environment->addStaticText(text, rect, false, true, this, 259); Environment->addStaticText(text, rect, false, true, this, 259);

@ -1,4 +1,5 @@
#include "irrlichtwrapper.h" #include "irrlichtwrapper.h"
#include "constants.h"
IrrlichtWrapper::IrrlichtWrapper(IrrlichtDevice *device) IrrlichtWrapper::IrrlichtWrapper(IrrlichtDevice *device)
{ {
@ -119,10 +120,17 @@ video::ITexture * CrackTextureMod::make(video::ITexture *original,
assert(baseimage); assert(baseimage);
video::ITexture *other = driver->getTexture("../data/crack.png"); video::ITexture *other = driver->getTexture("../data/crack.png");
// We have to get the whole texture because getting a smaller area // We have to get the whole texture because getting a smaller area
// messes the whole thing. It is probably a bug in Irrlicht. // messes the whole thing. It is probably a bug in Irrlicht.
// NOTE: This doesn't work probably because some systems scale
// the image to fit a texture or something...
/*video::IImage *otherimage = driver->createImage(
other, core::position2d<s32>(0,0), other->getSize());*/
// This should work on more systems
video::IImage *otherimage = driver->createImage( video::IImage *otherimage = driver->createImage(
other, core::position2d<s32>(0,0), other->getSize()); other, core::position2d<s32>(0,0),
v2u32(16, CRACK_ANIMATION_LENGTH * 16));
assert(otherimage); assert(otherimage);

@ -184,9 +184,8 @@ TODO: There has to be some better way to handle static objects than to
Doing now: Doing now:
====================================================================== ======================================================================
TODO: Tool capability table: Which materials, at what speed, how much TODO: When server sees that client is removing an inexistent block or
wearing adding a block to an existent position, resend the MapBlock.
TODO: Transferring of the table from server to client
====================================================================== ======================================================================
@ -1547,8 +1546,8 @@ int main(int argc, char *argv[])
menu->drop();*/ menu->drop();*/
// Launch pause menu // Launch pause menu
/*(new GUIPauseMenu(guienv, guiroot, -1, g_device, (new GUIPauseMenu(guienv, guiroot, -1, g_device,
&g_active_menu_count))->drop();*/ &g_active_menu_count))->drop();
// First line of debug text // First line of debug text
gui::IGUIStaticText *guitext = guienv->addStaticText( gui::IGUIStaticText *guitext = guienv->addStaticText(
@ -2349,23 +2348,36 @@ int main(int argc, char *argv[])
while(client.getChatMessage(message)) while(client.getChatMessage(message))
{ {
chat_lines.push_back(ChatLine(message)); chat_lines.push_back(ChatLine(message));
if(chat_lines.size() > 5) /*if(chat_lines.size() > 6)
{ {
core::list<ChatLine>::Iterator core::list<ChatLine>::Iterator
i = chat_lines.begin(); i = chat_lines.begin();
chat_lines.erase(i); chat_lines.erase(i);
} }*/
} }
// Append them to form the whole static text and throw // Append them to form the whole static text and throw
// it to the gui element // it to the gui element
std::wstring whole; std::wstring whole;
// This will correspond to the line number counted from
// top to bottom, from size-1 to 0
s16 line_number = chat_lines.size();
// Count of messages to be removed from the top
u16 to_be_removed_count = 0; u16 to_be_removed_count = 0;
for(core::list<ChatLine>::Iterator for(core::list<ChatLine>::Iterator
i = chat_lines.begin(); i = chat_lines.begin();
i != chat_lines.end(); i++) i != chat_lines.end(); i++)
{ {
// After this, line number is valid for this loop
line_number--;
// Increment age
(*i).age += dtime; (*i).age += dtime;
if((*i).age > 300.0) /*
This results in a maximum age of 60*6 to the
lowermost line and a maximum of 6 lines
*/
float allowed_age = (6-line_number) * 60.0;
if((*i).age > allowed_age)
{ {
to_be_removed_count++; to_be_removed_count++;
continue; continue;

@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "voxel.h" #include "voxel.h"
#include "porting.h" #include "porting.h"
#if 0
MapBlockPointerCache::MapBlockPointerCache(Map *map) MapBlockPointerCache::MapBlockPointerCache(Map *map)
{ {
m_map = map; m_map = map;
@ -62,6 +63,7 @@ MapBlock * MapBlockPointerCache::getBlockNoCreate(v3s16 p)
m_blocks[p] = b; m_blocks[p] = b;
return b; return b;
} }
#endif
/* /*
Map Map
@ -1728,23 +1730,24 @@ MapBlock * ServerMap::emergeBlock(
block->unDummify(); block->unDummify();
} }
// Randomize a bit. This makes dungeons. #if 0
/*bool low_block_is_empty = false; /*
if(rand() % 4 == 0) Initialize dungeon making by creating a random table
low_block_is_empty = true;*/ */
const s32 ued_max = 5;
const s32 ued = 4; const s32 ued_min = 3;
//const s32 ued = 8; bool underground_emptiness[ued_max*ued_max*ued_max];
bool underground_emptiness[ued*ued*ued]; s32 ued = (rand()%(ued_max-ued_min+1))+1;
//s32 ued = ued_max;
for(s32 i=0; i<ued*ued*ued; i++) for(s32 i=0; i<ued*ued*ued; i++)
{ {
underground_emptiness[i] = ((rand() % 5) == 0); underground_emptiness[i] = ((rand() % 5) == 0);
} }
#if 1
/* /*
This is a messy hack to sort the emptiness a bit This is a messy hack to sort the emptiness a bit
*/ */
// Iterator through a few times
for(s32 j=0; j<2; j++) for(s32 j=0; j<2; j++)
for(s32 y0=0; y0<ued; y0++) for(s32 y0=0; y0<ued; y0++)
for(s32 z0=0; z0<ued; z0++) for(s32 z0=0; z0<ued; z0++)
@ -1764,6 +1767,7 @@ MapBlock * ServerMap::emergeBlock(
/*v3s16(0,1,0), // top /*v3s16(0,1,0), // top
v3s16(0,-1,0), // bottom*/ v3s16(0,-1,0), // bottom*/
}; };
for(s32 i=0; i<4; i++) for(s32 i=0; i<4; i++)
{ {
v3s16 p1 = p0 + dirs[i]; v3s16 p1 = p0 + dirs[i];
@ -1809,6 +1813,140 @@ MapBlock * ServerMap::emergeBlock(
} }
#endif #endif
/*
Create dungeon making table
*/
const s32 ued = MAP_BLOCKSIZE;
bool underground_emptiness[ued*ued*ued];
for(s32 i=0; i<ued*ued*ued; i++)
{
underground_emptiness[i] = 0;
}
// Generate dungeons
{
/*
Initialize orp and ors. Try to find if some neighboring
MapBlock has a tunnel ended in its side
*/
v3f orp;
s16 ors;
// Check z-
try
{
s16 z = -1;
for(s16 y=0; y<ued; y++)
for(s16 x=0; x<ued; x++)
{
v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
if(getNode(ap).d == CONTENT_AIR)
{
orp = v3f(x+1,y+1,0);
ors = 4;
}
}
}
catch(InvalidPositionException &e){}
// Check z+
try
{
s16 z = ued;
for(s16 y=0; y<ued; y++)
for(s16 x=0; x<ued; x++)
{
v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
if(getNode(ap).d == CONTENT_AIR)
{
orp = v3f(x+1,y+1,ued-1);
ors = 4;
}
}
}
catch(InvalidPositionException &e){}
// Check x-
try
{
s16 x = -1;
for(s16 y=0; y<ued; y++)
for(s16 z=0; z<ued; z++)
{
v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
if(getNode(ap).d == CONTENT_AIR)
{
orp = v3f(0,y+1,z+1);
ors = 4;
}
}
}
catch(InvalidPositionException &e){}
// Check x+
try
{
s16 x = ued;
for(s16 y=0; y<ued; y++)
for(s16 z=0; z<ued; z++)
{
v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
if(getNode(ap).d == CONTENT_AIR)
{
orp = v3f(ued-1,y+1,z+1);
ors = 4;
}
}
}
catch(InvalidPositionException &e){}
/*
Generate some tunnel starting from orp and ors
*/
for(u16 i=0; i<3; i++)
{
v3f rp(
(float)(rand()%(ued-1))+0.5,
(float)(rand()%(ued-1))+0.5,
(float)(rand()%(ued-1))+0.5
);
s16 min_d = 0;
s16 max_d = 4;
s16 rs = (rand()%(max_d-min_d+1))+min_d;
v3f vec = rp - orp;
for(float f=0; f<1.0; f+=0.04)
{
v3f fp = orp + vec * f;
v3s16 cp(fp.X, fp.Y, fp.Z);
s16 d0 = -rs/2;
s16 d1 = d0 + rs - 1;
for(s16 z0=d0; z0<=d1; z0++)
{
s16 si = rs - abs(z0);
for(s16 x0=-si; x0<=si-1; x0++)
{
s16 si2 = rs - abs(x0);
for(s16 y0=-si2+1; y0<=si2-1; y0++)
{
s16 z = cp.Z + z0;
s16 y = cp.Y + y0;
s16 x = cp.X + x0;
v3s16 p(x,y,z);
if(isInArea(p, ued) == false)
continue;
underground_emptiness[ued*ued*z + ued*y + x] = 1;
}
}
}
}
orp = rp;
ors = rs;
}
}
// This is the basic material of what the visible flat ground // This is the basic material of what the visible flat ground
// will consist of // will consist of
u8 material = CONTENT_GRASS; u8 material = CONTENT_GRASS;

@ -43,6 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class Map; class Map;
#if 0
/* /*
A cache for short-term fast access to map data A cache for short-term fast access to map data
@ -108,6 +109,7 @@ private:
u32 m_from_cache_count; u32 m_from_cache_count;
u32 m_from_map_count; u32 m_from_map_count;
}; };
#endif
class CacheLock class CacheLock
{ {
@ -303,6 +305,7 @@ public:
} }
// virtual from NodeContainer // virtual from NodeContainer
// throws InvalidPositionException if not found
MapNode getNode(v3s16 p) MapNode getNode(v3s16 p)
{ {
v3s16 blockpos = getNodeBlockPos(p); v3s16 blockpos = getNodeBlockPos(p);
@ -313,6 +316,7 @@ public:
} }
// virtual from NodeContainer // virtual from NodeContainer
// throws InvalidPositionException if not found
void setNode(v3s16 p, MapNode & n) void setNode(v3s16 p, MapNode & n)
{ {
v3s16 blockpos = getNodeBlockPos(p); v3s16 blockpos = getNodeBlockPos(p);

@ -2215,13 +2215,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
} }
else if(command == TOSERVER_INVENTORY_ACTION) else if(command == TOSERVER_INVENTORY_ACTION)
{ {
// Ignore inventory changes if in creative mode /*// Ignore inventory changes if in creative mode
if(g_settings.getBool("creative_mode") == true) if(g_settings.getBool("creative_mode") == true)
{ {
dstream<<"TOSERVER_INVENTORY_ACTION: ignoring in creative mode" dstream<<"TOSERVER_INVENTORY_ACTION: ignoring in creative mode"
<<std::endl; <<std::endl;
return; return;
} }*/
// Strip command and create a stream // Strip command and create a stream
std::string datastring((char*)&data[2], datasize-2); std::string datastring((char*)&data[2], datasize-2);
dstream<<"TOSERVER_INVENTORY_ACTION: data="<<datastring<<std::endl; dstream<<"TOSERVER_INVENTORY_ACTION: data="<<datastring<<std::endl;
@ -2231,10 +2231,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
if(a != NULL) if(a != NULL)
{ {
/* /*
Handle craftresult specially Handle craftresult specially if not in creative mode
*/ */
bool disable_action = false; bool disable_action = false;
if(a->getType() == IACTION_MOVE) if(a->getType() == IACTION_MOVE
&& g_settings.getBool("creative_mode") == false)
{ {
IMoveAction *ma = (IMoveAction*)a; IMoveAction *ma = (IMoveAction*)a;
// Don't allow moving anything to craftresult // Don't allow moving anything to craftresult
@ -2311,13 +2312,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
message += (wchar_t)readU16(buf); message += (wchar_t)readU16(buf);
} }
dstream<<"CHAT: "<<wide_to_narrow(message)<<std::endl;
// Get player name of this client // Get player name of this client
std::wstring name = narrow_to_wide(player->getName()); std::wstring name = narrow_to_wide(player->getName());
std::wstring line = std::wstring(L"<")+name+L"> "+message; std::wstring line = std::wstring(L"<")+name+L"> "+message;
dstream<<"CHAT: "<<wide_to_narrow(line)<<std::endl;
/* /*
Send the message to all other clients Send the message to all other clients
*/ */
@ -2674,127 +2675,128 @@ void Server::SendInventory(u16 peer_id)
/* /*
Calculate crafting stuff Calculate crafting stuff
*/ */
if(g_settings.getBool("creative_mode") == false)
InventoryList *clist = player->inventory.getList("craft");
InventoryList *rlist = player->inventory.getList("craftresult");
if(rlist)
{ {
rlist->clearItems(); InventoryList *clist = player->inventory.getList("craft");
} InventoryList *rlist = player->inventory.getList("craftresult");
if(clist && rlist) if(rlist)
{
InventoryItem *items[9];
for(u16 i=0; i<9; i++)
{ {
items[i] = clist->getItem(i); rlist->clearItems();
} }
if(clist && rlist)
bool found = false;
// Wood
if(!found)
{ {
ItemSpec specs[9]; InventoryItem *items[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_TREE); for(u16 i=0; i<9; i++)
if(checkItemCombination(items, specs))
{ {
rlist->addItem(new MaterialItem(CONTENT_WOOD, 4)); items[i] = clist->getItem(i);
found = true; }
bool found = false;
// Wood
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_TREE);
if(checkItemCombination(items, specs))
{
rlist->addItem(new MaterialItem(CONTENT_WOOD, 4));
found = true;
}
}
// Stick
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
if(checkItemCombination(items, specs))
{
rlist->addItem(new CraftItem("Stick", 4));
found = true;
}
}
// Sign
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[4] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[5] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
if(checkItemCombination(items, specs))
{
rlist->addItem(new MapBlockObjectItem("Sign"));
found = true;
}
}
// Torch
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_COALSTONE);
specs[3] = ItemSpec(ITEM_CRAFT, "Stick");
if(checkItemCombination(items, specs))
{
rlist->addItem(new MaterialItem(CONTENT_TORCH, 4));
found = true;
}
}
// Wooden pick
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[2] = 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("WPick", 0));
found = true;
}
}
// Stone pick
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_STONE);
specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_STONE);
specs[2] = 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("STPick", 0));
found = true;
}
}
// Mese pick
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE);
specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE);
specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE);
specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
if(checkItemCombination(items, specs))
{
rlist->addItem(new ToolItem("MesePick", 0));
found = true;
}
} }
} }
} // if creative_mode == false
// Stick
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
if(checkItemCombination(items, specs))
{
rlist->addItem(new CraftItem("Stick", 4));
found = true;
}
}
// Sign
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[4] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[5] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
if(checkItemCombination(items, specs))
{
rlist->addItem(new MapBlockObjectItem("Sign"));
found = true;
}
}
// Torch
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_COALSTONE);
specs[3] = ItemSpec(ITEM_CRAFT, "Stick");
if(checkItemCombination(items, specs))
{
rlist->addItem(new MaterialItem(CONTENT_TORCH, 4));
found = true;
}
}
// Wooden pick
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[2] = 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("WPick", 0));
found = true;
}
}
// Stone pick
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_STONE);
specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_STONE);
specs[2] = 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("STPick", 0));
found = true;
}
}
// Mese pick
if(!found)
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE);
specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE);
specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE);
specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
if(checkItemCombination(items, specs))
{
rlist->addItem(new ToolItem("MesePick", 0));
found = true;
}
}
}
/* /*
Serialize it Serialize it
@ -3025,18 +3027,32 @@ void Server::handlePeerChange(PeerChange &c)
if(g_settings.getBool("creative_mode")) if(g_settings.getBool("creative_mode"))
{ {
// Give a good pick // Give some good picks
{ {
InventoryItem *item = new ToolItem("STPick", 32000); InventoryItem *item = new ToolItem("STPick", 0);
void* r = player->inventory.addItem("main", item); void* r = player->inventory.addItem("main", item);
assert(r == NULL); assert(r == NULL);
} }
// Give all materials {
InventoryItem *item = new ToolItem("MesePick", 0);
void* r = player->inventory.addItem("main", item);
assert(r == NULL);
}
/*
Give materials
*/
assert(USEFUL_CONTENT_COUNT <= PLAYER_INVENTORY_SIZE); assert(USEFUL_CONTENT_COUNT <= PLAYER_INVENTORY_SIZE);
// add torch first
InventoryItem *item = new MaterialItem(CONTENT_TORCH, 1);
player->inventory.addItem("main", item);
// Then others
for(u16 i=0; i<USEFUL_CONTENT_COUNT; i++) for(u16 i=0; i<USEFUL_CONTENT_COUNT; i++)
{ {
// Skip some materials // Skip some materials
if(i == CONTENT_OCEAN) if(i == CONTENT_OCEAN || i == CONTENT_TORCH)
continue; continue;
InventoryItem *item = new MaterialItem(i, 1); InventoryItem *item = new MaterialItem(i, 1);
@ -3048,12 +3064,6 @@ void Server::handlePeerChange(PeerChange &c)
void* r = player->inventory.addItem("main", item); void* r = player->inventory.addItem("main", item);
assert(r == NULL); assert(r == NULL);
} }
/*// Rat
{
InventoryItem *item = new MapBlockObjectItem("Rat");
bool r = player->inventory.addItem("main", item);
assert(r == true);
}*/
} }
else else
{ {

@ -550,6 +550,41 @@ inline bool isInArea(v2s16 p, s16 d)
); );
} }
inline s16 rangelim(s16 i, s16 min, s16 max)
{
if(i < min)
return min;
if(i > max)
return max;
return i;
}
inline s16 rangelim(s16 i, s16 max)
{
if(i < 0)
return 0;
if(i > max)
return max;
return i;
}
inline v3s16 arealim(v3s16 p, s16 d)
{
if(p.X < 0)
p.X = 0;
if(p.Y < 0)
p.Y = 0;
if(p.Z < 0)
p.Z = 0;
if(p.X > d-1)
p.X = d-1;
if(p.Y > d-1)
p.Y = d-1;
if(p.Z > d-1)
p.Z = d-1;
return p;
}
inline std::wstring narrow_to_wide(const std::string& mbs) inline std::wstring narrow_to_wide(const std::string& mbs)
{ {
size_t wcl = mbs.size(); size_t wcl = mbs.size();