X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fcontent_sao.cpp;h=85340981db7c64be614e1cbfdbd709d118e857a5;hb=db4911f9565cae6d982e5fac2627fe45048fab8f;hp=0b81855c16aec55f0c9fffaa685e9ed411ba86ca;hpb=112b85d0fb97b896da977a3915dab73015681896;p=oweals%2Fminetest.git diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 0b81855c1..85340981d 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -20,852 +20,732 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "content_sao.h" #include "collision.h" #include "environment.h" +#include "settings.h" +#include "main.h" // For g_profiler +#include "profiler.h" +#include "serialization.h" // For compressZlib +#include "tool.h" // For ToolCapabilities +#include "gamedef.h" core::map ServerActiveObject::m_types; /* - TestSAO + DummyLoadSAO */ -// 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) +class DummyLoadSAO : public ServerActiveObject { - return new TestSAO(env, id, pos); -} +public: + DummyLoadSAO(ServerEnvironment *env, v3f pos, u8 type): + ServerActiveObject(env, pos) + { + ServerActiveObject::registerType(type, create); + } + // Pretend to be the test object (to fool the client) + u8 getType() const + { return ACTIVEOBJECT_TYPE_TEST; } + // And never save to disk + bool isStaticAllowed() const + { return false; } + + static ServerActiveObject* create(ServerEnvironment *env, v3f pos, + const std::string &data) + { + return new DummyLoadSAO(env, pos, 0); + } -void TestSAO::step(float dtime, bool send_recommended) -{ - m_age += dtime; - if(m_age > 10) + void step(float dtime, bool send_recommended) { m_removed = true; - return; + infostream<<"DummyLoadSAO step"< 8*BS) - m_base_position.Y = 2*BS; +private: +}; - if(send_recommended == false) - return; +// Prototype (registers item for deserialization) +DummyLoadSAO proto1_DummyLoadSAO(NULL, v3f(0,0,0), ACTIVEOBJECT_TYPE_RAT); +DummyLoadSAO proto2_DummyLoadSAO(NULL, v3f(0,0,0), ACTIVEOBJECT_TYPE_OERKKI1); +DummyLoadSAO proto3_DummyLoadSAO(NULL, v3f(0,0,0), ACTIVEOBJECT_TYPE_FIREFLY); +DummyLoadSAO proto4_DummyLoadSAO(NULL, v3f(0,0,0), ACTIVEOBJECT_TYPE_MOBV2); + +/* + TestSAO +*/ - m_timer1 -= dtime; - if(m_timer1 < 0.0) +class TestSAO : public ServerActiveObject +{ +public: + TestSAO(ServerEnvironment *env, v3f pos): + ServerActiveObject(env, pos), + m_timer1(0), + m_age(0) { - m_timer1 += 0.125; - //dstream<<"TestSAO: id="< 10) + { + m_removed = true; + return; + } - data += itos(0); // 0 = position - data += " "; - data += itos(m_base_position.X); - data += " "; - data += itos(m_base_position.Y); - data += " "; - data += itos(m_base_position.Z); + m_base_position.Y += dtime * BS * 2; + if(m_base_position.Y > 8*BS) + m_base_position.Y = 2*BS; - ActiveObjectMessage aom(getId(), false, data); - m_messages_out.push_back(aom); + if(send_recommended == false) + return; + + m_timer1 -= dtime; + if(m_timer1 < 0.0) + { + m_timer1 += 0.125; + + std::string data; + + data += itos(0); // 0 = position + data += " "; + data += itos(m_base_position.X); + data += " "; + data += itos(m_base_position.Y); + data += " "; + data += itos(m_base_position.Z); + + ActiveObjectMessage aom(getId(), false, data); + m_messages_out.push_back(aom); + } } -} +private: + float m_timer1; + float m_age; +}; + +// Prototype (registers item for deserialization) +TestSAO proto_TestSAO(NULL, v3f(0,0,0)); /* ItemSAO */ -// 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) -{ - ServerActiveObject::registerType(getType(), create); -} - -ServerActiveObject* ItemSAO::create(ServerEnvironment *env, u16 id, v3f pos, - const std::string &data) +class ItemSAO : public ServerActiveObject { - 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 \"" - < 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); - - if(send_recommended == false) - return; + float getMinimumSavedMovement() + { return 0.1*BS; } - if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS) + static ServerActiveObject* create(ServerEnvironment *env, v3f pos, + const std::string &data) { - 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()); - m_messages_out.push_back(aom); + 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 itemstring = deSerializeString(is); + infostream<<"create(): Creating item \"" + < item="< 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; + IGameDef *gamedef = m_env->getGameDef(); + moveresult = collisionMoveSimple(&m_env->getMap(), gamedef, + pos_max_d, box, dtime, pos_f, m_speed_f); + + if(send_recommended == false) + return; -void RatSAO::step(float dtime, bool send_recommended) -{ - assert(m_env); + 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); + // command (0 = update position) + writeU8(os, 0); + // pos + writeV3F1000(os, m_base_position); + // create message and add to list + ActiveObjectMessage aom(getId(), false, os.str()); + m_messages_out.push_back(aom); + } + if(m_itemstring_changed) + { + m_itemstring_changed = false; + + std::ostringstream os(std::ios::binary); + // command (1 = update itemstring) + writeU8(os, 1); + // itemstring + os< 60) + std::string getStaticData() { - // Die - m_removed = true; - return; - }*/ - - // Apply gravity - m_speed_f.Y -= dtime*9.81*BS; - - /* - Move around if some player is close - */ - 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++) + infostream<<__FUNCTION_NAME<getPosition(); - if(m_base_position.getDistanceFrom(playerpos) < BS*10.0) + try{ + IItemDefManager *idef = m_env->getGameDef()->idef(); + ItemStack item; + item.deSerialize(m_itemstring, idef); + infostream<<__FUNCTION_NAME<<": m_itemstring=\""< item=\""<getBool("creative_mode") == true) { - m_counter1 -= dtime; - if(m_counter1 < 0.0) - { - m_counter1 += 1.0; - m_speed_f.Y = 5.0*BS; - } + m_removed = true; + return 0; } - + + // Take item into inventory + ItemStack item = createItemStack(); + Inventory *inv = puncher->getInventory(); + if(inv != NULL) { - m_counter2 -= dtime; - if(m_counter2 < 0.0) + std::string wieldlist = puncher->getWieldList(); + ItemStack leftover = inv->addItem(wieldlist, item); + puncher->setInventoryModified(); + if(leftover.empty()) + { + m_removed = true; + } + else { - m_counter2 += (float)(myrand()%100)/100*3.0; - m_yaw += ((float)(myrand()%200)-100)/100*180; - m_yaw = wrapDegrees(m_yaw); + m_itemstring = leftover.getItemString(); + m_itemstring_changed = true; } } + + return 0; } - - m_oldpos = m_base_position; - - /* - Move it, with collision detection - */ - - core::aabbox3d 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; - - setBasePosition(pos_f); - - 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()); - m_messages_out.push_back(aom); - } -} - -std::string RatSAO::getClientInitializationData() -{ - std::ostringstream os(std::ios::binary); - // version - writeU8(os, 0); - // pos - writeV3F1000(os, m_base_position); - return os.str(); -} +private: + std::string m_itemstring; + bool m_itemstring_changed; + v3f m_speed_f; + v3f m_last_sent_position; + IntervalLimiter m_move_interval; +}; -std::string RatSAO::getStaticData() -{ - //dstream<<__FUNCTION_NAME< max_increase) - dl = max_increase; + // Only register type if no environment supplied + if(env == NULL){ + ServerActiveObject::registerType(getType(), create); + return; + } - v3f d = d_wanted.normalize() * dl; - - speed.X += d.X; - speed.Z += d.Z; - speed.Y = target_speed.Y; + // Initialize something to armor groups + m_armor_groups["fleshy"] = 3; + m_armor_groups["snappy"] = 2; } -// Prototype -Oerkki1SAO proto_Oerkki1SAO(NULL, 0, v3f(0,0,0)); - -Oerkki1SAO::Oerkki1SAO(ServerEnvironment *env, u16 id, v3f pos): - ServerActiveObject(env, id, pos), - m_is_active(false), - m_speed_f(0,0,0) +LuaEntitySAO::~LuaEntitySAO() { - ServerActiveObject::registerType(getType(), create); - - m_oldpos = v3f(0,0,0); - m_last_sent_position = v3f(0,0,0); - m_yaw = 0; - m_counter1 = 0; - m_counter2 = 0; - m_age = 0; - m_touching_ground = false; - m_hp = 20; - m_after_jump_timer = 0; + if(m_registered){ + lua_State *L = m_env->getLua(); + scriptapi_luaentity_rm(L, m_id); + } + delete m_prop; } -ServerActiveObject* Oerkki1SAO::create(ServerEnvironment *env, u16 id, v3f pos, - const std::string &data) +void LuaEntitySAO::addedToEnvironment() { - std::istringstream is(data, std::ios::binary); - // read version - u8 version = readU8(is); - // read hp - u8 hp = readU8(is); - // check if version is supported - if(version != 0) - return NULL; - Oerkki1SAO *o = new Oerkki1SAO(env, id, pos); - o->m_hp = hp; - return o; + ServerActiveObject::addedToEnvironment(); + + // Create entity from name + lua_State *L = m_env->getLua(); + m_registered = scriptapi_luaentity_add(L, m_id, m_init_name.c_str()); + + if(m_registered){ + // Get properties + scriptapi_luaentity_get_properties(L, m_id, m_prop); + // Initialize HP from properties + m_hp = m_prop->hp_max; + } + + // Activate entity, supplying serialized state + scriptapi_luaentity_activate(L, m_id, m_init_state.c_str()); } -void Oerkki1SAO::step(float dtime, bool send_recommended) +ServerActiveObject* LuaEntitySAO::create(ServerEnvironment *env, v3f pos, + const std::string &data) { - assert(m_env); - - if(m_is_active == false) - { - if(m_inactive_interval.step(dtime, 0.5)==false) - return; - } - - /* - The AI - */ - - m_age += dtime; - if(m_age > 120) - { - // Die - m_removed = true; - return; - } - - m_after_jump_timer -= dtime; - - v3f old_speed = m_speed_f; - - // Apply gravity - m_speed_f.Y -= dtime*9.81*BS; - - /* - Move around if some player is close - */ - bool player_is_close = false; - bool player_is_too_close = false; - v3f near_player_pos; - // 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(); - f32 dist = m_base_position.getDistanceFrom(playerpos); - if(dist < BS*1.45) - { - player_is_too_close = true; - near_player_pos = playerpos; - break; + std::string name; + std::string state; + s16 hp = 1; + v3f velocity; + float yaw = 0; + if(data != ""){ + std::istringstream is(data, std::ios::binary); + // read version + u8 version = readU8(is); + // check if version is supported + if(version == 0){ + name = deSerializeString(is); + state = deSerializeLongString(is); } - else if(dist < BS*15.0) - { - player_is_close = true; - near_player_pos = playerpos; + else if(version == 1){ + name = deSerializeString(is); + state = deSerializeLongString(is); + hp = readS16(is); + velocity = readV3F1000(is); + yaw = readF1000(is); } } + // create object + infostream<<"LuaEntitySAO::create(name=\""<m_hp = hp; + sao->m_velocity = velocity; + sao->m_yaw = yaw; + return sao; +} - m_is_active = player_is_close; - - v3f target_speed = m_speed_f; - - if(!player_is_close) - { - target_speed = v3f(0,0,0); - } - else - { - // Move around - - v3f ndir = near_player_pos - m_base_position; - ndir.Y = 0; - ndir.normalize(); - - f32 nyaw = 180./PI*atan2(ndir.Z,ndir.X); - if(nyaw < m_yaw - 180) - nyaw += 360; - else if(nyaw > m_yaw + 180) - nyaw -= 360; - m_yaw = 0.95*m_yaw + 0.05*nyaw; - m_yaw = wrapDegrees(m_yaw); - - f32 speed = 2*BS; - - if((m_touching_ground || m_after_jump_timer > 0.0) - && !player_is_too_close) - { - v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI)); - target_speed.X = speed * dir.X; - target_speed.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 += 0.2; - // Jump - target_speed.Y = 5.0*BS; - m_after_jump_timer = 1.0; - } - } - - { - m_counter2 -= dtime; - if(m_counter2 < 0.0) - { - m_counter2 += (float)(myrand()%100)/100*3.0; - //m_yaw += ((float)(myrand()%200)-100)/100*180; - m_yaw += ((float)(myrand()%200)-100)/100*90; - m_yaw = wrapDegrees(m_yaw); - } - } - } - - if((m_speed_f - target_speed).getLength() > BS*4 || player_is_too_close) - accelerate_xz(m_speed_f, target_speed, dtime*BS*8); - else - accelerate_xz(m_speed_f, target_speed, dtime*BS*4); - - m_oldpos = m_base_position; - - /* - Move it, with collision detection - */ - - core::aabbox3d 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 = collisionMovePrecise(&m_env->getMap(), pos_max_d, - box, dtime, pos_f, m_speed_f); - m_touching_ground = moveresult.touching_ground; +void LuaEntitySAO::step(float dtime, bool send_recommended) +{ + m_last_sent_position_timer += dtime; - // Do collision damage - float tolerance = BS*12; - float factor = BS*0.5; - v3f speed_diff = old_speed - m_speed_f; - // Increase effect in X and Z - speed_diff.X *= 2; - speed_diff.Z *= 2; - float vel = speed_diff.getLength(); - if(vel > tolerance) - { - f32 damage_f = (vel - tolerance)/BS*factor; - u16 damage = (u16)(damage_f+0.5); - doDamage(damage); + if(m_prop->physical){ + core::aabbox3d box = m_prop->collisionbox; + box.MinEdge *= BS; + box.MaxEdge *= BS; + collisionMoveResult moveresult; + f32 pos_max_d = BS*0.25; // Distance per iteration + v3f p_pos = getBasePosition(); + v3f p_velocity = m_velocity; + IGameDef *gamedef = m_env->getGameDef(); + moveresult = collisionMovePrecise(&m_env->getMap(), gamedef, + pos_max_d, box, dtime, p_pos, p_velocity); + // Apply results + setBasePosition(p_pos); + m_velocity = p_velocity; + + m_velocity += dtime * m_acceleration; + } else { + m_base_position += dtime * m_velocity + 0.5 * dtime + * dtime * m_acceleration; + m_velocity += dtime * m_acceleration; } - setBasePosition(pos_f); + if(m_registered){ + lua_State *L = m_env->getLua(); + scriptapi_luaentity_step(L, m_id, dtime); + } - if(send_recommended == false && m_speed_f.getLength() < 3.0*BS) + if(send_recommended == false) return; + + // TODO: force send when acceleration changes enough? + float minchange = 0.2*BS; + if(m_last_sent_position_timer > 1.0){ + minchange = 0.01*BS; + } else if(m_last_sent_position_timer > 0.2){ + minchange = 0.05*BS; + } + float move_d = m_base_position.getDistanceFrom(m_last_sent_position); + move_d += m_last_sent_move_precision; + float vel_d = m_velocity.getDistanceFrom(m_last_sent_velocity); + if(move_d > minchange || vel_d > minchange || + fabs(m_yaw - m_last_sent_yaw) > 1.0){ + sendPosition(true, false); + } - if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS) - { - m_last_sent_position = pos_f; - + if(m_armor_groups_sent == false){ + m_armor_groups_sent = true; std::ostringstream os(std::ios::binary); - // command (0 = update position) - writeU8(os, 0); - // pos - writeV3F1000(os, m_base_position); - // yaw - writeF1000(os, m_yaw); + writeU8(os, LUAENTITY_CMD_UPDATE_ARMOR_GROUPS); + writeU16(os, m_armor_groups.size()); + for(ItemGroupList::const_iterator i = m_armor_groups.begin(); + i != m_armor_groups.end(); i++){ + os<first); + writeS16(os, i->second); + } // create message and add to list - ActiveObjectMessage aom(getId(), false, os.str()); + ActiveObjectMessage aom(getId(), true, os.str()); m_messages_out.push_back(aom); } } -std::string Oerkki1SAO::getClientInitializationData() +std::string LuaEntitySAO::getClientInitializationData() { std::ostringstream os(std::ios::binary); // version - writeU8(os, 0); + writeU8(os, 1); // pos writeV3F1000(os, m_base_position); + // yaw + writeF1000(os, m_yaw); + // hp + writeS16(os, m_hp); + // properties + std::ostringstream prop_os(std::ios::binary); + m_prop->serialize(prop_os); + os<getLua(); + std::string state = scriptapi_luaentity_get_staticdata(L, m_id); + os<getWieldedItem(); + punchitem = &punchitem_static; } + PunchDamageResult result = getPunchDamage( + m_armor_groups, + toolcap, + punchitem, + time_from_last_punch); + + if(result.did_punch) { - std::ostringstream os(std::ios::binary); - // command (1 = damage) - writeU8(os, 1); - // amount - writeU8(os, d); - // create message and add to list - ActiveObjectMessage aom(getId(), false, os.str()); - m_messages_out.push_back(aom); + setHP(getHP() - result.damage); + + actionstream<getDescription()<<", damage "<getLua(); + scriptapi_luaentity_punch(L, m_id, puncher, + time_from_last_punch, toolcap, dir); + + return result.wear; } -/* - FireflySAO -*/ +void LuaEntitySAO::rightClick(ServerActiveObject *clicker) +{ + if(!m_registered) + return; + lua_State *L = m_env->getLua(); + scriptapi_luaentity_rightclick(L, m_id, clicker); +} -// Prototype -FireflySAO proto_FireflySAO(NULL, 0, v3f(0,0,0)); +void LuaEntitySAO::setHP(s16 hp) +{ + if(hp < 0) hp = 0; + m_hp = hp; +} -FireflySAO::FireflySAO(ServerEnvironment *env, u16 id, v3f pos): - ServerActiveObject(env, id, pos), - m_is_active(false), - m_speed_f(0,0,0) +s16 LuaEntitySAO::getHP() { - ServerActiveObject::registerType(getType(), create); - - m_oldpos = v3f(0,0,0); - m_last_sent_position = v3f(0,0,0); - m_yaw = 0; - m_counter1 = 0; - m_counter2 = 0; - m_age = 0; - m_touching_ground = false; + return m_hp; } -ServerActiveObject* FireflySAO::create(ServerEnvironment *env, u16 id, v3f pos, - const std::string &data) +void LuaEntitySAO::setPos(v3f pos) { - 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; - return new FireflySAO(env, id, pos); + m_base_position = pos; + sendPosition(false, true); } -void FireflySAO::step(float dtime, bool send_recommended) +void LuaEntitySAO::moveTo(v3f pos, bool continuous) { - assert(m_env); + m_base_position = pos; + if(!continuous) + sendPosition(true, true); +} - if(m_is_active == false) - { - if(m_inactive_interval.step(dtime, 0.5)==false) - return; - } +float LuaEntitySAO::getMinimumSavedMovement() +{ + return 0.1 * BS; +} - /* - The AI - */ - - // Apply (less) gravity - m_speed_f.Y -= dtime*3*BS; - - /* - Move around if some player is close - */ - 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) - { - player_is_close = true; - break; - } - } +std::string LuaEntitySAO::getDescription() +{ + std::ostringstream os(std::ios::binary); + os<<"LuaEntitySAO at ("; + os<<(m_base_position.X/BS)<<","; + os<<(m_base_position.Y/BS)<<","; + os<<(m_base_position.Z/BS); + os<<")"; + return os.str(); +} - m_is_active = player_is_close; - - if(player_is_close == false) - { - m_speed_f.X = 0; - m_speed_f.Z = 0; - } - else - { - // Move around - v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI)); - f32 speed = BS/2; - 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; - m_speed_f.Y = 5.0*BS; - } - } +void LuaEntitySAO::setVelocity(v3f velocity) +{ + m_velocity = velocity; +} - { - m_counter2 -= dtime; - if(m_counter2 < 0.0) - { - m_counter2 += (float)(myrand()%100)/100*3.0; - m_yaw += ((float)(myrand()%200)-100)/100*180; - m_yaw = wrapDegrees(m_yaw); - } - } - } - - m_oldpos = m_base_position; - - /* - Move it, with collision detection - */ - - core::aabbox3d box(-BS/3.,-BS*2/3.0,-BS/3., BS/3.,BS*4./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; - - setBasePosition(pos_f); +v3f LuaEntitySAO::getVelocity() +{ + return m_velocity; +} - if(send_recommended == false) - return; +void LuaEntitySAO::setAcceleration(v3f acceleration) +{ + m_acceleration = acceleration; +} - if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS) - { - m_last_sent_position = pos_f; +v3f LuaEntitySAO::getAcceleration() +{ + return m_acceleration; +} - 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()); - m_messages_out.push_back(aom); - } +void LuaEntitySAO::setYaw(float yaw) +{ + m_yaw = yaw; +} + +float LuaEntitySAO::getYaw() +{ + return m_yaw; } -std::string FireflySAO::getClientInitializationData() +void LuaEntitySAO::setTextureMod(const std::string &mod) { std::ostringstream os(std::ios::binary); - // version - writeU8(os, 0); - // pos - writeV3F1000(os, m_base_position); - return os.str(); + // command + writeU8(os, LUAENTITY_CMD_SET_TEXTURE_MOD); + // parameters + os<getSendRecommendedInterval(); + + std::ostringstream os(std::ios::binary); + // command + writeU8(os, LUAENTITY_CMD_UPDATE_POSITION); + + // do_interpolate + writeU8(os, do_interpolate); + // pos + writeV3F1000(os, m_base_position); + // velocity + writeV3F1000(os, m_velocity); + // acceleration + writeV3F1000(os, m_acceleration); + // yaw + writeF1000(os, m_yaw); + // is_end_position (for interpolation) + writeU8(os, is_movement_end); + // update_interval (for interpolation) + writeF1000(os, update_interval); + + // create message and add to list + ActiveObjectMessage aom(getId(), false, os.str()); + m_messages_out.push_back(aom); +} +