mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-01 17:38:41 +00:00
maualy merged object linking interface from cao_sao_split patch
This commit is contained in:
parent
61ae136431
commit
52996cd5eb
11 changed files with 209 additions and 145 deletions
|
@ -49,7 +49,7 @@ void ClientLinkableObject::stepLinkedObjects(v3f pos,float dtime) {
|
|||
}
|
||||
|
||||
bool ClientLinkableObject::handleLinkUnlinkMessages(u8 cmd,std::istringstream* is,ClientEnvironment *m_env) {
|
||||
if(cmd == AO_Message_type::Link) // Link entity
|
||||
if(cmd == 3) // Link entity
|
||||
{
|
||||
//Object to link entity to
|
||||
u16 object_id = readU16(*is);
|
||||
|
@ -69,7 +69,7 @@ bool ClientLinkableObject::handleLinkUnlinkMessages(u8 cmd,std::istringstream* i
|
|||
return true;
|
||||
|
||||
}
|
||||
else if(cmd == AO_Message_type::UnLink) // UnLink entity
|
||||
else if(cmd == 4) // UnLink entity
|
||||
{
|
||||
if (this->m_Parent == NULL) {
|
||||
errorstream << "Unlinking object not linked!" << std::endl;
|
||||
|
|
|
@ -30,21 +30,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "utility.h"
|
||||
#include "log.h"
|
||||
|
||||
|
||||
//this ain't the right place to define this but until cao/sao split
|
||||
//is decided it'll have to stay here
|
||||
struct AO_Message_type {
|
||||
static const u8 SetPosition = 0x00;
|
||||
static const u8 SetTextureMod = 0x01;
|
||||
static const u8 SetSprite = 0x02;
|
||||
static const u8 Punched = 0x03;
|
||||
static const u8 TakeDamage = 0x04;
|
||||
static const u8 Shoot = 0x05;
|
||||
static const u8 Link = 0x06;
|
||||
static const u8 UnLink = 0x07;
|
||||
};
|
||||
|
||||
|
||||
class ClientLinkableObject {
|
||||
public:
|
||||
ClientLinkableObject();
|
||||
|
|
|
@ -17,11 +17,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "content_cao.h"
|
||||
#include "tile.h"
|
||||
#include "environment.h"
|
||||
#include "collision.h"
|
||||
#include "collidableobject.h"
|
||||
#include "clientlinkableobject.h"
|
||||
#include "settings.h"
|
||||
#include <ICameraSceneNode.h>
|
||||
#include <ITextSceneNode.h>
|
||||
|
@ -1682,7 +1682,7 @@ void MobV2CAO::setLooks(const std::string &looks)
|
|||
|
||||
#include "luaentity_common.h"
|
||||
|
||||
class LuaEntityCAO : public ClientActiveObject , public CollidableObject
|
||||
class LuaEntityCAO : public ClientActiveObject , public CollidableObject , public ClientLinkableObject
|
||||
{
|
||||
private:
|
||||
core::aabbox3d<f32> m_selection_box;
|
||||
|
@ -1897,36 +1897,40 @@ public:
|
|||
|
||||
void step(float dtime, ClientEnvironment *env)
|
||||
{
|
||||
if(m_prop->physical){
|
||||
core::aabbox3d<f32> box = m_prop->collisionbox;
|
||||
box.MinEdge *= BS;
|
||||
box.MaxEdge *= BS;
|
||||
collisionMoveResult moveresult;
|
||||
f32 pos_max_d = BS*0.125; // Distance per iteration
|
||||
f32 stepheight = 0;
|
||||
v3f p_pos = m_position;
|
||||
v3f p_velocity = m_velocity;
|
||||
v3f p_acceleration = m_acceleration;
|
||||
moveresult = collisionMovePrecise(env,
|
||||
pos_max_d, box, stepheight, dtime,
|
||||
p_pos, p_velocity, p_acceleration);
|
||||
// Apply results
|
||||
m_position = p_pos;
|
||||
m_velocity = p_velocity;
|
||||
m_acceleration = p_acceleration;
|
||||
if(!this->isLinked()) {
|
||||
if(m_prop->physical){
|
||||
core::aabbox3d<f32> box = m_prop->collisionbox;
|
||||
box.MinEdge *= BS;
|
||||
box.MaxEdge *= BS;
|
||||
collisionMoveResult moveresult;
|
||||
f32 pos_max_d = BS*0.125; // Distance per iteration
|
||||
f32 stepheight = 0;
|
||||
v3f p_pos = m_position;
|
||||
v3f p_velocity = m_velocity;
|
||||
v3f p_acceleration = m_acceleration;
|
||||
moveresult = collisionMovePrecise(env,
|
||||
pos_max_d, box, stepheight, dtime,
|
||||
p_pos, p_velocity, p_acceleration);
|
||||
// Apply results
|
||||
m_position = p_pos;
|
||||
m_velocity = p_velocity;
|
||||
m_acceleration = p_acceleration;
|
||||
|
||||
bool is_end_position = moveresult.collides;
|
||||
pos_translator.update(m_position, is_end_position, dtime);
|
||||
pos_translator.translate(dtime);
|
||||
updateNodePos();
|
||||
} else {
|
||||
m_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration;
|
||||
m_velocity += dtime * m_acceleration;
|
||||
pos_translator.update(m_position, pos_translator.aim_is_end, pos_translator.anim_time);
|
||||
pos_translator.translate(dtime);
|
||||
updateNodePos();
|
||||
bool is_end_position = moveresult.collides;
|
||||
pos_translator.update(m_position, is_end_position, dtime);
|
||||
pos_translator.translate(dtime);
|
||||
updateNodePos();
|
||||
} else {
|
||||
m_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration;
|
||||
m_velocity += dtime * m_acceleration;
|
||||
pos_translator.update(m_position, pos_translator.aim_is_end, pos_translator.anim_time);
|
||||
pos_translator.translate(dtime);
|
||||
updateNodePos();
|
||||
}
|
||||
}
|
||||
|
||||
stepLinkedObjects(this->m_position,dtime);
|
||||
|
||||
m_anim_timer += dtime;
|
||||
if(m_anim_timer >= m_anim_framelength){
|
||||
m_anim_timer -= m_anim_framelength;
|
||||
|
@ -2098,6 +2102,10 @@ public:
|
|||
|
||||
updateTexturePos();
|
||||
}
|
||||
else if (handleLinkUnlinkMessages(cmd,&is,this->m_env))
|
||||
{
|
||||
//Link unlink already done in handleLinkUnlinkMessages!
|
||||
}
|
||||
}
|
||||
|
||||
aabb3f* getCollisionBox() {
|
||||
|
@ -2114,6 +2122,17 @@ public:
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void setPosition(v3f toset, float dtime){
|
||||
if (this->isLinked()) {
|
||||
this->m_position = toset + this->m_linkOffset;
|
||||
pos_translator.update(m_position, pos_translator.aim_is_end, pos_translator.anim_time);
|
||||
pos_translator.translate(dtime);
|
||||
updateNodePos();
|
||||
}
|
||||
}
|
||||
|
||||
void updateLinkState(bool value) {}
|
||||
};
|
||||
|
||||
// Prototype
|
||||
|
@ -2123,7 +2142,7 @@ LuaEntityCAO proto_LuaEntityCAO(NULL, NULL);
|
|||
PlayerCAO
|
||||
*/
|
||||
|
||||
class PlayerCAO : public ClientActiveObject, public CollidableObject
|
||||
class PlayerCAO : public ClientActiveObject, public CollidableObject , public ClientLinkableObject
|
||||
{
|
||||
private:
|
||||
core::aabbox3d<f32> m_selection_box;
|
||||
|
@ -2342,9 +2361,12 @@ public:
|
|||
|
||||
void step(float dtime, ClientEnvironment *env)
|
||||
{
|
||||
pos_translator.translate(dtime);
|
||||
if(!isLinked()) {
|
||||
pos_translator.translate(dtime);
|
||||
updateNodePos();
|
||||
}
|
||||
|
||||
updateVisibility();
|
||||
updateNodePos();
|
||||
|
||||
if(m_damage_visual_timer > 0){
|
||||
m_damage_visual_timer -= dtime;
|
||||
|
@ -2385,6 +2407,10 @@ public:
|
|||
m_dead = readU8(is);
|
||||
updateVisibility();
|
||||
}
|
||||
else if (handleLinkUnlinkMessages(cmd,&is,this->m_env))
|
||||
{
|
||||
//Link unlink already done in handleLinkUnlinkMessages!
|
||||
}
|
||||
}
|
||||
|
||||
void updateTextures(const std::string &mod)
|
||||
|
@ -2410,6 +2436,26 @@ 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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Prototype
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
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
|
||||
(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.
|
||||
|
||||
You should have received a copy of the GNU 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.
|
||||
*/
|
||||
|
||||
#ifndef CONTENT_CAO_HEADER
|
||||
#define CONTENT_CAO_HEADER
|
||||
|
||||
#endif
|
||||
|
|
@ -1852,3 +1852,24 @@ aabb3f* LuaEntitySAO::getCollisionBox() {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bool LuaEntitySAO::sendLinkMsg(ServerActiveObject* parent,v3f offset) {
|
||||
std::ostringstream os(std::ios::binary);
|
||||
writeU8(os, 3);
|
||||
// parameters
|
||||
writeU16(os, parent->getId());
|
||||
writeV3F1000(os, offset);
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), false, os.str());
|
||||
m_messages_out.push_back(aom);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LuaEntitySAO::sendUnlinkMsg() {
|
||||
std::ostringstream os(std::ios::binary);
|
||||
writeU8(os, 4);
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), false, os.str());
|
||||
m_messages_out.push_back(aom);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "serverobject.h"
|
||||
#include "content_object.h"
|
||||
#include "collidableobject.h"
|
||||
#include "serverlinkableobject.h"
|
||||
|
||||
class TestSAO : public ServerActiveObject
|
||||
{
|
||||
|
@ -193,7 +194,7 @@ private:
|
|||
|
||||
struct LuaEntityProperties;
|
||||
|
||||
class LuaEntitySAO : public ServerActiveObject, public CollidableObject
|
||||
class LuaEntitySAO : public ServerActiveObject, public CollidableObject , public ServerLinkableObject
|
||||
{
|
||||
public:
|
||||
LuaEntitySAO(ServerEnvironment *env, v3f pos,
|
||||
|
@ -224,6 +225,8 @@ public:
|
|||
bool select_horiz_by_yawpitch);
|
||||
std::string getName();
|
||||
aabb3f* getCollisionBox();
|
||||
bool sendLinkMsg(ServerActiveObject* parent,v3f offset);
|
||||
bool sendUnlinkMsg();
|
||||
private:
|
||||
void sendPosition(bool do_interpolate, bool is_movement_end);
|
||||
|
||||
|
|
|
@ -1908,6 +1908,7 @@ void ClientEnvironment::step(float dtime)
|
|||
Get the speed the player is going
|
||||
*/
|
||||
bool is_climbing = lplayer->is_climbing;
|
||||
bool linked = lplayer->m_linked;
|
||||
|
||||
f32 player_speed = lplayer->getSpeed().getLength();
|
||||
|
||||
|
@ -1936,90 +1937,91 @@ void ClientEnvironment::step(float dtime)
|
|||
/*
|
||||
Stuff that has a maximum time increment
|
||||
*/
|
||||
|
||||
u32 loopcount = 0;
|
||||
do
|
||||
{
|
||||
loopcount++;
|
||||
|
||||
f32 dtime_part;
|
||||
if(dtime_downcount > dtime_max_increment)
|
||||
if (!linked) {
|
||||
u32 loopcount = 0;
|
||||
do
|
||||
{
|
||||
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;
|
||||
}
|
||||
loopcount++;
|
||||
|
||||
/*
|
||||
Handle local player
|
||||
*/
|
||||
|
||||
{
|
||||
v3f lplayerpos = lplayer->getPosition();
|
||||
|
||||
// Apply physics
|
||||
if(free_move == false && is_climbing == false)
|
||||
f32 dtime_part;
|
||||
if(dtime_downcount > dtime_max_increment)
|
||||
{
|
||||
// Gravity
|
||||
v3f speed = lplayer->getSpeed();
|
||||
if(lplayer->swimming_up == false)
|
||||
speed.Y -= 9.81 * BS * dtime_part * 2;
|
||||
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;
|
||||
}
|
||||
|
||||
// Water resistance
|
||||
if(lplayer->in_water_stable || lplayer->in_water)
|
||||
/*
|
||||
Handle local player
|
||||
*/
|
||||
|
||||
{
|
||||
v3f lplayerpos = lplayer->getPosition();
|
||||
|
||||
// Apply physics
|
||||
if(free_move == false && is_climbing == false)
|
||||
{
|
||||
f32 max_down = 2.0*BS;
|
||||
if(speed.Y < -max_down) speed.Y = -max_down;
|
||||
// Gravity
|
||||
v3f speed = lplayer->getSpeed();
|
||||
if(lplayer->swimming_up == false)
|
||||
speed.Y -= 9.81 * BS * dtime_part * 2;
|
||||
|
||||
f32 max = 2.5*BS;
|
||||
if(speed.getLength() > max)
|
||||
// Water resistance
|
||||
if(lplayer->in_water_stable || lplayer->in_water)
|
||||
{
|
||||
speed = speed / speed.getLength() * max;
|
||||
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);
|
||||
}
|
||||
|
||||
lplayer->setSpeed(speed);
|
||||
/*
|
||||
Move the lplayer.
|
||||
This also does collision detection.
|
||||
*/
|
||||
lplayer->move(dtime_part, this, position_max_increment,
|
||||
&player_collisions);
|
||||
}
|
||||
|
||||
/*
|
||||
Move the lplayer.
|
||||
This also does collision detection.
|
||||
*/
|
||||
lplayer->move(dtime_part, this, position_max_increment,
|
||||
&player_collisions);
|
||||
}
|
||||
}
|
||||
while(dtime_downcount > 0.001);
|
||||
while(dtime_downcount > 0.001);
|
||||
|
||||
//std::cout<<"Looped "<<loopcount<<" times."<<std::endl;
|
||||
//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)
|
||||
for(core::list<CollisionInfo>::Iterator
|
||||
i = player_collisions.begin();
|
||||
i != player_collisions.end(); i++)
|
||||
{
|
||||
//f32 tolerance = BS*10; // 2 without damage
|
||||
f32 tolerance = BS*12; // 3 without damage
|
||||
f32 factor = 1;
|
||||
if(info.speed > tolerance)
|
||||
CollisionInfo &info = *i;
|
||||
if(info.t == COLLISION_FALL)
|
||||
{
|
||||
f32 damage_f = (info.speed - tolerance)/BS*factor;
|
||||
u16 damage = (u16)(damage_f+0.5);
|
||||
damageLocalPlayer(damage, true);
|
||||
//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);
|
||||
damageLocalPlayer(damage, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
A quick draft of lava damage
|
||||
|
|
|
@ -188,7 +188,8 @@ void Player::deSerialize(std::istream &is)
|
|||
LocalPlayer::LocalPlayer(IGameDef *gamedef):
|
||||
Player(gamedef),
|
||||
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
|
||||
// doesn't support health points
|
||||
|
|
|
@ -240,6 +240,10 @@ public:
|
|||
|
||||
PlayerControl control;
|
||||
|
||||
inline void Link(bool value) {
|
||||
m_linked = value;
|
||||
}
|
||||
bool m_linked;
|
||||
private:
|
||||
// This is used for determining the sneaking range
|
||||
v3s16 m_sneak_node;
|
||||
|
|
|
@ -130,6 +130,9 @@ void ServerRemotePlayer::step(float dtime, bool send_recommended)
|
|||
if(send_recommended == false)
|
||||
return;
|
||||
|
||||
if(isLinked())
|
||||
return;
|
||||
|
||||
if(m_position_not_sent)
|
||||
{
|
||||
m_position_not_sent = false;
|
||||
|
@ -278,4 +281,24 @@ aabb3f* ServerRemotePlayer::getCollisionBox() {
|
|||
return &m_collisionbox;
|
||||
}
|
||||
|
||||
bool ServerRemotePlayer::sendLinkMsg(ServerActiveObject* parent,v3f offset) {
|
||||
std::ostringstream os(std::ios::binary);
|
||||
writeU8(os, 3);
|
||||
// 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, 4);
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), true, os.str());
|
||||
m_messages_out.push_back(aom);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,13 +23,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "player.h"
|
||||
#include "serverobject.h"
|
||||
#include "collidableobject.h"
|
||||
#include "serverlinkableobject.h"
|
||||
#include "content_object.h" // Object type IDs
|
||||
|
||||
/*
|
||||
Player on the server
|
||||
*/
|
||||
|
||||
class ServerRemotePlayer : public Player, public ServerActiveObject , public CollidableObject
|
||||
class ServerRemotePlayer : public Player, public ServerActiveObject , public CollidableObject , public ServerLinkableObject
|
||||
{
|
||||
public:
|
||||
ServerRemotePlayer(ServerEnvironment *env);
|
||||
|
@ -95,6 +96,8 @@ public:
|
|||
// Incremented by step(), read and reset by Server
|
||||
float m_time_from_last_punch;
|
||||
aabb3f* getCollisionBox();
|
||||
bool sendLinkMsg(ServerActiveObject* parent,v3f offset);
|
||||
bool sendUnlinkMsg();
|
||||
private:
|
||||
bool m_position_not_sent;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue