Improve mobv2
authorPerttu Ahola <celeron55@gmail.com>
Sat, 15 Oct 2011 09:17:21 +0000 (12:17 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Sat, 15 Oct 2011 09:17:21 +0000 (12:17 +0300)
src/client.cpp
src/client.h
src/clientobject.h
src/content_cao.cpp
src/content_cao.h
src/content_sao.cpp
src/content_sao.h
src/environment.cpp
src/game.cpp
src/server.cpp
src/serverobject.h

index 1e81a464c89a22d05582c2e5a64666146d015bc1..c54bf34ce58ad2dde046cd4a6b3fa77d30d90d7e 100644 (file)
@@ -1523,7 +1523,7 @@ void Client::groundAction(u8 action, v3s16 nodepos_undersurface,
        Send(0, data, true);
 }
 
-void Client::clickActiveObject(u8 button, u16 id, u16 item)
+void Client::clickActiveObject(u8 button, u16 id, u16 item_i)
 {
        if(connectedAndInitialized() == false){
                dout_client<<DTIME<<"Client::clickActiveObject() "
@@ -1531,6 +1531,38 @@ void Client::clickActiveObject(u8 button, u16 id, u16 item)
                                <<std::endl;
                return;
        }
+
+       Player *player = m_env.getLocalPlayer();
+       if(player == NULL)
+               return;
+
+       ClientActiveObject *obj = m_env.getActiveObject(id);
+       if(obj){
+               if(button == 0){
+                       ToolItem *titem = NULL;
+                       std::string toolname = "";
+
+                       InventoryList *mlist = player->inventory.getList("main");
+                       if(mlist != NULL)
+                       {
+                               InventoryItem *item = mlist->getItem(item_i);
+                               if(item && (std::string)item->getName() == "ToolItem")
+                               {
+                                       titem = (ToolItem*)item;
+                                       toolname = titem->getToolName();
+                               }
+                       }
+
+                       v3f playerpos = player->getPosition();
+                       v3f objpos = obj->getPosition();
+                       v3f dir = (objpos - playerpos).normalize();
+                       
+                       bool disable_send = obj->directReportPunch(toolname, dir);
+
+                       if(disable_send)
+                               return;
+               }
+       }
        
        /*
                length: 7
@@ -1544,7 +1576,7 @@ void Client::clickActiveObject(u8 button, u16 id, u16 item)
        writeU16(&data[0], TOSERVER_CLICK_ACTIVEOBJECT);
        writeU8(&data[2], button);
        writeU16(&data[3], id);
-       writeU16(&data[5], item);
+       writeU16(&data[5], item_i);
        Send(0, data, true);
 }
 
index 87c7e328dbca8ac94762cf317b5e09a3325591be..85e85dcd64014b123849867111731b6b9d39f9d0 100644 (file)
@@ -183,7 +183,7 @@ public:
 
        void groundAction(u8 action, v3s16 nodepos_undersurface,
                        v3s16 nodepos_oversurface, u16 item);
-       void clickActiveObject(u8 button, u16 id, u16 item);
+       void clickActiveObject(u8 button, u16 id, u16 item_i);
 
        void sendSignNodeText(v3s16 p, std::string text);
        void sendInventoryAction(InventoryAction *a);
index 6a12c718b2661ce31230f3e6ae21aea914f1d904..60d293ff41049ff2f2aed0e5c34683609c4fff14 100644 (file)
@@ -60,7 +60,7 @@ public:
        virtual void processMessage(const std::string &data){}
 
        virtual std::string infoText() {return "";}
-
+       
        /*
                This takes the return value of
                ServerActiveObject::getClientInitializationData
@@ -70,6 +70,10 @@ public:
        // Create a certain type of ClientActiveObject
        static ClientActiveObject* create(u8 type);
 
+       // If returns true, punch will not be sent to the server
+       virtual bool directReportPunch(const std::string &toolname, v3f dir)
+       { return false; }
+
 protected:
        // Used for creating objects based on type
        typedef ClientActiveObject* (*Factory)();
index 88c8d58a99a1c703b72d78ae5d4d95582cc3ee14..53e4a6d13e5374b569f896a13052f12c5f806c15 100644 (file)
@@ -874,7 +874,10 @@ MobV2CAO::MobV2CAO():
        m_last_light(0),
        m_shooting(0),
        m_shooting_unset_timer(0),
+       m_sprite_size(BS,BS),
+       m_sprite_y(0),
        m_bright_shooting(false),
+       m_lock_full_brightness(false),
        m_player_hit_timer(0)
 {
        ClientActiveObject::registerType(getType(), create);
@@ -897,10 +900,10 @@ void MobV2CAO::addToScene(scene::ISceneManager *smgr)
        if(m_node != NULL)
                return;
        
-       std::string texture_name = m_properties->get("texture_name");
-       //dstream<<"MobV2CAO::addToScene using texture_name="<<texture_name<<std::endl;
+       /*dstream<<"MobV2CAO::addToScene using texture_name="<<
+                       m_texture_name<<std::endl;*/
        std::string texture_string = "[makealpha2:128,0,0;128,128,0:";
-       texture_string += texture_name;
+       texture_string += m_texture_name;
        
        scene::MyBillboardSceneNode *bill = new scene::MyBillboardSceneNode(
                        smgr->getRootSceneNode(), smgr, -1, v3f(0,0,0), v2f(1,1));
@@ -986,7 +989,7 @@ void MobV2CAO::updateNodePos()
        if(m_node == NULL)
                return;
 
-       m_node->setPosition(pos_translator.vect_show + m_sprite_pos);
+       m_node->setPosition(pos_translator.vect_show + v3f(0,m_sprite_y,0));
 }
 
 void MobV2CAO::step(float dtime, ClientEnvironment *env)
@@ -1137,15 +1140,16 @@ void MobV2CAO::processMessage(const std::string &data)
        {
                //u16 damage = readU16(is);
 
-               u8 li = decode_light(m_last_light);
+               /*u8 li = decode_light(m_last_light);
                if(li >= 100)
                        li = 30;
                else
-                       li = 255;
-               video::SColor color(255,li,li,li);
+                       li = 255;*/
+
+               /*video::SColor color(255,255,0,0);
                m_node->setColor(color);
 
-               m_damage_visual_timer = 0.2;
+               m_damage_visual_timer = 0.2;*/
        }
        // Trigger shooting
        else if(cmd == 2)
@@ -1183,38 +1187,19 @@ void MobV2CAO::initialize(const std::string &data)
                std::istringstream tmp_is(tmp_os.str(), std::ios::binary);
                m_properties->parseConfigLines(tmp_is, "MobArgsEnd");
 
-               /*dstream<<"INFO: MobV2CAO::initialize(): got properties:"<<std::endl;
-               m_properties->writeLines(dstream);*/
-
-               m_properties->setDefault("texture_name", "stone.png");
+               dstream<<"INFO: MobV2CAO::initialize(): got properties:"<<std::endl;
+               m_properties->writeLines(dstream);
+               
+               m_properties->setDefault("looks", "dummy_default");
                m_properties->setDefault("yaw", "0");
                m_properties->setDefault("pos", "(0,0,0)");
-               m_properties->setDefault("sprite_size", "(1,1)");
-               m_properties->setDefault("sprite_pos", "(0,0,0)");
-               m_properties->setDefault("selection_size", "(0.4,0.4)");
-               m_properties->setDefault("selection_y", "-0.4");
-               m_properties->setDefault("sprite_type", "humanoid_1");
-               m_properties->setDefault("simple_anim_frames", "1");
-               m_properties->setDefault("simple_anim_frametime", "0.5");
-               m_properties->setDefault("lock_full_brightness", "false");
                m_properties->setDefault("player_hit_damage", "0");
                m_properties->setDefault("player_hit_distance", "1.5");
                m_properties->setDefault("player_hit_interval", "1.5");
                
+               setLooks(m_properties->get("looks"));
                m_yaw = m_properties->getFloat("yaw");
                m_position = m_properties->getV3F("pos");
-               m_sprite_size = m_properties->getV2F("sprite_size") * BS;
-               m_sprite_pos = m_properties->getV3F("sprite_pos") * BS;
-               v2f selection_size = m_properties->getV2F("selection_size") * BS;
-               float selection_y = m_properties->getFloat("selection_y") * BS;
-               m_selection_box = core::aabbox3d<f32>(
-                               -selection_size.X, selection_y, -selection_size.X,
-                               selection_size.X, selection_y+selection_size.Y,
-                               selection_size.X);
-               m_sprite_type = m_properties->get("sprite_type");
-               m_simple_anim_frames = m_properties->getS32("simple_anim_frames");
-               m_simple_anim_frametime = m_properties->getFloat("simple_anim_frametime");
-               m_lock_full_brightness = m_properties->getBool("lock_full_brightness");
                m_player_hit_damage = m_properties->getS32("player_hit_damage");
                m_player_hit_distance = m_properties->getFloat("player_hit_distance");
                m_player_hit_interval = m_properties->getFloat("player_hit_interval");
@@ -1225,4 +1210,55 @@ void MobV2CAO::initialize(const std::string &data)
        updateNodePos();
 }
 
