X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fserverobject.cpp;h=d31e9a31cdc7fd7cd6e9f6a66b85e1ea2c3275f1;hb=30c34cc23e9a060ef964854038a314a94ad5cbae;hp=2fd3a1bfb16e52a7e28239807749264b95dd7bde;hpb=69dbc046eb5a82b38c6d5c3302e9b3b0b3c1bcf1;p=dragonfireclient.git diff --git a/src/serverobject.cpp b/src/serverobject.cpp index 2fd3a1bfb..d31e9a31c 100644 --- a/src/serverobject.cpp +++ b/src/serverobject.cpp @@ -20,11 +20,18 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serverobject.h" #include #include "environment.h" +#include "inventory.h" +#include "collision.h" + +core::map ServerActiveObject::m_types; ServerActiveObject::ServerActiveObject(ServerEnvironment *env, u16 id, v3f pos): ActiveObject(id), m_known_by_count(0), m_removed(false), + m_pending_deactivation(false), + m_static_exists(false), + m_static_block(1337,1337,1337), m_env(env), m_base_position(pos) { @@ -34,18 +41,59 @@ ServerActiveObject::~ServerActiveObject() { } +ServerActiveObject* ServerActiveObject::create(u8 type, + ServerEnvironment *env, u16 id, v3f pos, + const std::string &data) +{ + // Find factory function + core::map::Node *n; + n = m_types.find(type); + if(n == NULL) + { + // If factory is not found, just return. + dstream<<"WARNING: ServerActiveObject: No factory for type=" + <getValue(); + ServerActiveObject *object = (*f)(env, id, pos, data); + return object; +} + +void ServerActiveObject::registerType(u16 type, Factory f) +{ + core::map::Node *n; + n = m_types.find(type); + if(n) + return; + m_types.insert(type, f); +} + + /* TestSAO */ +// Prototype +TestSAO proto_TestSAO(NULL, 0, v3f(0,0,0)); + TestSAO::TestSAO(ServerEnvironment *env, u16 id, v3f pos): ServerActiveObject(env, id, pos), m_timer1(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 &messages) +void TestSAO::step(float dtime, Queue &messages, + bool send_recommended) { m_age += dtime; if(m_age > 10) @@ -58,6 +106,9 @@ void TestSAO::step(float dtime, Queue &messages) if(m_base_position.Y > 8*BS) m_base_position.Y = 2*BS; + if(send_recommended == false) + return; + m_timer1 -= dtime; if(m_timer1 < 0.0) { @@ -79,422 +130,541 @@ void TestSAO::step(float dtime, Queue &messages) } } -/* - LuaSAO -*/ - -extern "C"{ -#include "lstring.h" -} /* - object_set_base_position(self, x,y,z) - x,y,z = object_get_base_position(self) - object_add_message(self, data) - object_remove(self) + ItemSAO */ -/* - object_set_base_position(self, x, y, z) -*/ -static int lf_object_set_base_position(lua_State *L) +// Prototype +ItemSAO proto_ItemSAO(NULL, 0, v3f(0,0,0), ""); + +ItemSAO::ItemSAO(ServerEnvironment *env, u16 id, v3f pos, + const std::string inventorystring): + ServerActiveObject(env, id, pos), + m_inventorystring(inventorystring), + m_speed_f(0,0,0), + m_last_sent_position(0,0,0) { - // 4: z - lua_Number z = lua_tonumber(L, -1); - lua_pop(L, 1); - // 3: y - lua_Number y = lua_tonumber(L, -1); - lua_pop(L, 1); - // 2: x - lua_Number x = lua_tonumber(L, -1); - lua_pop(L, 1); - // 1: self - LuaSAO *self = (LuaSAO*)lua_touserdata(L, -1); - lua_pop(L, 1); - - assert(self); - - self->setBasePosition(v3f(x*BS,y*BS,z*BS)); - - return 0; // Number of return values + ServerActiveObject::registerType(getType(), create); } -/* - object_get_base_position(self) -*/ -static int lf_object_get_base_position(lua_State *L) +ServerActiveObject* ItemSAO::create(ServerEnvironment *env, u16 id, v3f pos, + const std::string &data) { - // 1: self - LuaSAO *self = (LuaSAO*)lua_touserdata(L, -1); - lua_pop(L, 1); - - assert(self); - - v3f pos = self->getBasePosition(); - - lua_pushnumber(L, pos.X/BS); - lua_pushnumber(L, pos.Y/BS); - lua_pushnumber(L, pos.Z/BS); - return 3; // Number of return values + std::istringstream is(data, std::ios::binary); + char buf[1]; + // read version + is.read(buf, 1); + u8 version = buf[0]; + // check if version is supported + if(version != 0) + return NULL; + std::string inventorystring = deSerializeString(is); + dstream<<"ItemSAO::create(): Creating item \"" + < &messages, + bool send_recommended) { - // 2: data - size_t datalen = 0; - const char *data_c = lua_tolstring(L, -1, &datalen); - lua_pop(L, 1); - // 1: self - LuaSAO *self = (LuaSAO*)lua_touserdata(L, -1); - lua_pop(L, 1); - - assert(self); - assert(data_c); + assert(m_env); + + const float interval = 0.2; + if(m_move_interval.step(dtime, interval)==false) + return; + dtime = interval; - std::string data(data_c, datalen); - //dstream<<"object_add_message: data="< box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.); + collisionMoveResult moveresult; + // Apply gravity + m_speed_f += v3f(0, -dtime*9.81*BS, 0); + // Maximum movement without glitches + f32 pos_max_d = BS*0.25; + // Limit speed + if(m_speed_f.getLength()*dtime > pos_max_d) + m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime); + v3f pos_f = getBasePosition(); + v3f pos_f_old = pos_f; + moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d, + box, dtime, pos_f, m_speed_f); - // Create message and add to queue - ActiveObjectMessage aom(self->getId()); - aom.reliable = true; - aom.datastring = data; - self->m_message_queue.push_back(aom); + if(send_recommended == false) + return; - return 0; // Number of return values + if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS) + { + setBasePosition(pos_f); + m_last_sent_position = pos_f; + + std::ostringstream os(std::ios::binary); + char buf[6]; + // command (0 = update position) + buf[0] = 0; + os.write(buf, 1); + // pos + writeS32((u8*)buf, m_base_position.X*1000); + os.write(buf, 4); + writeS32((u8*)buf, m_base_position.Y*1000); + os.write(buf, 4); + writeS32((u8*)buf, m_base_position.Z*1000); + os.write(buf, 4); + // create message and add to list + ActiveObjectMessage aom(getId(), false, os.str()); + messages.push_back(aom); + } } -/* - object_get_node(x,y,z) -*/ -static int lf_object_get_node(lua_State *L) +std::string ItemSAO::getClientInitializationData() { - // 4: z - lua_Number z = lua_tonumber(L, -1); - lua_pop(L, 1); - // 3: y - lua_Number y = lua_tonumber(L, -1); - lua_pop(L, 1); - // 2: x - lua_Number x = lua_tonumber(L, -1); - lua_pop(L, 1); - // 1: self - LuaSAO *self = (LuaSAO*)lua_touserdata(L, -1); - lua_pop(L, 1); - - assert(self); + std::ostringstream os(std::ios::binary); + char buf[6]; + // version + buf[0] = 0; + os.write(buf, 1); + // pos + writeS32((u8*)buf, m_base_position.X*1000); + os.write(buf, 4); + writeS32((u8*)buf, m_base_position.Y*1000); + os.write(buf, 4); + writeS32((u8*)buf, m_base_position.Z*1000); + os.write(buf, 4); + // inventorystring + os<getEnv()->getMap().getNodeNoEx(pos); - - // Create a table with some data about the node - lua_newtable(L); - lua_pushstring(L, "content"); - lua_pushinteger(L, n.d); - lua_settable(L, -3); - lua_pushstring(L, "walkable"); - lua_pushboolean(L, content_features(n.d).walkable); - lua_settable(L, -3); - - // Return the table - return 1; +InventoryItem * ItemSAO::createInventoryItem() +{ + try{ + std::istringstream is(m_inventorystring, std::ios_base::binary); + InventoryItem *item = InventoryItem::deSerialize(is); + dstream<<__FUNCTION_NAME<<": m_inventorystring=\"" + < item="<m_removed = true; - return 0; -} +// Prototype +RatSAO proto_RatSAO(NULL, 0, v3f(0,0,0)); -LuaSAO::LuaSAO(ServerEnvironment *env, u16 id, v3f pos): +RatSAO::RatSAO(ServerEnvironment *env, u16 id, v3f pos): ServerActiveObject(env, id, pos), - L(NULL) + m_is_active(false), + m_speed_f(0,0,0) { - dstream<<"LuaSAO::LuaSAO(): id="< &messages, + bool send_recommended) { + assert(m_env); + + if(m_is_active == false) + { + if(m_inactive_interval.step(dtime, 0.5)==false) + return; + } + /* - Read client-side script from file - */ - - std::string relative_path; - relative_path += "luaobjects/"; - relative_path += m_script_name; - relative_path += "/client.lua"; - std::string full_path = porting::getDataPath(relative_path.c_str()); - std::string script; - std::ifstream file(full_path.c_str(), std::ios::binary | std::ios::ate); - int size = file.tellg(); - SharedBuffer buf(size); - file.seekg(0, std::ios::beg); - file.read(&buf[0], size); - file.close(); - - /* - Create data string + The AI */ - std::string data; - // Append script - std::string script_string(&buf[0], buf.getSize()); - data += serializeLongString(script_string); + /*m_age += dtime; + if(m_age > 60) + { + // Die + m_removed = true; + return; + }*/ + + // Apply gravity + m_speed_f.Y -= dtime*9.81*BS; /* - Get data from server-side script for inclusion + Move around if some player is close */ - std::string other_data; - - do{ - - const char *funcname = "get_client_init_data"; - lua_getglobal(L, funcname); - if(!lua_isfunction(L,-1)) + bool player_is_close = false; + // Check connected players + core::list players = m_env->getPlayers(true); + core::list::Iterator i; + for(i = players.begin(); + i != players.end(); i++) + { + Player *player = *i; + v3f playerpos = player->getPosition(); + if(m_base_position.getDistanceFrom(playerpos) < BS*10.0) { - lua_pop(L,1); - dstream<<"WARNING: LuaSAO: Function not found: " - < box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.); + collisionMoveResult moveresult; + // Maximum movement without glitches + f32 pos_max_d = BS*0.25; + // Limit speed + if(m_speed_f.getLength()*dtime > pos_max_d) + m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime); + v3f pos_f = getBasePosition(); + v3f pos_f_old = pos_f; + moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d, + box, dtime, pos_f, m_speed_f); + m_touching_ground = moveresult.touching_ground; - data += serializeLongString(other_data); + setBasePosition(pos_f); - return data; + if(send_recommended == false) + return; + + if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS) + { + m_last_sent_position = pos_f; + + std::ostringstream os(std::ios::binary); + // command (0 = update position) + writeU8(os, 0); + // pos + writeV3F1000(os, m_base_position); + // yaw + writeF1000(os, m_yaw); + // create message and add to list + ActiveObjectMessage aom(getId(), false, os.str()); + messages.push_back(aom); + } } -std::string LuaSAO::getServerInitializationData() +std::string RatSAO::getClientInitializationData() { - std::string data; - - // Script name - data.append(serializeString(m_script_name)); - - /* - Get data from server-side script for inclusion - */ - std::string other_data; - - do{ + std::ostringstream os(std::ios::binary); + // version + writeU8(os, 0); + // pos + writeV3F1000(os, m_base_position); + return os.str(); +} - const char *funcname = "get_server_init_data"; - lua_getglobal(L, funcname); - if(!lua_isfunction(L,-1)) - { - lua_pop(L,1); - dstream<<"WARNING: LuaSAO: Function not found: " - <m_hp = hp; + return o; +} + +void Oerkki1SAO::step(float dtime, Queue &messages, + bool send_recommended) +{ + assert(m_env); - loadScripts(script_name); + if(m_is_active == false) + { + if(m_inactive_interval.step(dtime, 0.5)==false) + return; + } /* - Call initialize(self, data) in the script + The AI */ - - const char *funcname = "initialize"; - lua_getglobal(L, funcname); - if(!lua_isfunction(L,-1)) + + m_age += dtime; + if(m_age > 120) { - lua_pop(L,1); - dstream<<"WARNING: LuaSAO: Function not found: " - < players = m_env->getPlayers(true); + core::list::Iterator i; + for(i = players.begin(); + i != players.end(); i++) { - dstream<<"WARNING: LuaSAO: Error running function " - <getPosition(); + if(m_base_position.getDistanceFrom(playerpos) < BS*15.0) + { + player_is_close = true; + near_player_pos = playerpos; + break; + } } -} -void LuaSAO::loadScripts(const std::string &script_name) -{ - m_script_name = script_name; + m_is_active = player_is_close; - std::string relative_path; - relative_path += "luaobjects/"; - relative_path += script_name; - std::string server_file = relative_path + "/server.lua"; - std::string server_path = porting::getDataPath(server_file.c_str()); - - // Load the file - int ret; - ret = luaL_loadfile(L, server_path.c_str()); - if(ret) + if(player_is_close == false) { - const char *message = lua_tostring(L, -1); - lua_pop(L, 1); - dstream<<"LuaSAO::loadScript(): lua_loadfile failed: " - < m_yaw + 180) + nyaw -= 360; + m_yaw = 0.95*m_yaw + 0.05*nyaw; + m_yaw = wrapDegrees(m_yaw); + + v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI)); + f32 speed = 2*BS; + m_speed_f.X = speed * dir.X; + m_speed_f.Z = speed * dir.Z; + + if(m_touching_ground && (m_oldpos - m_base_position).getLength() + < dtime*speed/2) + { + m_counter1 -= dtime; + if(m_counter1 < 0.0) + { + m_counter1 += 1.0; + // Jump + m_speed_f.Y = 5.0*BS; + } + } -void LuaSAO::step(float dtime, Queue &messages) -{ - lua_getglobal(L, "step"); - if(!lua_isfunction(L,-1)) - { - lua_pop(L,1); - dstream<<"WARNING: LuaSAO::step(): step function not found"< box(-BS/3.,0.0,-BS/3., BS/3.,BS*5./3.,BS/3.); + collisionMoveResult moveresult; + // Maximum movement without glitches + f32 pos_max_d = BS*0.25; + // Limit speed + if(m_speed_f.getLength()*dtime > pos_max_d) + m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime); + v3f pos_f = getBasePosition(); + v3f pos_f_old = pos_f; + moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d, + box, dtime, pos_f, m_speed_f); + m_touching_ground = moveresult.touching_ground; - // Call (2 parameters, 0 result) - if(lua_pcall(L, 2, 0, 0)) - { - dstream<<"WARNING: LuaSAO::step(): Error running function step(): " - < 0.05*BS) { - messages.push_back(m_message_queue.pop_front()); + m_last_sent_position = pos_f; + + std::ostringstream os(std::ios::binary); + // command (0 = update position) + writeU8(os, 0); + // pos + writeV3F1000(os, m_base_position); + // yaw + writeF1000(os, m_yaw); + // create message and add to list + ActiveObjectMessage aom(getId(), false, os.str()); + messages.push_back(aom); } } +std::string Oerkki1SAO::getClientInitializationData() +{ + std::ostringstream os(std::ios::binary); + // version + writeU8(os, 0); + // pos + writeV3F1000(os, m_base_position); + return os.str(); +} + +std::string Oerkki1SAO::getStaticData() +{ + //dstream<<__FUNCTION_NAME<