]> git.lizzy.rs Git - minetest.git/blobdiff - src/content_sao.cpp
Allow the LUA API to set animations to meshes as well as the animation speed. Also...
[minetest.git] / src / content_sao.cpp
index c6419c1dd5bb22ff397a94ceee084741eccbc023..6c2abf8f6b3a7e91f253dbed26ff7e90ae945a73 100644 (file)
@@ -3,16 +3,16 @@ Minetest-c55
 Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
 
 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
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 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.
+GNU Lesser General Public License for more details.
 
-You should have received a copy of the GNU General Public License along
+You should have received a copy of the GNU Lesser 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.
 */
@@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "player.h"
 #include "scriptapi.h"
 #include "genericobject.h"
+#include "util/serialize.h"
 
 core::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
 
@@ -141,6 +142,9 @@ TestSAO proto_TestSAO(NULL, v3f(0,0,0));
 
 /*
        ItemSAO
+
+       DEPRECATED: New dropped items are implemented in Lua; see
+                   builtin/item_entity.lua.
 */
 
 class ItemSAO : public ServerActiveObject
@@ -202,9 +206,12 @@ class ItemSAO : public ServerActiveObject
                        m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
                v3f pos_f = getBasePosition();
                v3f pos_f_old = pos_f;
+               v3f accel_f = v3f(0,0,0);
+               f32 stepheight = 0;
                IGameDef *gamedef = m_env->getGameDef();
                moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
-                               pos_max_d, box, dtime, pos_f, m_speed_f);
+                               pos_max_d, box, stepheight, dtime,
+                               pos_f, m_speed_f, accel_f);
                
                if(send_recommended == false)
                        return;
@@ -285,13 +292,6 @@ class ItemSAO : public ServerActiveObject
                        ServerActiveObject *puncher,
                        float time_from_last_punch)
        {
-               // Directly delete item in creative mode
-               if(g_settings->getBool("creative_mode") == true)
-               {
-                       m_removed = true;
-                       return 0;
-               }
-               
                // Take item into inventory
                ItemStack item = createItemStack();
                Inventory *inv = puncher->getInventory();
@@ -376,9 +376,9 @@ LuaEntitySAO::~LuaEntitySAO()
        }
 }
 
-void LuaEntitySAO::addedToEnvironment()
+void LuaEntitySAO::addedToEnvironment(u32 dtime_s)
 {
-       ServerActiveObject::addedToEnvironment();
+       ServerActiveObject::addedToEnvironment(dtime_s);
        
        // Create entity from name
        lua_State *L = m_env->getLua();
@@ -389,10 +389,9 @@ void LuaEntitySAO::addedToEnvironment()
                scriptapi_luaentity_get_properties(L, m_id, &m_prop);
                // Initialize HP from properties
                m_hp = m_prop.hp_max;
+               // Activate entity, supplying serialized state
+               scriptapi_luaentity_activate(L, m_id, m_init_state.c_str(), dtime_s);
        }
-       
-       // Activate entity, supplying serialized state
-       scriptapi_luaentity_activate(L, m_id, m_init_state.c_str());
 }
 
 ServerActiveObject* LuaEntitySAO::create(ServerEnvironment *env, v3f pos,
@@ -449,16 +448,18 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
                box.MaxEdge *= BS;
                collisionMoveResult moveresult;
                f32 pos_max_d = BS*0.25; // Distance per iteration
-               v3f p_pos = getBasePosition();
+               f32 stepheight = 0; // Maximum climbable step height
+               v3f p_pos = m_base_position;
                v3f p_velocity = m_velocity;
+               v3f p_acceleration = m_acceleration;
                IGameDef *gamedef = m_env->getGameDef();
-               moveresult = collisionMovePrecise(&m_env->getMap(), gamedef,
-                               pos_max_d, box, dtime, p_pos, p_velocity);
+               moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
+                               pos_max_d, box, stepheight, dtime,
+                               p_pos, p_velocity, p_acceleration);
                // Apply results
-               setBasePosition(p_pos);
+               m_base_position = p_pos;
                m_velocity = p_velocity;
-
-               m_velocity += dtime * m_acceleration;
+               m_acceleration = p_acceleration;
        } else {
                m_base_position += dtime * m_velocity + 0.5 * dtime
                                * dtime * m_acceleration;
@@ -738,6 +739,7 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
        );
        // create message and add to list
        ActiveObjectMessage aom(getId(), false, str);