+bool MobV2CAO::directReportPunch(const std::string &toolname, v3f dir)
+{
+       video::SColor color(255,255,0,0);
+       m_node->setColor(color);
+
+       m_damage_visual_timer = 0.05;
+
+       m_position += dir * BS;
+       pos_translator.sharpen();
+       pos_translator.update(m_position);
+       updateNodePos();
+       
+       return false;
+}
+
+void MobV2CAO::setLooks(const std::string &looks)
+{
+       v2f selection_size = v2f(0.4, 0.4) * BS;
+       float selection_y = 0 * BS;
+
+       if(looks == "dungeon_master"){
+               m_texture_name = "dungeon_master.png";
+               m_sprite_type = "humanoid_1";
+               m_sprite_size = v2f(2, 3) * BS;
+               m_sprite_y = 0.85 * BS;
+               selection_size = v2f(0.4, 2.6) * BS;
+               selection_y = -0.4 * BS;
+       }
+       else if(looks == "fireball"){
+               m_texture_name = "fireball.png";
+               m_sprite_type = "simple";
+               m_sprite_size = v2f(1, 1) * BS;
+               m_simple_anim_frames = 3;
+               m_simple_anim_frametime = 0.1;
+               m_lock_full_brightness = true;
+       }
+       else{
+               m_texture_name = "stone.png";
+               m_sprite_type = "simple";
+               m_sprite_size = v2f(1, 1) * BS;
+               m_simple_anim_frames = 3;
+               m_simple_anim_frametime = 0.333;
+               selection_size = v2f(0.4, 0.4) * BS;
+               selection_y = 0 * BS;
+       }
+
+       m_selection_box = core::aabbox3d<f32>(
+                       -selection_size.X, selection_y, -selection_size.X,
+                       selection_size.X, selection_y+selection_size.Y,
+                       selection_size.X);
+}
 
