#include "environment.h"
#include "map.h"
#include "emerge.h"
-#include "serverobject.h" // TODO this is used for cleanup of only
+#include "content_sao.h" // TODO this is used for cleanup of only
#include "log.h"
#include "util/srp.h"
if (player == NULL)
return;
+ PlayerSAO *sao = player->getPlayerSAO();
+ if (sao == NULL)
+ return;
+
// Won't send anything if already sending
if(m_blocks_sending.size() >= g_settings->getU16
("max_simultaneous_block_sends_per_client"))
return;
}
- v3f playerpos = player->getPosition();
+ v3f playerpos = sao->getBasePosition();
v3f playerspeed = player->getSpeed();
v3f playerspeeddir(0,0,0);
if(playerspeed.getLength() > 1.0*BS)
v3s16 center = getNodeBlockPos(center_nodepos);
// Camera position and direction
- v3f camera_pos = player->getEyePosition();
+ v3f camera_pos = sao->getEyePosition();
v3f camera_dir = v3f(0,0,1);
- camera_dir.rotateYZBy(player->getPitch());
- camera_dir.rotateXZBy(player->getYaw());
+ camera_dir.rotateYZBy(sao->getPitch());
+ camera_dir.rotateXZBy(sao->getYaw());
/*infostream<<"camera_dir=("<<camera_dir.X<<","<<camera_dir.Y<<","
<<camera_dir.Z<<")"<<std::endl;*/
#endif
{
ServerEnvironment *s_env = dynamic_cast<ServerEnvironment*>(env);
- if (s_env != 0) {
+ if (s_env != NULL) {
f32 distance = speed_f->getLength();
std::vector<u16> s_objects;
s_env->getObjectsInsideRadius(s_objects, *pos_f, distance * 1.5);
LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
const std::string &name, const std::string &state):
- ServerActiveObject(env, pos),
+ UnitSAO(env, pos),
m_init_name(name),
m_init_state(state),
m_registered(false),
- m_hp(-1),
m_velocity(0,0,0),
m_acceleration(0,0,0),
- m_yaw(0),
m_properties_sent(true),
m_last_sent_yaw(0),
m_last_sent_position(0,0,0),
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::string str = gob_cmd_set_texture_mod(mod);
// No prototype, PlayerSAO does not need to be deserialized
-PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id_,
- const std::set<std::string> &privs, bool is_singleplayer):
- ServerActiveObject(env_, v3f(0,0,0)),
- m_player(player_),
+PlayerSAO::PlayerSAO(ServerEnvironment *env_, u16 peer_id_, bool is_singleplayer):
+ UnitSAO(env_, v3f(0,0,0)),
+ m_player(NULL),
m_peer_id(peer_id_),
m_inventory(NULL),
m_damage(0),
m_position_not_sent(false),
m_armor_groups_sent(false),
m_properties_sent(true),
- m_privs(privs),
m_is_singleplayer(is_singleplayer),
m_animation_speed(0),
m_animation_blend(0),
m_bone_position_sent(false),
m_attachment_parent_id(0),
m_attachment_sent(false),
+ m_breath(PLAYER_MAX_BREATH),
+ m_pitch(0),
// public
m_physics_override_speed(1),
m_physics_override_jump(1),
m_physics_override_sneak_glitch(true),
m_physics_override_sent(false)
{
- assert(m_player); // pre-condition
assert(m_peer_id != 0); // pre-condition
- setBasePosition(m_player->getPosition());
- m_inventory = &m_player->inventory;
m_armor_groups["fleshy"] = 100;
m_prop.hp_max = PLAYER_MAX_HP;
// end of default appearance
m_prop.is_visible = true;
m_prop.makes_footstep_sound = true;
+ m_hp = PLAYER_MAX_HP;
}
PlayerSAO::~PlayerSAO()
delete m_inventory;
}
+void PlayerSAO::initialize(RemotePlayer *player, const std::set<std::string> &privs)
+{
+ assert(player);
+ m_player = player;
+ m_privs = privs;
+ m_inventory = &m_player->inventory;
+}
+
std::string PlayerSAO::getDescription()
{
return std::string("player ") + m_player->getName();
void PlayerSAO::addedToEnvironment(u32 dtime_s)
{
ServerActiveObject::addedToEnvironment(dtime_s);
- ServerActiveObject::setBasePosition(m_player->getPosition());
+ ServerActiveObject::setBasePosition(m_base_position);
m_player->setPlayerSAO(this);
m_player->peer_id = m_peer_id;
- m_last_good_position = m_player->getPosition();
+ m_last_good_position = m_base_position;
}
// Called before removing from environment
{
ServerActiveObject::removingFromEnvironment();
if (m_player->getPlayerSAO() == this) {
- m_player->setPlayerSAO(NULL);
m_player->peer_id = 0;
m_env->savePlayer(m_player);
+ m_player->setPlayerSAO(NULL);
m_env->removePlayer(m_player);
for (UNORDERED_SET<u32>::iterator it = m_attached_particle_spawners.begin();
it != m_attached_particle_spawners.end(); ++it) {
os<<serializeString(m_player->getName()); // name
writeU8(os, 1); // is_player
writeS16(os, getId()); //id
- writeV3F1000(os, m_player->getPosition() + v3f(0,BS*1,0));
- writeF1000(os, m_player->getYaw());
+ writeV3F1000(os, m_base_position + v3f(0,BS*1,0));
+ writeF1000(os, m_yaw);
writeS16(os, getHP());
writeU8(os, 6 + m_bone_position.size() + m_attachment_child_ids.size()); // number of messages stuffed in here
writeU8(os, 0); // version
os<<serializeString(m_player->getName()); // name
writeU8(os, 1); // is_player
- writeV3F1000(os, m_player->getPosition() + v3f(0,BS*1,0));
- writeF1000(os, m_player->getYaw());
+ writeV3F1000(os, m_base_position + v3f(0,BS*1,0));
+ writeF1000(os, m_yaw);
writeS16(os, getHP());
writeU8(os, 2); // number of messages stuffed in here
os<<serializeLongString(getPropertyPacket()); // message 1
m_attachment_bone = "";
m_attachment_position = v3f(0,0,0);
m_attachment_rotation = v3f(0,0,0);
- m_player->setPosition(m_last_good_position);
+ setBasePosition(m_last_good_position);
((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id);
}
// Each frame, parent position is copied if the object is attached, otherwise it's calculated normally
// If the object gets detached this comes into effect automatically from the last known origin
- if(isAttached())
- {
+ if (isAttached()) {
v3f pos = m_env->getActiveObject(m_attachment_parent_id)->getBasePosition();
m_last_good_position = pos;
- m_player->setPosition(pos);
+ setBasePosition(pos);
}
- if(send_recommended == false)
+ if (!send_recommended)
return;
// If the object is attached client-side, don't waste bandwidth sending its position to clients
if(isAttached()) // Just in case we ever do send attachment position too
pos = m_env->getActiveObject(m_attachment_parent_id)->getBasePosition();
else
- pos = m_player->getPosition() + v3f(0,BS*1,0);
+ pos = m_base_position + v3f(0,BS*1,0);
std::string str = gob_cmd_update_position(
pos,
v3f(0,0,0),
v3f(0,0,0),
- m_player->getYaw(),
+ m_yaw,
true,
false,
update_interval
m_messages_out.push(aom);
}
- if(m_armor_groups_sent == false) {
+ if (!m_armor_groups_sent) {
m_armor_groups_sent = true;
std::string str = gob_cmd_update_armor_groups(
m_armor_groups);
m_messages_out.push(aom);
}
- if(m_physics_override_sent == false){
+ if (!m_physics_override_sent) {
m_physics_override_sent = true;
std::string str = gob_cmd_update_physics_override(m_physics_override_speed,
m_physics_override_jump, m_physics_override_gravity,
m_messages_out.push(aom);
}
- if(m_animation_sent == false){
+ if (!m_animation_sent) {
m_animation_sent = true;
std::string str = gob_cmd_update_animation(
m_animation_range, m_animation_speed, m_animation_blend, m_animation_loop);
void PlayerSAO::setBasePosition(const v3f &position)
{
+ if (m_player && position != m_base_position)
+ m_player->setDirty(true);
+
// This needs to be ran for attachments too
ServerActiveObject::setBasePosition(position);
m_position_not_sent = true;
}
-void PlayerSAO::setPos(v3f pos)
+void PlayerSAO::setPos(const v3f &pos)
{
if(isAttached())
return;
- m_player->setPosition(pos);
+
+ setBasePosition(pos);
// Movement caused by this command is always valid
m_last_good_position = pos;
((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id);
{
if(isAttached())
return;
- m_player->setPosition(pos);
+
+ setBasePosition(pos);
// Movement caused by this command is always valid
m_last_good_position = pos;
((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id);
}
-void PlayerSAO::setYaw(float yaw)
+void PlayerSAO::setYaw(const float yaw, bool send_data)
{
- m_player->setYaw(yaw);
- ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id);
+ if (m_player && yaw != m_yaw)
+ m_player->setDirty(true);
+
+ UnitSAO::setYaw(yaw);
+
+ // Datas should not be sent at player initialization
+ if (send_data)
+ ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id);
}
-void PlayerSAO::setPitch(float pitch)
+void PlayerSAO::setPitch(const float pitch, bool send_data)
{
- m_player->setPitch(pitch);
- ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id);
+ if (m_player && pitch != m_pitch)
+ m_player->setDirty(true);
+
+ m_pitch = pitch;
+
+ if (send_data)
+ ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id);
}
int PlayerSAO::punch(v3f dir,
return hitparams.wear;
}
-void PlayerSAO::rightClick(ServerActiveObject *clicker)
-{
-}
-
-s16 PlayerSAO::getHP() const
+void PlayerSAO::rightClick(ServerActiveObject *)
{
- return m_player->hp;
}
s16 PlayerSAO::readDamage()
return damage;
}
-void PlayerSAO::setHP(s16 hp)
+void PlayerSAO::setHP(s16 hp, bool direct)
{
- s16 oldhp = m_player->hp;
+ if (direct) {
+ m_hp = hp;
+ return;
+ }
+
+ s16 oldhp = m_hp;
- s16 hp_change = m_env->getScriptIface()->on_player_hpchange(this,
- hp - oldhp);
+ s16 hp_change = m_env->getScriptIface()->on_player_hpchange(this, hp - oldhp);
if (hp_change == 0)
return;
hp = oldhp + hp_change;
else if (hp > PLAYER_MAX_HP)
hp = PLAYER_MAX_HP;
- if(hp < oldhp && g_settings->getBool("enable_damage") == false) {
+ if (hp < oldhp && !g_settings->getBool("enable_damage")) {
return;
}
- m_player->hp = hp;
+ m_hp = hp;
if (oldhp > hp)
m_damage += (oldhp - hp);
m_properties_sent = false;
}
-u16 PlayerSAO::getBreath() const
+void PlayerSAO::setBreath(const u16 breath)
{
- return m_player->getBreath();
-}
+ if (m_player && breath != m_breath)
+ m_player->setDirty(true);
-void PlayerSAO::setBreath(u16 breath)
-{
- m_player->setBreath(breath);
+ m_breath = breath;
}
void PlayerSAO::setArmorGroups(const ItemGroupList &armor_groups)
{
if (isAttached() || m_is_singleplayer ||
g_settings->getBool("disable_anticheat")) {
- m_last_good_position = m_player->getPosition();
+ m_last_good_position = m_base_position;
return false;
}
// Tolerance. The lag pool does this a bit.
//player_max_speed *= 2.5;
- v3f diff = (m_player->getPosition() - m_last_good_position);
+ v3f diff = (m_base_position - m_last_good_position);
float d_vert = diff.Y;
diff.Y = 0;
float d_horiz = diff.getLength();
required_time = d_vert / player_max_speed; // Moving upwards
if (m_move_pool.grab(required_time)) {
- m_last_good_position = m_player->getPosition();
+ m_last_good_position = m_base_position;
} else {
actionstream << "Player " << m_player->getName()
<< " moved too fast; resetting position"
<< std::endl;
- m_player->setPosition(m_last_good_position);
+ setBasePosition(m_last_good_position);
cheated = true;
}
return cheated;
}
-bool PlayerSAO::getCollisionBox(aabb3f *toset) {
- //update collision box
- *toset = m_player->getCollisionbox();
-
+bool PlayerSAO::getCollisionBox(aabb3f *toset)
+{
+ *toset = aabb3f(-BS * 0.30, 0.0, -BS * 0.30, BS * 0.30, BS * 1.75, BS * 0.30);
toset->MinEdge += m_base_position;
toset->MaxEdge += m_base_position;
-
return true;
}
-bool PlayerSAO::collideWithObjects(){
+bool PlayerSAO::collideWithObjects()
+{
return true;
}
#include "serverobject.h"
#include "itemgroup.h"
#include "object_properties.h"
+#include "constants.h"
+
+class UnitSAO: public ServerActiveObject
+{
+public:
+ UnitSAO(ServerEnvironment *env, v3f pos):
+ ServerActiveObject(env, pos),
+ m_hp(-1), m_yaw(0) {}
+ virtual ~UnitSAO() {}
+
+ virtual void setYaw(const float yaw) { m_yaw = yaw; }
+ float getYaw() const { return m_yaw; };
+ f32 getRadYaw() const { return m_yaw * core::DEGTORAD; }
+ // Deprecated
+ f32 getRadYawDep() const { return (m_yaw + 90.) * core::DEGTORAD; }
+
+ s16 getHP() const { return m_hp; }
+ // Use a function, if isDead can be defined by other conditions
+ bool isDead() const { return m_hp == 0; }
+protected:
+ s16 m_hp;
+ float m_yaw;
+};
/*
LuaEntitySAO needs some internals exposed.
*/
-class LuaEntitySAO : public ServerActiveObject
+class LuaEntitySAO : public UnitSAO
{
public:
LuaEntitySAO(ServerEnvironment *env, v3f pos,
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);
bool m_registered;
struct ObjectProperties m_prop;
- s16 m_hp;
v3f m_velocity;
v3f m_acceleration;
- float m_yaw;
+
ItemGroupList m_armor_groups;
bool m_properties_sent;
class RemotePlayer;
-class PlayerSAO : public ServerActiveObject
+class PlayerSAO : public UnitSAO
{
public:
- PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id_,
- const std::set<std::string> &privs, bool is_singleplayer);
+ PlayerSAO(ServerEnvironment *env_, u16 peer_id_, bool is_singleplayer);
~PlayerSAO();
ActiveObjectType getType() const
{ return ACTIVEOBJECT_TYPE_PLAYER; }
bool isAttached();
void step(float dtime, bool send_recommended);
void setBasePosition(const v3f &position);
- void setPos(v3f pos);
+ void setPos(const v3f &pos);
void moveTo(v3f pos, bool continuous);
- void setYaw(float);
- void setPitch(float);
+ void setYaw(const float yaw, bool send_data = true);
+ void setPitch(const float pitch, bool send_data = true);
+ f32 getPitch() const { return m_pitch; }
+ f32 getRadPitch() const { return m_pitch * core::DEGTORAD; }
+ // Deprecated
+ f32 getRadPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; }
/*
Interaction interface
ServerActiveObject *puncher,
float time_from_last_punch);
void rightClick(ServerActiveObject *clicker);
- s16 getHP() const;
- void setHP(s16 hp);
+ void setHP(s16 hp, bool direct = false);
s16 readDamage();
- u16 getBreath() const;
- void setBreath(u16 breath);
+ u16 getBreath() const { return m_breath; }
+ void setBreath(const u16 breath);
void setArmorGroups(const ItemGroupList &armor_groups);
ItemGroupList getArmorGroups();
void setAnimation(v2f frame_range, float frame_speed, float frame_blend, bool frame_loop);
bool getCollisionBox(aabb3f *toset);
bool collideWithObjects();
+ void initialize(RemotePlayer *player, const std::set<std::string> &privs);
+
+ v3f getEyePosition() const { return m_base_position + getEyeOffset(); }
+ v3f getEyeOffset() const { return v3f(0, BS * 1.625f, 0); }
+
private:
std::string getPropertyPacket();
v3f m_attachment_position;
v3f m_attachment_rotation;
bool m_attachment_sent;
-
-
+ u16 m_breath;
+ f32 m_pitch;
public:
float m_physics_override_speed;
float m_physics_override_jump;
for (std::vector<RemotePlayer *>::iterator it = m_players.begin();
it != m_players.end();
++it) {
- RemotePlayer *player = static_cast<RemotePlayer*>(*it);
- if (player->checkModified()) {
- player->save(players_path, m_gamedef);
+ if ((*it)->checkModified()) {
+ (*it)->save(players_path, m_gamedef);
}
}
}
player->save(players_path, m_gamedef);
}
-RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername)
+RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername, PlayerSAO *sao)
{
bool newplayer = false;
bool found = false;
std::ifstream is(path.c_str(), std::ios_base::binary);
if (!is.good())
continue;
- player->deSerialize(is, path);
+
+ player->deSerialize(is, path, sao);
is.close();
if (player->getName() == playername) {
<< " not found" << std::endl;
if (newplayer)
delete player;
+
return NULL;
}
- if (newplayer)
+ if (newplayer) {
addPlayer(player);
+ }
player->setModified(false);
return player;
}
i != m_players.end(); ++i) {
RemotePlayer *player = dynamic_cast<RemotePlayer *>(*i);
assert(player);
+
// Ignore disconnected players
if (player->peer_id == 0)
continue;
+ PlayerSAO *playersao = player->getPlayerSAO();
+ assert(playersao);
+
v3s16 blockpos = getNodeBlockPos(
- floatToInt(player->getPosition(), BS));
+ floatToInt(playersao->getBasePosition(), BS));
players_blockpos.push_back(blockpos);
}
Finds out what new objects have been added to
inside a radius around a position
*/
-void ServerEnvironment::getAddedActiveObjects(RemotePlayer *player, s16 radius,
+void ServerEnvironment::getAddedActiveObjects(PlayerSAO *playersao, s16 radius,
s16 player_radius,
std::set<u16> ¤t_objects,
std::queue<u16> &added_objects)
if (player_radius_f < 0)
player_radius_f = 0;
-
/*
Go through the object list,
- discard m_removed objects,
- discard objects that are found in current_objects.
- add remaining objects to added_objects
*/
- for(ActiveObjectMap::iterator i = m_active_objects.begin();
+ for (ActiveObjectMap::iterator i = m_active_objects.begin();
i != m_active_objects.end(); ++i) {
u16 id = i->first;
// Get object
ServerActiveObject *object = i->second;
- if(object == NULL)
+ if (object == NULL)
continue;
// Discard if removed or deactivating
if(object->m_removed || object->m_pending_deactivation)
continue;
- f32 distance_f = object->getBasePosition().getDistanceFrom(player->getPosition());
+ f32 distance_f = object->getBasePosition().
+ getDistanceFrom(playersao->getBasePosition());
if (object->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
// Discard if too far
if (distance_f > player_radius_f && player_radius_f != 0)
Finds out what objects have been removed from
inside a radius around a position
*/
-void ServerEnvironment::getRemovedActiveObjects(RemotePlayer *player, s16 radius,
+void ServerEnvironment::getRemovedActiveObjects(PlayerSAO *playersao, s16 radius,
s16 player_radius,
std::set<u16> ¤t_objects,
std::queue<u16> &removed_objects)
if (player_radius_f < 0)
player_radius_f = 0;
-
/*
Go through current_objects; object is removed if:
- object is not found in m_active_objects (this is actually an
continue;
}
- f32 distance_f = object->getBasePosition().getDistanceFrom(player->getPosition());
+ f32 distance_f = object->getBasePosition().getDistanceFrom(playersao->getBasePosition());
if (object->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
if (distance_f <= player_radius_f || player_radius_f == 0)
continue;
class GameScripting;
class Player;
class RemotePlayer;
+class PlayerSAO;
class Environment
{
// Save players
void saveLoadedPlayers();
void savePlayer(RemotePlayer *player);
- RemotePlayer *loadPlayer(const std::string &playername);
+ RemotePlayer *loadPlayer(const std::string &playername, PlayerSAO *sao);
void addPlayer(RemotePlayer *player);
void removePlayer(RemotePlayer *player);
Find out what new objects have been added to
inside a radius around a position
*/
- void getAddedActiveObjects(RemotePlayer *player, s16 radius,
+ void getAddedActiveObjects(PlayerSAO *playersao, s16 radius,
s16 player_radius,
std::set<u16> ¤t_objects,
std::queue<u16> &added_objects);
Find out what new objects have been removed from
inside a radius around a position
*/
- void getRemovedActiveObjects(RemotePlayer *player, s16 radius,
+ void getRemovedActiveObjects(PlayerSAO *playersao, s16 radius,
s16 player_radius,
std::set<u16> ¤t_objects,
std::queue<u16> &removed_objects);
LocalPlayer::LocalPlayer(Client *gamedef, const char *name):
Player(name, gamedef->idef()),
parent(0),
+ hp(PLAYER_MAX_HP),
got_teleported(false),
isAttached(false),
touching_ground(false),
light_color(255,255,255,255),
hurt_tilt_timer(0.0f),
hurt_tilt_strength(0.0f),
+ m_position(0,0,0),
m_sneak_node(32767,32767,32767),
m_sneak_node_exists(false),
m_need_to_get_new_sneak_node(true),
m_old_node_below(32767,32767,32767),
m_old_node_below_type("air"),
m_can_jump(false),
+ m_breath(PLAYER_MAX_BREATH),
+ m_yaw(0),
+ m_pitch(0),
+ camera_barely_in_ceiling(false),
+ m_collisionbox(-BS * 0.30, 0.0, -BS * 0.30, BS * 0.30, BS * 1.75, BS * 0.30),
m_cao(NULL),
m_gamedef(gamedef)
{
ClientActiveObject *parent;
+ u16 hp;
bool got_teleported;
bool isAttached;
bool touching_ground;
u32 maxHudId() const { return hud.size(); }
+ u16 getBreath() const { return m_breath; }
+ void setBreath(u16 breath) { m_breath = breath; }
+
+ v3s16 getLightPosition() const
+ {
+ return floatToInt(m_position + v3f(0,BS+BS/2,0), BS);
+ }
+
+ void setYaw(f32 yaw)
+ {
+ m_yaw = yaw;
+ }
+
+ f32 getYaw() const { return m_yaw; }
+
+ void setPitch(f32 pitch)
+ {
+ m_pitch = pitch;
+ }
+
+ f32 getPitch() const { return m_pitch; }
+
+ void setPosition(const v3f &position)
+ {
+ m_position = position;
+ }
+
+ v3f getPosition() const { return m_position; }
+ v3f getEyePosition() const { return m_position + getEyeOffset(); }
+ v3f getEyeOffset() const
+ {
+ float eye_height = camera_barely_in_ceiling ? 1.5f : 1.625f;
+ return v3f(0, BS * eye_height, 0);
+ }
private:
void accelerateHorizontal(const v3f &target_speed, const f32 max_increase);
void accelerateVertical(const v3f &target_speed, const f32 max_increase);
+ v3f m_position;
// This is used for determining the sneaking range
v3s16 m_sneak_node;
// Whether the player is allowed to sneak
v3s16 m_old_node_below;
std::string m_old_node_below_type;
bool m_can_jump;
+ u16 m_breath;
+ f32 m_yaw;
+ f32 m_pitch;
+ bool camera_barely_in_ceiling;
+ aabb3f m_collisionbox;
GenericCAO* m_cao;
Client *m_gamedef;
m_media_downloader->addFile(name, sha1_raw);
}
- std::vector<std::string> remote_media;
try {
std::string str;
return;
}
- // If player is dead we don't care of this packet
- if (player->isDead()) {
- verbosestream << "TOSERVER_PLAYERPOS: " << player->getName()
- << " is dead. Ignoring packet";
- return;
- }
-
PlayerSAO *playersao = player->getPlayerSAO();
if (playersao == NULL) {
errorstream << "Server::ProcessData(): Canceling: "
return;
}
- player->setPosition(position);
+ // If player is dead we don't care of this packet
+ if (playersao->isDead()) {
+ verbosestream << "TOSERVER_PLAYERPOS: " << player->getName()
+ << " is dead. Ignoring packet";
+ return;
+ }
+
+ playersao->setBasePosition(position);
player->setSpeed(speed);
- player->setPitch(pitch);
- player->setYaw(yaw);
+ playersao->setPitch(pitch, false);
+ playersao->setYaw(yaw, false);
player->keyPressed = keyPressed;
player->control.up = (keyPressed & 1);
player->control.down = (keyPressed & 2);
if (g_settings->getBool("enable_damage")) {
actionstream << player->getName() << " damaged by "
- << (int)damage << " hp at " << PP(player->getPosition() / BS)
+ << (int)damage << " hp at " << PP(playersao->getBasePosition() / BS)
<< std::endl;
playersao->setHP(playersao->getHP() - damage);
return;
}
- /*
- * If player is dead, we don't need to update the breath
- * He is dead !
- */
- if (player->isDead()) {
- verbosestream << "TOSERVER_BREATH: " << player->getName()
- << " is dead. Ignoring packet";
- return;
- }
-
PlayerSAO *playersao = player->getPlayerSAO();
if (playersao == NULL) {
return;
}
+ /*
+ * If player is dead, we don't need to update the breath
+ * He is dead !
+ */
+ if (playersao->isDead()) {
+ verbosestream << "TOSERVER_BREATH: " << player->getName()
+ << " is dead. Ignoring packet";
+ return;
+ }
+
playersao->setBreath(breath);
SendPlayerBreath(pkt->getPeerId());
}
return;
}
- if (!player->isDead())
+ PlayerSAO *playersao = player->getPlayerSAO();
+ assert(playersao);
+
+ if (!playersao->isDead())
return;
RespawnPlayer(pkt->getPeerId());
actionstream << player->getName() << " respawns at "
- << PP(player->getPosition()/BS) << std::endl;
+ << PP(playersao->getBasePosition() / BS) << std::endl;
// ActiveObject is added to environment in AsyncRunStep after
// the previous addition has been successfully removed
return;
}
- if (player->isDead()) {
+ if (playersao->isDead()) {
verbosestream << "TOSERVER_INTERACT: " << player->getName()
- << " is dead. Ignoring packet";
+ << " is dead. Ignoring packet";
return;
}
ToolCapabilities toolcap =
punchitem.getToolCapabilities(m_itemdef);
v3f dir = (pointed_object->getBasePosition() -
- (player->getPosition() + player->getEyeOffset())
+ (playersao->getBasePosition() + playersao->getEyeOffset())
).normalize();
float time_from_last_punch =
playersao->resetTimeFromLastPunch();
Player::Player(const char *name, IItemDefManager *idef):
- camera_barely_in_ceiling(false),
inventory(idef),
- hp(PLAYER_MAX_HP),
peer_id(PEER_ID_INEXISTENT),
keyPressed(0),
// protected
- m_breath(PLAYER_MAX_BREATH),
- m_pitch(0),
- m_yaw(0),
- m_speed(0,0,0),
- m_position(0,0,0),
- m_collisionbox(-BS*0.30,0.0,-BS*0.30,BS*0.30,BS*1.75,BS*0.30)
+ m_speed(0,0,0)
{
strlcpy(m_name, name, PLAYERNAME_SIZE);
clearHud();
}
-v3s16 Player::getLightPosition() const
-{
- return floatToInt(m_position + v3f(0,BS+BS/2,0), BS);
-}
-
u32 Player::addHud(HudElement *toadd)
{
MutexAutoLock lock(m_mutex);
m_speed = speed;
}
- v3f getPosition()
- {
- return m_position;
- }
-
- v3s16 getLightPosition() const;
-
- v3f getEyeOffset()
- {
- float eye_height = camera_barely_in_ceiling ? 1.5f : 1.625f;
- return v3f(0, BS * eye_height, 0);
- }
-
- v3f getEyePosition()
- {
- return m_position + getEyeOffset();
- }
-
- virtual void setPosition(const v3f &position)
- {
- m_position = position;
- }
-
- virtual void setPitch(f32 pitch)
- {
- m_pitch = pitch;
- }
-
- virtual void setYaw(f32 yaw)
- {
- m_yaw = yaw;
- }
-
- f32 getPitch() const { return m_pitch; }
- f32 getYaw() const { return m_yaw; }
- u16 getBreath() const { return m_breath; }
-
- virtual void setBreath(u16 breath) { m_breath = breath; }
-
- f32 getRadPitch() const { return m_pitch * core::DEGTORAD; }
- f32 getRadYaw() const { return m_yaw * core::DEGTORAD; }
const char *getName() const { return m_name; }
- aabb3f getCollisionbox() const { return m_collisionbox; }
u32 getFreeHudID()
{
return size;
}
- bool camera_barely_in_ceiling;
v3f eye_offset_first;
v3f eye_offset_third;
v2s32 local_animations[4];
float local_animation_speed;
- u16 hp;
-
u16 peer_id;
std::string inventory_formspec;
s32 hud_hotbar_itemcount;
protected:
char m_name[PLAYERNAME_SIZE];
- u16 m_breath;
- f32 m_pitch;
- f32 m_yaw;
v3f m_speed;
- v3f m_position;
- aabb3f m_collisionbox;
std::vector<HudElement *> hud;
private:
infostream << "Failed to open " << path << std::endl;
return;
}
- testplayer.deSerialize(is, path);
+ testplayer.deSerialize(is, path, NULL);
is.close();
if (strcmp(testplayer.getName(), m_name) == 0) {
// Open file and serialize
return;
}
-void RemotePlayer::deSerialize(std::istream &is, const std::string &playername)
+void RemotePlayer::deSerialize(std::istream &is, const std::string &playername,
+ PlayerSAO *sao)
{
Settings args;
if (!args.parseConfigLines(is, "PlayerArgsEnd")) {
- throw SerializationError("PlayerArgsEnd of player " +
- playername + " not found!");
+ throw SerializationError("PlayerArgsEnd of player " + playername + " not found!");
}
m_dirty = true;
//args.getS32("version"); // Version field value not used
std::string name = args.get("name");
strlcpy(m_name, name.c_str(), PLAYERNAME_SIZE);
- setPitch(args.getFloat("pitch"));
- setYaw(args.getFloat("yaw"));
- setPosition(args.getV3F("position"));
- try {
- hp = args.getS32("hp");
- } catch(SettingNotFoundException &e) {
- hp = PLAYER_MAX_HP;
- }
- try {
- m_breath = args.getS32("breath");
- } catch(SettingNotFoundException &e) {
- m_breath = PLAYER_MAX_BREATH;
+ if (sao) {
+ try {
+ sao->setHP(args.getS32("hp"), true);
+ } catch(SettingNotFoundException &e) {
+ sao->setHP(PLAYER_MAX_HP, true);
+ }
+
+ try {
+ sao->setBasePosition(args.getV3F("position"));
+ } catch (SettingNotFoundException &e) {}
+
+ try {
+ sao->setPitch(args.getFloat("pitch"), false);
+ } catch (SettingNotFoundException &e) {}
+ try {
+ sao->setYaw(args.getFloat("yaw"), false);
+ } catch (SettingNotFoundException &e) {}
+
+ try {
+ sao->setBreath(args.getS32("breath"));
+ } catch (SettingNotFoundException &e) {}
}
inventory.deSerialize(is);
- if(inventory.getList("craftpreview") == NULL) {
+ if (inventory.getList("craftpreview") == NULL) {
// Convert players without craftpreview
inventory.addList("craftpreview", 1);
args.setS32("version", 1);
args.set("name", m_name);
//args.set("password", m_password);
- args.setFloat("pitch", m_pitch);
- args.setFloat("yaw", m_yaw);
- args.setV3F("position", m_position);
- args.setS32("hp", hp);
- args.setS32("breath", m_breath);
+
+ if (m_sao) {
+ args.setS32("hp", m_sao->getHP());
+ args.setV3F("position", m_sao->getBasePosition());
+ args.setFloat("pitch", m_sao->getPitch());
+ args.setFloat("yaw", m_sao->getYaw());
+ args.setS32("breath", m_sao->getBreath());
+ }
args.writeLines(os);
inventory.serialize(os);
}
-void RemotePlayer::setPosition(const v3f &position)
-{
- if (position != m_position)
- m_dirty = true;
-
- Player::setPosition(position);
- if(m_sao)
- m_sao->setBasePosition(position);
-}
-
const RemotePlayerChatResult RemotePlayer::canSendChatMessage()
{
// Rate limit messages
virtual ~RemotePlayer() {}
void save(std::string savedir, IGameDef *gamedef);
- void deSerialize(std::istream &is, const std::string &playername);
+ void deSerialize(std::istream &is, const std::string &playername, PlayerSAO *sao);
PlayerSAO *getPlayerSAO() { return m_sao; }
void setPlayerSAO(PlayerSAO *sao) { m_sao = sao; }
- void setPosition(const v3f &position);
const RemotePlayerChatResult canSendChatMessage();
*ratio = m_day_night_ratio;
}
- // Use a function, if isDead can be defined by other conditions
- bool isDead() const { return hp == 0; }
-
void setHotbarImage(const std::string &name)
{
hud_hotbar_image = name;
return hud_hotbar_selected_image;
}
- // Deprecated
- f32 getRadPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; }
-
- // Deprecated
- f32 getRadYawDep() const { return (m_yaw + 90.) * core::DEGTORAD; }
-
void setSky(const video::SColor &bgcolor, const std::string &type,
const std::vector<std::string> ¶ms)
{
inventory.setModified(x);
}
- virtual void setBreath(u16 breath)
- {
- if (breath != m_breath)
- m_dirty = true;
- Player::setBreath(breath);
- }
-
- virtual void setPitch(f32 pitch)
- {
- if (pitch != m_pitch)
- m_dirty = true;
- Player::setPitch(pitch);
- }
-
- virtual void setYaw(f32 yaw)
- {
- if (yaw != m_yaw)
- m_dirty = true;
- Player::setYaw(yaw);
- }
-
void setLocalAnimations(v2s32 frames[4], float frame_speed)
{
for (int i = 0; i < 4; i++)
*frame_speed = local_animation_speed;
}
+ void setDirty(bool dirty) { m_dirty = true; }
+
u16 protocol_version;
private:
/*
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- RemotePlayer *player = getplayer(ref);
- if (player == NULL) return 0;
+ PlayerSAO* co = getplayersao(ref);
+ if (co == NULL) return 0;
// Do it
- float pitch = player->getRadPitchDep();
- float yaw = player->getRadYawDep();
+ float pitch = co->getRadPitchDep();
+ float yaw = co->getRadYawDep();
v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
push_v3f(L, v);
return 1;
"Deprecated call to get_look_pitch, use get_look_vertical instead");
ObjectRef *ref = checkobject(L, 1);
- RemotePlayer *player = getplayer(ref);
- if (player == NULL) return 0;
+ PlayerSAO* co = getplayersao(ref);
+ if (co == NULL) return 0;
// Do it
- lua_pushnumber(L, player->getRadPitchDep());
+ lua_pushnumber(L, co->getRadPitchDep());
return 1;
}
"Deprecated call to get_look_yaw, use get_look_horizontal instead");
ObjectRef *ref = checkobject(L, 1);
- RemotePlayer *player = getplayer(ref);
- if (player == NULL) return 0;
+ PlayerSAO* co = getplayersao(ref);
+ if (co == NULL) return 0;
// Do it
- lua_pushnumber(L, player->getRadYawDep());
+ lua_pushnumber(L, co->getRadYawDep());
return 1;
}
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- RemotePlayer *player = getplayer(ref);
- if (player == NULL) return 0;
+ PlayerSAO* co = getplayersao(ref);
+ if (co == NULL) return 0;
// Do it
- lua_pushnumber(L, player->getRadPitch());
+ lua_pushnumber(L, co->getRadPitch());
return 1;
}
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- RemotePlayer *player = getplayer(ref);
- if (player == NULL) return 0;
+ PlayerSAO* co = getplayersao(ref);
+ if (co == NULL) return 0;
// Do it
- lua_pushnumber(L, player->getRadYaw());
+ lua_pushnumber(L, co->getRadYaw());
return 1;
}
continue;
}
+ PlayerSAO *playersao = player->getPlayerSAO();
+ if (playersao == NULL)
+ continue;
+
std::queue<u16> removed_objects;
std::queue<u16> added_objects;
- m_env->getRemovedActiveObjects(player, radius, player_radius,
+ m_env->getRemovedActiveObjects(playersao, radius, player_radius,
client->m_known_objects, removed_objects);
- m_env->getAddedActiveObjects(player, radius, player_radius,
+ m_env->getAddedActiveObjects(playersao, radius, player_radius,
client->m_known_objects, added_objects);
// Ignore if nothing happened
SendPlayerBreath(peer_id);
// Show death screen if necessary
- if (player->isDead())
+ if (playersao->isDead())
SendDeathscreen(peer_id, false, v3f(0,0,0));
// Note things in chat if not in simple singleplayer mode
DSTACK(FUNCTION_NAME);
RemotePlayer *player = m_env->getPlayer(peer_id);
assert(player);
+ PlayerSAO *sao = player->getPlayerSAO();
+ assert(sao);
NetworkPacket pkt(TOCLIENT_MOVE_PLAYER, sizeof(v3f) + sizeof(f32) * 2, peer_id);
- pkt << player->getPosition() << player->getPitch() << player->getYaw();
+ pkt << sao->getBasePosition() << sao->getPitch() << sao->getYaw();
{
- v3f pos = player->getPosition();
- f32 pitch = player->getPitch();
- f32 yaw = player->getYaw();
+ v3f pos = sao->getBasePosition();
verbosestream << "Server: Sending TOCLIENT_MOVE_PLAYER"
<< " pos=(" << pos.X << "," << pos.Y << "," << pos.Z << ")"
- << " pitch=" << pitch
- << " yaw=" << yaw
+ << " pitch=" << sao->getPitch()
+ << " yaw=" << sao->getYaw()
<< std::endl;
}
if (!player)
continue;
+ PlayerSAO *sao = player->getPlayerSAO();
+ if (!sao)
+ continue;
+
if (pos_exists) {
- if(player->getPosition().getDistanceFrom(pos) >
+ if(sao->getBasePosition().getDistanceFrom(pos) >
params.max_hear_distance)
continue;
}
pkt << p;
std::vector<u16> clients = m_clients.getClientIDs();
- for(std::vector<u16>::iterator i = clients.begin();
- i != clients.end(); ++i) {
+ for (std::vector<u16>::iterator i = clients.begin(); i != clients.end(); ++i) {
if (far_players) {
// Get player
if (RemotePlayer *player = m_env->getPlayer(*i)) {
+ PlayerSAO *sao = player->getPlayerSAO();
+ if (!sao)
+ continue;
+
// If player is far away, only set modified blocks not sent
- v3f player_pos = player->getPosition();
- if(player_pos.getDistanceFrom(p_f) > maxd) {
+ v3f player_pos = sao->getBasePosition();
+ if (player_pos.getDistanceFrom(p_f) > maxd) {
far_players->push_back(*i);
continue;
}
v3f p_f = intToFloat(p, BS);
std::vector<u16> clients = m_clients.getClientIDs();
- for(std::vector<u16>::iterator i = clients.begin();
- i != clients.end(); ++i) {
-
- if(far_players) {
+ for(std::vector<u16>::iterator i = clients.begin(); i != clients.end(); ++i) {
+ if (far_players) {
// Get player
if (RemotePlayer *player = m_env->getPlayer(*i)) {
+ PlayerSAO *sao = player->getPlayerSAO();
+ if (!sao)
+ continue;
+
// If player is far away, only set modified blocks not sent
- v3f player_pos = player->getPosition();
+ v3f player_pos = sao->getBasePosition();
if(player_pos.getDistanceFrom(p_f) > maxd) {
far_players->push_back(*i);
continue;
return NULL;
}
- // Load player if it isn't already loaded
- if (!player) {
- player = m_env->loadPlayer(name);
- }
+ // Create a new player active object
+ PlayerSAO *playersao = new PlayerSAO(m_env, peer_id, isSingleplayer());
+ player = m_env->loadPlayer(name, playersao);
// Create player if it doesn't exist
if (!player) {
// Set player position
infostream<<"Server: Finding spawn place for player \""
<<name<<"\""<<std::endl;
- v3f pos = findSpawnPos();
- player->setPosition(pos);
+ playersao->setBasePosition(findSpawnPos());
// Make sure the player is saved
player->setModified(true);
// If the player exists, ensure that they respawn inside legal bounds
// This fixes an assert crash when the player can't be added
// to the environment
- if (objectpos_over_limit(player->getPosition())) {
+ if (objectpos_over_limit(playersao->getBasePosition())) {
actionstream << "Respawn position for player \""
<< name << "\" outside limits, resetting" << std::endl;
- v3f pos = findSpawnPos();
- player->setPosition(pos);
+ playersao->setBasePosition(findSpawnPos());
}
}
- // Create a new player active object
- PlayerSAO *playersao = new PlayerSAO(m_env, player, peer_id,
- getPlayerEffectivePrivs(player->getName()),
- isSingleplayer());
+ playersao->initialize(player, getPlayerEffectivePrivs(player->getName()));
player->protocol_version = proto_version;
Some more dynamic interface
*/
- virtual void setPos(v3f pos)
+ virtual void setPos(const v3f &pos)
{ setBasePosition(pos); }
// continuous: if true, object does not stop immediately at pos
virtual void moveTo(v3f pos, bool continuous)
void TestPlayer::testSave(IGameDef *gamedef)
{
RemotePlayer rplayer("testplayer_save", gamedef->idef());
- rplayer.setBreath(10);
- rplayer.hp = 8;
- rplayer.setYaw(0.1f);
- rplayer.setPitch(0.6f);
- rplayer.setPosition(v3f(450.2f, -15.7f, 68.1f));
+ PlayerSAO sao(NULL, 1, false);
+ sao.initialize(&rplayer, std::set<std::string>());
+ rplayer.setPlayerSAO(&sao);
+ sao.setBreath(10);
+ sao.setHP(8, true);
+ sao.setYaw(0.1f, false);
+ sao.setPitch(0.6f, false);
+ sao.setBasePosition(v3f(450.2f, -15.7f, 68.1f));
rplayer.save(".", gamedef);
UASSERT(fs::PathExists("testplayer_save"));
}
void TestPlayer::testLoad(IGameDef *gamedef)
{
RemotePlayer rplayer("testplayer_load", gamedef->idef());
- rplayer.setBreath(10);
- rplayer.hp = 8;
- rplayer.setYaw(0.1f);
- rplayer.setPitch(0.6f);
- rplayer.setPosition(v3f(450.2f, -15.7f, 68.1f));
+ PlayerSAO sao(NULL, 1, false);
+ sao.initialize(&rplayer, std::set<std::string>());
+ rplayer.setPlayerSAO(&sao);
+ sao.setBreath(10);
+ sao.setHP(8, true);
+ sao.setYaw(0.1f, false);
+ sao.setPitch(0.6f, false);
+ sao.setBasePosition(v3f(450.2f, -15.7f, 68.1f));
rplayer.save(".", gamedef);
UASSERT(fs::PathExists("testplayer_load"));
RemotePlayer rplayer_load("testplayer_load", gamedef->idef());
+ PlayerSAO sao_load(NULL, 2, false);
std::ifstream is("testplayer_load", std::ios_base::binary);
UASSERT(is.good());
- rplayer_load.deSerialize(is, "testplayer_load");
+ rplayer_load.deSerialize(is, "testplayer_load", &sao_load);
is.close();
UASSERT(strcmp(rplayer_load.getName(), "testplayer_load") == 0);
- UASSERT(rplayer.getBreath() == 10);
- UASSERT(rplayer.hp == 8);
- UASSERT(rplayer.getYaw() == 0.1f);
- UASSERT(rplayer.getPitch() == 0.6f);
- UASSERT(rplayer.getPosition() == v3f(450.2f, -15.7f, 68.1f));
+ UASSERT(sao_load.getBreath() == 10);
+ UASSERT(sao_load.getHP() == 8);
+ UASSERT(sao_load.getYaw() == 0.1f);
+ UASSERT(sao_load.getPitch() == 0.6f);
+ UASSERT(sao_load.getBasePosition() == v3f(450.2f, -15.7f, 68.1f));
}