+       m_messages_out.push_back(aom);
 }
 
 /*
@@ -746,7 +748,8 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
 
 // No prototype, PlayerSAO does not need to be deserialized
 
-PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_):
+PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
+               const std::set<std::string> &privs, bool is_singleplayer):
        ServerActiveObject(env_, v3f(0,0,0)),
        m_player(player_),
        m_peer_id(peer_id_),
@@ -754,10 +757,15 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_):
        m_last_good_position(0,0,0),
        m_last_good_position_age(0),
        m_time_from_last_punch(0),
+       m_nocheat_dig_pos(32767, 32767, 32767),
+       m_nocheat_dig_time(0),
        m_wield_index(0),
        m_position_not_sent(false),
        m_armor_groups_sent(false),
        m_properties_sent(true),
+       m_privs(privs),
+       m_is_singleplayer(is_singleplayer),
+       // public
        m_teleported(false),
        m_inventory_not_sent(false),
        m_hp_not_sent(false),
@@ -774,13 +782,15 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_):
        m_prop.physical = false;
        m_prop.weight = 75;
        m_prop.collisionbox = core::aabbox3d<f32>(-1/3.,-1.0,-1/3., 1/3.,1.0,1/3.);
+       // start of default appearance, this should be overwritten by LUA
        m_prop.visual = "upright_sprite";
        m_prop.visual_size = v2f(1, 2);
        m_prop.textures.clear();
        m_prop.textures.push_back("player.png");
        m_prop.textures.push_back("player_back.png");
        m_prop.spritediv = v2s16(1,1);
-       m_prop.is_visible = (getHP() != 0);
+       // end of default appearance
+       m_prop.is_visible = (getHP() != 0); // TODO: Use a death animation instead for mesh players
        m_prop.makes_footstep_sound = true;
 }
 
@@ -797,9 +807,9 @@ std::string PlayerSAO::getDescription()
 }
 
 // Called after id has been set and has been inserted in environment
-void PlayerSAO::addedToEnvironment()
+void PlayerSAO::addedToEnvironment(u32 dtime_s)
 {
-       ServerActiveObject::addedToEnvironment();
+       ServerActiveObject::addedToEnvironment(dtime_s);
        ServerActiveObject::setBasePosition(m_player->getPosition());
        m_player->setPlayerSAO(this);
        m_player->peer_id = m_peer_id;
@@ -861,42 +871,61 @@ void PlayerSAO::step(float dtime, bool send_recommended)
        }
 
        m_time_from_last_punch += dtime;
-
-       /*
-               Check player movements
-
-               NOTE: Actually the server should handle player physics like the
-               client does and compare player's position to what is calculated
-               on our side. This is required when eg. players fly due to an
-               explosion.
-       */
-
-       //float player_max_speed = BS * 4.0; // Normal speed
-       float player_max_speed = BS * 20; // Fast speed
-       float player_max_speed_up = BS * 20;
-       player_max_speed *= 2.5; // Tolerance
-       player_max_speed_up *= 2.5;
-
-       m_last_good_position_age += dtime;
-       if(m_last_good_position_age >= 1.0){
-               float age = m_last_good_position_age;
-               v3f diff = (m_player->getPosition() - m_last_good_position);
-               float d_vert = diff.Y;
-               diff.Y = 0;
-               float d_horiz = diff.getLength();
-               /*infostream<<m_player->getName()<<"'s horizontal speed is "
-                               <<(d_horiz/age)<<std::endl;*/
-               if(d_horiz <= age * player_max_speed &&
-                               (d_vert < 0 || d_vert < age * player_max_speed_up)){
-                       m_last_good_position = m_player->getPosition();
+       m_nocheat_dig_time += dtime;
+       
+       if(m_is_singleplayer || g_settings->getBool("disable_anticheat"))
+       {
+               m_last_good_position = m_player->getPosition();
+               m_last_good_position_age = 0;
+       }
+       else
+       {
+               /*
+                       Check player movements
+
+                       NOTE: Actually the server should handle player physics like the
+                       client does and compare player's position to what is calculated
+                       on our side. This is required when eg. players fly due to an
+                       explosion. Altough a node-based alternative might be possible
+                       too, and much more lightweight.
+               */
+
+               float player_max_speed = 0;
+               float player_max_speed_up = 0;
+               if(m_privs.count("fast") != 0){
+                       // Fast speed
+                       player_max_speed = BS * 20;
+                       player_max_speed_up = BS * 20;
                } else {
-                       actionstream<<"Player "<<m_player->getName()
-                                       <<" moved too fast; resetting position"
-                                       <<std::endl;
-                       m_player->setPosition(m_last_good_position);
-                       m_teleported = true;
+                       // Normal speed
+                       player_max_speed = BS * 4.0;
+                       player_max_speed_up = BS * 4.0;
+               }
+               // Tolerance
+               player_max_speed *= 2.5;
+               player_max_speed_up *= 2.5;
+
+               m_last_good_position_age += dtime;
+               if(m_last_good_position_age >= 1.0){
+                       float age = m_last_good_position_age;
+                       v3f diff = (m_player->getPosition() - m_last_good_position);
+                       float d_vert = diff.Y;
+                       diff.Y = 0;
+                       float d_horiz = diff.getLength();
+                       /*infostream<<m_player->getName()<<"'s horizontal speed is "
+                                       <<(d_horiz/age)<<std::endl;*/
+                       if(d_horiz <= age * player_max_speed &&
+                                       (d_vert < 0 || d_vert < age * player_max_speed_up)){
+                               m_last_good_position = m_player->getPosition();
+                       } else {
+                               actionstream<<"Player "<<m_player->getName()
+                                               <<" moved too fast; resetting position"
+                                               <<std::endl;
+                               m_player->setPosition(m_last_good_position);
+                               m_teleported = true;
+                       }
+                       m_last_good_position_age = 0;
                }
-               m_last_good_position_age = 0;
        }
 
        if(send_recommended == false)
@@ -1109,16 +1138,6 @@ void PlayerSAO::disconnected()
        }
 }
 
-void PlayerSAO::createCreativeInventory()
-{
-       if(m_inventory != &m_player->inventory)
-               delete m_inventory;
-
-       m_inventory = new Inventory(m_player->inventory);
-       m_inventory->clearContents();
-       scriptapi_get_creative_inventory(m_env->getLua(), this);
-}
-
 std::string PlayerSAO::getPropertyPacket()
 {
        m_prop.is_visible = (getHP() != 0);