1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-08-06 17:41:04 +00:00

added player link support

This commit is contained in:
sapier 2012-01-15 22:41:10 +01:00
parent 14a64000ea
commit c17133d80a
6 changed files with 157 additions and 89 deletions

View file

@ -18,12 +18,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "content_cao.h" #include "content_cao.h"
#include "clientlinkableobject.h"
/* /*
PlayerCAO PlayerCAO
*/ */
class PlayerCAO : public ClientActiveObject class PlayerCAO : public ClientActiveObject, public ClientLinkableObject
{ {
private: private:
core::aabbox3d<f32> m_selection_box; core::aabbox3d<f32> m_selection_box;
@ -212,8 +213,10 @@ public:
void step(float dtime, ClientEnvironment *env) void step(float dtime, ClientEnvironment *env)
{ {
pos_translator.translate(dtime); if(!isLinked()) {
updateNodePos(); pos_translator.translate(dtime);
updateNodePos();
}
if(m_damage_visual_timer > 0){ if(m_damage_visual_timer > 0){
m_damage_visual_timer -= dtime; m_damage_visual_timer -= dtime;
@ -252,6 +255,11 @@ public:
m_damage_visual_timer = 0.5; m_damage_visual_timer = 0.5;
updateTextures("^[brighten"); updateTextures("^[brighten");
} }
else if (handleLinkUnlinkMessages(cmd,&is,this->m_env))
{
//Link unlink already done in handleLinkUnlinkMessages!
}
} }
void updateTextures(const std::string &mod) void updateTextures(const std::string &mod)
@ -277,6 +285,27 @@ public:
} }
} }
} }
void setPosition(v3f toset, float dtime){
if (isLinked()) {
this->m_position = toset + this->m_linkOffset;
pos_translator.update(this->m_position,false);
updateNodePos();
if(m_is_local_player) {
m_local_player->setPosition(this->m_position);
}
}
else {
errorstream<<"Got linked position update but not linked"<< std::endl;
}
}
void updateLinkState(bool value) {
if(m_is_local_player) {
m_local_player->Link(value);
}
}
inline v3f getPosition() { return m_position; } inline v3f getPosition() { return m_position; }

View file

@ -1890,6 +1890,7 @@ void ClientEnvironment::step(float dtime)
Get the speed the player is going Get the speed the player is going
*/ */
bool is_climbing = lplayer->is_climbing; bool is_climbing = lplayer->is_climbing;
bool linked = lplayer->m_linked;
f32 player_speed = lplayer->getSpeed().getLength(); f32 player_speed = lplayer->getSpeed().getLength();
@ -1918,96 +1919,98 @@ void ClientEnvironment::step(float dtime)
/* /*
Stuff that has a maximum time increment Stuff that has a maximum time increment
*/ */
//TODO at this position possibly a better solution is required!
if (!linked) {
u32 loopcount = 0;
do
{
loopcount++;
u32 loopcount = 0; f32 dtime_part;
do if(dtime_downcount > dtime_max_increment)
{
loopcount++;
f32 dtime_part;
if(dtime_downcount > dtime_max_increment)
{
dtime_part = dtime_max_increment;
dtime_downcount -= dtime_part;
}
else
{
dtime_part = dtime_downcount;
/*
Setting this to 0 (no -=dtime_part) disables an infinite loop
when dtime_part is so small that dtime_downcount -= dtime_part
does nothing
*/
dtime_downcount = 0;
}
/*
Handle local player
*/
{
v3f lplayerpos = lplayer->getPosition();
// Apply physics
if(free_move == false && is_climbing == false)
{ {
// Gravity dtime_part = dtime_max_increment;
v3f speed = lplayer->getSpeed(); dtime_downcount -= dtime_part;
if(lplayer->swimming_up == false) }
speed.Y -= 9.81 * BS * dtime_part * 2; else
{
// Water resistance dtime_part = dtime_downcount;
if(lplayer->in_water_stable || lplayer->in_water) /*
{ Setting this to 0 (no -=dtime_part) disables an infinite loop
f32 max_down = 2.0*BS; when dtime_part is so small that dtime_downcount -= dtime_part
if(speed.Y < -max_down) speed.Y = -max_down; does nothing
*/
f32 max = 2.5*BS; dtime_downcount = 0;
if(speed.getLength() > max)
{
speed = speed / speed.getLength() * max;
}
}
lplayer->setSpeed(speed);
} }
/* /*
Move the lplayer. Handle local player
This also does collision detection.
*/ */
lplayer->move(dtime_part, *m_map, position_max_increment,
&player_collisions);
}
}
while(dtime_downcount > 0.001);
//std::cout<<"Looped "<<loopcount<<" times."<<std::endl;
for(core::list<CollisionInfo>::Iterator
i = player_collisions.begin();
i != player_collisions.end(); i++)
{
CollisionInfo &info = *i;
if(info.t == COLLISION_FALL)
{
//f32 tolerance = BS*10; // 2 without damage
f32 tolerance = BS*12; // 3 without damage
f32 factor = 1;
if(info.speed > tolerance)
{ {
f32 damage_f = (info.speed - tolerance)/BS*factor; v3f lplayerpos = lplayer->getPosition();
u16 damage = (u16)(damage_f+0.5);
if(lplayer->hp > damage)
lplayer->hp -= damage;
else
lplayer->hp = 0;
ClientEnvEvent event; // Apply physics
event.type = CEE_PLAYER_DAMAGE; if(free_move == false && is_climbing == false)
event.player_damage.amount = damage; {
event.player_damage.send_to_server = true; // Gravity
m_client_event_queue.push_back(event); v3f speed = lplayer->getSpeed();
if(lplayer->swimming_up == false)
speed.Y -= 9.81 * BS * dtime_part * 2;
// Water resistance
if(lplayer->in_water_stable || lplayer->in_water)
{
f32 max_down = 2.0*BS;
if(speed.Y < -max_down) speed.Y = -max_down;
f32 max = 2.5*BS;
if(speed.getLength() > max)
{
speed = speed / speed.getLength() * max;
}
}
lplayer->setSpeed(speed);
}
/*
Move the lplayer.
This also does collision detection.
*/
lplayer->move(dtime_part, *m_map, position_max_increment,
&player_collisions);
}
}
while(dtime_downcount > 0.001);
//std::cout<<"Looped "<<loopcount<<" times."<<std::endl;
for(core::list<CollisionInfo>::Iterator
i = player_collisions.begin();
i != player_collisions.end(); i++)
{
CollisionInfo &info = *i;
if(info.t == COLLISION_FALL)
{
//f32 tolerance = BS*10; // 2 without damage
f32 tolerance = BS*12; // 3 without damage
f32 factor = 1;
if(info.speed > tolerance)
{
f32 damage_f = (info.speed - tolerance)/BS*factor;
u16 damage = (u16)(damage_f+0.5);
if(lplayer->hp > damage)
lplayer->hp -= damage;
else
lplayer->hp = 0;
ClientEnvEvent event;
event.type = CEE_PLAYER_DAMAGE;
event.player_damage.amount = damage;
event.player_damage.send_to_server = true;
m_client_event_queue.push_back(event);
}
} }
} }
} }

View file

@ -183,7 +183,8 @@ void Player::deSerialize(std::istream &is)
LocalPlayer::LocalPlayer(IGameDef *gamedef): LocalPlayer::LocalPlayer(IGameDef *gamedef):
Player(gamedef), Player(gamedef),
m_sneak_node(32767,32767,32767), m_sneak_node(32767,32767,32767),
m_sneak_node_exists(false) m_sneak_node_exists(false),
m_linked(false)
{ {
// Initialize hp to 0, so that no hearts will be shown if server // Initialize hp to 0, so that no hearts will be shown if server
// doesn't support health points // doesn't support health points

View file

@ -251,6 +251,13 @@ public:
PlayerControl control; PlayerControl control;
inline void Link(bool value) {
m_linked = value;
}
bool m_linked;
private: private:
// This is used for determining the sneaking range // This is used for determining the sneaking range
v3s16 m_sneak_node; v3s16 m_sneak_node;

View file

@ -101,13 +101,17 @@ void ServerRemotePlayer::step(float dtime, bool send_recommended)
if(send_recommended == false) if(send_recommended == false)
return; return;
if(isLinked())
return;
if(m_position_not_sent) if(m_position_not_sent)
{ {
m_position_not_sent = false; m_position_not_sent = false;
std::ostringstream os(std::ios::binary); std::ostringstream os(std::ios::binary);
// command (0 = update position) // command (0 = update position)
writeU8(os, 0); writeU8(os,AO_Message_type::SetPosition );
// pos // pos
writeV3F1000(os, getPosition()); writeV3F1000(os, getPosition());
// yaw // yaw
@ -173,7 +177,7 @@ void ServerRemotePlayer::punch(ServerActiveObject *puncher,
{ {
std::ostringstream os(std::ios::binary); std::ostringstream os(std::ios::binary);
// command (1 = punched) // command (1 = punched)
writeU8(os, 1); writeU8(os, AO_Message_type::Punched);
// damage // damage
writeS16(os, hitprop.hp); writeS16(os, hitprop.hp);
// create message and add to list // create message and add to list
@ -323,4 +327,24 @@ s16 ServerRemotePlayer::getHP()
return hp; return hp;
} }
bool ServerRemotePlayer::sendLinkMsg(ServerActiveObject* parent,v3f offset) {
std::ostringstream os(std::ios::binary);
writeU8(os, AO_Message_type::Link);
// parameters
writeU16(os, parent->getId());
writeV3F1000(os, offset);
// create message and add to list
ActiveObjectMessage aom(getId(), true, os.str());
m_messages_out.push_back(aom);
return true;
}
bool ServerRemotePlayer::sendUnlinkMsg() {
std::ostringstream os(std::ios::binary);
writeU8(os, AO_Message_type::UnLink);
// create message and add to list
ActiveObjectMessage aom(getId(), true, os.str());
m_messages_out.push_back(aom);
return true;
}

View file

@ -22,13 +22,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "player.h" #include "player.h"
#include "serverobject.h" #include "serverobject.h"
#include "serverlinkableobject.h"
#include "content_object.h" // Object type IDs #include "content_object.h" // Object type IDs
/* /*
Player on the server Player on the server
*/ */
class ServerRemotePlayer : public Player, public ServerActiveObject class ServerRemotePlayer : public Player, public ServerActiveObject, public ServerLinkableObject
{ {
public: public:
ServerRemotePlayer(ServerEnvironment *env); ServerRemotePlayer(ServerEnvironment *env);
@ -97,6 +98,9 @@ public:
// Incremented by step(), read and reset by Server // Incremented by step(), read and reset by Server
float m_time_from_last_punch; float m_time_from_last_punch;
bool sendLinkMsg(ServerActiveObject* parent,v3f offset);
bool sendUnlinkMsg();
private: private:
bool m_position_not_sent; bool m_position_not_sent;
}; };