new object system
parent
c0f0c6568b
commit
fd7a0735c9
|
@ -1193,7 +1193,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
}
|
}
|
||||||
else if(command == TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD)
|
else if(command == TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD)
|
||||||
{
|
{
|
||||||
if(g_settings.getBool("enable_experimental"))
|
//if(g_settings.getBool("enable_experimental"))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
u16 command
|
u16 command
|
||||||
|
@ -1252,7 +1252,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
}
|
}
|
||||||
else if(command == TOCLIENT_ACTIVE_OBJECT_MESSAGES)
|
else if(command == TOCLIENT_ACTIVE_OBJECT_MESSAGES)
|
||||||
{
|
{
|
||||||
if(g_settings.getBool("enable_experimental"))
|
//if(g_settings.getBool("enable_experimental"))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
u16 command
|
u16 command
|
||||||
|
@ -1594,6 +1594,31 @@ void Client::clickObject(u8 button, v3s16 blockpos, s16 id, u16 item)
|
||||||
Send(0, data, true);
|
Send(0, data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::clickActiveObject(u8 button, u16 id, u16 item)
|
||||||
|
{
|
||||||
|
if(connectedAndInitialized() == false){
|
||||||
|
dout_client<<DTIME<<"Client::clickActiveObject() "
|
||||||
|
"cancelled (not connected)"
|
||||||
|
<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
length: 7
|
||||||
|
[0] u16 command
|
||||||
|
[2] u8 button (0=left, 1=right)
|
||||||
|
[3] u16 id
|
||||||
|
[5] u16 item
|
||||||
|
*/
|
||||||
|
u8 datasize = 2 + 1 + 6 + 2 + 2;
|
||||||
|
SharedBuffer<u8> data(datasize);
|
||||||
|
writeU16(&data[0], TOSERVER_CLICK_ACTIVEOBJECT);
|
||||||
|
writeU8(&data[2], button);
|
||||||
|
writeU16(&data[3], id);
|
||||||
|
writeU16(&data[5], item);
|
||||||
|
Send(0, data, true);
|
||||||
|
}
|
||||||
|
|
||||||
void Client::sendSignText(v3s16 blockpos, s16 id, std::string text)
|
void Client::sendSignText(v3s16 blockpos, s16 id, std::string text)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -275,6 +275,7 @@ public:
|
||||||
void groundAction(u8 action, v3s16 nodepos_undersurface,
|
void groundAction(u8 action, v3s16 nodepos_undersurface,
|
||||||
v3s16 nodepos_oversurface, u16 item);
|
v3s16 nodepos_oversurface, u16 item);
|
||||||
void clickObject(u8 button, v3s16 blockpos, s16 id, u16 item);
|
void clickObject(u8 button, v3s16 blockpos, s16 id, u16 item);
|
||||||
|
void clickActiveObject(u8 button, u16 id, u16 item);
|
||||||
|
|
||||||
void sendSignText(v3s16 blockpos, s16 id, std::string text);
|
void sendSignText(v3s16 blockpos, s16 id, std::string text);
|
||||||
void sendSignNodeText(v3s16 p, std::string text);
|
void sendSignNodeText(v3s16 p, std::string text);
|
||||||
|
|
|
@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
#include "environment.h"
|
||||||
|
|
||||||
core::map<u16, ClientActiveObject::Factory> ClientActiveObject::m_types;
|
core::map<u16, ClientActiveObject::Factory> ClientActiveObject::m_types;
|
||||||
|
|
||||||
|
@ -148,7 +149,7 @@ void TestCAO::updateNodePos()
|
||||||
//m_node->setRotation(v3f(0, 45, 0));
|
//m_node->setRotation(v3f(0, 45, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCAO::step(float dtime)
|
void TestCAO::step(float dtime, ClientEnvironment *env)
|
||||||
{
|
{
|
||||||
if(m_node)
|
if(m_node)
|
||||||
{
|
{
|
||||||
|
@ -187,7 +188,7 @@ ItemCAO proto_ItemCAO;
|
||||||
|
|
||||||
ItemCAO::ItemCAO():
|
ItemCAO::ItemCAO():
|
||||||
ClientActiveObject(0),
|
ClientActiveObject(0),
|
||||||
m_selection_box(-BS*0.4,0.0,-BS*0.4, BS*0.4,BS*0.8,BS*0.4),
|
m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.),
|
||||||
m_node(NULL),
|
m_node(NULL),
|
||||||
m_position(v3f(0,10*BS,0))
|
m_position(v3f(0,10*BS,0))
|
||||||
{
|
{
|
||||||
|
@ -219,10 +220,10 @@ void ItemCAO::addToScene(scene::ISceneManager *smgr)
|
||||||
video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
|
video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
|
||||||
video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
|
video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
|
||||||
video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0),*/
|
video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0),*/
|
||||||
video::S3DVertex(BS/3,0,0, 0,0,0, c, 0,1),
|
video::S3DVertex(BS/3.,0,0, 0,0,0, c, 0,1),
|
||||||
video::S3DVertex(-BS/3,0,0, 0,0,0, c, 1,1),
|
video::S3DVertex(-BS/3.,0,0, 0,0,0, c, 1,1),
|
||||||
video::S3DVertex(-BS/3,0+BS*2/3,0, 0,0,0, c, 1,0),
|
video::S3DVertex(-BS/3.,0+BS*2./3.,0, 0,0,0, c, 1,0),
|
||||||
video::S3DVertex(BS/3,0+BS*2/3,0, 0,0,0, c, 0,0),
|
video::S3DVertex(BS/3.,0+BS*2./3.,0, 0,0,0, c, 0,0),
|
||||||
};
|
};
|
||||||
u16 indices[] = {0,1,2,2,3,0};
|
u16 indices[] = {0,1,2,2,3,0};
|
||||||
buf->append(vertices, 4, indices, 6);
|
buf->append(vertices, 4, indices, 6);
|
||||||
|
@ -272,12 +273,17 @@ void ItemCAO::updateNodePos()
|
||||||
m_node->setPosition(m_position);
|
m_node->setPosition(m_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemCAO::step(float dtime)
|
void ItemCAO::step(float dtime, ClientEnvironment *env)
|
||||||
{
|
{
|
||||||
if(m_node)
|
if(m_node)
|
||||||
{
|
{
|
||||||
v3f rot = m_node->getRotation();
|
/*v3f rot = m_node->getRotation();
|
||||||
rot.Y += dtime * 120;
|
rot.Y += dtime * 120;
|
||||||
|
m_node->setRotation(rot);*/
|
||||||
|
LocalPlayer *player = env->getLocalPlayer();
|
||||||
|
assert(player);
|
||||||
|
v3f rot = m_node->getRotation();
|
||||||
|
rot.Y = 180.0 - (player->getYaw());
|
||||||
m_node->setRotation(rot);
|
m_node->setRotation(rot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ Some planning
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
class ClientEnvironment;
|
||||||
|
|
||||||
class ClientActiveObject : public ActiveObject
|
class ClientActiveObject : public ActiveObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -51,11 +53,13 @@ public:
|
||||||
virtual v3f getPosition(){return v3f(0,0,0);}
|
virtual v3f getPosition(){return v3f(0,0,0);}
|
||||||
|
|
||||||
// Step object in time
|
// Step object in time
|
||||||
virtual void step(float dtime){}
|
virtual void step(float dtime, ClientEnvironment *env){}
|
||||||
|
|
||||||
// Process a message sent by the server side object
|
// Process a message sent by the server side object
|
||||||
virtual void processMessage(const std::string &data){}
|
virtual void processMessage(const std::string &data){}
|
||||||
|
|
||||||
|
virtual std::string infoText() {return "";}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This takes the return value of
|
This takes the return value of
|
||||||
ServerActiveObject::getClientInitializationData
|
ServerActiveObject::getClientInitializationData
|
||||||
|
@ -66,9 +70,11 @@ public:
|
||||||
static ClientActiveObject* create(u8 type);
|
static ClientActiveObject* create(u8 type);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// Used for creating objects based on type
|
||||||
typedef ClientActiveObject* (*Factory)();
|
typedef ClientActiveObject* (*Factory)();
|
||||||
static void registerType(u16 type, Factory f);
|
static void registerType(u16 type, Factory f);
|
||||||
private:
|
private:
|
||||||
|
// Used for creating objects based on type
|
||||||
static core::map<u16, Factory> m_types;
|
static core::map<u16, Factory> m_types;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -112,7 +118,7 @@ public:
|
||||||
v3s16 getLightPosition();
|
v3s16 getLightPosition();
|
||||||
void updateNodePos();
|
void updateNodePos();
|
||||||
|
|
||||||
void step(float dtime);
|
void step(float dtime, ClientEnvironment *env);
|
||||||
|
|
||||||
void processMessage(const std::string &data);
|
void processMessage(const std::string &data);
|
||||||
|
|
||||||
|
@ -144,7 +150,7 @@ public:
|
||||||
v3s16 getLightPosition();
|
v3s16 getLightPosition();
|
||||||
void updateNodePos();
|
void updateNodePos();
|
||||||
|
|
||||||
void step(float dtime);
|
void step(float dtime, ClientEnvironment *env);
|
||||||
|
|
||||||
void processMessage(const std::string &data);
|
void processMessage(const std::string &data);
|
||||||
|
|
||||||
|
|
|
@ -249,6 +249,15 @@ enum ToServerCommand
|
||||||
textdata
|
textdata
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
TOSERVER_CLICK_ACTIVEOBJECT = 0x34,
|
||||||
|
/*
|
||||||
|
length: 7
|
||||||
|
[0] u16 command
|
||||||
|
[2] u8 button (0=left, 1=right)
|
||||||
|
[3] u16 id
|
||||||
|
[5] u16 item
|
||||||
|
*/
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time)
|
inline SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time)
|
||||||
|
|
|
@ -189,7 +189,7 @@ u32 Environment::getDayNightRatio()
|
||||||
ServerEnvironment::ServerEnvironment(ServerMap *map, Server *server):
|
ServerEnvironment::ServerEnvironment(ServerMap *map, Server *server):
|
||||||
m_map(map),
|
m_map(map),
|
||||||
m_server(server),
|
m_server(server),
|
||||||
m_random_spawn_timer(0)
|
m_random_spawn_timer(3)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,7 +422,7 @@ void ServerEnvironment::step(float dtime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(g_settings.getBool("enable_experimental"))
|
//if(g_settings.getBool("enable_experimental"))
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -438,7 +438,7 @@ void ServerEnvironment::step(float dtime)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Remove (m_removed && m_known_by_count==0) objects
|
Remove objects that satisfy (m_removed && m_known_by_count==0)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
core::list<u16> objects_to_remove;
|
core::list<u16> objects_to_remove;
|
||||||
|
@ -457,16 +457,173 @@ void ServerEnvironment::step(float dtime)
|
||||||
objects_to_remove.push_back(id);
|
objects_to_remove.push_back(id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
// If not m_removed, don't remove.
|
||||||
|
if(obj->m_removed == false)
|
||||||
|
continue;
|
||||||
|
// Delete
|
||||||
|
delete obj;
|
||||||
|
// Id to be removed from m_active_objects
|
||||||
|
objects_to_remove.push_back(id);
|
||||||
|
}
|
||||||
|
// Remove references from m_active_objects
|
||||||
|
for(core::list<u16>::Iterator i = objects_to_remove.begin();
|
||||||
|
i != objects_to_remove.end(); i++)
|
||||||
|
{
|
||||||
|
m_active_objects.remove(*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const s16 to_active_max_blocks = 3;
|
||||||
|
const f32 to_static_max_f = (to_active_max_blocks+1)*MAP_BLOCKSIZE*BS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convert stored objects from blocks near the players to active.
|
||||||
|
*/
|
||||||
|
for(core::list<Player*>::Iterator i = m_players.begin();
|
||||||
|
i != m_players.end(); i++)
|
||||||
|
{
|
||||||
|
Player *player = *i;
|
||||||
|
v3f playerpos = player->getPosition();
|
||||||
|
|
||||||
|
v3s16 blockpos0 = getNodeBlockPos(floatToInt(playerpos, BS));
|
||||||
|
v3s16 bpmin = blockpos0 - v3s16(1,1,1)*to_active_max_blocks;
|
||||||
|
v3s16 bpmax = blockpos0 + v3s16(1,1,1)*to_active_max_blocks;
|
||||||
|
// Loop through all nearby blocks
|
||||||
|
for(s16 x=bpmin.X; x<=bpmax.X; x++)
|
||||||
|
for(s16 y=bpmin.Y; y<=bpmax.Y; y++)
|
||||||
|
for(s16 z=bpmin.Z; z<=bpmax.Z; z++)
|
||||||
|
{
|
||||||
|
v3s16 blockpos(x,y,z);
|
||||||
|
MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos);
|
||||||
|
if(block==NULL)
|
||||||
|
continue;
|
||||||
|
// Ignore if no stored objects (to not set changed flag)
|
||||||
|
if(block->m_static_objects.m_stored.size() == 0)
|
||||||
|
continue;
|
||||||
|
// This will contain the leftovers of the stored list
|
||||||
|
core::list<StaticObject> new_stored;
|
||||||
|
// Loop through stored static objects
|
||||||
|
for(core::list<StaticObject>::Iterator
|
||||||
|
i = block->m_static_objects.m_stored.begin();
|
||||||
|
i != block->m_static_objects.m_stored.end(); i++)
|
||||||
{
|
{
|
||||||
// If not m_removed, don't remove.
|
dstream<<"INFO: Server: Creating an active object from "
|
||||||
if(obj->m_removed == false)
|
<<"static data"<<std::endl;
|
||||||
|
StaticObject &s_obj = *i;
|
||||||
|
// Create an active object from the data
|
||||||
|
ServerActiveObject *obj = ServerActiveObject::create
|
||||||
|
(s_obj.type, this, 0, s_obj.pos, s_obj.data);
|
||||||
|
if(obj==NULL)
|
||||||
|
{
|
||||||
|
// This is necessary to preserve stuff during bugs
|
||||||
|
// and errors
|
||||||
|
new_stored.push_back(s_obj);
|
||||||
continue;
|
continue;
|
||||||
// Delete
|
}
|
||||||
delete obj;
|
// This will also add the object to the active static list
|
||||||
// Id to be removed from m_active_objects
|
addActiveObject(obj);
|
||||||
objects_to_remove.push_back(id);
|
//u16 id = addActiveObject(obj);
|
||||||
}
|
}
|
||||||
|
// Clear stored list
|
||||||
|
block->m_static_objects.m_stored.clear();
|
||||||
|
// Add leftover stuff to stored list
|
||||||
|
for(core::list<StaticObject>::Iterator
|
||||||
|
i = new_stored.begin();
|
||||||
|
i != new_stored.end(); i++)
|
||||||
|
{
|
||||||
|
StaticObject &s_obj = *i;
|
||||||
|
block->m_static_objects.m_stored.push_back(s_obj);
|
||||||
|
}
|
||||||
|
block->setChangedFlag();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convert objects that are far away from all the players to static.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
core::list<u16> objects_to_remove;
|
||||||
|
for(core::map<u16, ServerActiveObject*>::Iterator
|
||||||
|
i = m_active_objects.getIterator();
|
||||||
|
i.atEnd()==false; i++)
|
||||||
|
{
|
||||||
|
ServerActiveObject* obj = i.getNode()->getValue();
|
||||||
|
u16 id = i.getNode()->getKey();
|
||||||
|
v3f objectpos = obj->getBasePosition();
|
||||||
|
|
||||||
|
// This shouldn't happen but check it
|
||||||
|
if(obj == NULL)
|
||||||
|
{
|
||||||
|
dstream<<"WARNING: NULL object found in ServerEnvironment"
|
||||||
|
<<std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// If known by some client, don't convert to static.
|
||||||
|
if(obj->m_known_by_count > 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If close to some player, don't convert to static.
|
||||||
|
bool close_to_player = false;
|
||||||
|
for(core::list<Player*>::Iterator i = m_players.begin();
|
||||||
|
i != m_players.end(); i++)
|
||||||
|
{
|
||||||
|
Player *player = *i;
|
||||||
|
v3f playerpos = player->getPosition();
|
||||||
|
f32 d = playerpos.getDistanceFrom(objectpos);
|
||||||
|
if(d < to_static_max_f)
|
||||||
|
{
|
||||||
|
close_to_player = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(close_to_player)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Update the static data and remove the active object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Delete old static object
|
||||||
|
MapBlock *oldblock = NULL;
|
||||||
|
if(obj->m_static_exists)
|
||||||
|
{
|
||||||
|
MapBlock *block = m_map->getBlockNoCreateNoEx(obj->m_static_block);
|
||||||
|
if(block)
|
||||||
|
{
|
||||||
|
block->m_static_objects.remove(id);
|
||||||
|
oldblock = block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Add new static object
|
||||||
|
std::string staticdata = obj->getStaticData();
|
||||||
|
StaticObject s_obj(obj->getType(), objectpos, staticdata);
|
||||||
|
// Add to the block where the object is located in
|
||||||
|
v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS));
|
||||||
|
MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos);
|
||||||
|
if(block)
|
||||||
|
{
|
||||||
|
block->m_static_objects.insert(0, s_obj);
|
||||||
|
block->setChangedFlag();
|
||||||
|
}
|
||||||
|
// If not possible, add back to previous block
|
||||||
|
else if(oldblock)
|
||||||
|
{
|
||||||
|
oldblock->m_static_objects.insert(0, s_obj);
|
||||||
|
oldblock->setChangedFlag();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
dstream<<"WARNING: Server: Could not find a block for "
|
||||||
|
<<"storing static object"<<std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Delete active object
|
||||||
|
dstream<<"INFO: Server: Stored static data. Deleting object."
|
||||||
|
<<std::endl;
|
||||||
|
delete obj;
|
||||||
|
// Id to be removed from m_active_objects
|
||||||
|
objects_to_remove.push_back(id);
|
||||||
}
|
}
|
||||||
// Remove references from m_active_objects
|
// Remove references from m_active_objects
|
||||||
for(core::list<u16>::Iterator i = objects_to_remove.begin();
|
for(core::list<u16>::Iterator i = objects_to_remove.begin();
|
||||||
|
@ -479,11 +636,13 @@ void ServerEnvironment::step(float dtime)
|
||||||
/*
|
/*
|
||||||
TEST CODE
|
TEST CODE
|
||||||
*/
|
*/
|
||||||
|
#if 1
|
||||||
m_random_spawn_timer -= dtime;
|
m_random_spawn_timer -= dtime;
|
||||||
if(m_random_spawn_timer < 0)
|
if(m_random_spawn_timer < 0)
|
||||||
{
|
{
|
||||||
//m_random_spawn_timer += myrand_range(2.0, 20.0);
|
//m_random_spawn_timer += myrand_range(2.0, 20.0);
|
||||||
m_random_spawn_timer += 2.0;
|
//m_random_spawn_timer += 2.0;
|
||||||
|
m_random_spawn_timer += 200.0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Find some position
|
Find some position
|
||||||
|
@ -508,11 +667,10 @@ void ServerEnvironment::step(float dtime)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//TestSAO *obj = new TestSAO(this, 0, pos);
|
//TestSAO *obj = new TestSAO(this, 0, pos);
|
||||||
ServerActiveObject *obj = new ItemSAO(this, 0, pos, "CraftItem Stick 1");
|
//ServerActiveObject *obj = new ItemSAO(this, 0, pos, "CraftItem Stick 1");
|
||||||
|
//addActiveObject(obj);
|
||||||
// Add the object to the environment
|
|
||||||
addActiveObject(obj);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // enable_experimental
|
} // enable_experimental
|
||||||
}
|
}
|
||||||
|
@ -582,7 +740,25 @@ u16 ServerEnvironment::addActiveObject(ServerActiveObject *object)
|
||||||
}
|
}
|
||||||
dstream<<"INGO: ServerEnvironment::addActiveObject(): "
|
dstream<<"INGO: ServerEnvironment::addActiveObject(): "
|
||||||
<<"added (id="<<object->getId()<<")"<<std::endl;
|
<<"added (id="<<object->getId()<<")"<<std::endl;
|
||||||
|
|
||||||
m_active_objects.insert(object->getId(), object);
|
m_active_objects.insert(object->getId(), object);
|
||||||
|
|
||||||
|
// Add static object to active static list of the block
|
||||||
|
v3f objectpos = object->getBasePosition();
|
||||||
|
std::string staticdata = object->getStaticData();
|
||||||
|
StaticObject s_obj(object->getType(), objectpos, staticdata);
|
||||||
|
// Add to the block where the object is located in
|
||||||
|
v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS));
|
||||||
|
MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos);
|
||||||
|
if(block)
|
||||||
|
{
|
||||||
|
block->m_static_objects.m_active.insert(object->getId(), s_obj);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
dstream<<"WARNING: Server: Could not find a block for "
|
||||||
|
<<"storing newly added static active object"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
return object->getId();
|
return object->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -912,7 +1088,7 @@ void ClientEnvironment::step(float dtime)
|
||||||
{
|
{
|
||||||
ClientActiveObject* obj = i.getNode()->getValue();
|
ClientActiveObject* obj = i.getNode()->getValue();
|
||||||
// Step object
|
// Step object
|
||||||
obj->step(dtime);
|
obj->step(dtime, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
26
src/main.cpp
26
src/main.cpp
|
@ -2620,10 +2620,8 @@ int main(int argc, char *argv[])
|
||||||
if(g_input->getLeftClicked())
|
if(g_input->getLeftClicked())
|
||||||
{
|
{
|
||||||
std::cout<<DTIME<<"Left-clicked object"<<std::endl;
|
std::cout<<DTIME<<"Left-clicked object"<<std::endl;
|
||||||
#if 0
|
client.clickActiveObject(0,
|
||||||
client.clickObject(0, selected_object->getBlock()->getPos(),
|
selected_active_object->getId(), g_selected_item);
|
||||||
selected_object->getId(), g_selected_item);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if(g_input->getRightClicked())
|
else if(g_input->getRightClicked())
|
||||||
{
|
{
|
||||||
|
@ -2634,26 +2632,6 @@ int main(int argc, char *argv[])
|
||||||
*/
|
*/
|
||||||
if(selected_object->getTypeId() == MAPBLOCKOBJECT_TYPE_SIGN)
|
if(selected_object->getTypeId() == MAPBLOCKOBJECT_TYPE_SIGN)
|
||||||
{
|
{
|
||||||
dstream<<"Sign object right-clicked"<<std::endl;
|
|
||||||
|
|
||||||
if(random_input == false)
|
|
||||||
{
|
|
||||||
// Get a new text for it
|
|
||||||
|
|
||||||
TextDest *dest = new TextDestSign(
|
|
||||||
selected_object->getBlock()->getPos(),
|
|
||||||
selected_object->getId(),
|
|
||||||
&client);
|
|
||||||
|
|
||||||
SignObject *sign_object = (SignObject*)selected_object;
|
|
||||||
|
|
||||||
std::wstring wtext =
|
|
||||||
narrow_to_wide(sign_object->getText());
|
|
||||||
|
|
||||||
(new GUITextInputMenu(guienv, guiroot, -1,
|
|
||||||
&g_menumgr, dest,
|
|
||||||
wtext))->drop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Otherwise pass the event to the server as-is
|
Otherwise pass the event to the server as-is
|
||||||
|
|
16
src/map.cpp
16
src/map.cpp
|
@ -5239,6 +5239,14 @@ void ServerMap::saveBlock(MapBlock *block)
|
||||||
block->serializeObjects(o, version);
|
block->serializeObjects(o, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Versions up from 15 have static objects.
|
||||||
|
*/
|
||||||
|
if(version >= 15)
|
||||||
|
{
|
||||||
|
block->m_static_objects.serialize(o);
|
||||||
|
}
|
||||||
|
|
||||||
// We just wrote it to the disk
|
// We just wrote it to the disk
|
||||||
block->resetChangedFlag();
|
block->resetChangedFlag();
|
||||||
}
|
}
|
||||||
|
@ -5296,6 +5304,14 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSecto
|
||||||
block->updateObjects(is, version, NULL, 0);
|
block->updateObjects(is, version, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Versions up from 15 have static objects.
|
||||||
|
*/
|
||||||
|
if(version >= 15)
|
||||||
|
{
|
||||||
|
block->m_static_objects.deSerialize(is);
|
||||||
|
}
|
||||||
|
|
||||||
if(created_new)
|
if(created_new)
|
||||||
sector->insertBlock(block);
|
sector->insertBlock(block);
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "mapblockobject.h"
|
#include "mapblockobject.h"
|
||||||
#include "voxel.h"
|
#include "voxel.h"
|
||||||
#include "nodemetadata.h"
|
#include "nodemetadata.h"
|
||||||
|
#include "staticobject.h"
|
||||||
|
|
||||||
|
|
||||||
// Named by looking towards z+
|
// Named by looking towards z+
|
||||||
|
@ -681,6 +682,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NodeMetadataList m_node_metadata;
|
NodeMetadataList m_node_metadata;
|
||||||
|
StaticObjectList m_static_objects;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
virtual u16 typeId() const = 0;
|
virtual u16 typeId() const = 0;
|
||||||
virtual NodeMetadata* clone() = 0;
|
virtual NodeMetadata* clone() = 0;
|
||||||
virtual void serializeBody(std::ostream &os) = 0;
|
virtual void serializeBody(std::ostream &os) = 0;
|
||||||
virtual std::string infoText() {return "<todo: remove this text>";}
|
virtual std::string infoText() {return "";}
|
||||||
virtual Inventory* getInventory() {return NULL;}
|
virtual Inventory* getInventory() {return NULL;}
|
||||||
// This is called always after the inventory is modified, before
|
// This is called always after the inventory is modified, before
|
||||||
// the changes are copied elsewhere
|
// the changes are copied elsewhere
|
||||||
|
|
|
@ -47,11 +47,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
12: (dev) UnlimitedHeightmap now uses interpolated areas
|
12: (dev) UnlimitedHeightmap now uses interpolated areas
|
||||||
13: (dev) Mapgen v2
|
13: (dev) Mapgen v2
|
||||||
14: (dev) NodeMetadata
|
14: (dev) NodeMetadata
|
||||||
|
15: (dev) StaticObjects
|
||||||
*/
|
*/
|
||||||
// This represents an uninitialized or invalid format
|
// This represents an uninitialized or invalid format
|
||||||
#define SER_FMT_VER_INVALID 255
|
#define SER_FMT_VER_INVALID 255
|
||||||
// Highest supported serialization version
|
// Highest supported serialization version
|
||||||
#define SER_FMT_VER_HIGHEST 14
|
#define SER_FMT_VER_HIGHEST 15
|
||||||
// Lowest supported serialization version
|
// Lowest supported serialization version
|
||||||
#define SER_FMT_VER_LOWEST 2
|
#define SER_FMT_VER_LOWEST 2
|
||||||
|
|
||||||
|
|
190
src/server.cpp
190
src/server.cpp
|
@ -1228,7 +1228,7 @@ void Server::AsyncRunStep()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(g_settings.getBool("enable_experimental"))
|
//if(g_settings.getBool("enable_experimental"))
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1345,6 +1345,33 @@ void Server::AsyncRunStep()
|
||||||
<<added_objects.size()<<" added, "
|
<<added_objects.size()<<" added, "
|
||||||
<<"packet size is "<<reply.getSize()<<std::endl;
|
<<"packet size is "<<reply.getSize()<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/*
|
||||||
|
Collect a list of all the objects known by the clients
|
||||||
|
and report it back to the environment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
core::map<u16, bool> all_known_objects;
|
||||||
|
|
||||||
|
for(core::map<u16, RemoteClient*>::Iterator
|
||||||
|
i = m_clients.getIterator();
|
||||||
|
i.atEnd() == false; i++)
|
||||||
|
{
|
||||||
|
RemoteClient *client = i.getNode()->getValue();
|
||||||
|
// Go through all known objects of client
|
||||||
|
for(core::map<u16, bool>::Iterator
|
||||||
|
i = client->m_known_objects.getIterator();
|
||||||
|
i.atEnd()==false; i++)
|
||||||
|
{
|
||||||
|
u16 id = i.getNode()->getKey();
|
||||||
|
all_known_objects[id] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_env.setKnownActiveObjects(whatever);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1978,6 +2005,70 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
block->removeObject(id);
|
block->removeObject(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(command == TOSERVER_CLICK_ACTIVEOBJECT)
|
||||||
|
{
|
||||||
|
if(datasize < 7)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
length: 7
|
||||||
|
[0] u16 command
|
||||||
|
[2] u8 button (0=left, 1=right)
|
||||||
|
[3] u16 id
|
||||||
|
[5] u16 item
|
||||||
|
*/
|
||||||
|
u8 button = readU8(&data[2]);
|
||||||
|
u16 id = readS16(&data[3]);
|
||||||
|
//u16 item_i = readU16(&data[11]);
|
||||||
|
|
||||||
|
ServerActiveObject *obj = m_env.getActiveObject(id);
|
||||||
|
|
||||||
|
if(obj == NULL)
|
||||||
|
{
|
||||||
|
derr_server<<"Server: CLICK_ACTIVEOBJECT: object not found"
|
||||||
|
<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Check that object is reasonably close
|
||||||
|
|
||||||
|
// Left click, pick object up (usually)
|
||||||
|
if(button == 0)
|
||||||
|
{
|
||||||
|
InventoryList *ilist = player->inventory.getList("main");
|
||||||
|
if(g_settings.getBool("creative_mode") == false && ilist != NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Skip if inventory has no free space
|
||||||
|
if(ilist->getUsedSlots() == ilist->getSize())
|
||||||
|
{
|
||||||
|
dout_server<<"Player inventory has no free space"<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create the inventory item
|
||||||
|
*/
|
||||||
|
InventoryItem *item = NULL;
|
||||||
|
// If it is an item-object, take the item from it
|
||||||
|
if(obj->getType() == ACTIVEOBJECT_TYPE_ITEM
|
||||||
|
&& obj->m_removed == false)
|
||||||
|
{
|
||||||
|
item = ((ItemSAO*)obj)->createInventoryItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(item)
|
||||||
|
{
|
||||||
|
// Add to inventory and send inventory
|
||||||
|
ilist->addItem(item);
|
||||||
|
SendInventory(player->peer_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove object from environment
|
||||||
|
obj->m_removed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if(command == TOSERVER_GROUND_ACTION)
|
else if(command == TOSERVER_GROUND_ACTION)
|
||||||
{
|
{
|
||||||
if(datasize < 17)
|
if(datasize < 17)
|
||||||
|
@ -2327,68 +2418,40 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Handle other items
|
Place other item (not a block)
|
||||||
*/
|
*/
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
v3s16 blockpos = getNodeBlockPos(p_over);
|
v3s16 blockpos = getNodeBlockPos(p_over);
|
||||||
|
|
||||||
MapBlock *block = NULL;
|
/*
|
||||||
try
|
Check that the block is loaded so that the item
|
||||||
{
|
can properly be added to the static list too
|
||||||
block = m_env.getMap().getBlockNoCreate(blockpos);
|
*/
|
||||||
}
|
MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(blockpos);
|
||||||
catch(InvalidPositionException &e)
|
if(block==NULL)
|
||||||
{
|
{
|
||||||
derr_server<<"Error while placing object: "
|
derr_server<<"Error while placing object: "
|
||||||
"block not found"<<std::endl;
|
"block not found"<<std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
v3s16 block_pos_i_on_map = block->getPosRelative();
|
|
||||||
v3f block_pos_f_on_map = intToFloat(block_pos_i_on_map, BS);
|
|
||||||
|
|
||||||
v3f pos = intToFloat(p_over, BS);
|
v3f pos = intToFloat(p_over, BS);
|
||||||
pos -= block_pos_f_on_map;
|
pos.Y -= BS*0.45;
|
||||||
|
|
||||||
/*dout_server<<"pos="
|
|
||||||
<<"("<<pos.X<<","<<pos.Y<<","<<pos.Z<<")"
|
|
||||||
<<std::endl;*/
|
|
||||||
|
|
||||||
MapBlockObject *obj = NULL;
|
|
||||||
|
|
||||||
|
dout_server<<"Placing a miscellaneous item on map"
|
||||||
|
<<std::endl;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Handle block object items
|
Create an ItemSAO
|
||||||
*/
|
*/
|
||||||
if(std::string("MBOItem") == item->getName())
|
// Get item string
|
||||||
{
|
std::ostringstream os(std::ios_base::binary);
|
||||||
MapBlockObjectItem *oitem = (MapBlockObjectItem*)item;
|
item->serialize(os);
|
||||||
|
dout_server<<"Item string is \""<<os.str()<<"\""<<std::endl;
|
||||||
/*dout_server<<"Trying to place a MapBlockObjectItem: "
|
// Create object
|
||||||
"inventorystring=\""
|
ServerActiveObject *obj = new ItemSAO
|
||||||
<<oitem->getInventoryString()
|
(&m_env, 0, pos, os.str());
|
||||||
<<"\""<<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)
|
||||||
{
|
{
|
||||||
|
@ -2398,8 +2461,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
block->addObject(obj);
|
// Add the object to the environment
|
||||||
|
m_env.addActiveObject(obj);
|
||||||
|
|
||||||
dout_server<<"Placed object"<<std::endl;
|
dout_server<<"Placed object"<<std::endl;
|
||||||
|
|
||||||
InventoryList *ilist = player->inventory.getList("main");
|
InventoryList *ilist = player->inventory.getList("main");
|
||||||
|
@ -3874,30 +3938,6 @@ Player *Server::emergePlayer(const char *name, const char *password,
|
||||||
} // create new player
|
} // create new player
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void Server::UpdateBlockWaterPressure(MapBlock *block,
|
|
||||||
core::map<v3s16, MapBlock*> &modified_blocks)
|
|
||||||
{
|
|
||||||
MapVoxelManipulator v(&m_env.getMap());
|
|
||||||
v.m_disable_water_climb =
|
|
||||||
g_settings.getBool("disable_water_climb");
|
|
||||||
|
|
||||||
VoxelArea area(block->getPosRelative(),
|
|
||||||
block->getPosRelative() + v3s16(1,1,1)*(MAP_BLOCKSIZE-1));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
v.updateAreaWaterPressure(area, m_flow_active_nodes);
|
|
||||||
}
|
|
||||||
catch(ProcessingLimitException &e)
|
|
||||||
{
|
|
||||||
dstream<<"Processing limit reached (1)"<<std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
v.blitBack(modified_blocks);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Server::handlePeerChange(PeerChange &c)
|
void Server::handlePeerChange(PeerChange &c)
|
||||||
{
|
{
|
||||||
JMutexAutoLock envlock(m_env_mutex);
|
JMutexAutoLock envlock(m_env_mutex);
|
||||||
|
|
|
@ -20,11 +20,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "serverobject.h"
|
#include "serverobject.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "environment.h"
|
#include "environment.h"
|
||||||
|
#include "inventory.h"
|
||||||
|
|
||||||
|
core::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
|
||||||
|
|
||||||
ServerActiveObject::ServerActiveObject(ServerEnvironment *env, u16 id, v3f pos):
|
ServerActiveObject::ServerActiveObject(ServerEnvironment *env, u16 id, v3f pos):
|
||||||
ActiveObject(id),
|
ActiveObject(id),
|
||||||
m_known_by_count(0),
|
m_known_by_count(0),
|
||||||
m_removed(false),
|
m_removed(false),
|
||||||
|
m_static_exists(false),
|
||||||
|
m_static_block(1337,1337,1337),
|
||||||
m_env(env),
|
m_env(env),
|
||||||
m_base_position(pos)
|
m_base_position(pos)
|
||||||
{
|
{
|
||||||
|
@ -34,15 +39,55 @@ ServerActiveObject::~ServerActiveObject()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServerActiveObject* ServerActiveObject::create(u8 type,
|
||||||
|
ServerEnvironment *env, u16 id, v3f pos,
|
||||||
|
const std::string &data)
|
||||||
|
{
|
||||||
|
// Find factory function
|
||||||
|
core::map<u16, Factory>::Node *n;
|
||||||
|
n = m_types.find(type);
|
||||||
|
if(n == NULL)
|
||||||
|
{
|
||||||
|
// If factory is not found, just return.
|
||||||
|
dstream<<"WARNING: ServerActiveObject: No factory for type="
|
||||||
|
<<type<<std::endl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Factory f = n->getValue();
|
||||||
|
ServerActiveObject *object = (*f)(env, id, pos, data);
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerActiveObject::registerType(u16 type, Factory f)
|
||||||
|
{
|
||||||
|
core::map<u16, Factory>::Node *n;
|
||||||
|
n = m_types.find(type);
|
||||||
|
if(n)
|
||||||
|
return;
|
||||||
|
m_types.insert(type, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TestSAO
|
TestSAO
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Prototype
|
||||||
|
TestSAO proto_TestSAO(NULL, 0, v3f(0,0,0));
|
||||||
|
|
||||||
TestSAO::TestSAO(ServerEnvironment *env, u16 id, v3f pos):
|
TestSAO::TestSAO(ServerEnvironment *env, u16 id, v3f pos):
|
||||||
ServerActiveObject(env, id, pos),
|
ServerActiveObject(env, id, pos),
|
||||||
m_timer1(0),
|
m_timer1(0),
|
||||||
m_age(0)
|
m_age(0)
|
||||||
{
|
{
|
||||||
|
ServerActiveObject::registerType(getType(), create);
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerActiveObject* TestSAO::create(ServerEnvironment *env, u16 id, v3f pos,
|
||||||
|
const std::string &data)
|
||||||
|
{
|
||||||
|
return new TestSAO(env, id, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestSAO::step(float dtime, Queue<ActiveObjectMessage> &messages)
|
void TestSAO::step(float dtime, Queue<ActiveObjectMessage> &messages)
|
||||||
|
@ -84,6 +129,9 @@ void TestSAO::step(float dtime, Queue<ActiveObjectMessage> &messages)
|
||||||
ItemSAO
|
ItemSAO
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Prototype
|
||||||
|
ItemSAO proto_ItemSAO(NULL, 0, v3f(0,0,0), "");
|
||||||
|
|
||||||
ItemSAO::ItemSAO(ServerEnvironment *env, u16 id, v3f pos,
|
ItemSAO::ItemSAO(ServerEnvironment *env, u16 id, v3f pos,
|
||||||
const std::string inventorystring):
|
const std::string inventorystring):
|
||||||
ServerActiveObject(env, id, pos),
|
ServerActiveObject(env, id, pos),
|
||||||
|
@ -91,6 +139,19 @@ ItemSAO::ItemSAO(ServerEnvironment *env, u16 id, v3f pos,
|
||||||
{
|
{
|
||||||
dstream<<"Server: ItemSAO created with inventorystring=\""
|
dstream<<"Server: ItemSAO created with inventorystring=\""
|
||||||
<<m_inventorystring<<"\""<<std::endl;
|
<<m_inventorystring<<"\""<<std::endl;
|
||||||
|
ServerActiveObject::registerType(getType(), create);
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerActiveObject* ItemSAO::create(ServerEnvironment *env, u16 id, v3f pos,
|
||||||
|
const std::string &data)
|
||||||
|
{
|
||||||
|
std::istringstream is(data, std::ios::binary);
|
||||||
|
char buf[1];
|
||||||
|
is.read(buf, 1); // read version
|
||||||
|
std::string inventorystring = deSerializeString(is);
|
||||||
|
dstream<<"ItemSAO::create(): Creating item \""
|
||||||
|
<<inventorystring<<"\""<<std::endl;
|
||||||
|
return new ItemSAO(env, id, pos, inventorystring);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemSAO::step(float dtime, Queue<ActiveObjectMessage> &messages)
|
void ItemSAO::step(float dtime, Queue<ActiveObjectMessage> &messages)
|
||||||
|
@ -111,4 +172,34 @@ std::string ItemSAO::getClientInitializationData()
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ItemSAO::getStaticData()
|
||||||
|
{
|
||||||
|
dstream<<__FUNCTION_NAME<<std::endl;
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
char buf[1];
|
||||||
|
buf[0] = 0; //version
|
||||||
|
os.write(buf, 1);
|
||||||
|
os<<serializeString(m_inventorystring);
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
InventoryItem * ItemSAO::createInventoryItem()
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
std::istringstream is(m_inventorystring, std::ios_base::binary);
|
||||||
|
InventoryItem *item = InventoryItem::deSerialize(is);
|
||||||
|
dstream<<__FUNCTION_NAME<<": m_inventorystring=\""
|
||||||
|
<<m_inventorystring<<"\" -> item="<<item
|
||||||
|
<<std::endl;
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
catch(SerializationError &e)
|
||||||
|
{
|
||||||
|
dstream<<__FUNCTION_NAME<<": serialization error: "
|
||||||
|
<<"m_inventorystring=\""<<m_inventorystring<<"\""<<std::endl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,27 +39,28 @@ Some planning
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class ServerEnvironment;
|
class ServerEnvironment;
|
||||||
|
class InventoryItem;
|
||||||
|
|
||||||
class ServerActiveObject : public ActiveObject
|
class ServerActiveObject : public ActiveObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ServerActiveObject(ServerEnvironment *env, u16 id, v3f pos=v3f(0,0,0));
|
ServerActiveObject(ServerEnvironment *env, u16 id, v3f pos);
|
||||||
virtual ~ServerActiveObject();
|
virtual ~ServerActiveObject();
|
||||||
|
|
||||||
v3f getBasePosition()
|
// Create a certain type of ServerActiveObject
|
||||||
{
|
static ServerActiveObject* create(u8 type,
|
||||||
return m_base_position;
|
ServerEnvironment *env, u16 id, v3f pos,
|
||||||
}
|
const std::string &data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Some simple getters/setters
|
||||||
|
*/
|
||||||
|
v3f getBasePosition()
|
||||||
|
{return m_base_position;}
|
||||||
void setBasePosition(v3f pos)
|
void setBasePosition(v3f pos)
|
||||||
{
|
{m_base_position = pos;}
|
||||||
m_base_position = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerEnvironment* getEnv()
|
ServerEnvironment* getEnv()
|
||||||
{
|
{return m_env;}
|
||||||
return m_env;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Step object in time.
|
Step object in time.
|
||||||
|
@ -75,14 +76,10 @@ public:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The return value of this is passed to the server-side object
|
The return value of this is passed to the server-side object
|
||||||
when it is loaded from disk or from a static object
|
when it is created (converted from static to active - actually
|
||||||
|
the data is the static form)
|
||||||
*/
|
*/
|
||||||
virtual std::string getServerInitializationData(){return "";}
|
virtual std::string getStaticData(){return "";}
|
||||||
|
|
||||||
/*
|
|
||||||
This takes the return value of getServerInitializationData
|
|
||||||
*/
|
|
||||||
virtual void initialize(const std::string &data){}
|
|
||||||
|
|
||||||
// Number of players which know about this object
|
// Number of players which know about this object
|
||||||
u16 m_known_by_count;
|
u16 m_known_by_count;
|
||||||
|
@ -93,12 +90,33 @@ public:
|
||||||
it could be confused to some other object by some client.
|
it could be confused to some other object by some client.
|
||||||
- This is set to true by the step() method when the object wants
|
- This is set to true by the step() method when the object wants
|
||||||
to be deleted.
|
to be deleted.
|
||||||
|
- This can be set to true by anything else too.
|
||||||
*/
|
*/
|
||||||
bool m_removed;
|
bool m_removed;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Whether the object's static data has been stored to a block
|
||||||
|
*/
|
||||||
|
bool m_static_exists;
|
||||||
|
/*
|
||||||
|
The block from which the object was loaded from, and in which
|
||||||
|
a copy of the static data resides.
|
||||||
|
*/
|
||||||
|
v3s16 m_static_block;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// Used for creating objects based on type
|
||||||
|
typedef ServerActiveObject* (*Factory)
|
||||||
|
(ServerEnvironment *env, u16 id, v3f pos,
|
||||||
|
const std::string &data);
|
||||||
|
static void registerType(u16 type, Factory f);
|
||||||
|
|
||||||
ServerEnvironment *m_env;
|
ServerEnvironment *m_env;
|
||||||
v3f m_base_position;
|
v3f m_base_position;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Used for creating objects based on type
|
||||||
|
static core::map<u16, Factory> m_types;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TestSAO : public ServerActiveObject
|
class TestSAO : public ServerActiveObject
|
||||||
|
@ -106,9 +124,9 @@ class TestSAO : public ServerActiveObject
|
||||||
public:
|
public:
|
||||||
TestSAO(ServerEnvironment *env, u16 id, v3f pos);
|
TestSAO(ServerEnvironment *env, u16 id, v3f pos);
|
||||||
u8 getType() const
|
u8 getType() const
|
||||||
{
|
{return ACTIVEOBJECT_TYPE_TEST;}
|
||||||
return ACTIVEOBJECT_TYPE_TEST;
|
static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
|
||||||
}
|
const std::string &data);
|
||||||
void step(float dtime, Queue<ActiveObjectMessage> &messages);
|
void step(float dtime, Queue<ActiveObjectMessage> &messages);
|
||||||
private:
|
private:
|
||||||
float m_timer1;
|
float m_timer1;
|
||||||
|
@ -121,11 +139,13 @@ public:
|
||||||
ItemSAO(ServerEnvironment *env, u16 id, v3f pos,
|
ItemSAO(ServerEnvironment *env, u16 id, v3f pos,
|
||||||
const std::string inventorystring);
|
const std::string inventorystring);
|
||||||
u8 getType() const
|
u8 getType() const
|
||||||
{
|
{return ACTIVEOBJECT_TYPE_ITEM;}
|
||||||
return ACTIVEOBJECT_TYPE_ITEM;
|
static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
|
||||||
}
|
const std::string &data);
|
||||||
void step(float dtime, Queue<ActiveObjectMessage> &messages);
|
void step(float dtime, Queue<ActiveObjectMessage> &messages);
|
||||||
std::string getClientInitializationData();
|
std::string getClientInitializationData();
|
||||||
|
std::string getStaticData();
|
||||||
|
InventoryItem* createInventoryItem();
|
||||||
private:
|
private:
|
||||||
std::string m_inventorystring;
|
std::string m_inventorystring;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1839,15 +1839,17 @@ inline std::string serializeString(const std::string plain)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads a string with the length as the first two bytes
|
/*// Reads a string with the length as the first two bytes
|
||||||
inline std::string deSerializeString(const std::string encoded)
|
inline std::string deSerializeString(const std::string encoded)
|
||||||
{
|
{
|
||||||
u16 s_size = readU16((u8*)&encoded.c_str()[0]);
|
u16 s_size = readU16((u8*)&encoded.c_str()[0]);
|
||||||
|
if(s_size > encoded.length() - 2)
|
||||||
|
return "";
|
||||||
std::string s;
|
std::string s;
|
||||||
s.reserve(s_size);
|
s.reserve(s_size);
|
||||||
s.append(&encoded.c_str()[2], s_size);
|
s.append(&encoded.c_str()[2], s_size);
|
||||||
return s;
|
return s;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Reads a string with the length as the first two bytes
|
// Reads a string with the length as the first two bytes
|
||||||
inline std::string deSerializeString(std::istream &is)
|
inline std::string deSerializeString(std::istream &is)
|
||||||
|
@ -1878,15 +1880,17 @@ inline std::string serializeLongString(const std::string plain)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads a string with the length as the first four bytes
|
/*// Reads a string with the length as the first four bytes
|
||||||
inline std::string deSerializeLongString(const std::string encoded)
|
inline std::string deSerializeLongString(const std::string encoded)
|
||||||
{
|
{
|
||||||
u32 s_size = readU32((u8*)&encoded.c_str()[0]);
|
u32 s_size = readU32((u8*)&encoded.c_str()[0]);
|
||||||
|
if(s_size > encoded.length() - 4)
|
||||||
|
return "";
|
||||||
std::string s;
|
std::string s;
|
||||||
s.reserve(s_size);
|
s.reserve(s_size);
|
||||||
s.append(&encoded.c_str()[2], s_size);
|
s.append(&encoded.c_str()[4], s_size);
|
||||||
return s;
|
return s;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Reads a string with the length as the first four bytes
|
// Reads a string with the length as the first four bytes
|
||||||
inline std::string deSerializeLongString(std::istream &is)
|
inline std::string deSerializeLongString(std::istream &is)
|
||||||
|
|
Loading…
Reference in New Issue