forked from Mirrorlandia_minetest/minetest
base stuff for item->object conversion
This commit is contained in:
parent
10b06419ab
commit
f15670379d
BIN
data/sign.png
BIN
data/sign.png
Binary file not shown.
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
123
src/client.cpp
123
src/client.cpp
@ -568,6 +568,39 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||||||
// making some copypasta
|
// making some copypasta
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
if(command == TOCLIENT_REMOVENODE)
|
||||||
|
{
|
||||||
|
if(datasize < 8)
|
||||||
|
return;
|
||||||
|
v3s16 p;
|
||||||
|
p.X = readS16(&data[2]);
|
||||||
|
p.Y = readS16(&data[4]);
|
||||||
|
p.Z = readS16(&data[6]);
|
||||||
|
|
||||||
|
//TimeTaker t1("TOCLIENT_REMOVENODE", g_device);
|
||||||
|
|
||||||
|
// This will clear the cracking animation after digging
|
||||||
|
((ClientMap&)m_env.getMap()).clearTempMod(p);
|
||||||
|
|
||||||
|
removeNode(p);
|
||||||
|
}
|
||||||
|
else if(command == TOCLIENT_ADDNODE)
|
||||||
|
{
|
||||||
|
if(datasize < 8 + MapNode::serializedLength(ser_version))
|
||||||
|
return;
|
||||||
|
|
||||||
|
v3s16 p;
|
||||||
|
p.X = readS16(&data[2]);
|
||||||
|
p.Y = readS16(&data[4]);
|
||||||
|
p.Z = readS16(&data[6]);
|
||||||
|
|
||||||
|
//TimeTaker t1("TOCLIENT_ADDNODE", g_device);
|
||||||
|
|
||||||
|
MapNode n;
|
||||||
|
n.deSerialize(&data[8], ser_version);
|
||||||
|
|
||||||
|
addNode(p, n);
|
||||||
|
}
|
||||||
if(command == TOCLIENT_PLAYERPOS)
|
if(command == TOCLIENT_PLAYERPOS)
|
||||||
{
|
{
|
||||||
dstream<<"WARNING: Received deprecated TOCLIENT_PLAYERPOS"
|
dstream<<"WARNING: Received deprecated TOCLIENT_PLAYERPOS"
|
||||||
@ -1023,7 +1056,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||||||
/*
|
/*
|
||||||
Returns true if there was something in queue
|
Returns true if there was something in queue
|
||||||
*/
|
*/
|
||||||
bool Client::AsyncProcessPacket(LazyMeshUpdater &mesh_updater)
|
bool Client::AsyncProcessPacket()
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
|
||||||
@ -1053,40 +1086,7 @@ bool Client::AsyncProcessPacket(LazyMeshUpdater &mesh_updater)
|
|||||||
|
|
||||||
ToClientCommand command = (ToClientCommand)readU16(&data[0]);
|
ToClientCommand command = (ToClientCommand)readU16(&data[0]);
|
||||||
|
|
||||||
if(command == TOCLIENT_REMOVENODE)
|
if(command == TOCLIENT_BLOCKDATA)
|
||||||
{
|
|
||||||
if(datasize < 8)
|
|
||||||
return true;
|
|
||||||
v3s16 p;
|
|
||||||
p.X = readS16(&data[2]);
|
|
||||||
p.Y = readS16(&data[4]);
|
|
||||||
p.Z = readS16(&data[6]);
|
|
||||||
|
|
||||||
//TimeTaker t1("TOCLIENT_REMOVENODE", g_device);
|
|
||||||
|
|
||||||
// This will clear the cracking animation after digging
|
|
||||||
((ClientMap&)m_env.getMap()).clearTempMod(p);
|
|
||||||
|
|
||||||
removeNode(p);
|
|
||||||
}
|
|
||||||
else if(command == TOCLIENT_ADDNODE)
|
|
||||||
{
|
|
||||||
if(datasize < 8 + MapNode::serializedLength(ser_version))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
v3s16 p;
|
|
||||||
p.X = readS16(&data[2]);
|
|
||||||
p.Y = readS16(&data[4]);
|
|
||||||
p.Z = readS16(&data[6]);
|
|
||||||
|
|
||||||
//TimeTaker t1("TOCLIENT_ADDNODE", g_device);
|
|
||||||
|
|
||||||
MapNode n;
|
|
||||||
n.deSerialize(&data[8], ser_version);
|
|
||||||
|
|
||||||
addNode(p, n);
|
|
||||||
}
|
|
||||||
else if(command == TOCLIENT_BLOCKDATA)
|
|
||||||
{
|
{
|
||||||
// Ignore too small packet
|
// Ignore too small packet
|
||||||
if(datasize < 8)
|
if(datasize < 8)
|
||||||
@ -1226,24 +1226,11 @@ bool Client::AsyncProcessData()
|
|||||||
{
|
{
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
// We want to update the meshes as soon as a single packet has
|
bool r = AsyncProcessPacket();
|
||||||
// been processed
|
|
||||||
LazyMeshUpdater mesh_updater(&m_env);
|
|
||||||
bool r = AsyncProcessPacket(mesh_updater);
|
|
||||||
if(r == false)
|
if(r == false)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/*LazyMeshUpdater mesh_updater(&m_env);
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
bool r = AsyncProcessPacket(mesh_updater);
|
|
||||||
if(r == false)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Send(u16 channelnum, SharedBuffer<u8> data, bool reliable)
|
void Client::Send(u16 channelnum, SharedBuffer<u8> data, bool reliable)
|
||||||
@ -1252,42 +1239,6 @@ void Client::Send(u16 channelnum, SharedBuffer<u8> data, bool reliable)
|
|||||||
m_con.Send(PEER_ID_SERVER, channelnum, data, reliable);
|
m_con.Send(PEER_ID_SERVER, channelnum, data, reliable);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void Client::fetchBlock(v3s16 p, u8 flags)
|
|
||||||
{
|
|
||||||
if(connectedAndInitialized() == false)
|
|
||||||
throw ClientNotReadyException
|
|
||||||
("ClientNotReadyException: connectedAndInitialized() == false");
|
|
||||||
|
|
||||||
/*dstream<<"Client::fetchBlock(): Sending GETBLOCK for ("
|
|
||||||
<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
|
|
||||||
|
|
||||||
JMutexAutoLock conlock(m_con_mutex);
|
|
||||||
|
|
||||||
SharedBuffer<u8> data(9);
|
|
||||||
writeU16(&data[0], TOSERVER_GETBLOCK);
|
|
||||||
writeS16(&data[2], p.X);
|
|
||||||
writeS16(&data[4], p.Y);
|
|
||||||
writeS16(&data[6], p.Z);
|
|
||||||
writeU8(&data[8], flags);
|
|
||||||
m_con.Send(PEER_ID_SERVER, 1, data, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Calls fetchBlock() on some nearby missing blocks.
|
|
||||||
|
|
||||||
Returns when any of various network load indicators go over limit.
|
|
||||||
|
|
||||||
Does nearly the same thing as the old updateChangedVisibleArea()
|
|
||||||
*/
|
|
||||||
void Client::fetchBlocks()
|
|
||||||
{
|
|
||||||
if(connectedAndInitialized() == false)
|
|
||||||
throw ClientNotReadyException
|
|
||||||
("ClientNotReadyException: connectedAndInitialized() == false");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool Client::isFetchingBlocks()
|
bool Client::isFetchingBlocks()
|
||||||
{
|
{
|
||||||
JMutexAutoLock conlock(m_con_mutex);
|
JMutexAutoLock conlock(m_con_mutex);
|
||||||
@ -1369,7 +1320,7 @@ void Client::clickObject(u8 button, v3s16 blockpos, s16 id, u16 item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
[0] u16 command
|
[0] u16 command=TOSERVER_CLICK_OBJECT
|
||||||
[2] u8 button (0=left, 1=right)
|
[2] u8 button (0=left, 1=right)
|
||||||
[3] v3s16 block
|
[3] v3s16 block
|
||||||
[9] s16 id
|
[9] s16 id
|
||||||
|
34
src/client.h
34
src/client.h
@ -101,38 +101,6 @@ struct IncomingPacket
|
|||||||
s32 *m_refcount;
|
s32 *m_refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Remove this. It is not used as supposed.
|
|
||||||
class LazyMeshUpdater
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LazyMeshUpdater(Environment *env)
|
|
||||||
{
|
|
||||||
m_env = env;
|
|
||||||
}
|
|
||||||
~LazyMeshUpdater()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
TODO: This could be optimized. It will currently
|
|
||||||
double-update some blocks.
|
|
||||||
*/
|
|
||||||
for(core::map<v3s16, bool>::Iterator
|
|
||||||
i = m_blocks.getIterator();
|
|
||||||
i.atEnd() == false; i++)
|
|
||||||
{
|
|
||||||
v3s16 p = i.getNode()->getKey();
|
|
||||||
m_env->updateMeshes(p);
|
|
||||||
}
|
|
||||||
m_blocks.clear();
|
|
||||||
}
|
|
||||||
void add(v3s16 p)
|
|
||||||
{
|
|
||||||
m_blocks.insert(p, true);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
Environment *m_env;
|
|
||||||
core::map<v3s16, bool> m_blocks;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Client : public con::PeerHandler
|
class Client : public con::PeerHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -175,7 +143,7 @@ public:
|
|||||||
|
|
||||||
void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id);
|
void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id);
|
||||||
// Returns true if something was received
|
// Returns true if something was received
|
||||||
bool AsyncProcessPacket(LazyMeshUpdater &mesh_updater);
|
bool AsyncProcessPacket();
|
||||||
bool AsyncProcessData();
|
bool AsyncProcessData();
|
||||||
void Send(u16 channelnum, SharedBuffer<u8> data, bool reliable);
|
void Send(u16 channelnum, SharedBuffer<u8> data, bool reliable);
|
||||||
|
|
||||||
|
@ -66,6 +66,14 @@ InventoryItem* InventoryItem::deSerialize(std::istream &is)
|
|||||||
std::getline(is, inventorystring, '|');
|
std::getline(is, inventorystring, '|');
|
||||||
return new MapBlockObjectItem(inventorystring);
|
return new MapBlockObjectItem(inventorystring);
|
||||||
}
|
}
|
||||||
|
else if(name == "ToolItem")
|
||||||
|
{
|
||||||
|
std::string toolname;
|
||||||
|
std::getline(is, toolname, ' ');
|
||||||
|
u16 wear;
|
||||||
|
is>>wear;
|
||||||
|
return new ToolItem(toolname, wear);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dstream<<"Unknown InventoryItem name=\""<<name<<"\""<<std::endl;
|
dstream<<"Unknown InventoryItem name=\""<<name<<"\""<<std::endl;
|
||||||
@ -126,6 +134,19 @@ MapBlockObject * MapBlockObjectItem::createObject
|
|||||||
RatObject *obj = new RatObject(NULL, -1, pos);
|
RatObject *obj = new RatObject(NULL, -1, pos);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
else if(name == "ItemObj")
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Now we are an inventory item containing the serialization
|
||||||
|
string of an object that contains the serialization
|
||||||
|
string of an inventory item. Fuck this.
|
||||||
|
*/
|
||||||
|
//assert(0);
|
||||||
|
dstream<<__FUNCTION_NAME<<": WARNING: Ignoring ItemObj "
|
||||||
|
<<"because an item-object should never be inside "
|
||||||
|
<<"an object-item."<<std::endl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -196,6 +196,78 @@ private:
|
|||||||
std::string m_inventorystring;
|
std::string m_inventorystring;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ToolItem : public InventoryItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ToolItem(std::string toolname, u16 wear)
|
||||||
|
{
|
||||||
|
m_toolname = toolname;
|
||||||
|
m_wear = wear;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Implementation interface
|
||||||
|
*/
|
||||||
|
virtual const char* getName() const
|
||||||
|
{
|
||||||
|
return "ToolItem";
|
||||||
|
}
|
||||||
|
virtual void serialize(std::ostream &os)
|
||||||
|
{
|
||||||
|
os<<getName();
|
||||||
|
os<<" ";
|
||||||
|
os<<m_toolname;
|
||||||
|
os<<" ";
|
||||||
|
os<<m_wear;
|
||||||
|
}
|
||||||
|
virtual InventoryItem* clone()
|
||||||
|
{
|
||||||
|
return new ToolItem(m_toolname, m_wear);
|
||||||
|
}
|
||||||
|
#ifndef SERVER
|
||||||
|
video::ITexture * getImage()
|
||||||
|
{
|
||||||
|
if(m_toolname == "WPick")
|
||||||
|
return g_irrlicht->getTexture("../data/tool_wpick.png");
|
||||||
|
if(m_toolname == "STPick")
|
||||||
|
return g_irrlicht->getTexture("../data/tool_stpick.png");
|
||||||
|
// Default to cloud texture
|
||||||
|
return g_irrlicht->getTexture(tile_texture_path_get(TILE_CLOUD));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
std::string getText()
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
u16 f = 4;
|
||||||
|
u16 d = 65535/f;
|
||||||
|
u16 i;
|
||||||
|
for(i=0; i<(65535-m_wear)/d; i++)
|
||||||
|
os<<'X';
|
||||||
|
for(; i<f; i++)
|
||||||
|
os<<'-';
|
||||||
|
return os.str();
|
||||||
|
|
||||||
|
/*std::ostringstream os;
|
||||||
|
os<<m_toolname;
|
||||||
|
os<<" ";
|
||||||
|
os<<(m_wear/655);
|
||||||
|
return os.str();*/
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Special methods
|
||||||
|
*/
|
||||||
|
std::string getToolName()
|
||||||
|
{
|
||||||
|
return m_toolname;
|
||||||
|
}
|
||||||
|
u16 getWear()
|
||||||
|
{
|
||||||
|
return m_wear;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::string m_toolname;
|
||||||
|
u16 m_wear;
|
||||||
|
};
|
||||||
|
|
||||||
class InventoryList
|
class InventoryList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
136
src/main.cpp
136
src/main.cpp
@ -105,6 +105,10 @@ SUGG: Make the amount of blocks sending to client and the total
|
|||||||
main network eater of this system, so it is the one that has
|
main network eater of this system, so it is the one that has
|
||||||
to be throttled so that RTTs stay low.
|
to be throttled so that RTTs stay low.
|
||||||
|
|
||||||
|
SUGG: Meshes of blocks could be split into 6 meshes facing into
|
||||||
|
different directions and then only those drawn that need to be
|
||||||
|
- Also an 1-dimensional tile map would be nice probably
|
||||||
|
|
||||||
TODO: Untie client network operations from framerate
|
TODO: Untie client network operations from framerate
|
||||||
- Needs some input queues or something
|
- Needs some input queues or something
|
||||||
- Not really necessary?
|
- Not really necessary?
|
||||||
@ -173,7 +177,9 @@ TODO: Check if the usage of Client::isFetchingBlocks() in
|
|||||||
Doing now:
|
Doing now:
|
||||||
======================================================================
|
======================================================================
|
||||||
|
|
||||||
TODO: Convert the text input system to use a modal menu... or something
|
TODO: Tool items
|
||||||
|
|
||||||
|
- Actually, tool items should be just a little special MapBlockItems
|
||||||
|
|
||||||
======================================================================
|
======================================================================
|
||||||
|
|
||||||
@ -269,9 +275,6 @@ extern void set_default_settings();
|
|||||||
Random stuff
|
Random stuff
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//u16 g_selected_material = 0;
|
|
||||||
u16 g_selected_item = 0;
|
|
||||||
|
|
||||||
IrrlichtDevice *g_device = NULL;
|
IrrlichtDevice *g_device = NULL;
|
||||||
Client *g_client = NULL;
|
Client *g_client = NULL;
|
||||||
|
|
||||||
@ -292,6 +295,8 @@ Queue<InventoryAction*> inventory_action_queue;
|
|||||||
// This is a copy of the inventory that the client's environment has
|
// This is a copy of the inventory that the client's environment has
|
||||||
Inventory local_inventory;
|
Inventory local_inventory;
|
||||||
|
|
||||||
|
u16 g_selected_item = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Debug streams
|
Debug streams
|
||||||
*/
|
*/
|
||||||
@ -1833,6 +1838,10 @@ int main(int argc, char *argv[])
|
|||||||
MapBlockObject *selected_object = client.getSelectedObject
|
MapBlockObject *selected_object = client.getSelectedObject
|
||||||
(d*BS, camera_position, shootline);
|
(d*BS, camera_position, shootline);
|
||||||
|
|
||||||
|
/*
|
||||||
|
If it's pointing to a MapBlockObject
|
||||||
|
*/
|
||||||
|
|
||||||
if(selected_object != NULL)
|
if(selected_object != NULL)
|
||||||
{
|
{
|
||||||
//dstream<<"Client returned selected_object != NULL"<<std::endl;
|
//dstream<<"Client returned selected_object != NULL"<<std::endl;
|
||||||
@ -2041,6 +2050,8 @@ int main(int argc, char *argv[])
|
|||||||
} // regular block
|
} // regular block
|
||||||
} // for coords
|
} // for coords
|
||||||
|
|
||||||
|
static float nodig_delay_counter = 0.0;
|
||||||
|
|
||||||
if(nodefound)
|
if(nodefound)
|
||||||
{
|
{
|
||||||
static v3s16 nodepos_old(-32768,-32768,-32768);
|
static v3s16 nodepos_old(-32768,-32768,-32768);
|
||||||
@ -2048,18 +2059,6 @@ int main(int argc, char *argv[])
|
|||||||
static float dig_time = 0.0;
|
static float dig_time = 0.0;
|
||||||
static u16 dig_index = 0;
|
static u16 dig_index = 0;
|
||||||
|
|
||||||
if(nodepos != nodepos_old)
|
|
||||||
{
|
|
||||||
std::cout<<DTIME<<"Pointing at ("<<nodepos.X<<","
|
|
||||||
<<nodepos.Y<<","<<nodepos.Z<<")"<<std::endl;
|
|
||||||
|
|
||||||
if(nodepos_old != v3s16(-32768,-32768,-32768))
|
|
||||||
{
|
|
||||||
client.clearTempMod(nodepos_old);
|
|
||||||
dig_time = 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hilightboxes.push_back(nodefacebox);
|
hilightboxes.push_back(nodefacebox);
|
||||||
|
|
||||||
if(g_input->getLeftReleased())
|
if(g_input->getLeftReleased())
|
||||||
@ -2067,42 +2066,87 @@ int main(int argc, char *argv[])
|
|||||||
client.clearTempMod(nodepos);
|
client.clearTempMod(nodepos);
|
||||||
dig_time = 0.0;
|
dig_time = 0.0;
|
||||||
}
|
}
|
||||||
if(g_input->getLeftClicked() ||
|
|
||||||
(g_input->getLeftState() && nodepos != nodepos_old))
|
if(nodig_delay_counter > 0.0)
|
||||||
{
|
{
|
||||||
dstream<<DTIME<<"Started digging"<<std::endl;
|
nodig_delay_counter -= dtime;
|
||||||
client.groundAction(0, nodepos, neighbourpos, g_selected_item);
|
|
||||||
}
|
}
|
||||||
if(g_input->getLeftClicked())
|
else
|
||||||
{
|
{
|
||||||
client.setTempMod(nodepos, NodeMod(NODEMOD_CRACK, 0));
|
if(nodepos != nodepos_old)
|
||||||
}
|
|
||||||
if(g_input->getLeftState())
|
|
||||||
{
|
|
||||||
MapNode n = client.getNode(nodepos);
|
|
||||||
|
|
||||||
// TODO: Get this from some table that is sent by server
|
|
||||||
float dig_time_complete = 0.5;
|
|
||||||
if(n.d == CONTENT_STONE)
|
|
||||||
dig_time_complete = 1.5;
|
|
||||||
|
|
||||||
dig_index = (u16)((float)CRACK_ANIMATION_LENGTH
|
|
||||||
* dig_time/dig_time_complete);
|
|
||||||
|
|
||||||
if(dig_index < CRACK_ANIMATION_LENGTH)
|
|
||||||
{
|
{
|
||||||
//dstream<<"dig_index="<<dig_index<<std::endl;
|
std::cout<<DTIME<<"Pointing at ("<<nodepos.X<<","
|
||||||
client.setTempMod(nodepos, NodeMod(NODEMOD_CRACK, dig_index));
|
<<nodepos.Y<<","<<nodepos.Z<<")"<<std::endl;
|
||||||
}
|
|
||||||
else
|
if(nodepos_old != v3s16(-32768,-32768,-32768))
|
||||||
{
|
{
|
||||||
dstream<<DTIME<<"Digging completed"<<std::endl;
|
client.clearTempMod(nodepos_old);
|
||||||
client.groundAction(3, nodepos, neighbourpos, g_selected_item);
|
dig_time = 0.0;
|
||||||
client.clearTempMod(nodepos);
|
}
|
||||||
client.removeNode(nodepos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dig_time += dtime;
|
if(g_input->getLeftClicked() ||
|
||||||
|
(g_input->getLeftState() && nodepos != nodepos_old))
|
||||||
|
{
|
||||||
|
dstream<<DTIME<<"Started digging"<<std::endl;
|
||||||
|
client.groundAction(0, nodepos, neighbourpos, g_selected_item);
|
||||||
|
}
|
||||||
|
if(g_input->getLeftClicked())
|
||||||
|
{
|
||||||
|
client.setTempMod(nodepos, NodeMod(NODEMOD_CRACK, 0));
|
||||||
|
}
|
||||||
|
if(g_input->getLeftState())
|
||||||
|
{
|
||||||
|
MapNode n = client.getNode(nodepos);
|
||||||
|
|
||||||
|
// TODO: Get this from some table that is sent by server
|
||||||
|
float dig_time_complete = 0.5;
|
||||||
|
if(n.d == CONTENT_STONE || n.d == CONTENT_COALSTONE)
|
||||||
|
{
|
||||||
|
dig_time_complete = 10.0;
|
||||||
|
|
||||||
|
InventoryList *mlist = local_inventory.getList("main");
|
||||||
|
if(mlist != NULL)
|
||||||
|
{
|
||||||
|
InventoryItem *item = mlist->getItem(g_selected_item);
|
||||||
|
if((std::string)item->getName() == "ToolItem")
|
||||||
|
{
|
||||||
|
ToolItem *titem = (ToolItem*)item;
|
||||||
|
if(titem->getToolName() == "WPick")
|
||||||
|
{
|
||||||
|
dig_time_complete = 1.2;
|
||||||
|
}
|
||||||
|
else if(titem->getToolName() == "STPick")
|
||||||
|
{
|
||||||
|
dig_time_complete = 0.6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dig_index = (u16)((float)CRACK_ANIMATION_LENGTH
|
||||||
|
* dig_time/dig_time_complete);
|
||||||
|
|
||||||
|
if(dig_index < CRACK_ANIMATION_LENGTH)
|
||||||
|
{
|
||||||
|
//dstream<<"dig_index="<<dig_index<<std::endl;
|
||||||
|
client.setTempMod(nodepos, NodeMod(NODEMOD_CRACK, dig_index));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dstream<<DTIME<<"Digging completed"<<std::endl;
|
||||||
|
client.groundAction(3, nodepos, neighbourpos, g_selected_item);
|
||||||
|
client.clearTempMod(nodepos);
|
||||||
|
client.removeNode(nodepos);
|
||||||
|
|
||||||
|
dig_time = 0;
|
||||||
|
|
||||||
|
nodig_delay_counter = dig_time_complete
|
||||||
|
/ (float)CRACK_ANIMATION_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
dig_time += dtime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(g_input->getRightClicked())
|
if(g_input->getRightClicked())
|
||||||
|
@ -21,6 +21,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "mapblock.h"
|
#include "mapblock.h"
|
||||||
// Only for ::getNodeBox, TODO: Get rid of this
|
// Only for ::getNodeBox, TODO: Get rid of this
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
#include "inventory.h"
|
||||||
|
#include "irrlichtwrapper.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
MapBlockObject
|
MapBlockObject
|
||||||
@ -293,10 +295,101 @@ void RatObject::addToScene(scene::ISceneManager *smgr)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
ItemObject
|
||||||
|
*/
|
||||||
#ifndef SERVER
|
#ifndef SERVER
|
||||||
|
void ItemObject::addToScene(scene::ISceneManager *smgr)
|
||||||
|
{
|
||||||
|
if(m_node != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//video::IVideoDriver* driver = smgr->getVideoDriver();
|
||||||
|
|
||||||
|
// Get image of item for showing
|
||||||
|
video::ITexture *texture = getItemImage();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create a mesh
|
||||||
|
*/
|
||||||
|
|
||||||
|
scene::SMesh *mesh = new scene::SMesh();
|
||||||
|
{
|
||||||
|
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
||||||
|
video::SColor c(255,255,255,255);
|
||||||
|
video::S3DVertex vertices[4] =
|
||||||
|
{
|
||||||
|
/*video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, 0,1),
|
||||||
|
video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 1,1),
|
||||||
|
video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 1,0),
|
||||||
|
video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 0,0),*/
|
||||||
|
video::S3DVertex(BS/3,-BS/2,0, 0,0,0, c, 0,1),
|
||||||
|
video::S3DVertex(-BS/3,-BS/2,0, 0,0,0, c, 1,1),
|
||||||
|
video::S3DVertex(-BS/3,-BS/2+BS*2/3,0, 0,0,0, c, 1,0),
|
||||||
|
video::S3DVertex(BS/3,-BS/2+BS*2/3,0, 0,0,0, c, 0,0),
|
||||||
|
};
|
||||||
|
u16 indices[] = {0,1,2,2,3,0};
|
||||||
|
buf->append(vertices, 4, indices, 6);
|
||||||
|
// Set material
|
||||||
|
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
|
||||||
|
buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
|
||||||
|
buf->getMaterial().setTexture(0, texture);
|
||||||
|
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||||
|
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
|
||||||
|
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||||
|
// Add to mesh
|
||||||
|
mesh->addMeshBuffer(buf);
|
||||||
|
buf->drop();
|
||||||
|
}
|
||||||
|
m_node = smgr->addMeshSceneNode(mesh, NULL);
|
||||||
|
// Set it to use the materials of the meshbuffers directly.
|
||||||
|
// This is needed for changing the texture in the future
|
||||||
|
((scene::IMeshSceneNode*)m_node)->setReadOnlyMaterials(true);
|
||||||
|
mesh->drop();
|
||||||
|
|
||||||
|
updateSceneNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
video::ITexture * ItemObject::getItemImage()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Create an inventory item to see what is its image
|
||||||
|
*/
|
||||||
|
video::ITexture *texture = NULL;
|
||||||
|
InventoryItem *item = createInventoryItem();
|
||||||
|
if(item)
|
||||||
|
texture = item->getImage();
|
||||||
|
/*else
|
||||||
|
texture = g_irrlicht->getTexture("../data/cloud.png");*/
|
||||||
|
if(item)
|
||||||
|
delete item;
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
InventoryItem * ItemObject::createInventoryItem()
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
std::istringstream is(m_itemstring, std::ios_base::binary);
|
||||||
|
InventoryItem *item = InventoryItem::deSerialize(is);
|
||||||
|
dstream<<__FUNCTION_NAME<<": m_itemstring=\""
|
||||||
|
<<m_itemstring<<"\" -> item="<<item
|
||||||
|
<<std::endl;
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
catch(SerializationError &e)
|
||||||
|
{
|
||||||
|
dstream<<__FUNCTION_NAME<<": serialization error: "
|
||||||
|
<<"m_itemstring=\""<<m_itemstring<<"\""<<std::endl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PlayerObject
|
PlayerObject
|
||||||
*/
|
*/
|
||||||
|
#ifndef SERVER
|
||||||
void PlayerObject::addToScene(scene::ISceneManager *smgr)
|
void PlayerObject::addToScene(scene::ISceneManager *smgr)
|
||||||
{
|
{
|
||||||
if(m_node != NULL)
|
if(m_node != NULL)
|
||||||
@ -480,6 +573,10 @@ void MapBlockObjectList::update(std::istream &is, u8 version,
|
|||||||
{
|
{
|
||||||
obj = new RatObject(m_block, id, pos);
|
obj = new RatObject(m_block, id, pos);
|
||||||
}
|
}
|
||||||
|
else if(type_id == MAPBLOCKOBJECT_TYPE_ITEM)
|
||||||
|
{
|
||||||
|
obj = new ItemObject(m_block, id, pos);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// This is fatal because we cannot know the length
|
// This is fatal because we cannot know the length
|
||||||
|
@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#define MAPBLOCKOBJECT_TYPE_PLAYER 0
|
#define MAPBLOCKOBJECT_TYPE_PLAYER 0
|
||||||
#define MAPBLOCKOBJECT_TYPE_SIGN 2
|
#define MAPBLOCKOBJECT_TYPE_SIGN 2
|
||||||
#define MAPBLOCKOBJECT_TYPE_RAT 3
|
#define MAPBLOCKOBJECT_TYPE_RAT 3
|
||||||
|
#define MAPBLOCKOBJECT_TYPE_ITEM 4
|
||||||
// Used for handling selecting special stuff
|
// Used for handling selecting special stuff
|
||||||
//#define MAPBLOCKOBJECT_TYPE_PSEUDO 1000
|
//#define MAPBLOCKOBJECT_TYPE_PSEUDO 1000
|
||||||
|
|
||||||
@ -719,6 +720,182 @@ protected:
|
|||||||
float m_age;
|
float m_age;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
An object on the map that represents an inventory item
|
||||||
|
*/
|
||||||
|
|
||||||
|
class InventoryItem;
|
||||||
|
|
||||||
|
class ItemObject : public MapBlockObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// The constructor of every MapBlockObject should be like this
|
||||||
|
ItemObject(MapBlock *block, s16 id, v3f pos):
|
||||||
|
MapBlockObject(block, id, pos),
|
||||||
|
m_node(NULL)
|
||||||
|
{
|
||||||
|
/*m_selection_box = new core::aabbox3d<f32>
|
||||||
|
(-BS*0.4,-BS*0.5,-BS*0.4, BS*0.4,BS*0.5,BS*0.4);*/
|
||||||
|
m_selection_box = new core::aabbox3d<f32>
|
||||||
|
(-BS/3,-BS/2,-BS/3, BS/3,-BS/2+BS*2/3,BS/3);
|
||||||
|
m_yaw = 0.0;
|
||||||
|
}
|
||||||
|
virtual ~ItemObject()
|
||||||
|
{
|
||||||
|
delete m_selection_box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Implementation interface
|
||||||
|
*/
|
||||||
|
virtual u16 getTypeId() const
|
||||||
|
{
|
||||||
|
return MAPBLOCKOBJECT_TYPE_ITEM;
|
||||||
|
}
|
||||||
|
virtual void serialize(std::ostream &os, u8 version)
|
||||||
|
{
|
||||||
|
serializeBase(os, version);
|
||||||
|
u8 buf[2];
|
||||||
|
|
||||||
|
// Write text length
|
||||||
|
writeU16(buf, m_itemstring.size());
|
||||||
|
os.write((char*)buf, 2);
|
||||||
|
|
||||||
|
// Write text
|
||||||
|
os.write(m_itemstring.c_str(), m_itemstring.size());
|
||||||
|
}
|
||||||
|
virtual void update(std::istream &is, u8 version)
|
||||||
|
{
|
||||||
|
u8 buf[2];
|
||||||
|
|
||||||
|
// Read text length
|
||||||
|
is.read((char*)buf, 2);
|
||||||
|
u16 size = readU16(buf);
|
||||||
|
|
||||||
|
// Read text
|
||||||
|
std::string old_itemstring = m_itemstring;
|
||||||
|
m_itemstring.clear();
|
||||||
|
for(u16 i=0; i<size; i++)
|
||||||
|
{
|
||||||
|
is.read((char*)buf, 1);
|
||||||
|
m_itemstring += buf[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SERVER
|
||||||
|
if(m_itemstring != old_itemstring && m_node)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Update texture
|
||||||
|
*/
|
||||||
|
video::ITexture *texture = getItemImage();
|
||||||
|
scene::IMesh *mesh = m_node->getMesh();
|
||||||
|
if(mesh->getMeshBufferCount() >= 1)
|
||||||
|
{
|
||||||
|
scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
|
||||||
|
//dstream<<"Setting texture "<<texture<<std::endl;
|
||||||
|
buf->getMaterial().setTexture(0, texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSceneNode();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool serverStep(float dtime, u32 daynight_ratio)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SERVER
|
||||||
|
virtual void clientStep(float dtime)
|
||||||
|
{
|
||||||
|
m_yaw += dtime * 90;
|
||||||
|
if(m_yaw >= 360.)
|
||||||
|
m_yaw -= 360.;
|
||||||
|
|
||||||
|
updateSceneNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void addToScene(scene::ISceneManager *smgr);
|
||||||
|
|
||||||
|
virtual void removeFromScene()
|
||||||
|
{
|
||||||
|
if(m_node != NULL)
|
||||||
|
{
|
||||||
|
m_node->remove();
|
||||||
|
m_node = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual void updateLight(u8 light_at_pos)
|
||||||
|
{
|
||||||
|
if(m_node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u8 li = decode_light(light_at_pos);
|
||||||
|
video::SColor color(255,li,li,li);
|
||||||
|
|
||||||
|
scene::IMesh *mesh = m_node->getMesh();
|
||||||
|
|
||||||
|
u16 mc = mesh->getMeshBufferCount();
|
||||||
|
for(u16 j=0; j<mc; j++)
|
||||||
|
{
|
||||||
|
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
||||||
|
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
|
||||||
|
u16 vc = buf->getVertexCount();
|
||||||
|
for(u16 i=0; i<vc; i++)
|
||||||
|
{
|
||||||
|
vertices[i].Color = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
virtual std::string infoText()
|
||||||
|
{
|
||||||
|
return std::string("\"") + m_itemstring + "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::string getInventoryString()
|
||||||
|
{
|
||||||
|
return std::string("ItemObj ")+m_itemstring;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Special methods
|
||||||
|
*/
|
||||||
|
|
||||||
|
InventoryItem * createInventoryItem();
|
||||||
|
|
||||||
|
#ifndef SERVER
|
||||||
|
video::ITexture * getItemImage();
|
||||||
|
|
||||||
|
void updateSceneNode()
|
||||||
|
{
|
||||||
|
if(m_node != NULL)
|
||||||
|
{
|
||||||
|
m_node->setPosition(getAbsolutePos());
|
||||||
|
m_node->setRotation(v3f(0, m_yaw, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void setItemString(std::string inventorystring)
|
||||||
|
{
|
||||||
|
m_itemstring = inventorystring;
|
||||||
|
setBlockChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getItemString()
|
||||||
|
{
|
||||||
|
return m_itemstring;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
scene::IMeshSceneNode *m_node;
|
||||||
|
std::string m_itemstring;
|
||||||
|
f32 m_yaw;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NOTE: Not used.
|
NOTE: Not used.
|
||||||
*/
|
*/
|
||||||
|
117
src/server.cpp
117
src/server.cpp
@ -1635,7 +1635,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
}
|
}
|
||||||
catch(InvalidPositionException &e)
|
catch(InvalidPositionException &e)
|
||||||
{
|
{
|
||||||
derr_server<<"PICK_OBJECT block not found"<<std::endl;
|
derr_server<<"CLICK_OBJECT block not found"<<std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1643,7 +1643,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
|
|
||||||
if(obj == NULL)
|
if(obj == NULL)
|
||||||
{
|
{
|
||||||
derr_server<<"PICK_OBJECT object not found"<<std::endl;
|
derr_server<<"CLICK_OBJECT object not found"<<std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1662,10 +1662,24 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
dout_server<<"Player inventory has no free space"<<std::endl;
|
dout_server<<"Player inventory has no free space"<<std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create the inventory item
|
||||||
|
*/
|
||||||
|
InventoryItem *item = NULL;
|
||||||
|
// If it is an item-object, take the item from it
|
||||||
|
if(obj->getTypeId() == MAPBLOCKOBJECT_TYPE_ITEM)
|
||||||
|
{
|
||||||
|
item = ((ItemObject*)obj)->createInventoryItem();
|
||||||
|
}
|
||||||
|
// Else create an item of the object
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item = new MapBlockObjectItem
|
||||||
|
(obj->getInventoryString());
|
||||||
|
}
|
||||||
|
|
||||||
// Add to inventory and send inventory
|
// Add to inventory and send inventory
|
||||||
InventoryItem *item = new MapBlockObjectItem
|
|
||||||
(obj->getInventoryString());
|
|
||||||
ilist->addItem(item);
|
ilist->addItem(item);
|
||||||
SendInventory(player->peer_id);
|
SendInventory(player->peer_id);
|
||||||
}
|
}
|
||||||
@ -2021,17 +2035,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
v.blitBack(modified_blocks);
|
v.blitBack(modified_blocks);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Handle block object items
|
Handle other items
|
||||||
*/
|
*/
|
||||||
else if(std::string("MBOItem") == item->getName())
|
else
|
||||||
{
|
{
|
||||||
MapBlockObjectItem *oitem = (MapBlockObjectItem*)item;
|
|
||||||
|
|
||||||
/*dout_server<<"Trying to place a MapBlockObjectItem: "
|
|
||||||
"inventorystring=\""
|
|
||||||
<<oitem->getInventoryString()
|
|
||||||
<<"\""<<std::endl;*/
|
|
||||||
|
|
||||||
v3s16 blockpos = getNodeBlockPos(p_over);
|
v3s16 blockpos = getNodeBlockPos(p_over);
|
||||||
|
|
||||||
MapBlock *block = NULL;
|
MapBlock *block = NULL;
|
||||||
@ -2056,25 +2063,61 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
<<"("<<pos.X<<","<<pos.Y<<","<<pos.Z<<")"
|
<<"("<<pos.X<<","<<pos.Y<<","<<pos.Z<<")"
|
||||||
<<std::endl;*/
|
<<std::endl;*/
|
||||||
|
|
||||||
|
MapBlockObject *obj = NULL;
|
||||||
|
|
||||||
MapBlockObject *obj = oitem->createObject
|
/*
|
||||||
(pos, player->getYaw(), player->getPitch());
|
Handle block object items
|
||||||
|
*/
|
||||||
|
if(std::string("MBOItem") == item->getName())
|
||||||
|
{
|
||||||
|
MapBlockObjectItem *oitem = (MapBlockObjectItem*)item;
|
||||||
|
|
||||||
|
/*dout_server<<"Trying to place a MapBlockObjectItem: "
|
||||||
|
"inventorystring=\""
|
||||||
|
<<oitem->getInventoryString()
|
||||||
|
<<"\""<<std::endl;*/
|
||||||
|
|
||||||
|
obj = oitem->createObject
|
||||||
|
(pos, player->getYaw(), player->getPitch());
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Handle other items
|
||||||
|
*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dout_server<<"Placing a miscellaneous item on map"
|
||||||
|
<<std::endl;
|
||||||
|
/*
|
||||||
|
Create an ItemObject that contains the item.
|
||||||
|
*/
|
||||||
|
ItemObject *iobj = new ItemObject(NULL, -1, pos);
|
||||||
|
std::ostringstream os(std::ios_base::binary);
|
||||||
|
item->serialize(os);
|
||||||
|
dout_server<<"Item string is \""<<os.str()<<"\""<<std::endl;
|
||||||
|
iobj->setItemString(os.str());
|
||||||
|
obj = iobj;
|
||||||
|
}
|
||||||
|
|
||||||
if(obj == NULL)
|
if(obj == NULL)
|
||||||
derr_server<<"WARNING: oitem created NULL object"
|
|
||||||
<<std::endl;
|
|
||||||
|
|
||||||
block->addObject(obj);
|
|
||||||
|
|
||||||
//dout_server<<"Placed object"<<std::endl;
|
|
||||||
|
|
||||||
InventoryList *ilist = player->inventory.getList("main");
|
|
||||||
if(g_settings.getBool("creative_mode") == false && ilist)
|
|
||||||
{
|
{
|
||||||
// Remove from inventory and send inventory
|
derr_server<<"WARNING: item resulted in NULL object, "
|
||||||
ilist->deleteItem(item_i);
|
<<"not placing onto map"
|
||||||
// Send inventory
|
<<std::endl;
|
||||||
SendInventory(peer_id);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
block->addObject(obj);
|
||||||
|
|
||||||
|
dout_server<<"Placed object"<<std::endl;
|
||||||
|
|
||||||
|
InventoryList *ilist = player->inventory.getList("main");
|
||||||
|
if(g_settings.getBool("creative_mode") == false && ilist)
|
||||||
|
{
|
||||||
|
// Remove from inventory and send inventory
|
||||||
|
ilist->deleteItem(item_i);
|
||||||
|
// Send inventory
|
||||||
|
SendInventory(peer_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2445,6 +2488,12 @@ void Server::peerAdded(con::Peer *peer)
|
|||||||
|
|
||||||
if(g_settings.getBool("creative_mode"))
|
if(g_settings.getBool("creative_mode"))
|
||||||
{
|
{
|
||||||
|
// Give a good pick
|
||||||
|
{
|
||||||
|
InventoryItem *item = new ToolItem("STPick", 32000);
|
||||||
|
bool r = player->inventory.addItem("main", item);
|
||||||
|
assert(r == true);
|
||||||
|
}
|
||||||
// Give all materials
|
// Give all materials
|
||||||
assert(USEFUL_CONTENT_COUNT <= PLAYER_INVENTORY_SIZE);
|
assert(USEFUL_CONTENT_COUNT <= PLAYER_INVENTORY_SIZE);
|
||||||
for(u16 i=0; i<USEFUL_CONTENT_COUNT; i++)
|
for(u16 i=0; i<USEFUL_CONTENT_COUNT; i++)
|
||||||
@ -2471,6 +2520,16 @@ void Server::peerAdded(con::Peer *peer)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
InventoryItem *item = new ToolItem("WPick", 32000);
|
||||||
|
bool r = player->inventory.addItem("main", item);
|
||||||
|
assert(r == true);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
InventoryItem *item = new ToolItem("STPick", 32000);
|
||||||
|
bool r = player->inventory.addItem("main", item);
|
||||||
|
assert(r == true);
|
||||||
|
}
|
||||||
/*// Give some lights
|
/*// Give some lights
|
||||||
{
|
{
|
||||||
InventoryItem *item = new MaterialItem(CONTENT_TORCH, 999);
|
InventoryItem *item = new MaterialItem(CONTENT_TORCH, 999);
|
||||||
|
Loading…
Reference in New Issue
Block a user