index e240d739265fddaf5796adf3918a60d9e227a996..a362b6be5d7fe50471a94adade873fdd6b7fd94a 100644 (file)
@@ -33,19 +33,19 @@ class Settings;
 struct SmoothTranslator
 {
        v3f vect_old;
+       v3f vect_show;
+       v3f vect_aim;
        f32 anim_counter;
        f32 anim_time;
        f32 anim_time_counter;
-       v3f vect_show;
-       v3f vect_aim;
 
        SmoothTranslator():
                vect_old(0,0,0),
+               vect_show(0,0,0),
+               vect_aim(0,0,0),
                anim_counter(0),
                anim_time(0),
-               anim_time_counter(0),
-               vect_show(0,0,0),
-               vect_aim(0,0,0)
+               anim_time_counter(0)
        {}
 
        void init(v3f vect)
@@ -53,6 +53,14 @@ struct SmoothTranslator
                vect_old = vect;
                vect_show = vect;
                vect_aim = vect;
+               anim_counter = 0;
+               anim_time = 0;
+               anim_time_counter = 0;
+       }
+
+       void sharpen()
+       {
+               init(vect_show);
        }
 
        void update(v3f vect_new)
@@ -329,11 +337,17 @@ public:
                //{return m_position;}
        bool doShowSelectionBox(){return false;}
 
+       // If returns true, punch will not be sent to the server
+       bool directReportPunch(const std::string &toolname, v3f dir);
+
 private:
+       void setLooks(const std::string &looks);
+       
        IntervalLimiter m_attack_interval;
        core::aabbox3d<f32> m_selection_box;
        scene::MyBillboardSceneNode *m_node;
        v3f m_position;
+       std::string m_texture_name;
        float m_yaw;
        SmoothTranslator pos_translator;
        bool m_walking;
@@ -345,7 +359,7 @@ private:
        bool m_shooting;
        float m_shooting_unset_timer;
        v2f m_sprite_size;
