From 65ac1d46b33d252759bae7f9ad3b0e8866a10b15 Mon Sep 17 00:00:00 2001 From: sapier Date: Sun, 15 Jan 2012 21:35:25 +0100 Subject: [PATCH] split content_sao.cpp and content_sao.h to multiple files --- src/CMakeLists.txt | 7 + src/clientlinkableobject.h | 15 - src/content_abm.cpp | 3 + src/content_object.h | 28 +- src/content_sao.cpp | 1673 +---------------------------------- src/content_sao.h | 228 +---- src/content_sao_firefly.cpp | 193 ++++ src/content_sao_firefly.h | 49 + src/content_sao_item.cpp | 167 ++++ src/content_sao_item.h | 47 + src/content_sao_lua.cpp | 323 +++++++ src/content_sao_lua.h | 78 ++ src/content_sao_mobv2.cpp | 522 +++++++++++ src/content_sao_mobv2.h | 76 ++ src/content_sao_oerkki1.cpp | 314 +++++++ src/content_sao_oerkki1.h | 55 ++ src/content_sao_rat.cpp | 212 +++++ src/content_sao_rat.h | 50 ++ src/content_sao_test.cpp | 90 ++ src/inventory.cpp | 1 + src/scriptapi.cpp | 6 +- src/serverlinkableobject.h | 13 - 22 files changed, 2228 insertions(+), 1922 deletions(-) create mode 100644 src/content_sao_firefly.cpp create mode 100644 src/content_sao_firefly.h create mode 100644 src/content_sao_item.cpp create mode 100644 src/content_sao_item.h create mode 100644 src/content_sao_lua.cpp create mode 100644 src/content_sao_lua.h create mode 100644 src/content_sao_mobv2.cpp create mode 100644 src/content_sao_mobv2.h create mode 100644 src/content_sao_oerkki1.cpp create mode 100644 src/content_sao_oerkki1.h create mode 100644 src/content_sao_rat.cpp create mode 100644 src/content_sao_rat.h create mode 100644 src/content_sao_test.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6dd00b675..d076126b6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -107,6 +107,13 @@ set(common_SRCS scriptapi.cpp script.cpp log.cpp + content_sao_firefly.cpp + content_sao_item.cpp + content_sao_lua.cpp + content_sao_mobv2.cpp + content_sao_oerkki1.cpp + content_sao_rat.cpp + content_sao_test.cpp content_sao.cpp mapgen.cpp content_nodemeta.cpp diff --git a/src/clientlinkableobject.h b/src/clientlinkableobject.h index a6192d58c..c3aba4ae5 100644 --- a/src/clientlinkableobject.h +++ b/src/clientlinkableobject.h @@ -30,21 +30,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "utility.h" #include "log.h" - -//this ain't the right place to define this but until cao/sao split -//is decided it'll have to stay here -struct AO_Message_type { - static const u8 SetPosition = 0x00; - static const u8 SetTextureMod = 0x01; - static const u8 SetSprite = 0x02; - static const u8 Punched = 0x03; - static const u8 TakeDamage = 0x04; - static const u8 Shoot = 0x05; - static const u8 Link = 0x06; - static const u8 UnLink = 0x07; -}; - - class ClientLinkableObject { public: ClientLinkableObject(); diff --git a/src/content_abm.cpp b/src/content_abm.cpp index 63867b78b..38e128f5c 100644 --- a/src/content_abm.cpp +++ b/src/content_abm.cpp @@ -23,6 +23,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gamedef.h" #include "nodedef.h" #include "content_sao.h" +#include "content_sao_rat.h" +#include "content_sao_mobv2.h" +#include "content_sao_oerkki1.h" #include "settings.h" #include "mapblock.h" // For getNodeBlockPos #include "mapgen.h" // For mapgen::make_tree diff --git a/src/content_object.h b/src/content_object.h index 0b85e3cf1..9d75ba357 100644 --- a/src/content_object.h +++ b/src/content_object.h @@ -20,17 +20,27 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef CONTENT_OBJECT_HEADER #define CONTENT_OBJECT_HEADER -#define ACTIVEOBJECT_TYPE_TEST 1 -#define ACTIVEOBJECT_TYPE_ITEM 2 -#define ACTIVEOBJECT_TYPE_RAT 3 -#define ACTIVEOBJECT_TYPE_OERKKI1 4 -#define ACTIVEOBJECT_TYPE_FIREFLY 5 -#define ACTIVEOBJECT_TYPE_MOBV2 6 - -#define ACTIVEOBJECT_TYPE_LUAENTITY 7 +#define ACTIVEOBJECT_TYPE_TEST 0x01 +#define ACTIVEOBJECT_TYPE_ITEM 0x02 +#define ACTIVEOBJECT_TYPE_RAT 0x03 +#define ACTIVEOBJECT_TYPE_OERKKI1 0x04 +#define ACTIVEOBJECT_TYPE_FIREFLY 0x05 +#define ACTIVEOBJECT_TYPE_MOBV2 0x06 +#define ACTIVEOBJECT_TYPE_LUAENTITY 0x07 // Special type, not stored as a static object -#define ACTIVEOBJECT_TYPE_PLAYER 100 +#define ACTIVEOBJECT_TYPE_PLAYER 0x64 + +struct AO_Message_type { + static const u8 SetPosition = 0x00; + static const u8 SetTextureMod = 0x01; + static const u8 SetSprite = 0x02; + static const u8 Punched = 0x03; + static const u8 TakeDamage = 0x04; + static const u8 Shoot = 0x05; + static const u8 Link = 0x06; + static const u8 UnLink = 0x07; +}; #endif diff --git a/src/content_sao.cpp b/src/content_sao.cpp index b8189b258..d13f83ea9 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -46,966 +46,6 @@ void accelerate_xz(v3f &speed, v3f target_speed, f32 max_increase) speed.Y = target_speed.Y; } -/* - TestSAO -*/ - -// Prototype -TestSAO proto_TestSAO(NULL, v3f(0,0,0)); - -TestSAO::TestSAO(ServerEnvironment *env, v3f pos): - ServerActiveObject(env, pos), - m_timer1(0), - m_age(0) -{ - ServerActiveObject::registerType(getType(), create); -} - -ServerActiveObject* TestSAO::create(ServerEnvironment *env, v3f pos, - const std::string &data) -{ - return new TestSAO(env, pos); -} - -void TestSAO::step(float dtime, bool send_recommended) -{ - m_age += dtime; - if(m_age > 10) - { - m_removed = true; - return; - } - - m_base_position.Y += dtime * BS * 2; - 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) - { - 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); - } -} - - -/* - ItemSAO -*/ - -// Prototype -ItemSAO proto_ItemSAO(NULL, v3f(0,0,0), ""); - -ItemSAO::ItemSAO(ServerEnvironment *env, v3f pos, - const std::string inventorystring): - ServerActiveObject(env, 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, v3f pos, - const std::string &data) -{ - 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); - infostream<<"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; - 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; - - 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()); - m_messages_out.push_back(aom); - } -} - -std::string ItemSAO::getClientInitializationData() -{ - 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<getGameDef(); - InventoryItem *item = InventoryItem::deSerialize(is, gamedef); - infostream<<__FUNCTION_NAME<<": m_inventorystring=\"" - < item="<addToInventory(item); - if(fits) - m_removed = true; - else - delete item; -} - -/* - RatSAO -*/ - -// Prototype -RatSAO proto_RatSAO(NULL, v3f(0,0,0)); - -RatSAO::RatSAO(ServerEnvironment *env, v3f pos): - ServerActiveObject(env, pos), - m_is_active(false), - m_speed_f(0,0,0) -{ - ServerActiveObject::registerType(getType(), create); - - m_oldpos = v3f(0,0,0); - m_last_sent_position = v3f(0,0,0); - m_yaw = myrand_range(0,PI*2); - m_counter1 = 0; - m_counter2 = 0; - m_age = 0; - m_touching_ground = false; -} - -ServerActiveObject* RatSAO::create(ServerEnvironment *env, v3f pos, - const std::string &data) -{ - 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 RatSAO(env, pos); -} - -void RatSAO::step(float dtime, bool send_recommended) -{ - ScopeProfiler sp2(g_profiler, "RatSAO::step avg", SPT_AVG); - - 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 > 60) - { - // 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++) - { - Player *player = *i; - v3f playerpos = player->getPosition(); - if(m_base_position.getDistanceFrom(playerpos) < BS*10.0) - { - player_is_close = true; - break; - } - } - - 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 = 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; - m_speed_f.Y = 5.0*BS; - } - } - - { - 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.,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; - IGameDef *gamedef = m_env->getGameDef(); - moveresult = collisionMoveSimple(&m_env->getMap(), gamedef, - 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(); -} - -std::string RatSAO::getStaticData() -{ - //infostream<<__FUNCTION_NAME<getGameDef(); - InventoryItem *item = InventoryItem::deSerialize(is, gamedef); - bool fits = puncher->addToInventory(item); - if(fits) - m_removed = true; - else - delete item; -} - -/* - Oerkki1SAO -*/ - -// Prototype -Oerkki1SAO proto_Oerkki1SAO(NULL, v3f(0,0,0)); - -Oerkki1SAO::Oerkki1SAO(ServerEnvironment *env, v3f pos): - ServerActiveObject(env, pos), - m_is_active(false), - m_speed_f(0,0,0) -{ - 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; -} - -ServerActiveObject* Oerkki1SAO::create(ServerEnvironment *env, v3f pos, - const std::string &data) -{ - 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, pos); - o->m_hp = hp; - return o; -} - -void Oerkki1SAO::step(float dtime, bool send_recommended) -{ - ScopeProfiler sp2(g_profiler, "Oerkki1SAO::step avg", SPT_AVG); - - 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*0.6) - { - m_removed = true; - return; - player_is_too_close = true; - near_player_pos = playerpos; - } - else if(dist < BS*15.0 && !player_is_too_close) - { - player_is_close = true; - near_player_pos = playerpos; - } - } - - 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; - IGameDef *gamedef = m_env->getGameDef(); - moveresult = collisionMovePrecise(&m_env->getMap(), gamedef, - pos_max_d, box, dtime, pos_f, m_speed_f); - m_touching_ground = moveresult.touching_ground; - - // Do collision damage - float tolerance = BS*30; - 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); - } - - setBasePosition(pos_f); - - if(send_recommended == false && m_speed_f.getLength() < 3.0*BS) - 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 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() -{ - //infostream<<__FUNCTION_NAME<getBasePosition()).normalize(); - m_speed_f += dir*12*BS; - - // "Material" properties of an oerkki - MaterialProperties mp; - mp.diggability = DIGGABLE_NORMAL; - mp.crackiness = -1.0; - mp.cuttability = 1.0; - - ToolDiggingProperties tp; - puncher->getWieldDiggingProperties(&tp); - - HittingProperties hitprop = getHittingProperties(&mp, &tp, - time_from_last_punch); - - doDamage(hitprop.hp); - puncher->damageWieldedItem(hitprop.wear); -} - -void Oerkki1SAO::doDamage(u16 d) -{ - infostream<<"oerkki damage: "< 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; - } - } - - 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; - } - } - - { - 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; - IGameDef *gamedef = m_env->getGameDef(); - moveresult = collisionMoveSimple(&m_env->getMap(), gamedef, - 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 FireflySAO::getClientInitializationData() -{ - std::ostringstream os(std::ios::binary); - // version - writeU8(os, 0); - // pos - writeV3F1000(os, m_base_position); - return os.str(); -} - -std::string FireflySAO::getStaticData() -{ - //infostream<<__FUNCTION_NAME<update(*init_properties); - - m_properties->setV3F("pos", pos); - - setPropertyDefaults(); - readProperties(); -} - -MobV2SAO::~MobV2SAO() -{ - delete m_properties; -} - -ServerActiveObject* MobV2SAO::create(ServerEnvironment *env, v3f pos, - const std::string &data) -{ - std::istringstream is(data, std::ios::binary); - Settings properties; - properties.parseConfigLines(is, "MobArgsEnd"); - MobV2SAO *o = new MobV2SAO(env, pos, &properties); - return o; -} - -std::string MobV2SAO::getStaticData() -{ - updateProperties(); - - std::ostringstream os(std::ios::binary); - m_properties->writeLines(os); - return os.str(); -} - -std::string MobV2SAO::getClientInitializationData() -{ - //infostream<<__FUNCTION_NAME< modified_blocks; @@ -1083,710 +121,3 @@ static void explodeSquare(Map *map, v3s16 p0, v3s16 size) } map->dispatchEvent(&event); } - -void MobV2SAO::step(float dtime, bool send_recommended) -{ - ScopeProfiler sp2(g_profiler, "MobV2SAO::step avg", SPT_AVG); - - assert(m_env); - Map *map = &m_env->getMap(); - - m_age += dtime; - - if(m_die_age >= 0.0 && m_age >= m_die_age){ - m_removed = true; - return; - } - - m_random_disturb_timer += dtime; - if(m_random_disturb_timer >= 5.0) - { - m_random_disturb_timer = 0; - // 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*16) - { - if(myrand_range(0,3) == 0){ - actionstream<<"Mob id="<getName()<getName(); - m_disturb_timer = 0; - break; - } - } - } - } - - Player *disturbing_player = - m_env->getPlayer(m_disturbing_player.c_str()); - v3f disturbing_player_off = v3f(0,1,0); - v3f disturbing_player_norm = v3f(0,1,0); - float disturbing_player_distance = 1000000; - float disturbing_player_dir = 0; - if(disturbing_player){ - disturbing_player_off = - disturbing_player->getPosition() - m_base_position; - disturbing_player_distance = disturbing_player_off.getLength(); - disturbing_player_norm = disturbing_player_off; - disturbing_player_norm.normalize(); - disturbing_player_dir = 180./PI*atan2(disturbing_player_norm.Z, - disturbing_player_norm.X); - } - - m_disturb_timer += dtime; - - if(!m_falling) - { - m_shooting_timer -= dtime; - if(m_shooting_timer <= 0.0 && m_shooting){ - m_shooting = false; - - std::string shoot_type = m_properties->get("shoot_type"); - v3f shoot_pos(0,0,0); - shoot_pos.Y += m_properties->getFloat("shoot_y") * BS; - if(shoot_type == "fireball"){ - v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI)); - dir.Y = m_shoot_y; - dir.normalize(); - v3f speed = dir * BS * 10.0; - v3f pos = m_base_position + shoot_pos; - infostream<<__FUNCTION_NAME<<": Mob id="<addActiveObjectAsStatic(obj); - m_env->addActiveObject(obj); - } else { - infostream<<__FUNCTION_NAME<<": Mob id="<= reload_time && - !m_next_pos_exists && - (m_disturb_timer <= 60.0 || shoot_without_player)) - { - m_shoot_y = 0; - if(m_disturb_timer < 60.0 && disturbing_player && - disturbing_player_distance < 16*BS && - fabs(disturbing_player_norm.Y) < 0.8){ - m_yaw = disturbing_player_dir; - sendPosition(); - m_shoot_y += disturbing_player_norm.Y; - } else { - m_shoot_y = 0.01 * myrand_range(-30,10); - } - m_shoot_reload_timer = 0.0; - m_shooting = true; - m_shooting_timer = 1.5; - { - std::ostringstream os(std::ios::binary); - // command (2 = shooting) - writeU8(os, 2); - // time - writeF1000(os, m_shooting_timer + 0.1); - // bright? - writeU8(os, true); - // create message and add to list - ActiveObjectMessage aom(getId(), false, os.str()); - m_messages_out.push_back(aom); - } - } - } - - if(m_move_type == "ground_nodes") - { - if(!m_shooting){ - m_walk_around_timer -= dtime; - if(m_walk_around_timer <= 0.0){ - m_walk_around = !m_walk_around; - if(m_walk_around) - m_walk_around_timer = 0.1*myrand_range(10,50); - else - m_walk_around_timer = 0.1*myrand_range(30,70); - } - } - - /* Move */ - if(m_next_pos_exists){ - v3f pos_f = m_base_position; - v3f next_pos_f = intToFloat(m_next_pos_i, BS); - - v3f v = next_pos_f - pos_f; - m_yaw = atan2(v.Z, v.X) / PI * 180; - - v3f diff = next_pos_f - pos_f; - v3f dir = diff; - dir.normalize(); - float speed = BS * 0.5; - if(m_falling) - speed = BS * 3.0; - dir *= dtime * speed; - bool arrived = false; - if(dir.getLength() > diff.getLength()){ - dir = diff; - arrived = true; - } - pos_f += dir; - m_base_position = pos_f; - - if((pos_f - next_pos_f).getLength() < 0.1 || arrived){ - m_next_pos_exists = false; - } - } - - v3s16 pos_i = floatToInt(m_base_position, BS); - v3s16 size_blocks = v3s16(m_size.X+0.5,m_size.Y+0.5,m_size.X+0.5); - v3s16 pos_size_off(0,0,0); - if(m_size.X >= 2.5){ - pos_size_off.X = -1; - pos_size_off.Y = -1; - } - - if(!m_next_pos_exists){ - /* Check whether to drop down */ - if(checkFreePosition(map, - pos_i + pos_size_off + v3s16(0,-1,0), size_blocks)){ - m_next_pos_i = pos_i + v3s16(0,-1,0); - m_next_pos_exists = true; - m_falling = true; - } else { - m_falling = false; - } - } - - if(m_walk_around) - { - if(!m_next_pos_exists){ - /* Find some position where to go next */ - v3s16 dps[3*3*3]; - int num_dps = 0; - for(int dx=-1; dx<=1; dx++) - for(int dy=-1; dy<=1; dy++) - for(int dz=-1; dz<=1; dz++){ - if(dx == 0 && dy == 0) - continue; - if(dx != 0 && dz != 0 && dy != 0) - continue; - dps[num_dps++] = v3s16(dx,dy,dz); - } - u32 order[3*3*3]; - get_random_u32_array(order, num_dps); - for(int i=0; i= 2.5){ - pos_size_off.X = -1; - pos_size_off.Y = -1; - } - bool free = checkFreePosition(map, pos_i + pos_size_off, size_blocks); - if(!free){ - explodeSquare(map, pos_i, v3s16(3,3,3)); - m_removed = true; - return; - } - } - else - { - errorstream<<"MobV2SAO::step(): id="< 0.05*BS) - { - sendPosition(); - } -} - -void MobV2SAO::punch(ServerActiveObject *puncher, float time_from_last_punch) -{ - if(!puncher) - return; - - v3f dir = (getBasePosition() - puncher->getBasePosition()).normalize(); - - // A quick hack; SAO description is player name for player - std::string playername = puncher->getDescription(); - - Map *map = &m_env->getMap(); - - actionstream<= 2.5){ - pos_size_off.X = -1; - pos_size_off.Y = -1; - } - bool free = checkFreePosition(map, pos_i + pos_size_off, size_blocks); - if(free) - m_base_position = new_base_position; - } - sendPosition(); - - - // "Material" properties of the MobV2 - MaterialProperties mp; - mp.diggability = DIGGABLE_NORMAL; - mp.crackiness = -1.0; - mp.cuttability = 1.0; - - ToolDiggingProperties tp; - puncher->getWieldDiggingProperties(&tp); - - HittingProperties hitprop = getHittingProperties(&mp, &tp, - time_from_last_punch); - - doDamage(hitprop.hp); - puncher->damageWieldedItem(hitprop.wear); -} - -bool MobV2SAO::isPeaceful() -{ - return m_properties->getBool("is_peaceful"); -} - -void MobV2SAO::sendPosition() -{ - m_last_sent_position = m_base_position; - - 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 MobV2SAO::setPropertyDefaults() -{ - m_properties->setDefault("is_peaceful", "false"); - m_properties->setDefault("move_type", "ground_nodes"); - m_properties->setDefault("speed", "(0,0,0)"); - m_properties->setDefault("age", "0"); - m_properties->setDefault("yaw", "0"); - m_properties->setDefault("pos", "(0,0,0)"); - m_properties->setDefault("hp", "0"); - m_properties->setDefault("die_age", "-1"); - m_properties->setDefault("size", "(1,2)"); - m_properties->setDefault("shoot_type", "fireball"); - m_properties->setDefault("shoot_y", "0"); - m_properties->setDefault("mindless_rage", "false"); -} -void MobV2SAO::readProperties() -{ - m_move_type = m_properties->get("move_type"); - m_speed = m_properties->getV3F("speed"); - m_age = m_properties->getFloat("age"); - m_yaw = m_properties->getFloat("yaw"); - m_base_position = m_properties->getV3F("pos"); - m_hp = m_properties->getS32("hp"); - m_die_age = m_properties->getFloat("die_age"); - m_size = m_properties->getV2F("size"); -} -void MobV2SAO::updateProperties() -{ - m_properties->set("move_type", m_move_type); - m_properties->setV3F("speed", m_speed); - m_properties->setFloat("age", m_age); - m_properties->setFloat("yaw", m_yaw); - m_properties->setV3F("pos", m_base_position); - m_properties->setS32("hp", m_hp); - m_properties->setFloat("die_age", m_die_age); - m_properties->setV2F("size", m_size); - - m_properties->setS32("version", 0); -} - -void MobV2SAO::doDamage(u16 d) -{ - infostream<<"MobV2 hp="<getLua(); - scriptapi_luaentity_rm(L, m_id); - } - delete m_prop; -} - -void LuaEntitySAO::addedToEnvironment() -{ - ServerActiveObject::addedToEnvironment(); - - // Create entity from name and state - lua_State *L = m_env->getLua(); - m_registered = scriptapi_luaentity_add(L, m_id, m_init_name.c_str(), - m_init_state.c_str()); - - if(m_registered){ - // Get properties - scriptapi_luaentity_get_properties(L, m_id, m_prop); - } -} - -ServerActiveObject* LuaEntitySAO::create(ServerEnvironment *env, v3f pos, - const std::string &data) -{ - std::istringstream is(data, std::ios::binary); - // read version - u8 version = readU8(is); - // check if version is supported - if(version != 0) - return NULL; - // read name - std::string name = deSerializeString(is); - // read state - std::string state = deSerializeLongString(is); - // create object - infostream<<"LuaEntitySAO::create(name=\""<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; - } - - if(m_registered){ - lua_State *L = m_env->getLua(); - scriptapi_luaentity_step(L, m_id, dtime); - } - - 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); - } -} - -std::string LuaEntitySAO::getClientInitializationData() -{ - std::ostringstream os(std::ios::binary); - // version - writeU8(os, 0); - // pos - writeV3F1000(os, m_base_position); - // yaw - writeF1000(os, m_yaw); - // 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<getLua(); - scriptapi_luaentity_punch(L, m_id, puncher, time_from_last_punch); -} - -void LuaEntitySAO::rightClick(ServerActiveObject *clicker) -{ - if(!m_registered) - return; - lua_State *L = m_env->getLua(); - scriptapi_luaentity_rightclick(L, m_id, clicker); -} - -void LuaEntitySAO::setPos(v3f pos) -{ - m_base_position = pos; - sendPosition(false, true); -} - -void LuaEntitySAO::moveTo(v3f pos, bool continuous) -{ - m_base_position = pos; - if(!continuous) - sendPosition(true, true); -} - -float LuaEntitySAO::getMinimumSavedMovement() -{ - return 0.1 * BS; -} - -void LuaEntitySAO::setVelocity(v3f velocity) -{ - m_velocity = velocity; -} - -v3f LuaEntitySAO::getVelocity() -{ - return m_velocity; -} - -void LuaEntitySAO::setAcceleration(v3f acceleration) -{ - m_acceleration = acceleration; -} - -v3f LuaEntitySAO::getAcceleration() -{ - return m_acceleration; -} - -void LuaEntitySAO::setYaw(float yaw) -{ - m_yaw = yaw; -} - -float LuaEntitySAO::getYaw() -{ - return m_yaw; -} - -void LuaEntitySAO::setTextureMod(const std::string &mod) -{ - std::ostringstream os(std::ios::binary); - // command (1 = set texture modification) - writeU8(os, 1); - // parameters - os<getSendRecommendedInterval(); - - std::ostringstream os(std::ios::binary); - // command (0 = update position) - writeU8(os, 0); - - // 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); -} - diff --git a/src/content_sao.h b/src/content_sao.h index c2bb9c3f5..1c69919a0 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -22,223 +22,25 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serverobject.h" #include "content_object.h" - -class TestSAO : public ServerActiveObject -{ -public: - TestSAO(ServerEnvironment *env, v3f pos); - u8 getType() const - {return ACTIVEOBJECT_TYPE_TEST;} - static ServerActiveObject* create(ServerEnvironment *env, v3f pos, - const std::string &data); - void step(float dtime, bool send_recommended); -private: - float m_timer1; - float m_age; -}; - -class ItemSAO : public ServerActiveObject -{ -public: - ItemSAO(ServerEnvironment *env, v3f pos, - const std::string inventorystring); - u8 getType() const - {return ACTIVEOBJECT_TYPE_ITEM;} - static ServerActiveObject* create(ServerEnvironment *env, v3f pos, - const std::string &data); - void step(float dtime, bool send_recommended); - std::string getClientInitializationData(); - std::string getStaticData(); - InventoryItem* createInventoryItem(); - void punch(ServerActiveObject *puncher, float time_from_last_punch); - float getMinimumSavedMovement(){ return 0.1*BS; } -private: - std::string m_inventorystring; - v3f m_speed_f; - v3f m_last_sent_position; - IntervalLimiter m_move_interval; -}; - -class RatSAO : public ServerActiveObject -{ -public: - RatSAO(ServerEnvironment *env, v3f pos); - u8 getType() const - {return ACTIVEOBJECT_TYPE_RAT;} - static ServerActiveObject* create(ServerEnvironment *env, v3f pos, - const std::string &data); - void step(float dtime, bool send_recommended); - std::string getClientInitializationData(); - std::string getStaticData(); - void punch(ServerActiveObject *puncher, float time_from_last_punch); -private: - bool m_is_active; - IntervalLimiter m_inactive_interval; - v3f m_speed_f; - v3f m_oldpos; - v3f m_last_sent_position; - float m_yaw; - float m_counter1; - float m_counter2; - float m_age; - bool m_touching_ground; -}; - -class Oerkki1SAO : public ServerActiveObject -{ -public: - Oerkki1SAO(ServerEnvironment *env, v3f pos); - u8 getType() const - {return ACTIVEOBJECT_TYPE_OERKKI1;} - static ServerActiveObject* create(ServerEnvironment *env, v3f pos, - const std::string &data); - void step(float dtime, bool send_recommended); - std::string getClientInitializationData(); - std::string getStaticData(); - void punch(ServerActiveObject *puncher, float time_from_last_punch); - bool isPeaceful(){return false;} -private: - void doDamage(u16 d); - - bool m_is_active; - IntervalLimiter m_inactive_interval; - v3f m_speed_f; - v3f m_oldpos; - v3f m_last_sent_position; - float m_yaw; - float m_counter1; - float m_counter2; - float m_age; - bool m_touching_ground; - u8 m_hp; - float m_after_jump_timer; -}; - -class FireflySAO : public ServerActiveObject -{ -public: - FireflySAO(ServerEnvironment *env, v3f pos); - u8 getType() const - {return ACTIVEOBJECT_TYPE_FIREFLY;} - static ServerActiveObject* create(ServerEnvironment *env, v3f pos, - const std::string &data); - void step(float dtime, bool send_recommended); - std::string getClientInitializationData(); - std::string getStaticData(); -private: - bool m_is_active; - IntervalLimiter m_inactive_interval; - v3f m_speed_f; - v3f m_oldpos; - v3f m_last_sent_position; - float m_yaw; - float m_counter1; - float m_counter2; - float m_age; - bool m_touching_ground; -}; +#include "collision.h" +#include "environment.h" +#include "settings.h" +#include "main.h" // For g_profiler +#include "profiler.h" +#include "serialization.h" // For compressZlib +#include "materials.h" // For MaterialProperties +#include "tooldef.h" // ToolDiggingProperties class Settings; -class MobV2SAO : public ServerActiveObject -{ -public: - MobV2SAO(ServerEnvironment *env, v3f pos, - Settings *init_properties); - virtual ~MobV2SAO(); - u8 getType() const - {return ACTIVEOBJECT_TYPE_MOBV2;} - static ServerActiveObject* create(ServerEnvironment *env, v3f pos, - const std::string &data); - std::string getStaticData(); - std::string getClientInitializationData(); - void step(float dtime, bool send_recommended); - void punch(ServerActiveObject *puncher, float time_from_last_punch); - bool isPeaceful(); -private: - void sendPosition(); - void setPropertyDefaults(); - void readProperties(); - void updateProperties(); - void doDamage(u16 d); - - std::string m_move_type; - v3f m_speed; - v3f m_last_sent_position; - v3f m_oldpos; - float m_yaw; - float m_counter1; - float m_counter2; - float m_age; - bool m_touching_ground; - int m_hp; - bool m_walk_around; - float m_walk_around_timer; - bool m_next_pos_exists; - v3s16 m_next_pos_i; - float m_shoot_reload_timer; - bool m_shooting; - float m_shooting_timer; - float m_die_age; - v2f m_size; - bool m_falling; - float m_disturb_timer; - std::string m_disturbing_player; - float m_random_disturb_timer; - float m_shoot_y; - - Settings *m_properties; -}; - -struct LuaEntityProperties; - -class LuaEntitySAO : public ServerActiveObject -{ -public: - LuaEntitySAO(ServerEnvironment *env, v3f pos, - const std::string &name, const std::string &state); - ~LuaEntitySAO(); - u8 getType() const - {return ACTIVEOBJECT_TYPE_LUAENTITY;} - virtual void addedToEnvironment(); - static ServerActiveObject* create(ServerEnvironment *env, v3f pos, - const std::string &data); - void step(float dtime, bool send_recommended); - std::string getClientInitializationData(); - std::string getStaticData(); - void punch(ServerActiveObject *puncher, float time_from_last_punch); - void rightClick(ServerActiveObject *clicker); - void setPos(v3f pos); - void moveTo(v3f pos, bool continuous); - float getMinimumSavedMovement(); - /* LuaEntitySAO-specific */ - void setVelocity(v3f velocity); - v3f getVelocity(); - void setAcceleration(v3f acceleration); - v3f getAcceleration(); - void setYaw(float yaw); - float getYaw(); - void setTextureMod(const std::string &mod); - void setSprite(v2s16 p, int num_frames, float framelength, - bool select_horiz_by_yawpitch); - std::string getName(); -private: - void sendPosition(bool do_interpolate, bool is_movement_end); +#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" - std::string m_init_name; - std::string m_init_state; - bool m_registered; - struct LuaEntityProperties *m_prop; - - v3f m_velocity; - v3f m_acceleration; - float m_yaw; - float m_last_sent_yaw; - v3f m_last_sent_position; - v3f m_last_sent_velocity; - float m_last_sent_position_timer; - float m_last_sent_move_precision; -}; +void accelerate_xz(v3f &speed, v3f target_speed, f32 max_increase); +bool checkFreePosition(Map *map, v3s16 p0, v3s16 size); +bool checkWalkablePosition(Map *map, v3s16 p0); +bool checkFreeAndWalkablePosition(Map *map, v3s16 p0, v3s16 size); +void get_random_u32_array(u32 a[], u32 len); +void explodeSquare(Map *map, v3s16 p0, v3s16 size); #endif diff --git a/src/content_sao_firefly.cpp b/src/content_sao_firefly.cpp new file mode 100644 index 000000000..ccb58fd93 --- /dev/null +++ b/src/content_sao_firefly.cpp @@ -0,0 +1,193 @@ +/* +Minetest-c55 +Copyright (C) 2010-2012 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "content_sao_firefly.h" + +/* + FireflySAO +*/ + +FireflySAO::FireflySAO(ServerEnvironment *env, v3f pos): + ServerActiveObject(env, pos), + m_is_active(false), + m_speed_f(0,0,0) +{ + 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; +} + +ServerActiveObject* FireflySAO::create(ServerEnvironment *env, v3f pos, + const std::string &data) +{ + 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, pos); +} + +void FireflySAO::step(float dtime, bool send_recommended) +{ + ScopeProfiler sp2(g_profiler, "FireflySAO::step avg", SPT_AVG); + + assert(m_env); + + if(m_is_active == false) + { + if(m_inactive_interval.step(dtime, 0.5)==false) + return; + } + + /* + 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; + } + } + + 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; + } + } + + { + 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; + IGameDef *gamedef = m_env->getGameDef(); + moveresult = collisionMoveSimple(&m_env->getMap(), gamedef, + 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, AO_Message_type::SetPosition); + // 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 FireflySAO::getClientInitializationData() +{ + std::ostringstream os(std::ios::binary); + // version + writeU8(os, 0); + // pos + writeV3F1000(os, m_base_position); + return os.str(); +} + +std::string FireflySAO::getStaticData() +{ + //infostream<<__FUNCTION_NAME< + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef CONTENT_SOA_FIREFLY_H_ +#define CONTENT_SOA_FIREFLY_H_ + +#include "content_sao.h" + +class FireflySAO : public ServerActiveObject +{ +public: + FireflySAO(ServerEnvironment *env, v3f pos); + u8 getType() const + {return ACTIVEOBJECT_TYPE_FIREFLY;} + static ServerActiveObject* create(ServerEnvironment *env, v3f pos, + const std::string &data); + void step(float dtime, bool send_recommended); + std::string getClientInitializationData(); + std::string getStaticData(); +private: + bool m_is_active; + IntervalLimiter m_inactive_interval; + v3f m_speed_f; + v3f m_oldpos; + v3f m_last_sent_position; + float m_yaw; + float m_counter1; + float m_counter2; + float m_age; + bool m_touching_ground; +}; + +#endif /* CONTENT_SOA_FIREFLY_H_ */ diff --git a/src/content_sao_item.cpp b/src/content_sao_item.cpp new file mode 100644 index 000000000..d380d32c3 --- /dev/null +++ b/src/content_sao_item.cpp @@ -0,0 +1,167 @@ +/* +Minetest-c55 +Copyright (C) 2010-2012 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "content_sao_item.h" + +/* + ItemSAO +*/ + +ItemSAO::ItemSAO(ServerEnvironment *env, v3f pos, + const std::string inventorystring): + ServerActiveObject(env, 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, v3f pos, + const std::string &data) +{ + 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); + infostream<<"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; + 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; + + 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] = AO_Message_type::SetPosition; + 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::string ItemSAO::getClientInitializationData() +{ + 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<getGameDef(); + InventoryItem *item = InventoryItem::deSerialize(is, gamedef); + infostream<<__FUNCTION_NAME<<": m_inventorystring=\"" + < item="<addToInventory(item); + if(fits) + m_removed = true; + else + delete item; +} + +// Prototype +ItemSAO proto_ItemSAO(NULL, v3f(0,0,0), ""); diff --git a/src/content_sao_item.h b/src/content_sao_item.h new file mode 100644 index 000000000..20c7f5662 --- /dev/null +++ b/src/content_sao_item.h @@ -0,0 +1,47 @@ +/* +Minetest-c55 +Copyright (C) 2010-2012 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef CONTENT_SAO_ITEM_H_ +#define CONTENT_SAO_ITEM_H_ + +#include "content_sao.h" + +class ItemSAO : public ServerActiveObject +{ +public: + ItemSAO(ServerEnvironment *env, v3f pos, + const std::string inventorystring); + u8 getType() const + {return ACTIVEOBJECT_TYPE_ITEM;} + static ServerActiveObject* create(ServerEnvironment *env, v3f pos, + const std::string &data); + void step(float dtime, bool send_recommended); + std::string getClientInitializationData(); + std::string getStaticData(); + InventoryItem* createInventoryItem(); + void punch(ServerActiveObject *puncher, float time_from_last_punch); + float getMinimumSavedMovement(){ return 0.1*BS; } +private: + std::string m_inventorystring; + v3f m_speed_f; + v3f m_last_sent_position; + IntervalLimiter m_move_interval; +}; + +#endif /* CONTENT_SAO_ITEM_H_ */ diff --git a/src/content_sao_lua.cpp b/src/content_sao_lua.cpp new file mode 100644 index 000000000..6092d613b --- /dev/null +++ b/src/content_sao_lua.cpp @@ -0,0 +1,323 @@ +/* +Minetest-c55 +Copyright (C) 2010-2012 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include +#include "content_sao_lua.h" + +/* + LuaEntitySAO +*/ + +LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos, + const std::string &name, const std::string &state): + ServerActiveObject(env, pos), + m_init_name(name), + m_init_state(state), + m_registered(false), + m_prop(new LuaEntityProperties), + m_velocity(0,0,0), + m_acceleration(0,0,0), + m_yaw(0), + m_last_sent_yaw(0), + m_last_sent_position(0,0,0), + m_last_sent_velocity(0,0,0), + m_last_sent_position_timer(0), + m_last_sent_move_precision(0) +{ + // Only register type if no environment supplied + if(env == NULL){ + ServerActiveObject::registerType(getType(), create); + return; + } +} + +LuaEntitySAO::~LuaEntitySAO() +{ + if(m_registered){ + lua_State *L = m_env->getLua(); + scriptapi_luaentity_rm(L, m_id); + } + delete m_prop; +} + +void LuaEntitySAO::addedToEnvironment() +{ + ServerActiveObject::addedToEnvironment(); + + // Create entity from name and state + lua_State *L = m_env->getLua(); + m_registered = scriptapi_luaentity_add(L, m_id, m_init_name.c_str(), + m_init_state.c_str()); + + if(m_registered){ + // Get properties + scriptapi_luaentity_get_properties(L, m_id, m_prop); + } +} + +ServerActiveObject* LuaEntitySAO::create(ServerEnvironment *env, v3f pos, + const std::string &data) +{ + std::istringstream is(data, std::ios::binary); + // read version + u8 version = readU8(is); + // check if version is supported + if(version != 0) + return NULL; + // read name + std::string name = deSerializeString(is); + // read state + std::string state = deSerializeLongString(is); + // create object + infostream<<"LuaEntitySAO::create(name=\""<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; + //if (moveresult.collides) errorstream << "collision" << std::endl; + //if (moveresult.touching_ground) errorstream << "ground" << std::endl; + m_velocity += dtime * m_acceleration; + } else { + m_base_position += dtime * m_velocity + 0.5 * dtime + * dtime * m_acceleration; + m_velocity += dtime * m_acceleration; + } + + //errorstream << this << " step: new_vel=(" << m_velocity.X << "," << m_velocity.Y << "," << m_velocity.Z << ")" << std::endl; + //errorstream << this << " step: new_pos=(" << m_base_position.X << "," << m_base_position.Y << "," << m_base_position.Z << ")" << std::endl; + + if(m_registered){ + lua_State *L = m_env->getLua(); + scriptapi_luaentity_step(L, m_id, dtime); + } + + 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 || + m_last_sent_position_timer > 10.0){ + sendPosition(true, false); + } +} + +std::string LuaEntitySAO::getClientInitializationData() +{ + std::ostringstream os(std::ios::binary); + // version + writeU8(os, 0); + // pos + writeV3F1000(os, m_base_position); + // yaw + writeF1000(os, m_yaw); + // 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<getLua(); + scriptapi_luaentity_punch(L, m_id, puncher, time_from_last_punch); +} + +void LuaEntitySAO::rightClick(ServerActiveObject *clicker) +{ + if(!m_registered) + return; + lua_State *L = m_env->getLua(); + scriptapi_luaentity_rightclick(L, m_id, clicker); +} + +void LuaEntitySAO::setPos(v3f pos) +{ + m_base_position = pos; + sendPosition(false, true); +} + +void LuaEntitySAO::moveTo(v3f pos, bool continuous) +{ + m_base_position = pos; + if(!continuous) + sendPosition(true, true); +} + +float LuaEntitySAO::getMinimumSavedMovement() +{ + return 0.1 * BS; +} + +void LuaEntitySAO::setVelocity(v3f velocity) +{ + //errorstream << this << " Set velocity: (" << velocity.X << "," << velocity.Y << "," <getSendRecommendedInterval(); + + std::ostringstream os(std::ios::binary); + // command (0 = update position) + writeU8(os, AO_Message_type::SetPosition); + + // 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); +} + +// Prototype +LuaEntitySAO proto_LuaEntitySAO(NULL, v3f(0,0,0), "_prototype", ""); diff --git a/src/content_sao_lua.h b/src/content_sao_lua.h new file mode 100644 index 000000000..b0f23ff49 --- /dev/null +++ b/src/content_sao_lua.h @@ -0,0 +1,78 @@ +/* +Minetest-c55 +Copyright (C) 2010-2012 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef CONTENT_SAO_LUA_H_ +#define CONTENT_SAO_LUA_H_ + +#include "content_sao.h" +#include "serverlinkableobject.h" +#include "scriptapi.h" +#include "luaentity_common.h" + +class LuaEntitySAO : public ServerActiveObject +{ +public: + LuaEntitySAO(ServerEnvironment *env, v3f pos, + const std::string &name, const std::string &state); + ~LuaEntitySAO(); + u8 getType() const + {return ACTIVEOBJECT_TYPE_LUAENTITY;} + virtual void addedToEnvironment(); + static ServerActiveObject* create(ServerEnvironment *env, v3f pos, + const std::string &data); + void step(float dtime, bool send_recommended); + std::string getClientInitializationData(); + std::string getStaticData(); + void punch(ServerActiveObject *puncher, float time_from_last_punch); + void rightClick(ServerActiveObject *clicker); + void setPos(v3f pos); + void moveTo(v3f pos, bool continuous); + float getMinimumSavedMovement(); + /* LuaEntitySAO-specific */ + void setVelocity(v3f velocity); + v3f getVelocity(); + void setAcceleration(v3f acceleration); + v3f getAcceleration(); + void setYaw(float yaw); + float getYaw(); + void setTextureMod(const std::string &mod); + void setSprite(v2s16 p, int num_frames, float framelength, + bool select_horiz_by_yawpitch); + std::string getName(); + +private: + void sendPosition(bool do_interpolate, bool is_movement_end); + + std::string m_init_name; + std::string m_init_state; + bool m_registered; + struct LuaEntityProperties *m_prop; + + v3f m_velocity; + v3f m_acceleration; + float m_yaw; + float m_last_sent_yaw; + v3f m_last_sent_position; + v3f m_last_sent_velocity; + float m_last_sent_position_timer; + float m_last_sent_move_precision; +}; + + +#endif /* CONTENT_SAO_LUA_H_ */ diff --git a/src/content_sao_mobv2.cpp b/src/content_sao_mobv2.cpp new file mode 100644 index 000000000..49b18a5a0 --- /dev/null +++ b/src/content_sao_mobv2.cpp @@ -0,0 +1,522 @@ +/* +Minetest-c55 +Copyright (C) 2010-2012 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "content_sao_mobv2.h" + +/* + MobV2SAO +*/ + +MobV2SAO::MobV2SAO(ServerEnvironment *env, v3f pos, + Settings *init_properties): + ServerActiveObject(env, pos), + m_move_type("ground_nodes"), + m_speed(0,0,0), + m_last_sent_position(0,0,0), + m_oldpos(0,0,0), + m_yaw(0), + m_counter1(0), + m_counter2(0), + m_age(0), + m_touching_ground(false), + m_hp(10), + m_walk_around(false), + m_walk_around_timer(0), + m_next_pos_exists(false), + m_shoot_reload_timer(0), + m_shooting(false), + m_shooting_timer(0), + m_falling(false), + m_disturb_timer(100000), + m_random_disturb_timer(0), + m_shoot_y(0) +{ + ServerActiveObject::registerType(getType(), create); + + m_properties = new Settings(); + if(init_properties) + m_properties->update(*init_properties); + + m_properties->setV3F("pos", pos); + + setPropertyDefaults(); + readProperties(); +} + +MobV2SAO::~MobV2SAO() +{ + delete m_properties; +} + +ServerActiveObject* MobV2SAO::create(ServerEnvironment *env, v3f pos, + const std::string &data) +{ + std::istringstream is(data, std::ios::binary); + Settings properties; + properties.parseConfigLines(is, "MobArgsEnd"); + MobV2SAO *o = new MobV2SAO(env, pos, &properties); + return o; +} + +std::string MobV2SAO::getStaticData() +{ + updateProperties(); + + std::ostringstream os(std::ios::binary); + m_properties->writeLines(os); + return os.str(); +} + +std::string MobV2SAO::getClientInitializationData() +{ + //infostream<<__FUNCTION_NAME<getMap(); + + m_age += dtime; + + if(m_die_age >= 0.0 && m_age >= m_die_age){ + m_removed = true; + return; + } + + m_random_disturb_timer += dtime; + if(m_random_disturb_timer >= 5.0) + { + m_random_disturb_timer = 0; + // 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*16) + { + if(myrand_range(0,3) == 0){ + actionstream<<"Mob id="<getName()<getName(); + m_disturb_timer = 0; + break; + } + } + } + } + + Player *disturbing_player = + m_env->getPlayer(m_disturbing_player.c_str()); + v3f disturbing_player_off = v3f(0,1,0); + v3f disturbing_player_norm = v3f(0,1,0); + float disturbing_player_distance = 1000000; + float disturbing_player_dir = 0; + if(disturbing_player){ + disturbing_player_off = + disturbing_player->getPosition() - m_base_position; + disturbing_player_distance = disturbing_player_off.getLength(); + disturbing_player_norm = disturbing_player_off; + disturbing_player_norm.normalize(); + disturbing_player_dir = 180./PI*atan2(disturbing_player_norm.Z, + disturbing_player_norm.X); + } + + m_disturb_timer += dtime; + + if(!m_falling) + { + m_shooting_timer -= dtime; + if(m_shooting_timer <= 0.0 && m_shooting){ + m_shooting = false; + + std::string shoot_type = m_properties->get("shoot_type"); + v3f shoot_pos(0,0,0); + shoot_pos.Y += m_properties->getFloat("shoot_y") * BS; + if(shoot_type == "fireball"){ + v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI)); + dir.Y = m_shoot_y; + dir.normalize(); + v3f speed = dir * BS * 10.0; + v3f pos = m_base_position + shoot_pos; + infostream<<__FUNCTION_NAME<<": Mob id="<addActiveObjectAsStatic(obj); + m_env->addActiveObject(obj); + } else { + infostream<<__FUNCTION_NAME<<": Mob id="<= reload_time && + !m_next_pos_exists && + (m_disturb_timer <= 60.0 || shoot_without_player)) + { + m_shoot_y = 0; + if(m_disturb_timer < 60.0 && disturbing_player && + disturbing_player_distance < 16*BS && + fabs(disturbing_player_norm.Y) < 0.8){ + m_yaw = disturbing_player_dir; + sendPosition(); + m_shoot_y += disturbing_player_norm.Y; + } else { + m_shoot_y = 0.01 * myrand_range(-30,10); + } + m_shoot_reload_timer = 0.0; + m_shooting = true; + m_shooting_timer = 1.5; + { + std::ostringstream os(std::ios::binary); + // command (2 = shooting) + writeU8(os, AO_Message_type::Shoot); + // time + writeF1000(os, m_shooting_timer + 0.1); + // bright? + writeU8(os, true); + // create message and add to list + ActiveObjectMessage aom(getId(), false, os.str()); + m_messages_out.push_back(aom); + } + } + } + + if(m_move_type == "ground_nodes") + { + if(!m_shooting){ + m_walk_around_timer -= dtime; + if(m_walk_around_timer <= 0.0){ + m_walk_around = !m_walk_around; + if(m_walk_around) + m_walk_around_timer = 0.1*myrand_range(10,50); + else + m_walk_around_timer = 0.1*myrand_range(30,70); + } + } + + /* Move */ + if(m_next_pos_exists){ + v3f pos_f = m_base_position; + v3f next_pos_f = intToFloat(m_next_pos_i, BS); + + v3f v = next_pos_f - pos_f; + m_yaw = atan2(v.Z, v.X) / PI * 180; + + v3f diff = next_pos_f - pos_f; + v3f dir = diff; + dir.normalize(); + float speed = BS * 0.5; + if(m_falling) + speed = BS * 3.0; + dir *= dtime * speed; + bool arrived = false; + if(dir.getLength() > diff.getLength()){ + dir = diff; + arrived = true; + } + pos_f += dir; + m_base_position = pos_f; + + if((pos_f - next_pos_f).getLength() < 0.1 || arrived){ + m_next_pos_exists = false; + } + } + + v3s16 pos_i = floatToInt(m_base_position, BS); + v3s16 size_blocks = v3s16(m_size.X+0.5,m_size.Y+0.5,m_size.X+0.5); + v3s16 pos_size_off(0,0,0); + if(m_size.X >= 2.5){ + pos_size_off.X = -1; + pos_size_off.Y = -1; + } + + if(!m_next_pos_exists){ + /* Check whether to drop down */ + if(checkFreePosition(map, + pos_i + pos_size_off + v3s16(0,-1,0), size_blocks)){ + m_next_pos_i = pos_i + v3s16(0,-1,0); + m_next_pos_exists = true; + m_falling = true; + } else { + m_falling = false; + } + } + + if(m_walk_around) + { + if(!m_next_pos_exists){ + /* Find some position where to go next */ + v3s16 dps[3*3*3]; + int num_dps = 0; + for(int dx=-1; dx<=1; dx++) + for(int dy=-1; dy<=1; dy++) + for(int dz=-1; dz<=1; dz++){ + if(dx == 0 && dy == 0) + continue; + if(dx != 0 && dz != 0 && dy != 0) + continue; + dps[num_dps++] = v3s16(dx,dy,dz); + } + u32 order[3*3*3]; + get_random_u32_array(order, num_dps); + for(int i=0; i= 2.5){ + pos_size_off.X = -1; + pos_size_off.Y = -1; + } + bool free = checkFreePosition(map, pos_i + pos_size_off, size_blocks); + if(!free){ + explodeSquare(map, pos_i, v3s16(3,3,3)); + m_removed = true; + return; + } + } + else + { + errorstream<<"MobV2SAO::step(): id="< 0.05*BS) + { + sendPosition(); + } +} + +void MobV2SAO::punch(ServerActiveObject *puncher, float time_from_last_punch) +{ + if(!puncher) + return; + + v3f dir = (getBasePosition() - puncher->getBasePosition()).normalize(); + + // A quick hack; SAO description is player name for player + std::string playername = puncher->getDescription(); + + Map *map = &m_env->getMap(); + + actionstream<= 2.5){ + pos_size_off.X = -1; + pos_size_off.Y = -1; + } + bool free = checkFreePosition(map, pos_i + pos_size_off, size_blocks); + if(free) + m_base_position = new_base_position; + } + sendPosition(); + + + // "Material" properties of the MobV2 + MaterialProperties mp; + mp.diggability = DIGGABLE_NORMAL; + mp.crackiness = -1.0; + mp.cuttability = 1.0; + + ToolDiggingProperties tp; + puncher->getWieldDiggingProperties(&tp); + + HittingProperties hitprop = getHittingProperties(&mp, &tp, + time_from_last_punch); + + doDamage(hitprop.hp); + puncher->damageWieldedItem(hitprop.wear); +} + +bool MobV2SAO::isPeaceful() +{ + return m_properties->getBool("is_peaceful"); +} + +void MobV2SAO::sendPosition() +{ + m_last_sent_position = m_base_position; + + std::ostringstream os(std::ios::binary); + // command (0 = update position) + writeU8(os, AO_Message_type::SetPosition); + // 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 MobV2SAO::setPropertyDefaults() +{ + m_properties->setDefault("is_peaceful", "false"); + m_properties->setDefault("move_type", "ground_nodes"); + m_properties->setDefault("speed", "(0,0,0)"); + m_properties->setDefault("age", "0"); + m_properties->setDefault("yaw", "0"); + m_properties->setDefault("pos", "(0,0,0)"); + m_properties->setDefault("hp", "0"); + m_properties->setDefault("die_age", "-1"); + m_properties->setDefault("size", "(1,2)"); + m_properties->setDefault("shoot_type", "fireball"); + m_properties->setDefault("shoot_y", "0"); + m_properties->setDefault("mindless_rage", "false"); +} +void MobV2SAO::readProperties() +{ + m_move_type = m_properties->get("move_type"); + m_speed = m_properties->getV3F("speed"); + m_age = m_properties->getFloat("age"); + m_yaw = m_properties->getFloat("yaw"); + m_base_position = m_properties->getV3F("pos"); + m_hp = m_properties->getS32("hp"); + m_die_age = m_properties->getFloat("die_age"); + m_size = m_properties->getV2F("size"); +} +void MobV2SAO::updateProperties() +{ + m_properties->set("move_type", m_move_type); + m_properties->setV3F("speed", m_speed); + m_properties->setFloat("age", m_age); + m_properties->setFloat("yaw", m_yaw); + m_properties->setV3F("pos", m_base_position); + m_properties->setS32("hp", m_hp); + m_properties->setFloat("die_age", m_die_age); + m_properties->setV2F("size", m_size); + + m_properties->setS32("version", 0); +} + +void MobV2SAO::doDamage(u16 d) +{ + infostream<<"MobV2 hp="< + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#ifndef CONTENT_SAO_MOBV2_H_ +#define CONTENT_SAO_MOBV2_H_ + +#include "content_sao.h" + +class MobV2SAO : public ServerActiveObject +{ +public: + MobV2SAO(ServerEnvironment *env, v3f pos, + Settings *init_properties); + virtual ~MobV2SAO(); + u8 getType() const + {return ACTIVEOBJECT_TYPE_MOBV2;} + static ServerActiveObject* create(ServerEnvironment *env, v3f pos, + const std::string &data); + std::string getStaticData(); + std::string getClientInitializationData(); + void step(float dtime, bool send_recommended); + void punch(ServerActiveObject *puncher, float time_from_last_punch); + bool isPeaceful(); +private: + void sendPosition(); + void setPropertyDefaults(); + void readProperties(); + void updateProperties(); + void doDamage(u16 d); + + std::string m_move_type; + v3f m_speed; + v3f m_last_sent_position; + v3f m_oldpos; + float m_yaw; + float m_counter1; + float m_counter2; + float m_age; + bool m_touching_ground; + int m_hp; + bool m_walk_around; + float m_walk_around_timer; + bool m_next_pos_exists; + v3s16 m_next_pos_i; + float m_shoot_reload_timer; + bool m_shooting; + float m_shooting_timer; + float m_die_age; + v2f m_size; + bool m_falling; + float m_disturb_timer; + std::string m_disturbing_player; + float m_random_disturb_timer; + float m_shoot_y; + + Settings *m_properties; +}; + +#endif /* CONTENT_SAO_MOBV2_H_ */ diff --git a/src/content_sao_oerkki1.cpp b/src/content_sao_oerkki1.cpp new file mode 100644 index 000000000..8b4c4f91e --- /dev/null +++ b/src/content_sao_oerkki1.cpp @@ -0,0 +1,314 @@ +/* +Minetest-c55 +Copyright (C) 2010-2012 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "content_sao_oerkki1.h" + +/* + Oerkki1SAO +*/ + +Oerkki1SAO::Oerkki1SAO(ServerEnvironment *env, v3f pos): + ServerActiveObject(env, pos), + m_is_active(false), + m_speed_f(0,0,0) +{ + 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; +} + +ServerActiveObject* Oerkki1SAO::create(ServerEnvironment *env, v3f pos, + const std::string &data) +{ + 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, pos); + o->m_hp = hp; + return o; +} + +void Oerkki1SAO::step(float dtime, bool send_recommended) +{ + ScopeProfiler sp2(g_profiler, "Oerkki1SAO::step avg", SPT_AVG); + + 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*0.6) + { + m_removed = true; + return; + player_is_too_close = true; + near_player_pos = playerpos; + } + else if(dist < BS*15.0 && !player_is_too_close) + { + player_is_close = true; + near_player_pos = playerpos; + } + } + + 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; + IGameDef *gamedef = m_env->getGameDef(); + moveresult = collisionMovePrecise(&m_env->getMap(), gamedef, + pos_max_d, box, dtime, pos_f, m_speed_f); + m_touching_ground = moveresult.touching_ground; + + // Do collision damage + float tolerance = BS*30; + 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); + } + + setBasePosition(pos_f); + + if(send_recommended == false && m_speed_f.getLength() < 3.0*BS) + 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, AO_Message_type::SetPosition); + // 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 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() +{ + //infostream<<__FUNCTION_NAME<getBasePosition()).normalize(); + m_speed_f += dir*12*BS; + + // "Material" properties of an oerkki + MaterialProperties mp; + mp.diggability = DIGGABLE_NORMAL; + mp.crackiness = -1.0; + mp.cuttability = 1.0; + + ToolDiggingProperties tp; + puncher->getWieldDiggingProperties(&tp); + + HittingProperties hitprop = getHittingProperties(&mp, &tp, + time_from_last_punch); + + doDamage(hitprop.hp); + puncher->damageWieldedItem(hitprop.wear); +} + +void Oerkki1SAO::doDamage(u16 d) +{ + infostream<<"oerkki damage: "< + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef CONTENT_SAO_OERKKI1_H_ +#define CONTENT_SAO_OERKKI1_H_ + +#include "content_sao.h" + +class Oerkki1SAO : public ServerActiveObject +{ +public: + Oerkki1SAO(ServerEnvironment *env, v3f pos); + u8 getType() const + {return ACTIVEOBJECT_TYPE_OERKKI1;} + static ServerActiveObject* create(ServerEnvironment *env, v3f pos, + const std::string &data); + void step(float dtime, bool send_recommended); + std::string getClientInitializationData(); + std::string getStaticData(); + void punch(ServerActiveObject *puncher, float time_from_last_punch); + bool isPeaceful(){return false;} +private: + void doDamage(u16 d); + + bool m_is_active; + IntervalLimiter m_inactive_interval; + v3f m_speed_f; + v3f m_oldpos; + v3f m_last_sent_position; + float m_yaw; + float m_counter1; + float m_counter2; + float m_age; + bool m_touching_ground; + u8 m_hp; + float m_after_jump_timer; +}; + +#endif /* CONTENT_SAO_OERKKI1_H_ */ diff --git a/src/content_sao_rat.cpp b/src/content_sao_rat.cpp new file mode 100644 index 000000000..e5534b2c0 --- /dev/null +++ b/src/content_sao_rat.cpp @@ -0,0 +1,212 @@ +/* +Minetest-c55 +Copyright (C) 2010-2012 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "content_sao_rat.h" + +/* + RatSAO +*/ +RatSAO::RatSAO(ServerEnvironment *env, v3f pos): + ServerActiveObject(env, pos), + m_is_active(false), + m_speed_f(0,0,0) +{ + ServerActiveObject::registerType(getType(), create); + + m_oldpos = v3f(0,0,0); + m_last_sent_position = v3f(0,0,0); + m_yaw = myrand_range(0,PI*2); + m_counter1 = 0; + m_counter2 = 0; + m_age = 0; + m_touching_ground = false; +} + +ServerActiveObject* RatSAO::create(ServerEnvironment *env, v3f pos, + const std::string &data) +{ + 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 RatSAO(env, pos); +} + +void RatSAO::step(float dtime, bool send_recommended) +{ + ScopeProfiler sp2(g_profiler, "RatSAO::step avg", SPT_AVG); + + 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 > 60) + { + // 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++) + { + Player *player = *i; + v3f playerpos = player->getPosition(); + if(m_base_position.getDistanceFrom(playerpos) < BS*10.0) + { + player_is_close = true; + break; + } + } + + 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 = 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; + m_speed_f.Y = 5.0*BS; + } + } + + { + 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.,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; + IGameDef *gamedef = m_env->getGameDef(); + moveresult = collisionMoveSimple(&m_env->getMap(), gamedef, + 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(); +} + +std::string RatSAO::getStaticData() +{ + //infostream<<__FUNCTION_NAME<getGameDef(); + InventoryItem *item = InventoryItem::deSerialize(is, gamedef); + bool fits = puncher->addToInventory(item); + if(fits) + m_removed = true; + else + delete item; +} + +// Prototype +RatSAO proto_RatSAO(NULL, v3f(0,0,0)); diff --git a/src/content_sao_rat.h b/src/content_sao_rat.h new file mode 100644 index 000000000..18172fe90 --- /dev/null +++ b/src/content_sao_rat.h @@ -0,0 +1,50 @@ +/* +Minetest-c55 +Copyright (C) 2010-2012 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef CONTENT_SAO_RAT_H_ +#define CONTENT_SAO_RAT_H_ + +#include "content_sao.h" + +class RatSAO : public ServerActiveObject +{ +public: + RatSAO(ServerEnvironment *env, v3f pos); + u8 getType() const + {return ACTIVEOBJECT_TYPE_RAT;} + static ServerActiveObject* create(ServerEnvironment *env, v3f pos, + const std::string &data); + void step(float dtime, bool send_recommended); + std::string getClientInitializationData(); + std::string getStaticData(); + void punch(ServerActiveObject *puncher, float time_from_last_punch); +private: + bool m_is_active; + IntervalLimiter m_inactive_interval; + v3f m_speed_f; + v3f m_oldpos; + v3f m_last_sent_position; + float m_yaw; + float m_counter1; + float m_counter2; + float m_age; + bool m_touching_ground; +}; + +#endif /* CONTENT_SAO_RAT_H_ */ diff --git a/src/content_sao_test.cpp b/src/content_sao_test.cpp new file mode 100644 index 000000000..d4afc3ff5 --- /dev/null +++ b/src/content_sao_test.cpp @@ -0,0 +1,90 @@ +/* +Minetest-c55 +Copyright (C) 2010-2012 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "content_sao.h" + + +class TestSAO : public ServerActiveObject +{ +public: + TestSAO(ServerEnvironment *env, v3f pos); + u8 getType() const + {return ACTIVEOBJECT_TYPE_TEST;} + static ServerActiveObject* create(ServerEnvironment *env, v3f pos, + const std::string &data); + void step(float dtime, bool send_recommended); +private: + float m_timer1; + float m_age; +}; + + +/* + TestSAO +*/ + +TestSAO::TestSAO(ServerEnvironment *env, v3f pos): + ServerActiveObject(env, pos), + m_timer1(0), + m_age(0) +{ + ServerActiveObject::registerType(getType(), create); +} + +ServerActiveObject* TestSAO::create(ServerEnvironment *env, v3f pos, + const std::string &data) +{ + return new TestSAO(env, pos); +} + +void TestSAO::step(float dtime, bool send_recommended) +{ + m_age += dtime; + if(m_age > 10) + { + m_removed = true; + return; + } + + m_base_position.Y += dtime * BS * 2; + 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) + { + m_timer1 += 0.125; + + std::string data; + + data += itos(AO_Message_type::SetPosition); // 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); + } +} diff --git a/src/inventory.cpp b/src/inventory.cpp index 0d38bed78..082fba526 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serverobject.h" #include "content_mapnode.h" #include "content_sao.h" +#include "content_sao_item.h" #include "environment.h" #include "mapblock.h" #include "player.h" diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 39a3b06ff..fa1f9d6be 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -35,7 +35,11 @@ extern "C" { #include "script.h" //#include "luna.h" #include "luaentity_common.h" -#include "content_sao.h" // For LuaEntitySAO +#include "content_sao.h" +#include "content_sao_lua.h" // For LuaEntitySAO +#include "content_sao_item.h" +#include "content_sao_rat.h" +#include "content_sao_firefly.h" #include "tooldef.h" #include "nodedef.h" #include "craftdef.h" diff --git a/src/serverlinkableobject.h b/src/serverlinkableobject.h index 182ebb12b..403de497b 100644 --- a/src/serverlinkableobject.h +++ b/src/serverlinkableobject.h @@ -27,19 +27,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "content_object.h" #include "log.h" -//this ain't the right place to define this but until cao/sao split -//is decided it'll have to stay here -struct AO_Message_type { - static const u8 SetPosition = 0x00; - static const u8 SetTextureMod = 0x01; - static const u8 SetSprite = 0x02; - static const u8 Punched = 0x03; - static const u8 TakeDamage = 0x04; - static const u8 Shoot = 0x05; - static const u8 Link = 0x06; - static const u8 UnLink = 0x07; -}; - class ServerLinkableObject { public: ServerLinkableObject(); -- 2.25.1