}
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);
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;
#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();
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>
#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;
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;
-
- 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();
+ 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();
+ }
}
+ stepLinkedObjects(this->m_position,dtime);
+
m_anim_timer += dtime;
if(m_anim_timer >= m_anim_framelength){
m_anim_timer -= m_anim_framelength;
updateTexturePos();
}
+ else if (handleLinkUnlinkMessages(cmd,&is,this->m_env))
+ {
+ //Link unlink already done in handleLinkUnlinkMessages!
+ }
}
aabb3f* getCollisionBox() {
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
PlayerCAO
*/
-class PlayerCAO : public ClientActiveObject, public CollidableObject
+class PlayerCAO : public ClientActiveObject, public CollidableObject , public ClientLinkableObject
{
private:
core::aabbox3d<f32> m_selection_box;
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;
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)
}
}
}
+ 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
+++ /dev/null
-/*
-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
-
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;
+}
+
#include "serverobject.h"
#include "content_object.h"
#include "collidableobject.h"
+#include "serverlinkableobject.h"
class TestSAO : public ServerActiveObject
{
struct LuaEntityProperties;
-class LuaEntitySAO : public ServerActiveObject, public CollidableObject
+class LuaEntitySAO : public ServerActiveObject, public CollidableObject , public ServerLinkableObject
{
public:
LuaEntitySAO(ServerEnvironment *env, v3f pos,
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);
Get the speed the player is going
*/
bool is_climbing = lplayer->is_climbing;
+ bool linked = lplayer->m_linked;
f32 player_speed = lplayer->getSpeed().getLength();
/*
Stuff that has a maximum time increment
*/
+ if (!linked) {
+ u32 loopcount = 0;
+ do
+ {
+ loopcount++;
- u32 loopcount = 0;
- do
- {
- 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;
+ }
- 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
+ Handle local player
*/
- dtime_downcount = 0;
- }
-
- /*
- Handle local player
- */
-
- {
- v3f lplayerpos = lplayer->getPosition();
- // Apply physics
- if(free_move == false && is_climbing == false)
{
- // Gravity
- v3f speed = lplayer->getSpeed();
- if(lplayer->swimming_up == false)
- speed.Y -= 9.81 * BS * dtime_part * 2;
+ v3f lplayerpos = lplayer->getPosition();
- // Water resistance
- if(lplayer->in_water_stable || lplayer->in_water)
+ // 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
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
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;
if(send_recommended == false)
return;
+ if(isLinked())
+ return;
+
if(m_position_not_sent)
{
m_position_not_sent = false;
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;
+}
#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);
// 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;
};