added derived object to add linkable object support
authorsapier <sapier at gmx dot net>
Sun, 15 Jan 2012 18:55:58 +0000 (19:55 +0100)
committersapier <sapier at gmx dot net>
Sun, 15 Jan 2012 18:55:58 +0000 (19:55 +0100)
src/CMakeLists.txt
src/clientlinkableobject.cpp [new file with mode: 0644]
src/clientlinkableobject.h [new file with mode: 0644]
src/scriptapi.cpp
src/serverlinkableobject.cpp [new file with mode: 0644]
src/serverlinkableobject.h [new file with mode: 0644]

index 3b3b326c454f9967ffef4a823507b737212616ea..baf9fed5a5345c27c9e52fd611fc22b876c89ee7 100644 (file)
@@ -115,6 +115,7 @@ set(common_SRCS
        collision.cpp
        nodemetadata.cpp
        serverobject.cpp
+       serverlinkableobject.cpp
        noise.cpp
        mineral.cpp
        porting.cpp
@@ -168,6 +169,7 @@ set(minetest_SRCS
        camera.cpp
        clouds.cpp
        clientobject.cpp
+       clientlinkableobject.cpp
        guiMainMenu.cpp
        guiKeyChangeMenu.cpp
        guiMessageMenu.cpp
diff --git a/src/clientlinkableobject.cpp b/src/clientlinkableobject.cpp
new file mode 100644 (file)
index 0000000..917edbd
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+Minetest-c55
+Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2012 sapier sapier at gmx dot net
+
+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.
+*/
+
+#include "clientlinkableobject.h"
+
+ClientLinkableObject::ClientLinkableObject() {
+
+       this->m_Parent = NULL;
+}
+
+ClientLinkableObject::~ClientLinkableObject() {
+       if (this->isLinked())
+               this->unlink(this);
+}
+
+
+void ClientLinkableObject::link(ClientLinkableObject* entity) {
+       //TODO check if entity is already linkt (shouldn't be the case but just to be sure)
+       this->m_LinkedObjects.push_back(entity);
+}
+
+void ClientLinkableObject::unlink(ClientLinkableObject* entity) {
+       this->m_LinkedObjects.remove(entity);
+}
+
+
+void ClientLinkableObject::stepLinkedObjects(v3f pos,float dtime) {
+       for(std::list<ClientLinkableObject*>::iterator i = this->m_LinkedObjects.begin();
+                       i != this->m_LinkedObjects.end(); i++) {
+                       (*i)->setPosition(pos,dtime);
+       }
+}
+
+bool ClientLinkableObject::handleLinkUnlinkMessages(u8 cmd,std::istringstream* is,ClientEnvironment *m_env) {
+       if(cmd == AO_Message_type::Link) // Link entity
+               {
+                       //Object to link entity to
+                       u16 object_id = readU16(*is);
+                       //offset against linked object
+                       v3f offset    = readV3F1000(*is);
+
+                       ClientActiveObject* parent_cao = m_env->getActiveObject(object_id);
+
+                       ClientLinkableObject* parent = dynamic_cast<ClientLinkableObject*>(parent_cao);
+
+                       if (parent != NULL) {
+                               this->linkEntity(offset,parent);
+                       }
+                       else {
+                               errorstream << "Invalid object to link to!" << std::endl;
+                       }
+                       return true;
+
+               }
+       else if(cmd == AO_Message_type::UnLink) // UnLink entity
+               {
+                       if (this->m_Parent == NULL) {
+                               errorstream << "Unlinking object not linked!" << std::endl;
+                       }
+
+                       this->unlinkEntity();
+                       return true;
+               }
+
+       return false;
+}
+
+
+bool ClientLinkableObject::linkEntity(v3f offset, ClientLinkableObject* parent) {
+       //already linked unlink first
+       if (this->m_Parent != NULL) {
+               return false;
+       }
+
+       //TODO add linkchain support
+       if (this->m_LinkedObjects.size() > 0) {
+               return false;
+       }
+
+       parent->link(this);
+       updateLinkState(true);
+       this->m_linkOffset      = offset;
+       this->m_Parent          = parent;
+       return true;
+}
+
+
+bool ClientLinkableObject::unlinkEntity() {
+       if (this->m_Parent != NULL) {
+
+                       updateLinkState(false);
+                       this->m_Parent->unlink(this);
+                       this->m_Parent = NULL;
+                       return true;
+
+               }
+
+               return false;
+}
+
+bool ClientLinkableObject::isLinked() {
+       if (this->m_Parent != NULL)
+               return true;
+       else
+               return false;
+}
diff --git a/src/clientlinkableobject.h b/src/clientlinkableobject.h
new file mode 100644 (file)
index 0000000..a6192d5
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+Minetest-c55
+Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2012 sapier sapier at gmx dot net
+
+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 CLIENTLINKABLEOBJECT_H_
+#define CLIENTLINKABLEOBJECT_H_
+
+#include <list>
+#include <sstream>
+#include <irrlichttypes.h>
+#include "clientobject.h"
+#include "environment.h"
+#include "content_object.h"
+#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();
+               ~ClientLinkableObject();
+               //internal communication between entitys NOT to be used by user
+               void link(ClientLinkableObject* entity);
+               void unlink(ClientLinkableObject* entity);
+
+               virtual void setPosition(v3f toset, float dtime) = 0;
+               virtual void updateLinkState(bool value) = 0;
+
+       protected:
+               void stepLinkedObjects(v3f pos,float dtime);
+
+               bool handleLinkUnlinkMessages(u8 cmd,std::istringstream* is,ClientEnvironment *m_env);
+
+
+               //user driven functions (exported by lua)
+               bool linkEntity(v3f offset, ClientLinkableObject* parent);
+               bool unlinkEntity();
+
+               bool isLinked();
+               v3f  m_linkOffset;
+
+
+       private:
+               ClientLinkableObject* m_Parent;
+
+               std::list<ClientLinkableObject*> m_LinkedObjects;
+};
+
+
+#endif /* CLIENTLINKABLEOBJECT_H_ */
index b617626a0bc3a2fb05359992bd40de5719ae4f0a..d14634276375b7b8a0caabf3ed7cc9bca786408a 100644 (file)
@@ -46,6 +46,7 @@ extern "C" {
 #include "mapblock.h" // For getNodeBlockPos
 #include "content_nodemeta.h"
 #include "utility.h"
+#include "serverlinkableobject.h"
 
 static void stackDump(lua_State *L, std::ostream &o)
 {
@@ -1753,7 +1754,7 @@ private:
                        get_server(L)->SendMovePlayer(player);
                return 0;
        }
-       
+
        // moveto(self, pos, continuous=false)
        static int l_moveto(lua_State *L)
        {
@@ -2173,6 +2174,62 @@ private:
                return 1;
        }
 
+       // link(parent, offset)
+       static int l_link(lua_State *L)
+       {
+               ObjectRef *ref_child  = checkobject(L, 1);
+               ObjectRef *ref_parent =  checkobject(L, 2);
+               v3f            offset = checkFloatPos(L, 3);
+
+               ServerActiveObject *child  = getobject(ref_child);
+               ServerActiveObject *parent = getobject(ref_parent);
+
+               if ((child == NULL) || (parent == NULL)) {
+                       errorstream << "LUA: link(): invalid parameters" << std::endl;
+                       return 0;
+               }
+
+
+               ServerLinkableObject* child_lua  = dynamic_cast<ServerLinkableObject*>(child);
+               ServerLinkableObject* parent_lua = dynamic_cast<ServerLinkableObject*>(parent);
+
+               if (child_lua == NULL)  return 0;
+               if (parent_lua == NULL) return 0;
+
+               if (child_lua->linkEntity(parent,offset)) {
+                       lua_pushboolean(L, true);
+                       return 1;
+               }
+               else {
+                       return 0;
+               }
+       }
+
+       // unlink()
+       static int l_unlink(lua_State *L)
+       {
+               ObjectRef *ref = checkobject(L, 1);
+
+               ServerActiveObject *obj = getobject(ref);
+
+               if (obj == NULL) {
+                       errorstream << "LUA: unlink(): invalid parameters" << std::endl;
+                       return 0;
+               }
+
+               ServerLinkableObject* tolink = dynamic_cast<ServerLinkableObject*>(obj);
+
+               if (tolink == NULL) return 0;
+
+               if (tolink->unlinkEntity()) {
+                       lua_pushboolean(L, true);
+                       return 1;
+               }
+               else {
+                       return 0;
+               }
+       }
+
 public:
        ObjectRef(ServerActiveObject *object):
                m_object(object)
@@ -2270,6 +2327,8 @@ const luaL_reg ObjectRef::methods[] = {
        method(ObjectRef, get_look_dir),
        method(ObjectRef, get_look_pitch),
        method(ObjectRef, get_look_yaw),
+       method(ObjectRef, link),
+       method(ObjectRef, unlink),
        {0,0}
 };
 
diff --git a/src/serverlinkableobject.cpp b/src/serverlinkableobject.cpp
new file mode 100644 (file)
index 0000000..f8e401b
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+Minetest-c55
+Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2012 sapier sapier at gmx dot net
+
+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.
+*/
+
+#include "serverlinkableobject.h"
+
+
+ServerLinkableObject::ServerLinkableObject() {
+       this->m_Linked = false;
+}
+
+ServerLinkableObject::~ServerLinkableObject() {}
+
+bool ServerLinkableObject::linkEntity(ServerActiveObject* parent,v3f offset) {
+       //check if entity is in correct state
+       if (this->m_Linked == true) {
+               errorstream<<"ServerLinkableObject: link but object already linked!"<<std::endl;
+               return false;
+       }
+       this->m_Linked = true;
+
+       errorstream<<"ServerLinkableObject: try to send link message!"<<std::endl;
+       return sendLinkMsg(parent,offset);
+}
+
+bool ServerLinkableObject::unlinkEntity() {
+       //check if entity is in correct state
+       if (this->m_Linked == false) {
+               errorstream<<"ServerLinkableObject: unlink but object not linked!"<<std::endl;
+               return false;
+       }
+
+       this->m_Linked = false;
+
+       errorstream<<"ServerLinkableObject: try to send unlink message!"<<std::endl;
+       return sendUnlinkMsg();
+}
diff --git a/src/serverlinkableobject.h b/src/serverlinkableobject.h
new file mode 100644 (file)
index 0000000..182ebb1
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+Minetest-c55
+Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2012 sapier sapier at gmx dot net
+
+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 SERVERLINKABLEOBJECT_H_
+#define SERVERLINKABLEOBJECT_H_
+
+#include <sstream>
+#include <irrlichttypes.h>
+#include "serverobject.h"
+#include "content_object.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 ServerLinkableObject {
+       public:
+               ServerLinkableObject();
+               ~ServerLinkableObject();
+
+               bool linkEntity(ServerActiveObject* parent,v3f offset);
+               bool unlinkEntity();
+
+               virtual bool sendLinkMsg(ServerActiveObject* parent,v3f offset) = 0;
+               virtual bool sendUnlinkMsg() = 0;
+
+       protected:
+               inline bool isLinked() { return m_Linked; }
+
+       private:
+               bool m_Linked;
+
+};
+
+#endif /* SERVERLINKABLEOBJECT_H_ */