-       v3f m_sprite_pos;
+       float m_sprite_y;
        bool m_bright_shooting;
        std::string m_sprite_type;
        int m_simple_anim_frames;
index 8c9761740db01ab2aa89d9214f2c8591e10d3c76..d81e3f87135ad779c8d9b61daa94e2ab45ee4fd4 100644 (file)
@@ -916,7 +916,8 @@ MobV2SAO::MobV2SAO(ServerEnvironment *env, u16 id, v3f pos,
        m_shoot_reload_timer(0),
        m_shooting(false),
        m_shooting_timer(0),
-       m_falling(false)
+       m_falling(false),
+       m_disturb_timer(100000)
 {
        ServerActiveObject::registerType(getType(), create);
        
@@ -1071,6 +1072,22 @@ void MobV2SAO::step(float dtime, bool send_recommended)
                m_removed = true;
                return;
        }
+
+       Player *disturbing_player =
+                       m_env->getPlayer(m_disturbing_player.c_str());
+       v3f disturbing_player_off = 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_off.normalize();
+               disturbing_player_dir = 180./M_PI*atan2(disturbing_player_off.Z,
+                               disturbing_player_off.X);
+       }
+
+       m_disturb_timer += dtime;
        
        if(!m_falling)
        {
@@ -1088,15 +1105,10 @@ void MobV2SAO::step(float dtime, bool send_recommended)
                                dstream<<__FUNCTION_NAME<<": Shooting fireball from "<<PP(pos)
                                                <<" at speed "<<PP(speed)<<std::endl;
                                Settings properties;
+                               properties.set("looks", "fireball");
                                properties.setV3F("speed", speed);
                                properties.setFloat("die_age", 5.0);
                                properties.set("move_type", "constant_speed");
-                               properties.set("texture_name", "fireball.png");
-                               properties.setV3F("sprite_pos", v3f(0.0, 0.0, 0.0));
-                               properties.setV2F("sprite_size", v2f(1.0, 1.0));
-                               properties.set("sprite_type", "simple");
-                               properties.set("simple_anim_frames", "3");
-                               properties.set("simple_anim_frametime", "0.1");
                                properties.setFloat("hp", 1000);
                                properties.set("lock_full_brightness", "true");
                                properties.set("player_hit_damage", "9");
@@ -1114,8 +1126,18 @@ void MobV2SAO::step(float dtime, bool send_recommended)
 
                m_shoot_reload_timer += dtime;
 
-               if(m_shoot_reload_timer >= 5.0 && !m_next_pos_exists)
+               float reload_time = 15.0;
+               if(m_disturb_timer <= 15.0)
+                       reload_time = 3.0;
+
+               if(m_shoot_reload_timer >= reload_time && !m_next_pos_exists)
                {
+                       if(m_disturb_timer < 30.0 && disturbing_player &&
+                                       disturbing_player_distance < 16*BS &&
+                                       fabs(disturbing_player_off.Y) < 5*BS){
+                               m_yaw = disturbing_player_dir;
+                               sendPosition();
+                       }
                        m_shoot_reload_timer = 0.0;
                        m_shooting = true;
                        m_shooting_timer = 1.5;
@@ -1261,23 +1283,35 @@ void MobV2SAO::step(float dtime, bool send_recommended)
 
        if(m_base_position.getDistanceFrom(m_last_sent_position) > 0.05*BS)
        {
-               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);
+               sendPosition();
        }
 }
 
-u16 MobV2SAO::punch(const std::string &toolname, v3f dir)
+u16 MobV2SAO::punch(const std::string &toolname, v3f dir,
+               const std::string &playername)
 {
+       assert(m_env);
+       Map *map = &m_env->getMap();
+
+       m_disturb_timer = 0;
+       m_disturbing_player = playername;
+       
+       m_yaw = wrapDegrees_180(180./M_PI*atan2(dir.Z, dir.X) + 180.);
+       v3f new_base_position = m_base_position + dir * BS;
+       {
+               v3s16 pos_i = floatToInt(new_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;
+               }
+               bool free = checkFreePosition(map, pos_i + pos_size_off, size_blocks);
+               if(free)
+                       m_base_position = new_base_position;
+       }
+       sendPosition();
+       
        u16 amount = 2;
        dstream<<"id="<<m_id<<": punch with \""<<toolname<<"\""<<std::endl;
        /* See tool names in inventory.h */
@@ -1297,6 +1331,22 @@ u16 MobV2SAO::punch(const std::string &toolname, v3f dir)
        return 65536/100;
 }
 
