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.
*/
#include "player.h"
#include "scriptapi.h"
#include "genericobject.h"
+#include "util/serialize.h"
core::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
/*
ItemSAO
+
+ DEPRECATED: New dropped items are implemented in Lua; see
+ builtin/item_entity.lua.
*/
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;
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();
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());
}
-
- // Activate entity, supplying serialized state
- scriptapi_luaentity_activate(L, m_id, m_init_state.c_str());
}
ServerActiveObject* LuaEntitySAO::create(ServerEnvironment *env, v3f pos,
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;
// No prototype, PlayerSAO does not need to be deserialized
PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
- const std::set<std::string> &privs):
+ const std::set<std::string> &privs, bool is_singleplayer):
ServerActiveObject(env_, v3f(0,0,0)),
m_player(player_),
m_peer_id(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_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 = 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 {
- // Normal speed
- player_max_speed = BS * 4.0;
- player_max_speed_up = BS * 4.0;
+ 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;
}
- // 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
+ {
+ /*
+ 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)
}
}
-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);