1
0
Fork 0
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:
sapier 2012-02-07 21:37:42 +01:00
parent 61ae136431
commit 52996cd5eb
11 changed files with 209 additions and 145 deletions

View file

@ -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;

View file

@ -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();

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
};