+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("move_type", "ground_nodes");
index 078feb273f4838775ad4e44f19ec0f150b6d420e..0586ef434def652116b1e78c9ff7d1400b14242f 100644 (file)
@@ -155,8 +155,10 @@ public:
        std::string getClientInitializationData();
        void step(float dtime, bool send_recommended);
        InventoryItem* createPickedUpItem(){return NULL;}
-       u16 punch(const std::string &toolname, v3f dir);
+       u16 punch(const std::string &toolname, v3f dir,
+                       const std::string &playername);
 private:
+       void sendPosition();
        void setPropertyDefaults();
        void readProperties();
        void updateProperties();
@@ -182,6 +184,8 @@ private:
        float m_die_age;
        v2f m_size;
        bool m_falling;
+       float m_disturb_timer;
+       std::string m_disturbing_player;
        
        Settings *m_properties;
 };
index 124e5631c026d3d24dc604e4196454f2ec9d0588..28a2ff339ccf63072a4d2517117cbcb64a4abc91 100644 (file)
@@ -645,17 +645,12 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
 
 static void getMob_dungeon_master(Settings &properties)
 {
-       properties.set("texture_name", "dungeon_master.png");
-       properties.setV3F("sprite_pos", v3f(0.0, 0.85, 0.0));
-       properties.setV2F("sprite_size", v2f(2.0, 3.0));
-       properties.setFloat("selection_y", -0.4);
-       properties.setV2F("selection_size", v2f(0.4, 2.6));
+       properties.set("looks", "dungeon_master");
        properties.setFloat("yaw", 1.57);
        properties.setFloat("hp", 20);
        properties.setBool("bright_shooting", true);
        properties.set("shoot_type", "fireball");
        properties.set("shoot_y", "0.7");
-       properties.set("sprite_type", "humanoid_1");
        properties.set("player_hit_damage", "1");
        properties.set("player_hit_distance", "1.0");
        properties.set("player_hit_interval", "0.5");
index e8d0238a3742a0c946e3b93329fd57f8a84a0868..926a169774f2a82c5a088c2fc84a6248a966423e 100644 (file)
@@ -1532,16 +1532,23 @@ void the_game(
                        //if(input->getLeftClicked())
                        if(input->getLeftState())
                        {
+                               bool do_punch = false;
+                               bool do_punch_damage = false;
                                if(object_hit_delay_timer <= 0.0){
+                                       do_punch = true;
+                                       do_punch_damage = true;
+                                       object_hit_delay_timer = object_hit_delay;
+                               }
+                               if(input->getLeftClicked()){
+                                       do_punch = true;
+                               }
+                               if(do_punch){
                                        dstream<<DTIME<<"Left-clicked object"<<std::endl;
+                                       left_punch = true;
+                               }
+                               if(do_punch_damage){
                                        client.clickActiveObject(0,
                                                        selected_active_object->getId(), g_selected_item);
-                                       object_hit_delay_timer = object_hit_delay;
-                                       left_punch = true;
-                               } else {
-                                       dstream<<DTIME<<"Left-clicked object faster than allowed"
-                                                       <<std::endl;
-                                       left_punch_muted = true;
                                }
                        }
                        else if(input->getRightClicked())
index d78a00ea3cacd848f2d7a9490c51489fabbaf74e..ba4921dd050f9e938e851cc62f03ce4914f4fbe9 100644 (file)
@@ -2340,7 +2340,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                v3f objpos = obj->getBasePosition();
                                v3f dir = (objpos - playerpos).normalize();
                                
-                               u16 wear = obj->punch(toolname, dir);
+                               u16 wear = obj->punch(toolname, dir, player->getName());
                                
                                if(titem)
                                {
index 01f199a4b59f406ea11f9a60e35baff35e10a3bc..a9bd0a7c4afc38b3d375f1b5cb56063222dda4ea 100644 (file)
@@ -104,7 +104,8 @@ public:
                If the object doesn't return an item, this will be called.
                Return value is tool wear.
        */
-       virtual u16 punch(const std::string &toolname, v3f dir)
+       virtual u16 punch(const std::string &toolname, v3f dir,
+                       const std::string &playername)
        {return 0;}
 
        /*