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:
parent
14a64000ea
commit
c17133d80a
6 changed files with 157 additions and 89 deletions
|
@ -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; }
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue