Index: code/branches/objecthierarchy/src/orxonox/CMakeLists.txt
===================================================================
--- code/branches/objecthierarchy/src/orxonox/CMakeLists.txt	(revision 1958)
+++ code/branches/objecthierarchy/src/orxonox/CMakeLists.txt	(revision 1959)
@@ -54,4 +54,7 @@
   objects/Tickable.cc
   objects/Test.cc
+  objects/Script.cc
+  objects/Trigger.cc
+  objects/DistanceTrigger.cc
 
   objects/infos/Info.cc
@@ -74,5 +77,6 @@
   WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/lib
 )
-	
+
+
 ADD_EXECUTABLE( orxonox ${ORXONOX_SRC_FILES} )
 
Index: code/branches/objecthierarchy/src/orxonox/objects/DistanceTrigger.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/DistanceTrigger.cc	(revision 1959)
+++ code/branches/objecthierarchy/src/orxonox/objects/DistanceTrigger.cc	(revision 1959)
@@ -0,0 +1,125 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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.
+ *
+ *   Author:
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "DistanceTrigger.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox {
+
+  CreateFactory(DistanceTrigger);
+
+  DistanceTrigger::DistanceTrigger()
+  {
+    RegisterObject(DistanceTrigger);
+
+    targetMask_.exclude(Class(BaseObject));
+  }
+
+  DistanceTrigger::~DistanceTrigger()
+  {
+  }
+
+  void DistanceTrigger::addTarget(Ogre::Node* targetNode)
+  {
+    this->targetSet_.insert(targetNode);
+  }
+
+  void DistanceTrigger::removeTarget(Ogre::Node* targetNode)
+  {
+    int returnval = this->targetSet_.erase(targetNode);
+    if (returnval == 0)
+    {
+      COUT(2) << "Warning: Node " << targetNode << " did not exist in targetSet of trigger " << this << " !" << std::endl;
+      COUT(4) << "Content of targetSet of trigger " << this << " :" << std::endl;
+      std::set<Ogre::Node*>::iterator it;
+      for(it = this->targetSet_.begin(); it != this->targetSet_.end(); it++)
+      {
+        COUT(4) << *it << std::endl;
+      }
+      COUT(4) << "End of targetSet of trigger " << this << std::endl;
+    }
+  }
+
+  void DistanceTrigger::addTargets(std::string targets)
+  {
+    Identifier* targetId = ID(targets);
+    targetMask_.include(targetId);
+    // trigger shouldn't react on itself or other triggers
+    targetMask_.exclude(Class(Trigger), true);
+
+  }
+
+  void DistanceTrigger::removeTargets(std::string targets)
+  {
+    Identifier* targetId = ID(targets);
+    targetMask_.exclude(targetId);
+  }
+
+  bool DistanceTrigger::checkDistance()
+  {
+    // Iterate through all WorldEntities
+    for(Iterator<WorldEntity> it = ObjectList<WorldEntity>::begin(); it; it++)
+    {
+      // check if WorldEntity is a target
+      if(targetMask_.isIncluded(it->getIdentifier()))
+      {
+        Vector3 distanceVec = it->getNode()->getWorldPosition() - this->getNode()->getWorldPosition();
+        if (distanceVec.length() < this->distance_)
+        {
+          return true;
+        }
+      }
+    }
+    return false;
+
+  }
+
+  void DistanceTrigger::setDistance(float dist)
+  {
+    this->distance_ = dist;
+  }
+
+  void DistanceTrigger::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+  {
+    Trigger::XMLPort(xmlelement, mode);
+
+    XMLPortParamLoadOnly(DistanceTrigger, "distance", setDistance, xmlelement, mode);
+    XMLPortParamLoadOnly(DistanceTrigger, "target", addTargets, xmlelement, mode);
+  }
+
+  bool DistanceTrigger::isTriggered(TriggerMode mode)
+  {
+    if(Trigger::isTriggered(mode))
+      return checkDistance();
+    else
+      return false;
+  }
+}
Index: code/branches/objecthierarchy/src/orxonox/objects/DistanceTrigger.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/DistanceTrigger.h	(revision 1959)
+++ code/branches/objecthierarchy/src/orxonox/objects/DistanceTrigger.h	(revision 1959)
@@ -0,0 +1,67 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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.
+ *
+ *   Author:
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _DistanceTrigger_H__
+#define _DistanceTrigger_H__
+
+#include "Trigger.h"
+
+#include <set>
+
+#include <OgreNode.h>
+
+#include "core/ClassTreeMask.h"
+#include "core/BaseObject.h"
+
+namespace orxonox {
+
+  class _OrxonoxExport DistanceTrigger : public Trigger
+  {
+    public:
+      DistanceTrigger();
+      ~DistanceTrigger();
+      void addTarget(Ogre::Node* targetNode);
+      void removeTarget(Ogre::Node* targetNode);
+      void addTargets(std::string targets);
+      void removeTargets(std::string targets);
+      void setDistance(float dist);
+      virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+      bool checkDistance();
+
+    protected:
+      bool isTriggered(TriggerMode mode);
+
+    private:
+      ClassTreeMask targetMask_;
+      std::set<Ogre::Node*> targetSet_;
+      float distance_;
+  };
+
+}
+
+#endif /* _Trigger_H__ */
Index: code/branches/objecthierarchy/src/orxonox/objects/Script.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/Script.cc	(revision 1959)
+++ code/branches/objecthierarchy/src/orxonox/objects/Script.cc	(revision 1959)
@@ -0,0 +1,70 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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.
+ *
+ *   Author:
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "Script.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "core/LuaBind.h"
+#include "core/Debug.h"
+
+namespace orxonox
+{
+  CreateFactory(Script);
+
+  Script::Script()
+  {
+    RegisterObject(Script);
+
+    code_ = "";
+  }
+
+  Script::~Script()
+  {
+  }
+
+  /**
+  @brief XML loading and saving.
+  @param xmlelement The XML-element
+  @param loading Loading (true) or saving (false)
+   */
+  void Script::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+  {
+    BaseObject::XMLPort(xmlelement, mode);
+
+    code_ = xmlelement.GetText(false);
+  }
+
+  void Script::execute()
+  {
+    LuaBind* lua = LuaBind::getInstance();
+    lua->loadString(this->code_);
+    lua->run();
+  }
+}
Index: code/branches/objecthierarchy/src/orxonox/objects/Script.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/Script.h	(revision 1959)
+++ code/branches/objecthierarchy/src/orxonox/objects/Script.h	(revision 1959)
@@ -0,0 +1,51 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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.
+ *
+ *   Author:
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Script_H__
+#define _Script_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+  class _OrxonoxExport Script : public BaseObject
+  {
+    public:
+      Script();
+      ~Script();
+      void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+      void execute();
+
+    private:
+      std::string code_;
+  };
+}
+
+#endif /* _Script_H__ */
Index: code/branches/objecthierarchy/src/orxonox/objects/Trigger.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/Trigger.cc	(revision 1959)
+++ code/branches/objecthierarchy/src/orxonox/objects/Trigger.cc	(revision 1959)
@@ -0,0 +1,290 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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.
+ *
+ *   Author:
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "Trigger.h"
+
+#include <OgreBillboard.h>
+#include "core/Debug.h"
+#include "core/CoreIncludes.h"
+#include "core/ConsoleCommand.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+
+  ConsoleCommand(Trigger, setVisibility, AccessLevel::Debug, false).setDefaultValues(0);
+
+  CreateFactory(Trigger);
+
+  Trigger::Trigger()
+  {
+    RegisterObject(Trigger);
+
+    mode_ = TM_EventTriggerAND;
+    bActive_ = false;
+    bInvertMode_ = false;
+    delay_ = 0.0;
+    bTriggered_ = false;
+    bUpdating_ = false;
+    remainingActivations_ = -1;
+    bStayOn_ = false;
+    latestState_ = 0x0;
+
+    debugBillboard_.setBillboardSet("Examples/Flare", ColourValue(1.0, 0.0, 0.0), 1);
+    this->getNode()->attachObject(debugBillboard_.getBillboardSet());
+  }
+
+  Trigger::~Trigger()
+  {
+  }
+
+  void Trigger::init()
+  {
+    this->setVisibility(true);
+    timeSinceLastEvent_ = delay_;
+  }
+
+  void Trigger::setVisibility(bool bVisible)
+  {
+    if(bVisible)
+      this->setScale(2,2,2);
+    else
+      this->setScale(0,0,0);
+  }
+
+  const Trigger* Trigger::getTrigger(unsigned int index) const
+  {
+    if (children_.size() <= index)
+      return NULL;
+
+    std::set<Trigger*>::iterator it;
+    it = children_.begin();
+
+    for ( unsigned int i = 0; i != index; i++ )
+    {
+      it++;
+    }
+    return *it;
+  }
+
+  void Trigger::tick(float dt)
+  {
+
+    bool newTriggered;
+    newTriggered = this->isTriggered();
+
+    // check if new triggering event is really new
+    if((this->latestState_ & 0x1) != newTriggered)
+    {
+      // create new state
+      if(newTriggered)
+      {
+        latestState_ |= 1; // set trigger bit
+        this->switchState();
+      }
+      else
+      {
+        latestState_ &= 0xFE; // set trigger bit
+        if (this->bStayOn_)
+          this->storeState();
+        else
+          this->switchState();
+      }
+    }
+
+    if(remainingTime_ > 0.0)
+    {
+      remainingTime_ -= dt;
+      // only increase when acctually waiting for a state in the queue
+      if(timeSinceLastEvent_ >= 0.0)
+        timeSinceLastEvent_ += dt;
+    }
+
+    while(remainingTime_ <= 0.0 && stateChanges_.size() > 0)
+    {
+      // time ran out, change state to new one
+      char newState = stateChanges_.front().second;
+      bTriggered_ = (newState & 0x1);
+      bActive_ = newState & 2;
+      this->stateChanges_.pop();
+      if(stateChanges_.size() != 0)
+        remainingTime_ = stateChanges_.front().first;
+      else
+        timeSinceLastEvent_ = delay_;
+    }
+
+
+
+    if (bTriggered_ && bActive_)
+      this->setBillboardColour(ColourValue(0.5, 1.0, 0.0));
+    else if (!bTriggered_ && bActive_)
+      this->setBillboardColour(ColourValue(0.0, 1.0, 0.0));
+    else if (bTriggered_ && !bActive_)
+      this->setBillboardColour(ColourValue(1.0, 0.5, 0.0));
+    else
+      this->setBillboardColour(ColourValue(1.0, 0.0, 0.0));
+    bUpdating_ = false;
+  }
+
+  void Trigger::setBillboardColour(ColourValue colour)
+  {
+    this->debugBillboard_.getBillboardSet()->getBillboard(0)->setColour(colour);
+  }
+
+  void Trigger::storeState()
+  {
+    // put state change into queue
+    this->stateChanges_.push(std::pair<float,char>(timeSinceLastEvent_, latestState_));
+    // reset time since last event
+    timeSinceLastEvent_ = 0.0;
+
+    if(this->stateChanges_.size() == 1)
+      remainingTime_ = stateChanges_.front().first;
+  }
+
+  bool Trigger::isTriggered(TriggerMode mode)
+  {
+    if(bUpdating_)
+      return bTriggered_;
+
+    if( children_.size() != 0 )
+    {
+      bUpdating_ = true;
+      bool returnval = false;
+      switch(mode)
+      {
+        case TM_EventTriggerAND:
+          returnval = checkAnd();
+          break;
+        case TM_EventTriggerOR:
+          returnval = checkOr();
+          break;
+        case TM_EventTriggerXOR:
+          returnval = checkXor();
+          break;
+        default:
+          returnval = false;
+          break;
+      }
+      if(bInvertMode_)
+        return !returnval;
+      else
+        return returnval;
+    }
+    return true;
+  }
+
+  void Trigger::setDelay(float delay)
+  {
+    this->delay_ = delay;
+  }
+
+  void Trigger::setMode(std::string modeName)
+  {
+    if (modeName == "and")
+      setMode(TM_EventTriggerAND);
+    else if (modeName == "or")
+      setMode(TM_EventTriggerOR);
+    else if (modeName == "xor")
+      setMode(TM_EventTriggerXOR);
+  }
+
+  void Trigger::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+  {
+    WorldEntity::XMLPort(xmlelement, mode);
+
+    XMLPortParamLoadOnly(Trigger, "delay", setDelay, xmlelement, mode);
+    XMLPortParamLoadOnly(Trigger, "stayOn", setStayOn, xmlelement, mode);
+    XMLPortParamLoadOnly(Trigger, "activations", setActivations, xmlelement, mode);
+    XMLPortParamLoadOnly(Trigger, "invert", setInvert, xmlelement, mode);
+    //XMLPortParamLoadOnlyTemplate(Trigger, "mode", setMode, xmlelement, mode, std::string);
+
+    XMLPortObject(Trigger, Trigger, "", addTrigger, getTrigger, xmlelement, mode, false, true);
+
+    this->init();
+  }
+
+  void Trigger::addTrigger(Trigger* trig)
+  {
+    if (this != trig)
+      this->children_.insert(trig);
+  }
+
+  bool Trigger::switchState()
+  {
+    if ( remainingActivations_ <= -1 || this->latestState_ & 2 || remainingActivations_ > 0)
+    {
+      this->latestState_ ^= 2; // toggle state bit
+      // increase activation count
+      if (this->latestState_ & 2) remainingActivations_--;
+      this->storeState();
+
+      return true;
+    }
+    return false;
+  }
+
+
+  bool Trigger::checkAnd()
+  {
+    std::set<Trigger*>::iterator it;
+    for(it = this->children_.begin(); it != this->children_.end(); it++)
+    {
+      if(!((*it)->isActive()))
+        return false;
+    }
+    return true;
+  }
+
+  bool Trigger::checkOr()
+  {
+    std::set<Trigger*>::iterator it;
+    for(it = this->children_.begin(); it != this->children_.end(); it++)
+    {
+      if((*it)->isActive())
+        return true;
+    }
+    return false;
+  }
+
+  bool Trigger::checkXor()
+  {
+    std::set<Trigger*>::iterator it;
+    bool test = false;
+    for(it = this->children_.begin(); it != this->children_.end(); it++)
+    {
+      if(test && (*it)->isActive())
+        return false;
+      if((*it)->isActive())
+        test = true;
+    }
+    return test;
+  }
+
+}
Index: code/branches/objecthierarchy/src/orxonox/objects/Trigger.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/Trigger.h	(revision 1959)
+++ code/branches/objecthierarchy/src/orxonox/objects/Trigger.h	(revision 1959)
@@ -0,0 +1,102 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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.
+ *
+ *   Author:
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Trigger_H__
+#define _Trigger_H__
+
+#include <set>
+#include <queue>
+
+#include "OrxonoxPrereqs.h"
+
+#include "WorldEntity.h"
+
+#include "../tools/BillboardSet.h"
+
+namespace orxonox {
+
+  enum TriggerMode
+  {
+    TM_EventTriggerAND,
+    TM_EventTriggerOR,
+    TM_EventTriggerXOR,
+  };
+
+  class _OrxonoxExport Trigger : public WorldEntity
+  {
+    public:
+      Trigger();
+      ~Trigger();
+
+      inline bool isActive() { return bActive_; }
+      void addTrigger(Trigger* trig);
+      void setInvert(int invert) { bInvertMode_ = invert; }
+      const Trigger* getTrigger(unsigned int index) const;
+      void setVisibility(bool bVisible);
+      void setDelay(float delay);
+      bool switchState();
+      virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+      inline TriggerMode getMode() { return mode_; }
+      inline void setMode(TriggerMode mode) { this->mode_ = mode; }
+      void setMode(std::string modeName);
+      inline void setStayOn(int stayOn) { if (stayOn == 1) this->bStayOn_ = true; else this->bStayOn_ = false; }
+      inline void setActivations(int activations) { this->remainingActivations_ = activations; }
+      void tick(float dt);
+
+    private:
+      void init();
+      bool checkAnd();
+      bool checkOr();
+      bool checkXor();
+      void setBillboardColour(ColourValue colour);
+      void storeState();
+
+    protected:
+      inline bool isTriggered() { return this->isTriggered(this->mode_); }
+      virtual bool isTriggered(TriggerMode mode);
+
+    private:
+      std::set<Trigger*> children_;
+      std::queue<std::pair<float,char> > stateChanges_;
+      float remainingTime_;
+      float timeSinceLastEvent_;
+      TriggerMode mode_;
+      bool bActive_;
+      bool bInvertMode_;
+      bool bTriggered_;
+      bool bUpdating_;
+      BillboardSet debugBillboard_;
+      float delay_;
+      int remainingActivations_;
+      bool bStayOn_;
+      char latestState_;
+  };
+
+}
+
+#endif /* _Trigger_H__ */
