Index: /trunk/src/world_entities/environments/mover.cc
===================================================================
--- /trunk/src/world_entities/environments/mover.cc	(revision 10696)
+++ /trunk/src/world_entities/environments/mover.cc	(revision 10696)
@@ -0,0 +1,353 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2007 orx
+
+   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, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Fabian 'x3n' Landau
+   co-programmer:
+*/
+
+#include "sound/resource_sound_buffer.h"
+#include "sound_engine.h"
+#include "util/loading/load_param_xml.h"
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "mover.h"
+
+#define CLOSED 0
+#define OPEN 1
+#define MOVE 2
+#define WAIT 3
+#define NEXT 4
+#define DELAY 5
+#define STAY 6
+
+ObjectListDefinition(Mover);
+CREATE_FACTORY(Mover);
+
+
+Mover::Mover(const TiXmlElement* root)
+{
+    PRINTF(0)("1_1 Mover %p created\n", this);
+    this->registerObject(this, Mover::_objectList);
+    this->toList(OM_ENVIRON);
+
+    this->bLoop = false;
+    this->bRepeat = false;
+    this->bWaitAfterEachStation = false;
+    this->bOnlyMoveWhileTriggered = false;
+    this->bAttachTrigger = false;
+    this->bReopen = false;
+    this->bReclose = false;
+    
+    this->triggers = 0;
+    this->stations = 0;
+
+    this->repeats = 0;
+    this->state = CLOSED;
+    this->station = 0;
+    this->repeatsToGo = 0;
+    this->time = 0;
+    
+    this->originCoor = Vector(0, 0, 0);
+    this->originDir = Vector(0, 0, 0);
+
+    this->soundSource_starting.setSourceNode(this);
+    this->soundSource_moving.setSourceNode(this);
+    this->soundSource_ending.setSourceNode(this);
+
+    PRINTF(0)("1_2\n");
+    if (root != NULL)
+        this->loadParams(root);
+        
+    this->updateNode(0.001);
+        
+    this->originCoor = this->getAbsCoor();
+    this->originDir = this->getAbsDir().getRotation();
+
+    PRINTF(0)("1_3\n");
+    if (this->stations)
+        this->station = this->stations->getNextStation(0);
+    PRINTF(0)("1_4\n");
+    if (this->triggers)
+        this->triggers->setBaseCoor(this->getAbsCoor());
+    PRINTF(0)("1_5\n");
+}
+
+Mover::~Mover()
+{
+    if (this->triggers)
+        delete this->triggers;
+    if (this->stations)
+        delete this->stations;
+    
+    if (this->soundSource_starting.isPlaying())
+        this->soundSource_starting.stop();
+    if (this->soundSource_moving.isPlaying())
+        this->soundSource_moving.stop();
+    if (this->soundSource_ending.isPlaying())
+        this->soundSource_ending.stop();
+}
+
+void Mover::loadParams(const TiXmlElement* root)
+{
+    PRINTF(0)("2_1\n");
+    WorldEntity::loadParams(root);
+
+    LoadParam(root, "bLoop", this, Mover, setLoop)
+        .describe("After getting triggered, the mover loops forever.")
+        .defaultValues(false);
+    LoadParam(root, "bRepeat", this, Mover, setRepeat)
+        .describe("After getting triggered, the mover moves n times.")
+        .defaultValues(1);
+    LoadParam(root, "bWaitAfterEachStation", this, Mover, setWaitAfterEachStation)
+        .describe("After each station, the mover waits until he gets triggered.")
+        .defaultValues(false);
+    LoadParam(root, "bOnlyMoveWhileTriggered", this, Mover, setOnlyMoveWhileTriggered)
+        .describe("The mover stops as soon as he gets untriggered.")
+        .defaultValues(false);
+    LoadParam(root, "bAttachTrigger", this, Mover, setAttachTrigger)
+        .describe("The trigger follows the mover.")
+        .defaultValues(false);
+    LoadParam(root, "bReopen", this, Mover, setReopen)
+        .describe("Stops closing and reopens the mover when he gets triggered again.")
+        .defaultValues(false);
+    LoadParam(root, "bReclose", this, Mover, setReclose)
+        .describe("Stops opening and recloses the mover when he gets untriggered.")
+        .defaultValues(false);
+    PRINTF(0)("2_2\n");
+    LoadParamXML(root, "triggers", this, Mover, setTriggers)
+        .describe("Adds a trigger that releases the mover.");
+    PRINTF(0)("2_3\n");
+    LoadParamXML(root, "stations", this, Mover, setStations)
+        .describe("Adds a station to the movers stations-list.");
+    PRINTF(0)("2_4\n");
+}
+
+void Mover::setTriggers(const TiXmlElement* root)
+{
+    PRINTF(0)("3_1\n");
+    this->triggers = new MoverTriggerList();
+    const TiXmlElement* element = root->FirstChildElement();
+    
+    PRINTF(0)("3_2\n");
+    while (element != NULL)
+    {
+        PRINTF(0)("3_3\n");
+//        PRINTF(0)("TiXmlElement Value:   %s\n", element->Value());
+        BaseObject *newObj = Factory::fabricate(element);
+//        PRINTF(0)("BaseObject ClassName: %s\n", newObj->getClassCName());
+//        MoverTrigger *newTrigger = ((MoverTrigger*)(&newObj));
+        MoverTrigger *newTrigger = (dynamic_cast< MoverTrigger *> ( newObj ));
+        this->triggers->addTrigger(newTrigger);
+//        this->triggers->addTrigger(MoverTrigger::createTrigger(element));
+        PRINTF(0)("3_4\n");
+        element = element->NextSiblingElement();
+        PRINTF(0)("3_5\n");
+    }
+    PRINTF(0)("3_6\n");
+}
+
+void Mover::setStations(const TiXmlElement* root)
+{
+    PRINTF(0)("4_1\n");
+    this->stations = new MoverStationList();
+    const TiXmlElement* element = root->FirstChildElement();
+
+    PRINTF(0)("4_2\n");
+    while (element != NULL)
+    {
+        PRINTF(0)("4_3\n");
+        this->stations->addStation(new MoverStation(element));
+        element = element->NextSiblingElement();
+    }
+    PRINTF(0)("4_4\n");
+}
+
+void Mover::tick(float dt)
+{
+//    PRINTF(0)("15_1 mover state of mover %p is %i, triggerlist is %p\n", this, this->state, this->triggers);
+    if (this->state == DELAY || this->state == MOVE || this->state == STAY)
+        this->time += dt;
+
+    if (this->state == NEXT)
+        this->changeState(this->next());
+        
+    if (this->state == WAIT)
+        this->changeState(this->wait());
+        
+    if (this->state == CLOSED)
+        this->changeState(this->closed());
+
+    if (this->state == OPEN)
+        this->changeState(this->open());
+
+    if (this->state == DELAY)
+        this->changeState(this->delay());
+
+    if (this->state == MOVE)
+        this->changeState(this->move(dt));
+
+    if (this->state == STAY)
+        this->changeState(this->stay());
+}
+
+void Mover::changeState(int state)
+{
+    if (this->state == state)
+        return;
+        
+    this->state = state;
+    
+    if (this->state == DELAY || this->state == STAY)
+        this->time = 0;
+}
+
+int Mover::closed()
+{
+    if (this->triggers && this->triggers->isTriggered())
+    {
+        if (this->bRepeat)
+            this->repeatsToGo = this->repeats;
+            
+        return DELAY;
+    }
+
+    return CLOSED;
+}
+
+int Mover::open()
+{
+    if (this->triggers && !this->triggers->isTriggered())
+    {
+        return DELAY;
+    }
+
+    return OPEN;
+}
+
+int Mover::wait()
+{
+    if (this->triggers && this->triggers->isTriggered())
+    {
+        this->soundSource_moving.play(this->stations->getMovingSound(this->station), OrxSound::SoundEngine::getInstance()->getEffectsVolume(), 0.5, true);
+        return MOVE;
+    }
+
+    return WAIT;
+}
+
+int Mover::next()
+{
+    bool isOpen = false;
+    bool isClosed = false;
+    if (this->stations)
+    {
+        isOpen = this->stations->isOpen(station);
+        isClosed = this->stations->isClosed(station);
+        this->station = this->stations->getNextStation(this->station);
+    }
+
+    if (isClosed && this->bRepeat)
+        this->repeatsToGo--;
+        
+    if (isClosed && (!this->bLoop && this->repeatsToGo <= 0))
+        return CLOSED;
+
+    if (isOpen && (!this->bLoop && this->repeatsToGo <= 0))
+        return OPEN;
+
+    if (this->bWaitAfterEachStation)
+        return WAIT;
+
+    if ((this->bLoop || this->repeats > 0) || (!isOpen && !isClosed))
+        return DELAY;
+        
+    return NEXT;
+}
+
+int Mover::delay()
+{
+    if (!this->stations || (this->time < this->stations->getDelay(this->station)))
+        return DELAY;
+
+    if (this->stations->getStartingSound(this->station).loaded())
+        this->soundSource_starting.play(this->stations->getStartingSound(this->station), OrxSound::SoundEngine::getInstance()->getEffectsVolume(), 0.5);
+    if (this->stations->getMovingSound(this->station).loaded())
+        this->soundSource_moving.play(this->stations->getMovingSound(this->station), OrxSound::SoundEngine::getInstance()->getEffectsVolume(), 0.5, true);
+
+    this->time = 0;
+    
+    return MOVE;
+}
+
+int Mover::move(float dt)
+{
+    if (this->stations)
+    {
+        this->setAbsCoor(this->originCoor + this->stations->getVelocity(this->station) * this->time);
+        this->setAbsDir(VtoQ(this->originDir + this->stations->getRotation(this->station) * this->time));
+    }
+    
+    if (this->bAttachTrigger && this->triggers)
+        this->triggers->setBaseCoor(this->getAbsCoor());
+
+    if (!this->bLoop && this->repeatsToGo <= 0)
+    {
+        if (this->stations && this->triggers && this->stations->changeDirection(this->bReopen, this->bReclose, this->triggers->isTriggered()))
+        {
+            this->time = this->stations->getMovingTime(this->station) - this->time;
+            this->originCoor = this->originCoor - this->stations->getRelTargetCoor(this->station);
+            this->originDir = this->originDir - this->stations->getRelTargetDir(this->station);
+        }
+    }
+
+    if (/*this->reachedStationsTarget(dt) || */(this->stations && (this->time >= 1.0 * this->stations->getMovingTime(this->station))))
+//    if (this->stations && (this->time >= this->stations->getMovingTime(this->station)))
+    {
+        this->setAbsCoor(this->originCoor + this->stations->getRelTargetCoor(this->station));
+        this->setAbsDir(VtoQ(this->originDir + this->stations->getRelTargetDir(this->station)));
+
+        if (this->stations->getEndingSound(this->station).loaded())
+            this->soundSource_ending.play(this->stations->getEndingSound(this->station), OrxSound::SoundEngine::getInstance()->getEffectsVolume(), 0.5);
+        this->soundSource_moving.stop();
+
+        this->originCoor = this->originCoor + this->stations->getRelTargetCoor(this->station);
+        this->originDir = this->originDir + this->stations->getRelTargetDir(this->station);
+        
+        return STAY;
+    }
+        
+    if (this->triggers && this->bOnlyMoveWhileTriggered && (!this->triggers->isTriggered()))
+    {
+        this->soundSource_moving.stop();
+        return WAIT;
+    }
+
+    return MOVE;
+}
+
+int Mover::stay()
+{
+    if (!this->stations || (this->time < this->stations->getStayOpenTime(this->station)))
+        return STAY;
+
+    return NEXT;
+}
+
+bool Mover::reachedStationsTarget(float dt)
+{
+    if (this->stations)
+        if ((this->getAbsCoor() - (this->originCoor + this->stations->getRelTargetCoor(this->station))).len() <= 1.2 * (this->stations->getVelocity(this->station) * dt).len())
+            if ((this->getAbsDir().getRotation() - (this->originDir + this->stations->getRelTargetDir(this->station))).len() <= 1.2 * (this->stations->getRotation(this->station) * dt).len())
+                return true;
+
+    return false;
+}
+
Index: /trunk/src/world_entities/environments/mover.diff
===================================================================
--- /trunk/src/world_entities/environments/mover.diff	(revision 10696)
+++ /trunk/src/world_entities/environments/mover.diff	(revision 10696)
@@ -0,0 +1,2757 @@
+Index: mover_trigger_list.cc
+===================================================================
+--- mover_trigger_list.cc	(revision 0)
++++ mover_trigger_list.cc	(revision 0)
+@@ -0,0 +1,126 @@
++/*
++   orxonox - the future of 3D-vertical-scrollers
++
++   Copyright (C) 2007 orx
++
++   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, or (at your option)
++   any later version.
++
++   ### File Specific:
++   main-programmer: Fabian 'x3n' Landau
++   co-programmer:
++*/
++
++#include "mover_trigger_list.h"
++#include "debug.h"
++
++
++MoverTriggerList::MoverTriggerList()
++{
++    PRINTF(0)("10_1 MoverTriggerList %p created\n", this);
++    this->first = 0;
++    PRINTF(0)("10_2 first element: %p\n", this->first);
++}
++
++MoverTriggerList::~MoverTriggerList()
++{
++    PRINTF(0)("13_1 MoverTriggerList %p destroyed\n", this);
++    MoverTriggerListElement *temp1 = this->first;
++    MoverTriggerListElement *temp2;
++    while (temp1 != 0)
++    {
++        temp2 = temp1->next;
++        delete temp1;
++        temp1 = temp2;
++    }
++}
++
++void MoverTriggerList::addTrigger(MoverTrigger *trigger)
++{
++    PRINTF(0)("11_1 added trigger %p to list %p\n", trigger, this);
++    if (trigger)
++    {
++        if (this->first == 0)
++        {
++            PRINTF(0)("11_2\n");
++            this->first = new MoverTriggerListElement(trigger);
++        }
++        else
++        {
++            PRINTF(0)("11_3\n");
++            MoverTriggerListElement *temp = this->first;
++            while (temp->next != 0)
++                temp = temp->next;
++
++            temp->next = new MoverTriggerListElement(trigger);
++            PRINTF(0)("11_4\n");
++        }
++    }
++    PRINTF(0)("11_5\n");
++}
++
++bool MoverTriggerList::isTriggered()
++{
++//    PRINTF(0)("16_1\n");
++    if (this->first == 0)
++    {
++//        PRINTF(0)("16_2\n");
++        return true;
++    }
++    else
++    {
++//        PRINTF(0)("16_3\n");
++        bool isTriggered = false;
++        MoverTriggerListElement *temp = this->first;
++
++        while (temp != 0)
++        {
++            if (temp->trigger->isTriggered())
++            {
++                isTriggered = true;
++            }
++            else
++            {
++                if (temp->trigger->isObligatory())
++                    return false;
++            }
++                    
++            temp = temp->next;
++        }
++
++//        PRINTF(0)("16_4\n");
++        return isTriggered;
++    }
++}
++
++void MoverTriggerList::setBaseCoor(Vector baseCoor)
++{
++//    PRINTF(0)("12_1 set base coor in %p\n", this);
++//    PRINTF(0)("12_2 first element: %p\n", this->first);
++    MoverTriggerListElement *temp = this->first;
++    while (temp != 0)
++    {
++//        PRINTF(0)("12_3\n");
++        temp->trigger->setBaseCoor(baseCoor);
++        temp = temp->next;
++    }
++//    PRINTF(0)("12_4\n");
++}
++
++
++////////////////////////////////////////////////////////
++
++
++MoverTriggerListElement::MoverTriggerListElement(MoverTrigger *trigger)
++{
++    this->trigger = trigger;
++    this->next = 0;
++}
++
++MoverTriggerListElement::~MoverTriggerListElement()
++{
++    if (this->trigger)
++        delete this->trigger;
++}
+Index: mover_trigger_pointer_list.cc
+===================================================================
+--- mover_trigger_pointer_list.cc	(revision 0)
++++ mover_trigger_pointer_list.cc	(revision 0)
+@@ -0,0 +1,97 @@
++/*
++   orxonox - the future of 3D-vertical-scrollers
++
++   Copyright (C) 2007 orx
++
++   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, or (at your option)
++   any later version.
++
++   ### File Specific:
++   main-programmer: Fabian 'x3n' Landau
++   co-programmer:
++*/
++
++#include "mover_trigger_pointer_list.h"
++#include "debug.h"
++
++
++MoverTriggerPointerList::MoverTriggerPointerList()
++{
++    this->first = 0;
++}
++
++MoverTriggerPointerList::~MoverTriggerPointerList()
++{
++    MoverTriggerPointerListElement *temp1 = this->first;
++    MoverTriggerPointerListElement *temp2;
++    while (temp1 != 0)
++    {
++        temp2 = temp1->next;
++        delete temp1;
++        temp1 = temp2;
++    }
++}
++
++void MoverTriggerPointerList::addTrigger(MoverTrigger *trigger)
++{
++    if (trigger)
++    {
++        if (this->first == 0)
++        {
++            this->first = new MoverTriggerPointerListElement(trigger);
++        }
++        else
++        {
++            MoverTriggerPointerListElement *temp = this->first;
++            while (temp->next != 0)
++                temp = temp->next;
++
++            temp->next = new MoverTriggerPointerListElement(trigger);
++        }
++    }
++}
++
++bool MoverTriggerPointerList::isTriggered()
++{
++    if (this->first == 0)
++    {
++        return false;
++    }
++    else
++    {
++        bool isTriggered = false;
++        MoverTriggerPointerListElement *temp = this->first;
++
++        while (temp != 0)
++        {
++            if (temp->trigger->isTriggered())
++            {
++                isTriggered = true;
++            }
++            else
++            {
++                if (temp->trigger->isObligatory())
++                    return false;
++            }
++                    
++            temp = temp->next;
++        }
++
++        return isTriggered;
++    }
++}
++
++////////////////////////////////////////////////////////
++
++
++MoverTriggerPointerListElement::MoverTriggerPointerListElement(MoverTrigger *trigger)
++{
++    this->trigger = trigger;
++    this->next = 0;
++}
++
++MoverTriggerPointerListElement::~MoverTriggerPointerListElement()
++{
++}
+Index: mover_trigger_event.h
+===================================================================
+--- mover_trigger_event.h	(revision 0)
++++ mover_trigger_event.h	(revision 0)
+@@ -0,0 +1,31 @@
++/*!
++ * @file mover_trigger_event.h
++ *  Gets triggered when a specific event occurs.
++ */
++
++#ifndef _MOVER_TRIGGER_EVENT_H
++#define _MOVER_TRIGGER_EVENT_H
++
++#include "mover_trigger.h"
++
++
++class EventTrigger : public MoverTrigger
++{
++    ObjectListDeclaration(EventTrigger);
++
++    public:
++        EventTrigger(const TiXmlElement* root = NULL);
++        virtual ~EventTrigger();
++        virtual void loadParams(const TiXmlElement* root);
++        void setEvent(const std::string& eventName) { this->eventName = eventName; }
++
++    private:
++        virtual bool checkIsTriggered();
++        std::string                 eventName;
++        MoverTriggerPointerList     *eventTriggers;
++        bool                        bIsChecking;
++};
++
++
++#endif
++
+Index: mover_trigger_key.cc
+===================================================================
+--- mover_trigger_key.cc	(revision 0)
++++ mover_trigger_key.cc	(revision 0)
+@@ -0,0 +1,49 @@
++/*
++   orxonox - the future of 3D-vertical-scrollers
++
++   Copyright (C) 2007 orx
++
++   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, or (at your option)
++   any later version.
++
++   ### File Specific:
++   main-programmer: Fabian 'x3n' Landau
++   co-programmer:
++*/
++
++#include "util/loading/load_param.h"
++#include "util/loading/factory.h"
++#include "mover_trigger_key.h"
++
++ObjectListDefinition(KeyTrigger);
++CREATE_FACTORY(KeyTrigger);
++
++
++KeyTrigger::KeyTrigger(const TiXmlElement* root)
++{
++    this->registerObject(this, KeyTrigger::_objectList);
++    this->toList(OM_ENVIRON);
++    this->keyName = "";
++
++    if (root != NULL)
++        this->loadParams(root);
++
++    this->init_post_params();
++}
++
++void KeyTrigger::loadParams(const TiXmlElement* root)
++{
++    MoverTrigger::loadParams(root);
++
++    LoadParam(root, "key", this, KeyTrigger, setKey)
++        .describe("The key that releases the trigger")
++        .defaultValues("");
++}
++
++bool KeyTrigger::checkIsTriggered()
++{
++    /* TODO */
++    return false;
++}
+Index: mover_trigger_delay_list.cc
+===================================================================
+--- mover_trigger_delay_list.cc	(revision 0)
++++ mover_trigger_delay_list.cc	(revision 0)
+@@ -0,0 +1,91 @@
++/*
++   orxonox - the future of 3D-vertical-scrollers
++
++   Copyright (C) 2007 orx
++
++   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, or (at your option)
++   any later version.
++
++   ### File Specific:
++   main-programmer: Fabian 'x3n' Landau
++   co-programmer:
++*/
++
++#include "mover_trigger_list.h"
++
++
++MoverTriggerDelayList::MoverTriggerDelayList()
++{
++    this->first = 0;
++}
++
++MoverTriggerDelayList::~MoverTriggerDelayList()
++{
++    while (this->first)
++        this->deleteFirstState();
++}
++
++void MoverTriggerDelayList::addState(bool state, bool oldState, float time)
++{
++    if (this->first == 0)
++        this->first = new MoverTriggerDelayListElement(state, oldState, time);
++    else
++    {
++        MoverTriggerDelayListElement *temp = this->first;
++        while (temp->next != 0)
++            temp = temp->next;
++            
++        temp->next = new MoverTriggerDelayListElement(state, oldState, time);
++    }
++}
++
++void MoverTriggerDelayList::deleteFirstState()
++{
++    if (this->first != 0)
++    {
++        MoverTriggerDelayListElement *temp = this->first->next;
++        delete this->first;
++        this->first = temp;
++    }
++}
++
++MoverTriggerDelayListElement *MoverTriggerDelayList::getFirstState()
++{
++    return this->first;
++}
++
++MoverTriggerDelayListElement *MoverTriggerDelayList::getLastState()
++{
++    MoverTriggerDelayListElement *temp = this->first;
++    while (temp != 0)
++    {
++        if (temp->next == 0)
++            return temp;
++            
++        temp = temp->next;
++    }
++            
++    return 0;
++}
++
++bool MoverTriggerDelayList::isEmpty()
++{
++    return (this->first == 0);
++}
++
++////////////////////////////////////////////////////////
++
++
++MoverTriggerDelayListElement::MoverTriggerDelayListElement(bool state, bool oldState, float time)
++{
++    this->state = state;
++    this->oldState = oldState;
++    this->time = time;
++    this->next = 0;
++}
++
++MoverTriggerDelayListElement::~MoverTriggerDelayListElement()
++{
++}
+Index: mover_trigger_key.h
+===================================================================
+--- mover_trigger_key.h	(revision 0)
++++ mover_trigger_key.h	(revision 0)
+@@ -0,0 +1,28 @@
++/*!
++ * @file mover_trigger_key.h
++ *  Gets triggered when player presses a key.
++ */
++
++#ifndef _MOVER_TRIGGER_KEY_H
++#define _MOVER_TRIGGER_KEY_H
++
++#include "mover_trigger.h"
++
++
++class KeyTrigger : public MoverTrigger
++{
++    ObjectListDeclaration(KeyTrigger);
++
++    public:
++        KeyTrigger(const TiXmlElement* root = NULL);
++        virtual void loadParams(const TiXmlElement* root);
++        void setKey(const std::string& keyName) { this->keyName = keyName; }
++
++    private:
++        virtual bool checkIsTriggered();
++        std::string keyName;
++};
++
++
++#endif
++
+Index: mover_trigger_intervisibility.h
+===================================================================
+--- mover_trigger_intervisibility.h	(revision 0)
++++ mover_trigger_intervisibility.h	(revision 0)
+@@ -0,0 +1,30 @@
++/*!
++ * @file mover_trigger_intervisibility.h
++ *  Gets triggered when the trigger "sees" the player.
++ */
++
++#ifndef _MOVER_TRIGGER_INTERVISIBILITY_H
++#define _MOVER_TRIGGER_INTERVISIBILITY_H
++
++#include "mover_trigger.h"
++
++
++class IntervisibilityTrigger : public MoverTrigger
++{
++    ObjectListDeclaration(IntervisibilityTrigger);
++
++    public:
++        IntervisibilityTrigger(const TiXmlElement* root = NULL);
++        virtual void loadParams(const TiXmlElement* root);
++        void setOnlyHumans(bool onlyHumans = true) { this->onlyHumans = onlyHumans; }
++        void setOnlyNPCs(bool onlyNPCs = true) { this->onlyNPCs = onlyNPCs; }
++
++    private:
++        virtual bool checkIsTriggered();
++        bool onlyHumans;
++        bool onlyNPCs;
++};
++
++
++#endif
++
+Index: mover_station_list.h
+===================================================================
+--- mover_station_list.h	(revision 0)
++++ mover_station_list.h	(revision 0)
+@@ -0,0 +1,59 @@
++/*!
++ * @file mover_station_list.h
++ *  A list to store and handle several stations.
++ */
++
++#ifndef _MOVER_STATION_LIST_H
++#define _MOVER_STATION_LIST_H
++
++#include "mover_station.h"
++#include "sound_buffer.h"
++
++
++class MoverStationListElement
++{
++    public:
++        MoverStationListElement(MoverStation *station);
++        ~MoverStationListElement();
++
++        MoverStation *station;
++        MoverStationListElement *next;
++        MoverStationListElement *prev;
++};
++
++
++class MoverStationList
++{
++    public:
++        MoverStationList();
++        ~MoverStationList();
++
++        void addStation(MoverStation *station);
++        MoverStation *getNextStation(MoverStation *station);
++        Vector getTotalRelCoor(MoverStation *station);
++        Vector getTotalRelDir(MoverStation *station);
++        bool isOpen(MoverStation *station);
++        bool isClosed(MoverStation *station);
++        bool changeDirection(bool bReopen, bool bRelocse, bool bIsTriggered);
++
++        Vector getRelTargetCoor(MoverStation *station);
++        Vector getRelTargetDir(MoverStation *station);
++        float getDelay(MoverStation *station) { return station->delay; }
++        float getStayOpenTime(MoverStation *station) { return station->stayOpenTime; }
++        float getMovingTime(MoverStation *station) { return station->movingTime; }
++        Vector getVelocity(MoverStation *station);
++        Vector getRotation(MoverStation *station);
++        OrxSound::SoundBuffer getStartingSound(MoverStation *station);
++        OrxSound::SoundBuffer getMovingSound(MoverStation *station);
++        OrxSound::SoundBuffer getEndingSound(MoverStation *station);
++
++    private:
++        MoverStation *getStation(int rank);
++        
++        MoverStationListElement *first;
++        MoverStationListElement *last;
++        bool goForward;
++};
++
++
++#endif
+Index: mover_trigger_mapstart.h
+===================================================================
+--- mover_trigger_mapstart.h	(revision 0)
++++ mover_trigger_mapstart.h	(revision 0)
+@@ -0,0 +1,27 @@
++/*!
++ * @file mover_trigger_mapstart.h
++ *  Gets triggered when the map starts.
++ */
++
++#ifndef _MOVER_TRIGGER_MAPSTART_H
++#define _MOVER_TRIGGER_MAPSTART_H
++
++#include "mover_trigger.h"
++
++
++class MapstartTrigger : public MoverTrigger
++{
++    ObjectListDeclaration(MapstartTrigger);
++
++    public:
++        MapstartTrigger(const TiXmlElement* root = NULL);
++        virtual void loadParams(const TiXmlElement* root);
++
++    private:
++        virtual bool checkIsTriggered();
++        bool bInit;
++};
++
++
++#endif
++
+Index: mover.cc
+===================================================================
+--- mover.cc	(revision 0)
++++ mover.cc	(revision 0)
+@@ -0,0 +1,353 @@
++/*
++   orxonox - the future of 3D-vertical-scrollers
++
++   Copyright (C) 2007 orx
++
++   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, or (at your option)
++   any later version.
++
++   ### File Specific:
++   main-programmer: Fabian 'x3n' Landau
++   co-programmer:
++*/
++
++#include "sound/resource_sound_buffer.h"
++#include "sound_engine.h"
++#include "util/loading/load_param_xml.h"
++#include "util/loading/load_param.h"
++#include "util/loading/factory.h"
++#include "mover.h"
++
++#define CLOSED 0
++#define OPEN 1
++#define MOVE 2
++#define WAIT 3
++#define NEXT 4
++#define DELAY 5
++#define STAY 6
++
++ObjectListDefinition(Mover);
++CREATE_FACTORY(Mover);
++
++
++Mover::Mover(const TiXmlElement* root)
++{
++    PRINTF(0)("1_1 Mover %p created\n", this);
++    this->registerObject(this, Mover::_objectList);
++    this->toList(OM_ENVIRON);
++
++    this->bLoop = false;
++    this->bRepeat = false;
++    this->bWaitAfterEachStation = false;
++    this->bOnlyMoveWhileTriggered = false;
++    this->bAttachTrigger = false;
++    this->bReopen = false;
++    this->bReclose = false;
++    
++    this->triggers = 0;
++    this->stations = 0;
++
++    this->repeats = 0;
++    this->state = CLOSED;
++    this->station = 0;
++    this->repeatsToGo = 0;
++    this->time = 0;
++    
++    this->originCoor = Vector(0, 0, 0);
++    this->originDir = Vector(0, 0, 0);
++
++    this->soundSource_starting.setSourceNode(this);
++    this->soundSource_moving.setSourceNode(this);
++    this->soundSource_ending.setSourceNode(this);
++
++    PRINTF(0)("1_2\n");
++    if (root != NULL)
++        this->loadParams(root);
++        
++    this->updateNode(0.001);
++        
++    this->originCoor = this->getAbsCoor();
++    this->originDir = this->getAbsDir().getRotation();
++
++    PRINTF(0)("1_3\n");
++    if (this->stations)
++        this->station = this->stations->getNextStation(0);
++    PRINTF(0)("1_4\n");
++    if (this->triggers)
++        this->triggers->setBaseCoor(this->getAbsCoor());
++    PRINTF(0)("1_5\n");
++}
++
++Mover::~Mover()
++{
++    if (this->triggers)
++        delete this->triggers;
++    if (this->stations)
++        delete this->stations;
++    
++    if (this->soundSource_starting.isPlaying())
++        this->soundSource_starting.stop();
++    if (this->soundSource_moving.isPlaying())
++        this->soundSource_moving.stop();
++    if (this->soundSource_ending.isPlaying())
++        this->soundSource_ending.stop();
++}
++
++void Mover::loadParams(const TiXmlElement* root)
++{
++    PRINTF(0)("2_1\n");
++    WorldEntity::loadParams(root);
++
++    LoadParam(root, "bLoop", this, Mover, setLoop)
++        .describe("After getting triggered, the mover loops forever.")
++        .defaultValues(false);
++    LoadParam(root, "bRepeat", this, Mover, setRepeat)
++        .describe("After getting triggered, the mover moves n times.")
++        .defaultValues(1);
++    LoadParam(root, "bWaitAfterEachStation", this, Mover, setWaitAfterEachStation)
++        .describe("After each station, the mover waits until he gets triggered.")
++        .defaultValues(false);
++    LoadParam(root, "bOnlyMoveWhileTriggered", this, Mover, setOnlyMoveWhileTriggered)
++        .describe("The mover stops as soon as he gets untriggered.")
++        .defaultValues(false);
++    LoadParam(root, "bAttachTrigger", this, Mover, setAttachTrigger)
++        .describe("The trigger follows the mover.")
++        .defaultValues(false);
++    LoadParam(root, "bReopen", this, Mover, setReopen)
++        .describe("Stops closing and reopens the mover when he gets triggered again.")
++        .defaultValues(false);
++    LoadParam(root, "bReclose", this, Mover, setReclose)
++        .describe("Stops opening and recloses the mover when he gets untriggered.")
++        .defaultValues(false);
++    PRINTF(0)("2_2\n");
++    LoadParamXML(root, "triggers", this, Mover, setTriggers)
++        .describe("Adds a trigger that releases the mover.");
++    PRINTF(0)("2_3\n");
++    LoadParamXML(root, "stations", this, Mover, setStations)
++        .describe("Adds a station to the movers stations-list.");
++    PRINTF(0)("2_4\n");
++}
++
++void Mover::setTriggers(const TiXmlElement* root)
++{
++    PRINTF(0)("3_1\n");
++    this->triggers = new MoverTriggerList();
++    const TiXmlElement* element = root->FirstChildElement();
++    
++    PRINTF(0)("3_2\n");
++    while (element != NULL)
++    {
++        PRINTF(0)("3_3\n");
++//        PRINTF(0)("TiXmlElement Value:   %s\n", element->Value());
++        BaseObject *newObj = Factory::fabricate(element);
++//        PRINTF(0)("BaseObject ClassName: %s\n", newObj->getClassCName());
++//        MoverTrigger *newTrigger = ((MoverTrigger*)(&newObj));
++        MoverTrigger *newTrigger = (dynamic_cast< MoverTrigger *> ( newObj ));
++        this->triggers->addTrigger(newTrigger);
++//        this->triggers->addTrigger(MoverTrigger::createTrigger(element));
++        PRINTF(0)("3_4\n");
++        element = element->NextSiblingElement();
++        PRINTF(0)("3_5\n");
++    }
++    PRINTF(0)("3_6\n");
++}
++
++void Mover::setStations(const TiXmlElement* root)
++{
++    PRINTF(0)("4_1\n");
++    this->stations = new MoverStationList();
++    const TiXmlElement* element = root->FirstChildElement();
++
++    PRINTF(0)("4_2\n");
++    while (element != NULL)
++    {
++        PRINTF(0)("4_3\n");
++        this->stations->addStation(new MoverStation(element));
++        element = element->NextSiblingElement();
++    }
++    PRINTF(0)("4_4\n");
++}
++
++void Mover::tick(float dt)
++{
++//    PRINTF(0)("15_1 mover state of mover %p is %i, triggerlist is %p\n", this, this->state, this->triggers);
++    if (this->state == DELAY || this->state == MOVE || this->state == STAY)
++        this->time += dt;
++
++    if (this->state == NEXT)
++        this->changeState(this->next());
++        
++    if (this->state == WAIT)
++        this->changeState(this->wait());
++        
++    if (this->state == CLOSED)
++        this->changeState(this->closed());
++
++    if (this->state == OPEN)
++        this->changeState(this->open());
++
++    if (this->state == DELAY)
++        this->changeState(this->delay());
++
++    if (this->state == MOVE)
++        this->changeState(this->move(dt));
++
++    if (this->state == STAY)
++        this->changeState(this->stay());
++}
++
++void Mover::changeState(int state)
++{
++    if (this->state == state)
++        return;
++        
++    this->state = state;
++    
++    if (this->state == DELAY || this->state == STAY)
++        this->time = 0;
++}
++
++int Mover::closed()
++{
++    if (this->triggers && this->triggers->isTriggered())
++    {
++        if (this->bRepeat)
++            this->repeatsToGo = this->repeats;
++            
++        return DELAY;
++    }
++
++    return CLOSED;
++}
++
++int Mover::open()
++{
++    if (this->triggers && !this->triggers->isTriggered())
++    {
++        return DELAY;
++    }
++
++    return OPEN;
++}
++
++int Mover::wait()
++{
++    if (this->triggers && this->triggers->isTriggered())
++    {
++        this->soundSource_moving.play(this->stations->getMovingSound(this->station), OrxSound::SoundEngine::getInstance()->getEffectsVolume(), 0.5, true);
++        return MOVE;
++    }
++
++    return WAIT;
++}
++
++int Mover::next()
++{
++    bool isOpen = false;
++    bool isClosed = false;
++    if (this->stations)
++    {
++        isOpen = this->stations->isOpen(station);
++        isClosed = this->stations->isClosed(station);
++        this->station = this->stations->getNextStation(this->station);
++    }
++
++    if (isClosed && this->bRepeat)
++        this->repeatsToGo--;
++        
++    if (isClosed && (!this->bLoop && this->repeatsToGo <= 0))
++        return CLOSED;
++
++    if (isOpen && (!this->bLoop && this->repeatsToGo <= 0))
++        return OPEN;
++
++    if (this->bWaitAfterEachStation)
++        return WAIT;
++
++    if ((this->bLoop || this->repeats > 0) || (!isOpen && !isClosed))
++        return DELAY;
++        
++    return NEXT;
++}
++
++int Mover::delay()
++{
++    if (!this->stations || (this->time < this->stations->getDelay(this->station)))
++        return DELAY;
++
++    if (this->stations->getStartingSound(this->station).loaded())
++        this->soundSource_starting.play(this->stations->getStartingSound(this->station), OrxSound::SoundEngine::getInstance()->getEffectsVolume(), 0.5);
++    if (this->stations->getMovingSound(this->station).loaded())
++        this->soundSource_moving.play(this->stations->getMovingSound(this->station), OrxSound::SoundEngine::getInstance()->getEffectsVolume(), 0.5, true);
++
++    this->time = 0;
++    
++    return MOVE;
++}
++
++int Mover::move(float dt)
++{
++    if (this->stations)
++    {
++        this->setAbsCoor(this->originCoor + this->stations->getVelocity(this->station) * this->time);
++        this->setAbsDir(VtoQ(this->originDir + this->stations->getRotation(this->station) * this->time));
++    }
++    
++    if (this->bAttachTrigger && this->triggers)
++        this->triggers->setBaseCoor(this->getAbsCoor());
++
++    if (!this->bLoop && this->repeatsToGo <= 0)
++    {
++        if (this->stations && this->triggers && this->stations->changeDirection(this->bReopen, this->bReclose, this->triggers->isTriggered()))
++        {
++            this->time = this->stations->getMovingTime(this->station) - this->time;
++            this->originCoor = this->originCoor - this->stations->getRelTargetCoor(this->station);
++            this->originDir = this->originDir - this->stations->getRelTargetDir(this->station);
++        }
++    }
++
++    if (/*this->reachedStationsTarget(dt) || */(this->stations && (this->time >= 1.0 * this->stations->getMovingTime(this->station))))
++//    if (this->stations && (this->time >= this->stations->getMovingTime(this->station)))
++    {
++        this->setAbsCoor(this->originCoor + this->stations->getRelTargetCoor(this->station));
++        this->setAbsDir(VtoQ(this->originDir + this->stations->getRelTargetDir(this->station)));
++
++        if (this->stations->getEndingSound(this->station).loaded())
++            this->soundSource_ending.play(this->stations->getEndingSound(this->station), OrxSound::SoundEngine::getInstance()->getEffectsVolume(), 0.5);
++        this->soundSource_moving.stop();
++
++        this->originCoor = this->originCoor + this->stations->getRelTargetCoor(this->station);
++        this->originDir = this->originDir + this->stations->getRelTargetDir(this->station);
++        
++        return STAY;
++    }
++        
++    if (this->triggers && this->bOnlyMoveWhileTriggered && (!this->triggers->isTriggered()))
++    {
++        this->soundSource_moving.stop();
++        return WAIT;
++    }
++
++    return MOVE;
++}
++
++int Mover::stay()
++{
++    if (!this->stations || (this->time < this->stations->getStayOpenTime(this->station)))
++        return STAY;
++
++    return NEXT;
++}
++
++bool Mover::reachedStationsTarget(float dt)
++{
++    if (this->stations)
++        if ((this->getAbsCoor() - (this->originCoor + this->stations->getRelTargetCoor(this->station))).len() <= 1.2 * (this->stations->getVelocity(this->station) * dt).len())
++            if ((this->getAbsDir().getRotation() - (this->originDir + this->stations->getRelTargetDir(this->station))).len() <= 1.2 * (this->stations->getRotation(this->station) * dt).len())
++                return true;
++
++    return false;
++}
++
+Index: mover_trigger_approach.cc
+===================================================================
+--- mover_trigger_approach.cc	(revision 0)
++++ mover_trigger_approach.cc	(revision 0)
+@@ -0,0 +1,106 @@
++/*
++   orxonox - the future of 3D-vertical-scrollers
++
++   Copyright (C) 2007 orx
++
++   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, or (at your option)
++   any later version.
++
++   ### File Specific:
++   main-programmer: Fabian 'x3n' Landau
++   co-programmer:
++*/
++
++#include "util/loading/load_param.h"
++#include "util/loading/factory.h"
++#include "mover_trigger_approach.h"
++#include "debug.h"
++
++ObjectListDefinition(ApproachTrigger);
++CREATE_FACTORY(ApproachTrigger);
++
++
++ApproachTrigger::ApproachTrigger(const TiXmlElement* root)
++{
++    PRINTF(0)("13_1 ApproachTrigger %p created\n", this);
++    this->registerObject(this, ApproachTrigger::_objectList);
++    this->toList(OM_ENVIRON);
++
++    this->onlyHumans = false;
++    this->onlyNPCs =  false;
++    this->radius = 0;
++    this->distanceX = 0;
++    this->distanceY = 0;
++    this->distanceZ = 0;
++
++    if (root != NULL)
++        this->loadParams(root);
++
++    this->init_post_params();
++}
++
++void ApproachTrigger::loadParams(const TiXmlElement* root)
++{
++    PRINTF(0)("13_2 ApproachTrigger loadParams\n", this);
++    MoverTrigger::loadParams(root);
++
++    LoadParam(root, "radius", this, ApproachTrigger, setRadius)
++        .describe("The radius wherein the player releases the trigger.")
++        .defaultValues(0);
++    LoadParam(root, "distance", this, ApproachTrigger, setDistance)
++        .describe("The distance of all axes wherein the player releases the trigger.")
++        .defaultValues(0, 0, 0);
++    LoadParam(root, "onlyHumans", this, ApproachTrigger, setOnlyHumans)
++        .describe("Only human players can release the trigger.")
++        .defaultValues(false);
++    LoadParam(root, "onlyNPCs", this, ApproachTrigger, setOnlyNPCs)
++        .describe("Only NPCs can release the trigger.")
++        .defaultValues(false);
++}
++
++#include "playable.h"
++#include "../npcs/generic_npc.h"
++
++bool ApproachTrigger::checkIsTriggered()
++{
++    WorldEntity* entity;
++    float distance;
++
++    // for all players
++    if (!this->onlyNPCs)
++    {
++        for (ObjectList<Playable>::const_iterator it = Playable::objectList().begin();
++            it != Playable::objectList().end();
++            ++it)
++        {
++            entity = (*it);
++            distance = (this->getAbsCoor() - entity->getAbsCoor()).len();
++            if (distance <= this->radius
++                || (fabs(this->getAbsCoor().x - entity->getAbsCoor().x) <= this->distanceX
++                    && fabs(this->getAbsCoor().y - entity->getAbsCoor().y) <= this->distanceY
++                    && fabs(this->getAbsCoor().z - entity->getAbsCoor().z) <= this->distanceZ))
++                return true;
++        }
++    }
++
++    // for all npcs
++    if (!this->onlyHumans)
++    {
++        for (ObjectList<GenericNPC>::const_iterator it = GenericNPC::objectList().begin();
++            it != GenericNPC::objectList().end();
++            ++it)
++        {
++            entity = (*it);
++            distance = (this->getAbsCoor() - entity->getAbsCoor()).len();
++            if (distance <= this->radius
++                || (fabs(this->getAbsCoor().x - entity->getAbsCoor().x) <= this->distanceX
++                    && fabs(this->getAbsCoor().y - entity->getAbsCoor().y) <= this->distanceY
++                    && fabs(this->getAbsCoor().z - entity->getAbsCoor().z) <= this->distanceZ))
++                return true;
++        }
++    }
++    
++    return false;
++}
+Index: mover_station.cc
+===================================================================
+--- mover_station.cc	(revision 0)
++++ mover_station.cc	(revision 0)
+@@ -0,0 +1,103 @@
++/*
++   orxonox - the future of 3D-vertical-scrollers
++
++   Copyright (C) 2007 orx
++
++   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, or (at your option)
++   any later version.
++
++   ### File Specific:
++   main-programmer: Fabian 'x3n' Landau
++   co-programmer:
++*/
++
++#include "util/loading/load_param.h"
++#include "util/loading/factory.h"
++#include "mover_station.h"
++#include "debug.h"
++
++ObjectListDefinition(MoverStation);
++CREATE_FACTORY(MoverStation);
++
++
++MoverStation::MoverStation(const TiXmlElement* root)
++{
++    PRINTF(0)("MoverStation %p erzeugt\n", this);
++    this->rank = 0;
++    this->relTargetCoor = Vector(0, 0, 0);
++    this->relTargetDir = Vector(0, 0, 0);
++    this->delay = 0;
++    this->movingTime = 0;
++    this->stayOpenTime = 0;
++    this->bAccelerate = false;
++    this->bDecelerate = false;
++    this->jumpToRank = 0;
++    this->bJumpToRank = false;
++    this->moveToRank = 0;
++    this->bMoveToRank = false;
++    this->bIsOpen = false;
++    this->bIsClosed = false;;
++
++    if (root != NULL)
++        this->loadParams(root);
++}
++
++MoverStation::~MoverStation()
++{
++}
++
++void MoverStation::loadParams(const TiXmlElement* root)
++{
++    WorldEntity::loadParams(root);
++
++    LoadParam(root, "rank", this, MoverStation, setRank)
++        .describe("The rank of the station in the stationlist of the mover.")
++        .defaultValues(0);
++    LoadParam(root, "rel-target-coor", this, MoverStation, setRelTargetCoor)
++        .describe("The relative coordinates of the stations target.")
++        .defaultValues(0, 0, 0);
++    LoadParam(root, "rel-target-dir", this, MoverStation, setRelTargetDir)
++        .describe("The relative direction of the stations target in all axes (roll/pitch/yaw).")
++        .defaultValues(0, 0, 0);
++    LoadParam(root, "delay", this, MoverStation, setDelay)
++        .describe("The amount of time the mover waits, before he starts moving.")
++        .defaultValues(0);
++    LoadParam(root, "moving-time", this, MoverStation, setMovingTime)
++        .describe("The amount of time the mover needs to move.")
++        .defaultValues(0);
++    LoadParam(root, "stay-open-time", this, MoverStation, setStayOpenTime)
++        .describe("The amount of time the mover waits when he reached the target.")
++        .defaultValues(0);
++    LoadParam(root, "bAccelerate", this, MoverStation, setAccelerate)
++        .describe("If true, the mover starts slowly and increases his speed.");
++    LoadParam(root, "bDecelerate", this, MoverStation, setDecelerate)
++        .describe("If true, the mover starts fast and decreases his speed.");
++    LoadParam(root, "jump-to-rank", this, MoverStation, setJumpToRank)
++        .describe("The rank of the station the mover should jump to, after reaching the target.")
++        .defaultValues(0);
++    LoadParam(root, "move-to-rank", this, MoverStation, setMoveToRank)
++        .describe("The rank of the station the mover should move to (instead of rel-target-coor).")
++        .defaultValues(0);
++    LoadParam(root, "bOpen", this, MoverStation, setOpen)
++        .describe("If true, the mover changes to state 'open' after reaching this station.");
++    LoadParam(root, "bClosed", this, MoverStation, setClosed)
++        .describe("If true, the mover changes to state 'closed' after reaching this station.");
++    LoadParam(root, "opening-sound", this, MoverStation, setOpeningSoundFile)
++        .describe("Sets the file of the opening sound source");
++    LoadParam(root, "opened-sound", this, MoverStation, setOpenedSoundFile)
++        .describe("Sets the file of the opened sound source");
++    LoadParam(root, "moving-sound", this, MoverStation, setMovingSoundFile)
++        .describe("Sets the file of the moving sound source");
++    LoadParam(root, "closing-sound", this, MoverStation, setClosingSoundFile)
++        .describe("Sets the file of the closing sound source");
++    LoadParam(root, "closed-sound", this, MoverStation, setClosedSoundFile)
++        .describe("Sets the file of the closed sound source");
++        
++    if (this->bMoveToRank)
++    {
++        this->relTargetCoor = Vector(0, 0, 0);
++        this->relTargetDir = Vector(0, 0, 0);
++    }
++}
+Index: mover_station.h
+===================================================================
+--- mover_station.h	(revision 0)
++++ mover_station.h	(revision 0)
+@@ -0,0 +1,67 @@
++/*!
++ * @file mover_station.h
++ *  A station for a mover.
++ */
++
++#ifndef _MOVER_STATION_H
++#define _MOVER_STATION_H
++
++#include "world_entity.h"
++#include "sound_buffer.h"
++#include "sound/resource_sound_buffer.h"
++
++
++class MoverStation : public WorldEntity
++{
++    friend class MoverStationList;
++
++    ObjectListDeclaration(MoverStation);
++
++    public:
++        MoverStation(const TiXmlElement* root = NULL);
++        virtual ~MoverStation();
++
++        virtual void loadParams(const TiXmlElement* root);
++
++        void setRank(int id) { this->rank = id; }
++        void setRelTargetCoor(float x = 0, float y = 0, float z = 0) { this->relTargetCoor = Vector(x, y, z); }
++        void setRelTargetDir(float wx = 0, float wy = 0, float wz = 0) { this->relTargetDir = Vector(wx, wy, wz); }
++        void setDelay(float t) { this->delay = t; }
++        void setMovingTime(float t) { this->movingTime = t; }
++        void setStayOpenTime(float t) { this->stayOpenTime = t; }
++        void setAccelerate() { this->bAccelerate = true; }
++        void setDecelerate() { this->bDecelerate = true; }
++        void setJumpToRank(int rank) { this->jumpToRank = rank; this->bJumpToRank = true; }
++        void setMoveToRank(int rank) { this->moveToRank = rank; this->bMoveToRank = true; }
++        void setOpen() { this->bIsOpen = true; }
++        void setClosed() { this->bIsClosed = true; }
++        void setOpeningSoundFile(const std::string& fileName) { this->soundBuffer_opening = OrxSound::ResourceSoundBuffer(fileName); }
++        void setOpenedSoundFile(const std::string& fileName) { this->soundBuffer_opened = OrxSound::ResourceSoundBuffer(fileName); }
++        void setMovingSoundFile(const std::string& fileName) { this->soundBuffer_moving = OrxSound::ResourceSoundBuffer(fileName); }
++        void setClosingSoundFile(const std::string& fileName) { this->soundBuffer_closing = OrxSound::ResourceSoundBuffer(fileName); }
++        void setClosedSoundFile(const std::string& fileName) { this->soundBuffer_closed = OrxSound::ResourceSoundBuffer(fileName); }
++
++    private:
++        int                     rank;
++        Vector                  relTargetCoor;
++        Vector              	relTargetDir;
++        float                   delay;
++        float                   movingTime;
++        float                   stayOpenTime;
++        bool                    bAccelerate;
++        bool                    bDecelerate;
++        int                     jumpToRank;
++        bool                    bJumpToRank;
++        int                     moveToRank;
++        bool                    bMoveToRank;
++        bool                    bIsOpen;
++        bool                    bIsClosed;
++        OrxSound::SoundBuffer   soundBuffer_opening;
++        OrxSound::SoundBuffer   soundBuffer_opened;
++        OrxSound::SoundBuffer   soundBuffer_moving;
++        OrxSound::SoundBuffer   soundBuffer_closing;
++        OrxSound::SoundBuffer   soundBuffer_closed;
++};
++
++
++#endif
+Index: mover_trigger_event_list.cc
+===================================================================
+--- mover_trigger_event_list.cc	(revision 0)
++++ mover_trigger_event_list.cc	(revision 0)
+@@ -0,0 +1,152 @@
++/*
++   orxonox - the future of 3D-vertical-scrollers
++
++   Copyright (C) 2007 orx
++
++   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, or (at your option)
++   any later version.
++
++   ### File Specific:
++   main-programmer: Fabian 'x3n' Landau
++   co-programmer:
++*/
++
++#include "mover_trigger_event_list.h"
++#include "debug.h"
++/*
++MoverTriggerEventList *listPointer = 0;
++
++MoverTriggerEventList::getListPointer()
++{
++    if (!this->listPointer)
++        this->listPointer = new MoverTriggerEventList();
++        
++    return this->listPointer;
++}
++*/
++MoverTriggerEventList::MoverTriggerEventList()
++{
++    this->first = 0;
++}
++
++
++MoverTriggerEventList::~MoverTriggerEventList()
++{
++    while (this->first != 0)
++    {
++        this->removeTrigger(this->first->trigger);
++    }
++}
++
++void MoverTriggerEventList::addTrigger(MoverTrigger *trigger)
++{
++    if (trigger)
++    {
++        if (!this->first)
++            this->first = new MoverTriggerEventListElement(trigger);
++        else
++        {
++            MoverTriggerEventListElement *temp = this->first;
++            while (temp->next != 0)
++                temp = temp->next;
++
++            temp->next = new MoverTriggerEventListElement(trigger);
++        }
++    }
++}
++
++void MoverTriggerEventList::removeTrigger(MoverTrigger *trigger)
++{
++    if (trigger)
++    {
++        if (this->first != 0)
++        {
++            if (this->first->trigger == trigger)
++            {
++                MoverTriggerEventListElement *temp = this->first->next;
++
++                delete this->first;
++                this->first = temp;
++            }
++            else
++            {
++                MoverTriggerEventListElement *temp = this->first;
++
++                while (temp != 0)
++                {
++                    if (temp->next && (temp->next->trigger == trigger))
++                    {
++                        MoverTriggerEventListElement *temp2 = temp->next->next;
++                        delete temp->next;
++                        temp->next = temp2;
++                    }
++
++                    temp = temp->next;
++                }
++            }
++        }
++    }
++}
++
++bool MoverTriggerEventList::isEmpty()
++{
++    return (this->first == 0);
++}
++
++bool MoverTriggerEventList::isTriggered(const std::string& triggerName)
++{
++    MoverTriggerEventListElement *temp = this->first;
++    bool isTriggered = false;
++    
++    while (temp != 0)
++    {
++        if (temp->trigger && (temp->trigger->getName() == triggerName))
++        {
++            if (temp->trigger->isTriggered())
++            {
++                isTriggered = true;
++            }
++            else
++            {
++                if (temp->trigger->isObligatory())
++                    return false;
++            }
++        }
++        
++        temp = temp->next;
++    }
++    
++    return isTriggered;
++}
++
++MoverTriggerPointerList *MoverTriggerEventList::getPointerList(const std::string& triggerName)
++{
++    MoverTriggerPointerList *list = new MoverTriggerPointerList();
++    MoverTriggerEventListElement *temp = this->first;
++
++    while (temp != 0)
++    {
++        if (temp->trigger && (temp->trigger->getName() == triggerName))
++            list->addTrigger(temp->trigger);
++
++        temp = temp->next;
++    }
++    
++    return list;
++}
++
++
++////////////////////////////////////////////////////////
++
++
++MoverTriggerEventListElement::MoverTriggerEventListElement(MoverTrigger *trigger)
++{
++    this->trigger = trigger;
++    this->next = 0;
++}
++
++MoverTriggerEventListElement::~MoverTriggerEventListElement()
++{
++}
+Index: mover_trigger_list.h
+===================================================================
+--- mover_trigger_list.h	(revision 0)
++++ mover_trigger_list.h	(revision 0)
+@@ -0,0 +1,40 @@
++/*!
++ * @file mover_trigger_list.h
++ *  A list to store and handle several triggers.
++ */
++
++#ifndef _MOVER_TRIGGER_LIST_H
++#define _MOVER_TRIGGER_LIST_H
++
++#include "mover_trigger.h"
++
++
++class MoverTrigger;
++
++class MoverTriggerListElement
++{
++    public:
++        MoverTriggerListElement(MoverTrigger *trigger);
++        ~MoverTriggerListElement();
++        
++        MoverTrigger *trigger;
++        MoverTriggerListElement *next;
++};
++
++
++class MoverTriggerList
++{
++    public:
++        MoverTriggerList();
++        ~MoverTriggerList();
++
++        void addTrigger(MoverTrigger *trigger);
++        bool isTriggered();
++        void setBaseCoor(Vector baseCoor);
++
++    private:
++        MoverTriggerListElement *first;
++};
++
++
++#endif
+Index: mover_trigger_pointer_list.h
+===================================================================
+--- mover_trigger_pointer_list.h	(revision 0)
++++ mover_trigger_pointer_list.h	(revision 0)
+@@ -0,0 +1,39 @@
++/*!
++ * @file mover_trigger_pointer_list.h
++ *  A list to store and handle several trigger pointers.
++ */
++
++#ifndef _MOVER_TRIGGER_POINTER_LIST_H
++#define _MOVER_TRIGGER_POINTER_LIST_H
++
++#include "mover_trigger.h"
++
++
++class MoverTrigger;
++
++class MoverTriggerPointerListElement
++{
++    public:
++        MoverTriggerPointerListElement(MoverTrigger *trigger);
++        ~MoverTriggerPointerListElement();
++        
++        MoverTrigger *trigger;
++        MoverTriggerPointerListElement *next;
++};
++
++
++class MoverTriggerPointerList
++{
++    public:
++        MoverTriggerPointerList();
++        ~MoverTriggerPointerList();
++
++        void addTrigger(MoverTrigger *trigger);
++        bool isTriggered();
++
++    private:
++        MoverTriggerPointerListElement *first;
++};
++
++
++#endif
+Index: mover_trigger_event_list.h
+===================================================================
+--- mover_trigger_event_list.h	(revision 0)
++++ mover_trigger_event_list.h	(revision 0)
+@@ -0,0 +1,48 @@
++/*!
++ * @file mover_trigger_event_list.h
++ *  A List to handle several events, caused by mover triggers.
++ */
++
++#ifndef _MOVER_TRIGGER_EVENT_LIST_H
++#define _MOVER_TRIGGER_EVENT_LIST_H
++
++#include "mover_trigger.h"
++#include "mover_trigger_pointer_list.h"
++
++
++class MoverTrigger;
++class MoverTriggerPointerList;
++
++class MoverTriggerEventListElement
++{
++    public:
++        MoverTriggerEventListElement(MoverTrigger *trigger);
++        ~MoverTriggerEventListElement();
++
++        MoverTrigger *trigger;
++        MoverTriggerEventListElement *next;
++};
++
++
++class MoverTriggerEventList
++{
++    public:
++//        static MoverTriggerEventList *getListPointer();
++        
++        void addTrigger(MoverTrigger *trigger);
++        void removeTrigger(MoverTrigger *trigger);
++        bool isEmpty();
++        bool isTriggered(const std::string& triggerName);
++        MoverTriggerPointerList *getPointerList(const std::string& triggerName);
++
++//    protected:
++        MoverTriggerEventList();
++        ~MoverTriggerEventList();
++
++    private:
++        MoverTriggerEventListElement *first;
++//        static MoverTriggerEventList *listPointer;
++};
++
++
++#endif
+Index: mover_trigger.cc
+===================================================================
+--- mover_trigger.cc	(revision 0)
++++ mover_trigger.cc	(revision 0)
+@@ -0,0 +1,327 @@
++/*
++   orxonox - the future of 3D-vertical-scrollers
++
++   Copyright (C) 2007 orx
++
++   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, or (at your option)
++   any later version.
++
++   ### File Specific:
++   main-programmer: Fabian 'x3n' Landau
++   co-programmer:
++*/
++
++#include "util/loading/load_param_xml.h"
++#include "util/loading/load_param.h"
++#include "util/loading/factory.h"
++#include "mover_trigger.h"
++#include "mover_trigger_approach.h"
++#include "mover_trigger_mapstart.h"
++#include "mover_trigger_key.h"
++#include "mover_trigger_event.h"
++#include "mover_trigger_intervisibility.h"
++#include <string.h>
++
++MoverTriggerEventList *MoverTrigger::events = 0;
++
++ObjectListDefinition(MoverTrigger);
++CREATE_FACTORY(MoverTrigger);
++
++
++MoverTrigger::MoverTrigger(const TiXmlElement* root)
++{
++    PRINTF(0)("5_1 MoverTrigger %p created\n", this);
++    this->registerObject(this, MoverTrigger::_objectList);
++    this->toList(OM_ENVIRON);
++
++    PRINTF(0)("5_2\n");
++    this->init_prae_params();
++    PRINTF(0)("5_3\n");
++
++    if (root != NULL)
++        this->loadParams(root);
++
++    PRINTF(0)("5_4\n");
++    this->init_post_params();
++    PRINTF(0)("5_5\n");
++}
++
++MoverTrigger::~MoverTrigger()
++{
++    PRINTF(0)("14_1 MoverTrigger %p destroyed\n", this);
++    if (this->triggers)
++        delete this->triggers;
++        
++    PRINTF(0)("14_2\n");
++    if (this->delaylist)
++        delete this->delaylist;
++    
++    PRINTF(0)("14_3\n");
++    if (MoverTrigger::events)
++    {
++        PRINTF(0)("14_4\n");
++        MoverTrigger::events->removeTrigger(this);
++        if (MoverTrigger::events->isEmpty())
++        {
++            PRINTF(0)("14_5\n");
++            delete MoverTrigger::events;
++            MoverTrigger::events = 0;
++        }
++    }
++    PRINTF(0)("14_6\n");
++}
++
++void MoverTrigger::init_prae_params()
++{
++    PRINTF(0)("6_1\n");
++    this->bIsTriggered = false;
++    this->delay = 0;
++    this->bIsWaitingForDelay = false;
++    this->relCoor = Vector(0, 0, 0);
++    this->bStayTriggered = false;
++    this->bTriggerOnceOnly = false;
++    this->bInvert = false;
++    this->bSwitch = false;
++    this->bObligatory = false;
++    this->bFirstRelease = true;
++    this->oldState = false;
++    this->time = 0;
++    
++    this->triggers = 0;
++    this->delaylist = 0;
++    
++//    if (!this->delaylist)
++        this->delaylist = new MoverTriggerDelayList();
++
++//    if (!this->triggers)
++        this->triggers = new MoverTriggerList();
++
++    PRINTF(0)("6_2\n");
++
++    if (!MoverTrigger::events)
++        MoverTrigger::events = new MoverTriggerEventList();
++        
++    PRINTF(0)("6_3\n");
++}
++
++void MoverTrigger::init_post_params()
++{
++    PRINTF(0)("6_4\n");
++    this->updateNode(0.001);
++    this->setBaseCoor(this->getAbsCoor());
++
++//    PRINTF(0)("6_5 MoverTrigger abs-coor: %f, %f, %f\n", this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z);
++
++    PRINTF(0)("6_5\n");
++    if (this->getName() != "")
++        MoverTrigger::events->addTrigger(this);
++        
++    PRINTF(0)("6_6\n");
++}
++
++void MoverTrigger::loadParams(const TiXmlElement* root)
++{
++    PRINTF(0)("7_1 MoverTrigger loadParams for trigger %p\n", this);
++    WorldEntity::loadParams(root);
++
++    LoadParam(root, "rel-coor", this, MoverTrigger, setRelCoor)
++        .describe("The relative position to the mover.")
++        .defaultValues(0, 0, 0);
++    LoadParam(root, "delay", this, MoverTrigger, setDelay)
++        .describe("The delay of the trigger.")
++        .defaultValues(0);
++    LoadParam(root, "bStayTriggered", this, MoverTrigger, setStayTriggered)
++        .describe("If the trigger gets released, he stays triggered forever.")
++        .defaultValues(false);
++    LoadParam(root, "bTriggerOnceOnly", this, MoverTrigger, setTriggerOnceOnly)
++        .describe("The trigger can only be released once.")
++        .defaultValues(false);
++    LoadParam(root, "bInvert", this, MoverTrigger, setInvert)
++        .describe("Inverts the state of the trigger.")
++        .defaultValues(false);
++    LoadParam(root, "bSwitch", this, MoverTrigger, setSwitch)
++        .describe("Each time the trigger gets triggered again, he switches his state.")
++        .defaultValues(false);
++    LoadParam(root, "bObligatory", this, MoverTrigger, setObligatory)
++        .describe("A obligatory trigger MUST be triggered to create an event.")
++        .defaultValues(false);
++    LoadParamXML(root, "triggers", this, MoverTrigger, setTriggers)
++        .describe("Adds a trigger that triggers the trigger.");
++}
++
++void MoverTrigger::setBaseCoor(Vector baseCoor)
++{
++//    PRINTF(0)("13_1\n");
++    this->setAbsCoor(baseCoor + this->relCoor);
++//    PRINTF(0)("13_2\n");
++    if (this->triggers)
++        this->triggers->setBaseCoor(baseCoor);
++//    PRINTF(0)("13_3\n");
++}
++
++void MoverTrigger::setTriggers(const TiXmlElement* root)
++{
++    PRINTF(0)("8_1\n");
++    if (!this->triggers)
++        this->triggers = new MoverTriggerList();
++        
++    const TiXmlElement* element = root->FirstChildElement();
++
++    PRINTF(0)("8_2\n");
++    while (element != NULL)
++    {
++        PRINTF(0)("8_3\n");
++        BaseObject *newObj = Factory::fabricate(element);
++//        MoverTrigger *newTrigger = ((MoverTrigger*)(&newObj));
++        MoverTrigger *newTrigger = (dynamic_cast< MoverTrigger *> ( newObj ));
++        this->triggers->addTrigger(newTrigger);
++//        this->triggers->addTrigger(MoverTrigger::createTrigger(element));
++        PRINTF(0)("8_4\n");
++        element = element->NextSiblingElement();
++    }
++    PRINTF(0)("8_5\n");
++}
++/*
++MoverTrigger *MoverTrigger::createTrigger(const TiXmlElement* root)
++{
++    PRINTF(0)("9_1\n");
++    PRINTF(0)("root->Value(): %s\n", root->Value());
++    if (strcmp(root->Value(), "MoverTrigger") == 0)
++    {
++        PRINTF(0)("9_2\n");
++        return new MoverTrigger(root);
++    }
++    else if (strcmp(root->Value(), "ApproachTrigger") == 0)
++    {
++        PRINTF(0)("9_3\n");
++        return new ApproachTrigger(root);
++    }
++    else if (strcmp(root->Value(), "MapstartTrigger") == 0)
++        return new MapstartTrigger(root);
++    else if (strcmp(root->Value(), "EventTrigger") == 0)
++        return new EventTrigger(root);
++    else if (strcmp(root->Value(), "KeyTrigger") == 0)
++        return new KeyTrigger(root);
++    else if (strcmp(root->Value(), "IntervisibilityTrigger") == 0)
++        return new IntervisibilityTrigger(root);
++    else
++    {
++        PRINTF(0)("9_4\n");
++        return new MoverTrigger(root);
++    }
++}
++*/
++void MoverTrigger::tick(float dt)
++{
++    this->time += dt;
++    
++    if (this->delaylist && this->delaylist->isEmpty())
++        this->time = 0;
++}
++
++bool MoverTrigger::isTriggered()
++{
++//    PRINTF(0)("17_1\n");
++    if (!this->bIsTriggered && this->bTriggerOnceOnly && !this->bFirstRelease)
++        return this->bInvert; // yes this makes sense... just think about it ;)
++
++//    PRINTF(0)("17_2\n");
++    if (!this->bStayTriggered || !this->bIsTriggered)
++    {
++//        PRINTF(0)("17_3\n");
++        if (this->triggers && this->delaylist)
++        {
++//            PRINTF(0)("17_4\n");
++            if (this->triggers->isTriggered())
++            {
++//                PRINTF(0)("17_5\n");
++                bool tempIsTriggered = this->checkIsTriggered();
++                if (this->delaylist->isEmpty())
++                {
++                    if (!this->bSwitch)
++                    {
++                        if (tempIsTriggered != this->bIsTriggered)
++                            this->delaylist->addState(tempIsTriggered, this->oldState, this->time + this->delay);
++                    }
++                    else
++                    {
++                        if (tempIsTriggered != this->oldState)
++                            this->delaylist->addState(tempIsTriggered, this->oldState, this->time + this->delay);
++                    }
++                }
++                else
++                {
++                    if (!this->bSwitch)
++                    {
++                        if (tempIsTriggered != this->delaylist->getLastState()->state)
++                            this->delaylist->addState(tempIsTriggered, this->oldState, this->time + this->delay);
++                    }
++                    else
++                    {
++                        if (tempIsTriggered != this->delaylist->getLastState()->oldState)
++                            this->delaylist->addState(tempIsTriggered, this->oldState, this->time + this->delay);
++                    }
++                }
++            }
++
++//            PRINTF(0)("17_6\n");
++            while (!this->delaylist->isEmpty())
++            {
++                MoverTriggerDelayListElement *element = this->delaylist->getFirstState();
++
++                if (element && (this->time >= element->time))
++                {
++                    if (!this->bSwitch)
++                    {
++                        this->bIsTriggered = element->state;
++                    }
++                    else
++                    {
++                        if (element->state && !this->oldState)
++                            this->bIsTriggered = !this->bIsTriggered;
++
++                        this->oldState = element->state;
++                    }
++
++                    this->delaylist->deleteFirstState();
++
++                    if (this->delaylist->isEmpty())
++                    {
++                        this->time = 0;
++                        break;
++                    }
++                    
++                    continue;
++                }
++                
++                break;
++            }
++        }
++        else
++            this->bIsTriggered = false;
++    }
++
++//    PRINTF(0)("17_7\n");
++    if (this->bIsTriggered && this->bTriggerOnceOnly && this->bFirstRelease)
++        this->bFirstRelease = false;
++
++//    PRINTF(0)("17_8\n");
++    if (this->bInvert)
++        return (!this->bIsTriggered);
++    else
++        return this->bIsTriggered;
++}
++
++bool MoverTrigger::isObligatory()
++{
++    return this->bObligatory;
++}
++
++bool MoverTrigger::checkIsTriggered()
++{
++    return true;
++}
++
++
+Index: mover_trigger_event.cc
+===================================================================
+--- mover_trigger_event.cc	(revision 0)
++++ mover_trigger_event.cc	(revision 0)
+@@ -0,0 +1,75 @@
++/*
++   orxonox - the future of 3D-vertical-scrollers
++
++   Copyright (C) 2007 orx
++
++   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, or (at your option)
++   any later version.
++
++   ### File Specific:
++   main-programmer: Fabian 'x3n' Landau
++   co-programmer:
++*/
++
++#include "util/loading/load_param.h"
++#include "util/loading/factory.h"
++#include "mover_trigger_event.h"
++#include "debug.h"
++
++ObjectListDefinition(EventTrigger);
++CREATE_FACTORY(EventTrigger);
++
++
++EventTrigger::EventTrigger(const TiXmlElement* root)
++{
++    PRINTF(0)("15_1 EventTrigger %p created\n", this);
++    this->registerObject(this, EventTrigger::_objectList);
++    this->toList(OM_ENVIRON);
++
++    this->eventName = "";
++    this->eventTriggers = 0;
++    this->bIsChecking = false;
++    
++    if (root != NULL)
++        this->loadParams(root);
++
++    this->init_post_params();
++}
++
++EventTrigger::~EventTrigger()
++{
++    delete this->eventTriggers;
++}
++
++void EventTrigger::loadParams(const TiXmlElement* root)
++{
++    MoverTrigger::loadParams(root);
++
++    LoadParam(root, "event", this, EventTrigger, setEvent)
++        .describe("The event that releases the trigger")
++        .defaultValues("");
++}
++
++bool EventTrigger::checkIsTriggered()
++{
++    if (this->bIsChecking)
++        return this->bIsTriggered; // to avoid event-loops
++        
++    if (!this->eventTriggers)
++    {
++        if (MoverTrigger::events)
++            this->eventTriggers = MoverTrigger::events->getPointerList(this->eventName);
++
++        if (!this->eventTriggers)
++            this->eventTriggers = new MoverTriggerPointerList();
++    }
++
++    this->bIsChecking = true;
++    bool isTriggered = this->eventTriggers->isTriggered();
++    this->bIsChecking = false;
++    
++    return isTriggered;
++}
++
+Index: mover_trigger.h
+===================================================================
+--- mover_trigger.h	(revision 0)
++++ mover_trigger.h	(revision 0)
+@@ -0,0 +1,73 @@
++/*!
++ * @file mover_trigger.h
++ *  Base-class for all mover triggers and container for an independent triggerlist.
++ */
++
++#ifndef _MOVER_TRIGGER_H
++#define _MOVER_TRIGGER_H
++
++#include "world_entity.h"
++#include "mover_trigger_list.h"
++#include "mover_trigger_event_list.h"
++#include "mover_trigger_delay_list.h"
++
++
++class MoverTriggerList;
++class MoverTriggerEventList;
++
++class MoverTrigger : public WorldEntity
++{
++    ObjectListDeclaration(MoverTrigger);
++    
++    public:
++        MoverTrigger(const TiXmlElement* root = NULL);
++        virtual ~MoverTrigger();
++
++        virtual void loadParams(const TiXmlElement* root);
++        virtual void tick(float dt);
++        
++        void setRelCoor(float x, float y, float z) { this->relCoor = Vector(x, y, z); }
++        void updateCoordinates(Vector baseCoor);
++        void setDelay(float delay) { this->delay = delay; }
++        void setStayTriggered(bool bStayTriggered = true) { this->bStayTriggered = bStayTriggered; }
++        void setTriggerOnceOnly(bool bTriggerOnceOnly = true) { this->bTriggerOnceOnly = bTriggerOnceOnly; }
++        void setInvert(bool bInvert = true) { this->bInvert = bInvert; }
++        void setSwitch(bool bSwitch = true) { this->bSwitch = bSwitch; }
++        void setObligatory(bool bObligatory = true) { this->bObligatory = bObligatory; }
++        void setTriggers(const TiXmlElement* root);
++        void setBaseCoor(Vector baseCoor);
++
++        bool isTriggered();
++        bool isObligatory();
++        static MoverTriggerEventList *events;
++        std::string getName() { return this->objectName; }
++        static MoverTrigger *createTrigger(const TiXmlElement* root);
++
++    protected:
++        void init_post_params();
++
++        bool                    bIsTriggered;
++
++    private:
++        void init_prae_params();
++        virtual bool checkIsTriggered();
++        
++        Vector                  relCoor;
++        float                   delay;
++        bool                    bIsWaitingForDelay;
++        bool                    bStayTriggered;
++        bool                    bTriggerOnceOnly;
++        bool                    bInvert;
++        bool                    bSwitch;
++        bool                    bObligatory;
++        float                   time;
++        bool                    bFirstRelease;
++        bool                    oldState;
++
++        MoverTriggerList        *triggers;
++        MoverTriggerDelayList   *delaylist;
++};
++
++
++#endif
++
+Index: mover_station_list.cc
+===================================================================
+--- mover_station_list.cc	(revision 0)
++++ mover_station_list.cc	(revision 0)
+@@ -0,0 +1,447 @@
++/*
++   orxonox - the future of 3D-vertical-scrollers
++
++   Copyright (C) 2007 orx
++
++   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, or (at your option)
++   any later version.
++
++   ### File Specific:
++   main-programmer: Fabian 'x3n' Landau
++   co-programmer:
++*/
++
++#include "mover_station_list.h"
++#include "debug.h"
++
++
++MoverStationList::MoverStationList()
++{
++    this->first = 0;
++    this->last = 0;
++    this->goForward = true;
++}
++
++MoverStationList::~MoverStationList()
++{
++    MoverStationListElement *temp1 = this->first;
++    MoverStationListElement *temp2;
++    while (temp1 != 0)
++    {
++        temp2 = temp1->next;
++        delete temp1;
++        temp1 = temp2;
++    }
++}
++
++void MoverStationList::addStation(MoverStation *station)
++{
++    PRINTF(0)("Füge MoverStation %p hinzu\n", station);
++    if (this->first == 0)
++    {
++        this->first = new MoverStationListElement(station);
++        this->last = this->first;
++        return;
++    }
++    else
++    {
++        if (this->first->station->rank > station->rank)
++        {
++            MoverStationListElement *temp = this->first;
++            this->first = new MoverStationListElement(station);
++            this->first->next = temp;
++            this->first->next->prev = this->first;
++            return;
++        }
++        else
++        {
++            MoverStationListElement *temp1 = this->first;
++            MoverStationListElement *temp2;
++            while (temp1->next != 0)
++            {
++                if (temp1->next->station->rank > station->rank)
++                {
++                    temp2 = temp1->next;
++                    temp1->next = new MoverStationListElement(station);
++                    temp1->next->prev = temp1;
++                    temp1->next->next = temp2;
++                    temp1->next->next->prev = temp1->next;
++                        
++                    return;
++                }
++                
++                temp1 = temp1->next;
++            }
++            
++            temp1->next = new MoverStationListElement(station);
++            temp1->next->prev = last;
++            last = temp1->next;
++        }
++    }
++}
++
++MoverStation *MoverStationList::getNextStation(MoverStation *station)
++{
++    if (this->goForward)
++    {
++        if (station)
++        {
++            MoverStationListElement *temp;
++            if (station->bJumpToRank)
++            {
++                temp = this->first;
++                while (temp != 0)
++                {
++                    if (temp->station->rank == station->jumpToRank)
++                        return temp->station;
++
++                    temp = temp->next;
++                }
++            } // no "else" here - if jumpToRank wasn't found, we return the following station (as usual)
++
++            if (station->bMoveToRank)
++            {
++                temp = this->first;
++                while (temp != 0)
++                {
++                    if (temp->station->rank == station->moveToRank)
++                        return temp->station;
++
++                    temp = temp->next;
++                }
++            } // no "else" here - if moveToRank wasn't found, we return the following station (as usual)
++
++            temp = this->first;
++            while (temp != 0)
++            {
++                if (temp->station == station)
++                {
++                    if (temp->next)
++                    {
++                        return temp->next->station;
++                    }
++                    else
++                    {
++                        this->goForward = false;
++                        return this->last->station;
++                    }
++                }
++                temp = temp->next;
++            }
++            return 0;
++        }
++        else
++        {
++            if (this->first)
++                return this->first->station;
++            else
++                return 0;
++        }
++    }
++    else
++    {
++        if (station)
++        {
++            MoverStationListElement *temp;
++            if (station->bJumpToRank)
++            {
++                temp = this->last;
++                while (temp != 0)
++                {
++                    if (temp->station->rank == station->jumpToRank)
++                        return temp->station;
++
++                    temp = temp->prev;
++                }
++            } // no "else" here - if jumpToRank wasn't found, we return the following station (as usual)
++
++            if (station->bMoveToRank)
++            {
++                temp = this->last;
++                while (temp != 0)
++                {
++                    if (temp->station->rank == station->moveToRank)
++                        return temp->station;
++
++                    temp = temp->prev;
++                }
++            } // no "else" here - if moveToRank wasn't found, we return the following station (as usual)
++
++            temp = this->last;
++            while (temp != 0)
++            {
++                if (temp->station == station)
++                {
++                    if (temp->prev)
++                    {
++                        return temp->prev->station;
++                    }
++                    else
++                    {
++                        this->goForward = true;
++                        return this->first->station;
++                    }
++                }
++                temp = temp->prev;
++            }
++            return 0;
++        }
++        else
++        {
++            if (this->last)
++                return this->last->station;
++            else
++                return 0;
++        }
++    }
++}
++
++Vector MoverStationList::getTotalRelCoor(MoverStation *station)
++{
++    MoverStationListElement *temp = this->first;
++    Vector totalRelCoor = Vector(0, 0, 0);
++
++    if (station)
++    {
++        if (this->goForward)
++        {
++            while (temp != 0)
++            {
++                totalRelCoor += temp->station->relTargetCoor;
++                if (temp->station == station)
++                    break;
++
++                temp = temp->next;
++            }
++        }
++        else
++        {
++            if (temp)
++            {
++                while (temp->next != 0)
++                {
++                    totalRelCoor += temp->next->station->relTargetCoor;
++                    if (temp->next->station == station)
++                        break;
++
++                    temp = temp->next;
++                }
++            }
++        }
++    }
++
++    return totalRelCoor;
++}
++
++Vector MoverStationList::getTotalRelDir(MoverStation *station)
++{
++    MoverStationListElement *temp = this->first;
++    Vector totalRelDir = Vector(0, 0, 0);
++    
++    if (station)
++    {
++        if (this->goForward)
++        {
++            while (temp != 0)
++            {
++                totalRelDir += temp->station->relTargetDir;
++                if (temp->station == station)
++                    break;
++
++                temp = temp->next;
++            }
++        }
++        else
++        {
++            if (temp)
++            {
++                while (temp->next != 0)
++                {
++                    totalRelDir += temp->next->station->relTargetDir;
++                    if (temp->next->station == station)
++                        break;
++
++                    temp = temp->next;
++                }
++            }
++        }
++    }
++
++    return totalRelDir;
++}
++
++bool MoverStationList::isOpen(MoverStation *station)
++{
++    if (station)
++        if ((this->goForward && this->last && this->last->station == station) || station->bIsOpen)
++            return true;
++        
++    return false;
++}
++
++bool MoverStationList::isClosed(MoverStation *station)
++{
++    if (station)
++        if ((!this->goForward && this->first && this->first->station == station) || station->bIsClosed)
++            return true;
++        
++    return false;
++}
++
++bool MoverStationList::changeDirection(bool bReopen, bool bReclose, bool bIsTriggered)
++{
++    if (this->goForward && bReclose && !bIsTriggered)
++    {
++        this->goForward = false;
++        return true;
++    }
++    
++    if (!this->goForward && bReopen && bIsTriggered)
++    {
++        this->goForward = true;
++        return true;
++    }
++    
++    return false;
++}
++
++Vector MoverStationList::getRelTargetCoor(MoverStation *station)
++{
++    if (station)
++    {
++        if (!station->bMoveToRank)
++        {
++            if (this->goForward)
++                return station->relTargetCoor;
++            else
++                return station->relTargetCoor * -1;
++        }
++        else
++        {
++            MoverStation *moveToStation = this->getStation(station->moveToRank);
++
++            if (moveToStation != 0)
++            {
++                if (this->goForward)
++                    return (this->getTotalRelCoor(station) - this->getTotalRelCoor(moveToStation)) * -1;
++                else
++                    return (this->getTotalRelCoor(station) - this->getTotalRelCoor(moveToStation));
++            }
++        }
++    }
++    
++    return Vector(0, 0, 0);
++}
++
++Vector MoverStationList::getRelTargetDir(MoverStation *station)
++{
++    if (station)
++    {
++        if (!station->bMoveToRank)
++        {
++            if (this->goForward)
++                return station->relTargetDir;
++            else
++                return station->relTargetDir * -1;
++        }
++        else
++        {
++            MoverStation *moveToStation = this->getStation(station->moveToRank);
++
++            if (moveToStation != 0)
++            {
++                if (this->goForward)
++                    return (station->relTargetDir - this->getTotalRelDir(moveToStation)) * -1;
++                else
++                    return station->relTargetDir - this->getTotalRelDir(moveToStation);
++            }
++        }
++    }
++    
++    return Vector(0, 0, 0);
++}
++
++Vector MoverStationList::getVelocity(MoverStation *station)
++{
++    if (station)
++        if (station->movingTime != 0)
++            return this->getRelTargetCoor(station) / station->movingTime;
++
++    return Vector(0, 0, 0);
++}
++
++Vector MoverStationList::getRotation(MoverStation *station)
++{
++    if (station)
++        if (station->movingTime != 0)
++            return this->getRelTargetDir(station) / station->movingTime;
++
++    return Vector(0, 0, 0);
++}
++
++OrxSound::SoundBuffer MoverStationList::getStartingSound(MoverStation *station)
++{
++    if (station)
++    {
++        if (this->goForward)
++            return station->soundBuffer_opening;
++        else
++            return station->soundBuffer_closing;
++    }
++
++    return OrxSound::ResourceSoundBuffer("");
++}
++
++OrxSound::SoundBuffer MoverStationList::getEndingSound(MoverStation *station)
++{
++    if (station)
++    {
++        if (this->goForward)
++            return station->soundBuffer_opened;
++        else
++            return station->soundBuffer_closed;
++    }
++
++    return OrxSound::ResourceSoundBuffer("");
++}
++
++OrxSound::SoundBuffer MoverStationList::getMovingSound(MoverStation *station)
++{
++    if (station)
++        return station->soundBuffer_moving;
++
++    return OrxSound::ResourceSoundBuffer("");
++}
++
++MoverStation *MoverStationList::getStation(int rank)
++{
++    MoverStationListElement *temp;
++
++    temp = this->first;
++    while (temp != 0)
++    {
++        if (temp->station->rank == rank)
++            return temp->station;
++
++        temp = temp->next;
++    }
++    
++    return 0;
++}
++
++////////////////////////////////////////////////////////
++
++
++MoverStationListElement::MoverStationListElement(MoverStation *station)
++{
++    this->station = station;
++    this->next = 0;
++    this->prev = 0;
++}
++
++MoverStationListElement::~MoverStationListElement()
++{
++    delete this->station;
++}
+Index: mover_trigger_intervisibility.cc
+===================================================================
+--- mover_trigger_intervisibility.cc	(revision 0)
++++ mover_trigger_intervisibility.cc	(revision 0)
+@@ -0,0 +1,54 @@
++/*
++   orxonox - the future of 3D-vertical-scrollers
++
++   Copyright (C) 2007 orx
++
++   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, or (at your option)
++   any later version.
++
++   ### File Specific:
++   main-programmer: Fabian 'x3n' Landau
++   co-programmer:
++*/
++
++#include "util/loading/load_param.h"
++#include "util/loading/factory.h"
++#include "mover_trigger_intervisibility.h"
++
++ObjectListDefinition(IntervisibilityTrigger);
++CREATE_FACTORY(IntervisibilityTrigger);
++
++
++IntervisibilityTrigger::IntervisibilityTrigger(const TiXmlElement* root)
++{
++    this->registerObject(this, IntervisibilityTrigger::_objectList);
++    this->toList(OM_ENVIRON);
++
++    this->onlyHumans = false;
++    this->onlyNPCs =  false;
++
++    if (root != NULL)
++        this->loadParams(root);
++
++    this->init_post_params();
++}
++
++void IntervisibilityTrigger::loadParams(const TiXmlElement* root)
++{
++    MoverTrigger::loadParams(root);
++
++    LoadParam(root, "onlyHumans", this, IntervisibilityTrigger, setOnlyHumans)
++        .describe("Only human players can release the trigger.")
++        .defaultValues(false);
++    LoadParam(root, "onlyNPCs", this, IntervisibilityTrigger, setOnlyNPCs)
++        .describe("Only NPCs can release the trigger.")
++        .defaultValues(false);
++}
++
++bool IntervisibilityTrigger::checkIsTriggered()
++{
++    /* TODO */
++    return false;
++}
+Index: mover_trigger_delay_list.h
+===================================================================
+--- mover_trigger_delay_list.h	(revision 0)
++++ mover_trigger_delay_list.h	(revision 0)
+@@ -0,0 +1,40 @@
++/*!
++ * @file mover_trigger_delay_list.h
++ *  A list to delay trigger-state-changes.
++ */
++
++#ifndef _MOVER_TRIGGER_DELAY_LIST_H
++#define _MOVER_TRIGGER_DELAY_LIST_H
++
++
++class MoverTriggerDelayListElement
++{
++    public:
++        MoverTriggerDelayListElement(bool state, bool oldState, float time);
++        ~MoverTriggerDelayListElement();
++        
++        bool state;
++        bool oldState;
++        float time;
++        MoverTriggerDelayListElement *next;
++};
++
++
++class MoverTriggerDelayList
++{
++    public:
++        MoverTriggerDelayList();
++        ~MoverTriggerDelayList();
++
++        void addState(bool state, bool oldState, float time);
++        void deleteFirstState();
++        MoverTriggerDelayListElement *getFirstState();
++        MoverTriggerDelayListElement *getLastState();
++        bool isEmpty();
++
++    private:
++        MoverTriggerDelayListElement *first;
++};
++
++
++#endif
+Index: mover_trigger_mapstart.cc
+===================================================================
+--- mover_trigger_mapstart.cc	(revision 0)
++++ mover_trigger_mapstart.cc	(revision 0)
+@@ -0,0 +1,53 @@
++/*
++   orxonox - the future of 3D-vertical-scrollers
++
++   Copyright (C) 2007 orx
++
++   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, or (at your option)
++   any later version.
++
++   ### File Specific:
++   main-programmer: Fabian 'x3n' Landau
++   co-programmer:
++*/
++
++#include "util/loading/load_param.h"
++#include "util/loading/factory.h"
++#include "mover_trigger_mapstart.h"
++#include "debug.h"
++
++ObjectListDefinition(MapstartTrigger);
++CREATE_FACTORY(MapstartTrigger);
++
++
++MapstartTrigger::MapstartTrigger(const TiXmlElement* root)
++{
++    PRINTF(0)("13_1 MapstartTrigger %p created\n", this);
++    this->registerObject(this, MapstartTrigger::_objectList);
++    this->toList(OM_ENVIRON);
++
++    this->bInit = true;
++
++    if (root != NULL)
++        this->loadParams(root);
++
++    this->init_post_params();
++}
++
++void MapstartTrigger::loadParams(const TiXmlElement* root)
++{
++    MoverTrigger::loadParams(root);
++}
++
++bool MapstartTrigger::checkIsTriggered()
++{
++    if (this->bInit)
++    {
++        this->bInit = false;
++        return true;
++    }
++    
++    return false;
++}
+Index: mover.h
+===================================================================
+--- mover.h	(revision 0)
++++ mover.h	(revision 0)
+@@ -0,0 +1,76 @@
++/*!
++ * @file mover.h
++ *  A mover is an object that moves along scripted paths, released by scripted events.
++ */
++
++#ifndef _MOVER_H
++#define _MOVER_H
++
++#include "world_entity.h"
++#include "mover_trigger.h"
++#include "mover_station.h"
++#include "mover_trigger_list.h"
++#include "mover_station_list.h"
++#include "sound_source.h"
++
++
++class Mover : public WorldEntity
++{
++    ObjectListDeclaration(Mover);
++
++    public:
++        Mover(const TiXmlElement* root = NULL);
++        virtual ~Mover();
++
++        virtual void loadParams(const TiXmlElement* root);
++        virtual void tick(float dt);
++
++        void setLoop(bool bLoop = true) { this->bLoop = bLoop; }
++        void setRepeat(int n) { this->bRepeat = true; this->repeats = n; }
++        void setWaitAfterEachStation(bool bWaitAfterEachStation = true) { this->bWaitAfterEachStation = bWaitAfterEachStation; }
++        void setOnlyMoveWhileTriggered(bool bOnlyMoveWhileTriggered = true) { this->bOnlyMoveWhileTriggered = bOnlyMoveWhileTriggered; }
++        void setAttachTrigger(bool bAttachTrigger = true) { this->bAttachTrigger = bAttachTrigger; }
++        void setTriggers(const TiXmlElement* root);
++        void setStations(const TiXmlElement* root);
++        void setReopen(bool bReopen = true) { this->bReopen = bReopen; }
++        void setReclose(bool bReclose = true) { this->bReclose = bReclose; }
++
++    private:
++        void changeState(int state);
++        int closed();
++        int open();
++        int move(float dt);
++        int wait();
++        int next();
++        int delay();
++        int stay();
++        bool reachedStationsTarget(float dt);
++        Quaternion VtoQ(Vector v) { return Quaternion(v.x, v.y, v.z); }
++        Vector QtoV(Quaternion Q) { return Vector(); }
++
++        bool                        bLoop;
++        bool                        bRepeat;
++        int                         repeats;
++        bool                        bWaitAfterEachStation;
++        bool                        bOnlyMoveWhileTriggered;
++        bool                        bAttachTrigger;
++        bool                        bReopen;
++        bool                        bReclose;
++        
++        MoverTriggerList            *triggers;
++        MoverStationList            *stations;
++        
++        int                         state;
++        MoverStation                *station;
++        float                       time;
++        int                         repeatsToGo;
++        Vector                      originCoor;
++        Vector                      originDir;
++
++        OrxSound::SoundSource       soundSource_starting;
++        OrxSound::SoundSource       soundSource_moving;
++        OrxSound::SoundSource       soundSource_ending;
++};
++
++
++#endif
+Index: mover_trigger_approach.h
+===================================================================
+--- mover_trigger_approach.h	(revision 0)
++++ mover_trigger_approach.h	(revision 0)
+@@ -0,0 +1,36 @@
++/*!
++ * @file mover_trigger_approach.h
++ *  Gets triggered when a player enters a radius or a box.
++ */
++
++#ifndef _MOVER_TRIGGER_APPROACH_H
++#define _MOVER_TRIGGER_APPROACH_H
++
++#include "mover_trigger.h"
++
++
++class ApproachTrigger : public MoverTrigger
++{
++    ObjectListDeclaration(ApproachTrigger);
++
++    public:
++        ApproachTrigger(const TiXmlElement* root = NULL);
++        virtual void loadParams(const TiXmlElement* root);
++        void setRadius(float radius) { this->radius = radius; }
++        void setDistance(float x, float y, float z) { this->distanceX = x; this->distanceY = y; this->distanceZ = z; }
++        void setOnlyHumans(bool onlyHumans = true) { this->onlyHumans = onlyHumans; }
++        void setOnlyNPCs(bool onlyNPCs = true) { this->onlyNPCs = onlyNPCs; }
++
++    private:
++        virtual bool checkIsTriggered();
++        float radius;
++        float distanceX;
++        float distanceY;
++        float distanceZ;
++        bool onlyHumans;
++        bool onlyNPCs;
++};
++
++
++#endif
++
Index: /trunk/src/world_entities/environments/mover.h
===================================================================
--- /trunk/src/world_entities/environments/mover.h	(revision 10696)
+++ /trunk/src/world_entities/environments/mover.h	(revision 10696)
@@ -0,0 +1,76 @@
+/*!
+ * @file mover.h
+ *  A mover is an object that moves along scripted paths, released by scripted events.
+ */
+
+#ifndef _MOVER_H
+#define _MOVER_H
+
+#include "world_entity.h"
+#include "mover_trigger.h"
+#include "mover_station.h"
+#include "mover_trigger_list.h"
+#include "mover_station_list.h"
+#include "sound_source.h"
+
+
+class Mover : public WorldEntity
+{
+    ObjectListDeclaration(Mover);
+
+    public:
+        Mover(const TiXmlElement* root = NULL);
+        virtual ~Mover();
+
+        virtual void loadParams(const TiXmlElement* root);
+        virtual void tick(float dt);
+
+        void setLoop(bool bLoop = true) { this->bLoop = bLoop; }
+        void setRepeat(int n) { this->bRepeat = true; this->repeats = n; }
+        void setWaitAfterEachStation(bool bWaitAfterEachStation = true) { this->bWaitAfterEachStation = bWaitAfterEachStation; }
+        void setOnlyMoveWhileTriggered(bool bOnlyMoveWhileTriggered = true) { this->bOnlyMoveWhileTriggered = bOnlyMoveWhileTriggered; }
+        void setAttachTrigger(bool bAttachTrigger = true) { this->bAttachTrigger = bAttachTrigger; }
+        void setTriggers(const TiXmlElement* root);
+        void setStations(const TiXmlElement* root);
+        void setReopen(bool bReopen = true) { this->bReopen = bReopen; }
+        void setReclose(bool bReclose = true) { this->bReclose = bReclose; }
+
+    private:
+        void changeState(int state);
+        int closed();
+        int open();
+        int move(float dt);
+        int wait();
+        int next();
+        int delay();
+        int stay();
+        bool reachedStationsTarget(float dt);
+        Quaternion VtoQ(Vector v) { return Quaternion(v.x, v.y, v.z); }
+        Vector QtoV(Quaternion Q) { return Vector(); }
+
+        bool                        bLoop;
+        bool                        bRepeat;
+        int                         repeats;
+        bool                        bWaitAfterEachStation;
+        bool                        bOnlyMoveWhileTriggered;
+        bool                        bAttachTrigger;
+        bool                        bReopen;
+        bool                        bReclose;
+        
+        MoverTriggerList            *triggers;
+        MoverStationList            *stations;
+        
+        int                         state;
+        MoverStation                *station;
+        float                       time;
+        int                         repeatsToGo;
+        Vector                      originCoor;
+        Vector                      originDir;
+
+        OrxSound::SoundSource       soundSource_starting;
+        OrxSound::SoundSource       soundSource_moving;
+        OrxSound::SoundSource       soundSource_ending;
+};
+
+
+#endif
Index: /trunk/src/world_entities/environments/mover_station.cc
===================================================================
--- /trunk/src/world_entities/environments/mover_station.cc	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_station.cc	(revision 10696)
@@ -0,0 +1,103 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2007 orx
+
+   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, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Fabian 'x3n' Landau
+   co-programmer:
+*/
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "mover_station.h"
+#include "debug.h"
+
+ObjectListDefinition(MoverStation);
+CREATE_FACTORY(MoverStation);
+
+
+MoverStation::MoverStation(const TiXmlElement* root)
+{
+    PRINTF(0)("MoverStation %p erzeugt\n", this);
+    this->rank = 0;
+    this->relTargetCoor = Vector(0, 0, 0);
+    this->relTargetDir = Vector(0, 0, 0);
+    this->delay = 0;
+    this->movingTime = 0;
+    this->stayOpenTime = 0;
+    this->bAccelerate = false;
+    this->bDecelerate = false;
+    this->jumpToRank = 0;
+    this->bJumpToRank = false;
+    this->moveToRank = 0;
+    this->bMoveToRank = false;
+    this->bIsOpen = false;
+    this->bIsClosed = false;;
+
+    if (root != NULL)
+        this->loadParams(root);
+}
+
+MoverStation::~MoverStation()
+{
+}
+
+void MoverStation::loadParams(const TiXmlElement* root)
+{
+    WorldEntity::loadParams(root);
+
+    LoadParam(root, "rank", this, MoverStation, setRank)
+        .describe("The rank of the station in the stationlist of the mover.")
+        .defaultValues(0);
+    LoadParam(root, "rel-target-coor", this, MoverStation, setRelTargetCoor)
+        .describe("The relative coordinates of the stations target.")
+        .defaultValues(0, 0, 0);
+    LoadParam(root, "rel-target-dir", this, MoverStation, setRelTargetDir)
+        .describe("The relative direction of the stations target in all axes (roll/pitch/yaw).")
+        .defaultValues(0, 0, 0);
+    LoadParam(root, "delay", this, MoverStation, setDelay)
+        .describe("The amount of time the mover waits, before he starts moving.")
+        .defaultValues(0);
+    LoadParam(root, "moving-time", this, MoverStation, setMovingTime)
+        .describe("The amount of time the mover needs to move.")
+        .defaultValues(0);
+    LoadParam(root, "stay-open-time", this, MoverStation, setStayOpenTime)
+        .describe("The amount of time the mover waits when he reached the target.")
+        .defaultValues(0);
+    LoadParam(root, "bAccelerate", this, MoverStation, setAccelerate)
+        .describe("If true, the mover starts slowly and increases his speed.");
+    LoadParam(root, "bDecelerate", this, MoverStation, setDecelerate)
+        .describe("If true, the mover starts fast and decreases his speed.");
+    LoadParam(root, "jump-to-rank", this, MoverStation, setJumpToRank)
+        .describe("The rank of the station the mover should jump to, after reaching the target.")
+        .defaultValues(0);
+    LoadParam(root, "move-to-rank", this, MoverStation, setMoveToRank)
+        .describe("The rank of the station the mover should move to (instead of rel-target-coor).")
+        .defaultValues(0);
+    LoadParam(root, "bOpen", this, MoverStation, setOpen)
+        .describe("If true, the mover changes to state 'open' after reaching this station.");
+    LoadParam(root, "bClosed", this, MoverStation, setClosed)
+        .describe("If true, the mover changes to state 'closed' after reaching this station.");
+    LoadParam(root, "opening-sound", this, MoverStation, setOpeningSoundFile)
+        .describe("Sets the file of the opening sound source");
+    LoadParam(root, "opened-sound", this, MoverStation, setOpenedSoundFile)
+        .describe("Sets the file of the opened sound source");
+    LoadParam(root, "moving-sound", this, MoverStation, setMovingSoundFile)
+        .describe("Sets the file of the moving sound source");
+    LoadParam(root, "closing-sound", this, MoverStation, setClosingSoundFile)
+        .describe("Sets the file of the closing sound source");
+    LoadParam(root, "closed-sound", this, MoverStation, setClosedSoundFile)
+        .describe("Sets the file of the closed sound source");
+        
+    if (this->bMoveToRank)
+    {
+        this->relTargetCoor = Vector(0, 0, 0);
+        this->relTargetDir = Vector(0, 0, 0);
+    }
+}
Index: /trunk/src/world_entities/environments/mover_station.h
===================================================================
--- /trunk/src/world_entities/environments/mover_station.h	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_station.h	(revision 10696)
@@ -0,0 +1,67 @@
+/*!
+ * @file mover_station.h
+ *  A station for a mover.
+ */
+
+#ifndef _MOVER_STATION_H
+#define _MOVER_STATION_H
+
+#include "world_entity.h"
+#include "sound_buffer.h"
+#include "sound/resource_sound_buffer.h"
+
+
+class MoverStation : public WorldEntity
+{
+    friend class MoverStationList;
+
+    ObjectListDeclaration(MoverStation);
+
+    public:
+        MoverStation(const TiXmlElement* root = NULL);
+        virtual ~MoverStation();
+
+        virtual void loadParams(const TiXmlElement* root);
+
+        void setRank(int id) { this->rank = id; }
+        void setRelTargetCoor(float x = 0, float y = 0, float z = 0) { this->relTargetCoor = Vector(x, y, z); }
+        void setRelTargetDir(float wx = 0, float wy = 0, float wz = 0) { this->relTargetDir = Vector(wx, wy, wz); }
+        void setDelay(float t) { this->delay = t; }
+        void setMovingTime(float t) { this->movingTime = t; }
+        void setStayOpenTime(float t) { this->stayOpenTime = t; }
+        void setAccelerate() { this->bAccelerate = true; }
+        void setDecelerate() { this->bDecelerate = true; }
+        void setJumpToRank(int rank) { this->jumpToRank = rank; this->bJumpToRank = true; }
+        void setMoveToRank(int rank) { this->moveToRank = rank; this->bMoveToRank = true; }
+        void setOpen() { this->bIsOpen = true; }
+        void setClosed() { this->bIsClosed = true; }
+        void setOpeningSoundFile(const std::string& fileName) { this->soundBuffer_opening = OrxSound::ResourceSoundBuffer(fileName); }
+        void setOpenedSoundFile(const std::string& fileName) { this->soundBuffer_opened = OrxSound::ResourceSoundBuffer(fileName); }
+        void setMovingSoundFile(const std::string& fileName) { this->soundBuffer_moving = OrxSound::ResourceSoundBuffer(fileName); }
+        void setClosingSoundFile(const std::string& fileName) { this->soundBuffer_closing = OrxSound::ResourceSoundBuffer(fileName); }
+        void setClosedSoundFile(const std::string& fileName) { this->soundBuffer_closed = OrxSound::ResourceSoundBuffer(fileName); }
+
+    private:
+        int                     rank;
+        Vector                  relTargetCoor;
+        Vector              	relTargetDir;
+        float                   delay;
+        float                   movingTime;
+        float                   stayOpenTime;
+        bool                    bAccelerate;
+        bool                    bDecelerate;
+        int                     jumpToRank;
+        bool                    bJumpToRank;
+        int                     moveToRank;
+        bool                    bMoveToRank;
+        bool                    bIsOpen;
+        bool                    bIsClosed;
+        OrxSound::SoundBuffer   soundBuffer_opening;
+        OrxSound::SoundBuffer   soundBuffer_opened;
+        OrxSound::SoundBuffer   soundBuffer_moving;
+        OrxSound::SoundBuffer   soundBuffer_closing;
+        OrxSound::SoundBuffer   soundBuffer_closed;
+};
+
+
+#endif
Index: /trunk/src/world_entities/environments/mover_station_list.cc
===================================================================
--- /trunk/src/world_entities/environments/mover_station_list.cc	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_station_list.cc	(revision 10696)
@@ -0,0 +1,447 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2007 orx
+
+   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, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Fabian 'x3n' Landau
+   co-programmer:
+*/
+
+#include "mover_station_list.h"
+#include "debug.h"
+
+
+MoverStationList::MoverStationList()
+{
+    this->first = 0;
+    this->last = 0;
+    this->goForward = true;
+}
+
+MoverStationList::~MoverStationList()
+{
+    MoverStationListElement *temp1 = this->first;
+    MoverStationListElement *temp2;
+    while (temp1 != 0)
+    {
+        temp2 = temp1->next;
+        delete temp1;
+        temp1 = temp2;
+    }
+}
+
+void MoverStationList::addStation(MoverStation *station)
+{
+    PRINTF(0)("Füge MoverStation %p hinzu\n", station);
+    if (this->first == 0)
+    {
+        this->first = new MoverStationListElement(station);
+        this->last = this->first;
+        return;
+    }
+    else
+    {
+        if (this->first->station->rank > station->rank)
+        {
+            MoverStationListElement *temp = this->first;
+            this->first = new MoverStationListElement(station);
+            this->first->next = temp;
+            this->first->next->prev = this->first;
+            return;
+        }
+        else
+        {
+            MoverStationListElement *temp1 = this->first;
+            MoverStationListElement *temp2;
+            while (temp1->next != 0)
+            {
+                if (temp1->next->station->rank > station->rank)
+                {
+                    temp2 = temp1->next;
+                    temp1->next = new MoverStationListElement(station);
+                    temp1->next->prev = temp1;
+                    temp1->next->next = temp2;
+                    temp1->next->next->prev = temp1->next;
+                        
+                    return;
+                }
+                
+                temp1 = temp1->next;
+            }
+            
+            temp1->next = new MoverStationListElement(station);
+            temp1->next->prev = last;
+            last = temp1->next;
+        }
+    }
+}
+
+MoverStation *MoverStationList::getNextStation(MoverStation *station)
+{
+    if (this->goForward)
+    {
+        if (station)
+        {
+            MoverStationListElement *temp;
+            if (station->bJumpToRank)
+            {
+                temp = this->first;
+                while (temp != 0)
+                {
+                    if (temp->station->rank == station->jumpToRank)
+                        return temp->station;
+
+                    temp = temp->next;
+                }
+            } // no "else" here - if jumpToRank wasn't found, we return the following station (as usual)
+
+            if (station->bMoveToRank)
+            {
+                temp = this->first;
+                while (temp != 0)
+                {
+                    if (temp->station->rank == station->moveToRank)
+                        return temp->station;
+
+                    temp = temp->next;
+                }
+            } // no "else" here - if moveToRank wasn't found, we return the following station (as usual)
+
+            temp = this->first;
+            while (temp != 0)
+            {
+                if (temp->station == station)
+                {
+                    if (temp->next)
+                    {
+                        return temp->next->station;
+                    }
+                    else
+                    {
+                        this->goForward = false;
+                        return this->last->station;
+                    }
+                }
+                temp = temp->next;
+            }
+            return 0;
+        }
+        else
+        {
+            if (this->first)
+                return this->first->station;
+            else
+                return 0;
+        }
+    }
+    else
+    {
+        if (station)
+        {
+            MoverStationListElement *temp;
+            if (station->bJumpToRank)
+            {
+                temp = this->last;
+                while (temp != 0)
+                {
+                    if (temp->station->rank == station->jumpToRank)
+                        return temp->station;
+
+                    temp = temp->prev;
+                }
+            } // no "else" here - if jumpToRank wasn't found, we return the following station (as usual)
+
+            if (station->bMoveToRank)
+            {
+                temp = this->last;
+                while (temp != 0)
+                {
+                    if (temp->station->rank == station->moveToRank)
+                        return temp->station;
+
+                    temp = temp->prev;
+                }
+            } // no "else" here - if moveToRank wasn't found, we return the following station (as usual)
+
+            temp = this->last;
+            while (temp != 0)
+            {
+                if (temp->station == station)
+                {
+                    if (temp->prev)
+                    {
+                        return temp->prev->station;
+                    }
+                    else
+                    {
+                        this->goForward = true;
+                        return this->first->station;
+                    }
+                }
+                temp = temp->prev;
+            }
+            return 0;
+        }
+        else
+        {
+            if (this->last)
+                return this->last->station;
+            else
+                return 0;
+        }
+    }
+}
+
+Vector MoverStationList::getTotalRelCoor(MoverStation *station)
+{
+    MoverStationListElement *temp = this->first;
+    Vector totalRelCoor = Vector(0, 0, 0);
+
+    if (station)
+    {
+        if (this->goForward)
+        {
+            while (temp != 0)
+            {
+                totalRelCoor += temp->station->relTargetCoor;
+                if (temp->station == station)
+                    break;
+
+                temp = temp->next;
+            }
+        }
+        else
+        {
+            if (temp)
+            {
+                while (temp->next != 0)
+                {
+                    totalRelCoor += temp->next->station->relTargetCoor;
+                    if (temp->next->station == station)
+                        break;
+
+                    temp = temp->next;
+                }
+            }
+        }
+    }
+
+    return totalRelCoor;
+}
+
+Vector MoverStationList::getTotalRelDir(MoverStation *station)
+{
+    MoverStationListElement *temp = this->first;
+    Vector totalRelDir = Vector(0, 0, 0);
+    
+    if (station)
+    {
+        if (this->goForward)
+        {
+            while (temp != 0)
+            {
+                totalRelDir += temp->station->relTargetDir;
+                if (temp->station == station)
+                    break;
+
+                temp = temp->next;
+            }
+        }
+        else
+        {
+            if (temp)
+            {
+                while (temp->next != 0)
+                {
+                    totalRelDir += temp->next->station->relTargetDir;
+                    if (temp->next->station == station)
+                        break;
+
+                    temp = temp->next;
+                }
+            }
+        }
+    }
+
+    return totalRelDir;
+}
+
+bool MoverStationList::isOpen(MoverStation *station)
+{
+    if (station)
+        if ((this->goForward && this->last && this->last->station == station) || station->bIsOpen)
+            return true;
+        
+    return false;
+}
+
+bool MoverStationList::isClosed(MoverStation *station)
+{
+    if (station)
+        if ((!this->goForward && this->first && this->first->station == station) || station->bIsClosed)
+            return true;
+        
+    return false;
+}
+
+bool MoverStationList::changeDirection(bool bReopen, bool bReclose, bool bIsTriggered)
+{
+    if (this->goForward && bReclose && !bIsTriggered)
+    {
+        this->goForward = false;
+        return true;
+    }
+    
+    if (!this->goForward && bReopen && bIsTriggered)
+    {
+        this->goForward = true;
+        return true;
+    }
+    
+    return false;
+}
+
+Vector MoverStationList::getRelTargetCoor(MoverStation *station)
+{
+    if (station)
+    {
+        if (!station->bMoveToRank)
+        {
+            if (this->goForward)
+                return station->relTargetCoor;
+            else
+                return station->relTargetCoor * -1;
+        }
+        else
+        {
+            MoverStation *moveToStation = this->getStation(station->moveToRank);
+
+            if (moveToStation != 0)
+            {
+                if (this->goForward)
+                    return (this->getTotalRelCoor(station) - this->getTotalRelCoor(moveToStation)) * -1;
+                else
+                    return (this->getTotalRelCoor(station) - this->getTotalRelCoor(moveToStation));
+            }
+        }
+    }
+    
+    return Vector(0, 0, 0);
+}
+
+Vector MoverStationList::getRelTargetDir(MoverStation *station)
+{
+    if (station)
+    {
+        if (!station->bMoveToRank)
+        {
+            if (this->goForward)
+                return station->relTargetDir;
+            else
+                return station->relTargetDir * -1;
+        }
+        else
+        {
+            MoverStation *moveToStation = this->getStation(station->moveToRank);
+
+            if (moveToStation != 0)
+            {
+                if (this->goForward)
+                    return (station->relTargetDir - this->getTotalRelDir(moveToStation)) * -1;
+                else
+                    return station->relTargetDir - this->getTotalRelDir(moveToStation);
+            }
+        }
+    }
+    
+    return Vector(0, 0, 0);
+}
+
+Vector MoverStationList::getVelocity(MoverStation *station)
+{
+    if (station)
+        if (station->movingTime != 0)
+            return this->getRelTargetCoor(station) / station->movingTime;
+
+    return Vector(0, 0, 0);
+}
+
+Vector MoverStationList::getRotation(MoverStation *station)
+{
+    if (station)
+        if (station->movingTime != 0)
+            return this->getRelTargetDir(station) / station->movingTime;
+
+    return Vector(0, 0, 0);
+}
+
+OrxSound::SoundBuffer MoverStationList::getStartingSound(MoverStation *station)
+{
+    if (station)
+    {
+        if (this->goForward)
+            return station->soundBuffer_opening;
+        else
+            return station->soundBuffer_closing;
+    }
+
+    return OrxSound::ResourceSoundBuffer("");
+}
+
+OrxSound::SoundBuffer MoverStationList::getEndingSound(MoverStation *station)
+{
+    if (station)
+    {
+        if (this->goForward)
+            return station->soundBuffer_opened;
+        else
+            return station->soundBuffer_closed;
+    }
+
+    return OrxSound::ResourceSoundBuffer("");
+}
+
+OrxSound::SoundBuffer MoverStationList::getMovingSound(MoverStation *station)
+{
+    if (station)
+        return station->soundBuffer_moving;
+
+    return OrxSound::ResourceSoundBuffer("");
+}
+
+MoverStation *MoverStationList::getStation(int rank)
+{
+    MoverStationListElement *temp;
+
+    temp = this->first;
+    while (temp != 0)
+    {
+        if (temp->station->rank == rank)
+            return temp->station;
+
+        temp = temp->next;
+    }
+    
+    return 0;
+}
+
+////////////////////////////////////////////////////////
+
+
+MoverStationListElement::MoverStationListElement(MoverStation *station)
+{
+    this->station = station;
+    this->next = 0;
+    this->prev = 0;
+}
+
+MoverStationListElement::~MoverStationListElement()
+{
+    delete this->station;
+}
Index: /trunk/src/world_entities/environments/mover_station_list.h
===================================================================
--- /trunk/src/world_entities/environments/mover_station_list.h	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_station_list.h	(revision 10696)
@@ -0,0 +1,59 @@
+/*!
+ * @file mover_station_list.h
+ *  A list to store and handle several stations.
+ */
+
+#ifndef _MOVER_STATION_LIST_H
+#define _MOVER_STATION_LIST_H
+
+#include "mover_station.h"
+#include "sound_buffer.h"
+
+
+class MoverStationListElement
+{
+    public:
+        MoverStationListElement(MoverStation *station);
+        ~MoverStationListElement();
+
+        MoverStation *station;
+        MoverStationListElement *next;
+        MoverStationListElement *prev;
+};
+
+
+class MoverStationList
+{
+    public:
+        MoverStationList();
+        ~MoverStationList();
+
+        void addStation(MoverStation *station);
+        MoverStation *getNextStation(MoverStation *station);
+        Vector getTotalRelCoor(MoverStation *station);
+        Vector getTotalRelDir(MoverStation *station);
+        bool isOpen(MoverStation *station);
+        bool isClosed(MoverStation *station);
+        bool changeDirection(bool bReopen, bool bRelocse, bool bIsTriggered);
+
+        Vector getRelTargetCoor(MoverStation *station);
+        Vector getRelTargetDir(MoverStation *station);
+        float getDelay(MoverStation *station) { return station->delay; }
+        float getStayOpenTime(MoverStation *station) { return station->stayOpenTime; }
+        float getMovingTime(MoverStation *station) { return station->movingTime; }
+        Vector getVelocity(MoverStation *station);
+        Vector getRotation(MoverStation *station);
+        OrxSound::SoundBuffer getStartingSound(MoverStation *station);
+        OrxSound::SoundBuffer getMovingSound(MoverStation *station);
+        OrxSound::SoundBuffer getEndingSound(MoverStation *station);
+
+    private:
+        MoverStation *getStation(int rank);
+        
+        MoverStationListElement *first;
+        MoverStationListElement *last;
+        bool goForward;
+};
+
+
+#endif
Index: /trunk/src/world_entities/environments/mover_trigger.cc
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger.cc	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger.cc	(revision 10696)
@@ -0,0 +1,327 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2007 orx
+
+   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, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Fabian 'x3n' Landau
+   co-programmer:
+*/
+
+#include "util/loading/load_param_xml.h"
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "mover_trigger.h"
+#include "mover_trigger_approach.h"
+#include "mover_trigger_mapstart.h"
+#include "mover_trigger_key.h"
+#include "mover_trigger_event.h"
+#include "mover_trigger_intervisibility.h"
+#include <string.h>
+
+MoverTriggerEventList *MoverTrigger::events = 0;
+
+ObjectListDefinition(MoverTrigger);
+CREATE_FACTORY(MoverTrigger);
+
+
+MoverTrigger::MoverTrigger(const TiXmlElement* root)
+{
+    PRINTF(0)("5_1 MoverTrigger %p created\n", this);
+    this->registerObject(this, MoverTrigger::_objectList);
+    this->toList(OM_ENVIRON);
+
+    PRINTF(0)("5_2\n");
+    this->init_prae_params();
+    PRINTF(0)("5_3\n");
+
+    if (root != NULL)
+        this->loadParams(root);
+
+    PRINTF(0)("5_4\n");
+    this->init_post_params();
+    PRINTF(0)("5_5\n");
+}
+
+MoverTrigger::~MoverTrigger()
+{
+    PRINTF(0)("14_1 MoverTrigger %p destroyed\n", this);
+    if (this->triggers)
+        delete this->triggers;
+        
+    PRINTF(0)("14_2\n");
+    if (this->delaylist)
+        delete this->delaylist;
+    
+    PRINTF(0)("14_3\n");
+    if (MoverTrigger::events)
+    {
+        PRINTF(0)("14_4\n");
+        MoverTrigger::events->removeTrigger(this);
+        if (MoverTrigger::events->isEmpty())
+        {
+            PRINTF(0)("14_5\n");
+            delete MoverTrigger::events;
+            MoverTrigger::events = 0;
+        }
+    }
+    PRINTF(0)("14_6\n");
+}
+
+void MoverTrigger::init_prae_params()
+{
+    PRINTF(0)("6_1\n");
+    this->bIsTriggered = false;
+    this->delay = 0;
+    this->bIsWaitingForDelay = false;
+    this->relCoor = Vector(0, 0, 0);
+    this->bStayTriggered = false;
+    this->bTriggerOnceOnly = false;
+    this->bInvert = false;
+    this->bSwitch = false;
+    this->bObligatory = false;
+    this->bFirstRelease = true;
+    this->oldState = false;
+    this->time = 0;
+    
+    this->triggers = 0;
+    this->delaylist = 0;
+    
+//    if (!this->delaylist)
+        this->delaylist = new MoverTriggerDelayList();
+
+//    if (!this->triggers)
+        this->triggers = new MoverTriggerList();
+
+    PRINTF(0)("6_2\n");
+
+    if (!MoverTrigger::events)
+        MoverTrigger::events = new MoverTriggerEventList();
+        
+    PRINTF(0)("6_3\n");
+}
+
+void MoverTrigger::init_post_params()
+{
+    PRINTF(0)("6_4\n");
+    this->updateNode(0.001);
+    this->setBaseCoor(this->getAbsCoor());
+
+//    PRINTF(0)("6_5 MoverTrigger abs-coor: %f, %f, %f\n", this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z);
+
+    PRINTF(0)("6_5\n");
+    if (this->getName() != "")
+        MoverTrigger::events->addTrigger(this);
+        
+    PRINTF(0)("6_6\n");
+}
+
+void MoverTrigger::loadParams(const TiXmlElement* root)
+{
+    PRINTF(0)("7_1 MoverTrigger loadParams for trigger %p\n", this);
+    WorldEntity::loadParams(root);
+
+    LoadParam(root, "rel-coor", this, MoverTrigger, setRelCoor)
+        .describe("The relative position to the mover.")
+        .defaultValues(0, 0, 0);
+    LoadParam(root, "delay", this, MoverTrigger, setDelay)
+        .describe("The delay of the trigger.")
+        .defaultValues(0);
+    LoadParam(root, "bStayTriggered", this, MoverTrigger, setStayTriggered)
+        .describe("If the trigger gets released, he stays triggered forever.")
+        .defaultValues(false);
+    LoadParam(root, "bTriggerOnceOnly", this, MoverTrigger, setTriggerOnceOnly)
+        .describe("The trigger can only be released once.")
+        .defaultValues(false);
+    LoadParam(root, "bInvert", this, MoverTrigger, setInvert)
+        .describe("Inverts the state of the trigger.")
+        .defaultValues(false);
+    LoadParam(root, "bSwitch", this, MoverTrigger, setSwitch)
+        .describe("Each time the trigger gets triggered again, he switches his state.")
+        .defaultValues(false);
+    LoadParam(root, "bObligatory", this, MoverTrigger, setObligatory)
+        .describe("A obligatory trigger MUST be triggered to create an event.")
+        .defaultValues(false);
+    LoadParamXML(root, "triggers", this, MoverTrigger, setTriggers)
+        .describe("Adds a trigger that triggers the trigger.");
+}
+
+void MoverTrigger::setBaseCoor(Vector baseCoor)
+{
+//    PRINTF(0)("13_1\n");
+    this->setAbsCoor(baseCoor + this->relCoor);
+//    PRINTF(0)("13_2\n");
+    if (this->triggers)
+        this->triggers->setBaseCoor(baseCoor);
+//    PRINTF(0)("13_3\n");
+}
+
+void MoverTrigger::setTriggers(const TiXmlElement* root)
+{
+    PRINTF(0)("8_1\n");
+    if (!this->triggers)
+        this->triggers = new MoverTriggerList();
+        
+    const TiXmlElement* element = root->FirstChildElement();
+
+    PRINTF(0)("8_2\n");
+    while (element != NULL)
+    {
+        PRINTF(0)("8_3\n");
+        BaseObject *newObj = Factory::fabricate(element);
+//        MoverTrigger *newTrigger = ((MoverTrigger*)(&newObj));
+        MoverTrigger *newTrigger = (dynamic_cast< MoverTrigger *> ( newObj ));
+        this->triggers->addTrigger(newTrigger);
+//        this->triggers->addTrigger(MoverTrigger::createTrigger(element));
+        PRINTF(0)("8_4\n");
+        element = element->NextSiblingElement();
+    }
+    PRINTF(0)("8_5\n");
+}
+/*
+MoverTrigger *MoverTrigger::createTrigger(const TiXmlElement* root)
+{
+    PRINTF(0)("9_1\n");
+    PRINTF(0)("root->Value(): %s\n", root->Value());
+    if (strcmp(root->Value(), "MoverTrigger") == 0)
+    {
+        PRINTF(0)("9_2\n");
+        return new MoverTrigger(root);
+    }
+    else if (strcmp(root->Value(), "ApproachTrigger") == 0)
+    {
+        PRINTF(0)("9_3\n");
+        return new ApproachTrigger(root);
+    }
+    else if (strcmp(root->Value(), "MapstartTrigger") == 0)
+        return new MapstartTrigger(root);
+    else if (strcmp(root->Value(), "EventTrigger") == 0)
+        return new EventTrigger(root);
+    else if (strcmp(root->Value(), "KeyTrigger") == 0)
+        return new KeyTrigger(root);
+    else if (strcmp(root->Value(), "IntervisibilityTrigger") == 0)
+        return new IntervisibilityTrigger(root);
+    else
+    {
+        PRINTF(0)("9_4\n");
+        return new MoverTrigger(root);
+    }
+}
+*/
+void MoverTrigger::tick(float dt)
+{
+    this->time += dt;
+    
+    if (this->delaylist && this->delaylist->isEmpty())
+        this->time = 0;
+}
+
+bool MoverTrigger::isTriggered()
+{
+//    PRINTF(0)("17_1\n");
+    if (!this->bIsTriggered && this->bTriggerOnceOnly && !this->bFirstRelease)
+        return this->bInvert; // yes this makes sense... just think about it ;)
+
+//    PRINTF(0)("17_2\n");
+    if (!this->bStayTriggered || !this->bIsTriggered)
+    {
+//        PRINTF(0)("17_3\n");
+        if (this->triggers && this->delaylist)
+        {
+//            PRINTF(0)("17_4\n");
+            if (this->triggers->isTriggered())
+            {
+//                PRINTF(0)("17_5\n");
+                bool tempIsTriggered = this->checkIsTriggered();
+                if (this->delaylist->isEmpty())
+                {
+                    if (!this->bSwitch)
+                    {
+                        if (tempIsTriggered != this->bIsTriggered)
+                            this->delaylist->addState(tempIsTriggered, this->oldState, this->time + this->delay);
+                    }
+                    else
+                    {
+                        if (tempIsTriggered != this->oldState)
+                            this->delaylist->addState(tempIsTriggered, this->oldState, this->time + this->delay);
+                    }
+                }
+                else
+                {
+                    if (!this->bSwitch)
+                    {
+                        if (tempIsTriggered != this->delaylist->getLastState()->state)
+                            this->delaylist->addState(tempIsTriggered, this->oldState, this->time + this->delay);
+                    }
+                    else
+                    {
+                        if (tempIsTriggered != this->delaylist->getLastState()->oldState)
+                            this->delaylist->addState(tempIsTriggered, this->oldState, this->time + this->delay);
+                    }
+                }
+            }
+
+//            PRINTF(0)("17_6\n");
+            while (!this->delaylist->isEmpty())
+            {
+                MoverTriggerDelayListElement *element = this->delaylist->getFirstState();
+
+                if (element && (this->time >= element->time))
+                {
+                    if (!this->bSwitch)
+                    {
+                        this->bIsTriggered = element->state;
+                    }
+                    else
+                    {
+                        if (element->state && !this->oldState)
+                            this->bIsTriggered = !this->bIsTriggered;
+
+                        this->oldState = element->state;
+                    }
+
+                    this->delaylist->deleteFirstState();
+
+                    if (this->delaylist->isEmpty())
+                    {
+                        this->time = 0;
+                        break;
+                    }
+                    
+                    continue;
+                }
+                
+                break;
+            }
+        }
+        else
+            this->bIsTriggered = false;
+    }
+
+//    PRINTF(0)("17_7\n");
+    if (this->bIsTriggered && this->bTriggerOnceOnly && this->bFirstRelease)
+        this->bFirstRelease = false;
+
+//    PRINTF(0)("17_8\n");
+    if (this->bInvert)
+        return (!this->bIsTriggered);
+    else
+        return this->bIsTriggered;
+}
+
+bool MoverTrigger::isObligatory()
+{
+    return this->bObligatory;
+}
+
+bool MoverTrigger::checkIsTriggered()
+{
+    return true;
+}
+
+
Index: /trunk/src/world_entities/environments/mover_trigger.h
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger.h	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger.h	(revision 10696)
@@ -0,0 +1,73 @@
+/*!
+ * @file mover_trigger.h
+ *  Base-class for all mover triggers and container for an independent triggerlist.
+ */
+
+#ifndef _MOVER_TRIGGER_H
+#define _MOVER_TRIGGER_H
+
+#include "world_entity.h"
+#include "mover_trigger_list.h"
+#include "mover_trigger_event_list.h"
+#include "mover_trigger_delay_list.h"
+
+
+class MoverTriggerList;
+class MoverTriggerEventList;
+
+class MoverTrigger : public WorldEntity
+{
+    ObjectListDeclaration(MoverTrigger);
+    
+    public:
+        MoverTrigger(const TiXmlElement* root = NULL);
+        virtual ~MoverTrigger();
+
+        virtual void loadParams(const TiXmlElement* root);
+        virtual void tick(float dt);
+        
+        void setRelCoor(float x, float y, float z) { this->relCoor = Vector(x, y, z); }
+        void updateCoordinates(Vector baseCoor);
+        void setDelay(float delay) { this->delay = delay; }
+        void setStayTriggered(bool bStayTriggered = true) { this->bStayTriggered = bStayTriggered; }
+        void setTriggerOnceOnly(bool bTriggerOnceOnly = true) { this->bTriggerOnceOnly = bTriggerOnceOnly; }
+        void setInvert(bool bInvert = true) { this->bInvert = bInvert; }
+        void setSwitch(bool bSwitch = true) { this->bSwitch = bSwitch; }
+        void setObligatory(bool bObligatory = true) { this->bObligatory = bObligatory; }
+        void setTriggers(const TiXmlElement* root);
+        void setBaseCoor(Vector baseCoor);
+
+        bool isTriggered();
+        bool isObligatory();
+        static MoverTriggerEventList *events;
+        std::string getName() { return this->objectName; }
+        static MoverTrigger *createTrigger(const TiXmlElement* root);
+
+    protected:
+        void init_post_params();
+
+        bool                    bIsTriggered;
+
+    private:
+        void init_prae_params();
+        virtual bool checkIsTriggered();
+        
+        Vector                  relCoor;
+        float                   delay;
+        bool                    bIsWaitingForDelay;
+        bool                    bStayTriggered;
+        bool                    bTriggerOnceOnly;
+        bool                    bInvert;
+        bool                    bSwitch;
+        bool                    bObligatory;
+        float                   time;
+        bool                    bFirstRelease;
+        bool                    oldState;
+
+        MoverTriggerList        *triggers;
+        MoverTriggerDelayList   *delaylist;
+};
+
+
+#endif
+
Index: /trunk/src/world_entities/environments/mover_trigger_approach.cc
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_approach.cc	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_approach.cc	(revision 10696)
@@ -0,0 +1,106 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2007 orx
+
+   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, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Fabian 'x3n' Landau
+   co-programmer:
+*/
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "mover_trigger_approach.h"
+#include "debug.h"
+
+ObjectListDefinition(ApproachTrigger);
+CREATE_FACTORY(ApproachTrigger);
+
+
+ApproachTrigger::ApproachTrigger(const TiXmlElement* root)
+{
+    PRINTF(0)("13_1 ApproachTrigger %p created\n", this);
+    this->registerObject(this, ApproachTrigger::_objectList);
+    this->toList(OM_ENVIRON);
+
+    this->onlyHumans = false;
+    this->onlyNPCs =  false;
+    this->radius = 0;
+    this->distanceX = 0;
+    this->distanceY = 0;
+    this->distanceZ = 0;
+
+    if (root != NULL)
+        this->loadParams(root);
+
+    this->init_post_params();
+}
+
+void ApproachTrigger::loadParams(const TiXmlElement* root)
+{
+    PRINTF(0)("13_2 ApproachTrigger loadParams\n", this);
+    MoverTrigger::loadParams(root);
+
+    LoadParam(root, "radius", this, ApproachTrigger, setRadius)
+        .describe("The radius wherein the player releases the trigger.")
+        .defaultValues(0);
+    LoadParam(root, "distance", this, ApproachTrigger, setDistance)
+        .describe("The distance of all axes wherein the player releases the trigger.")
+        .defaultValues(0, 0, 0);
+    LoadParam(root, "onlyHumans", this, ApproachTrigger, setOnlyHumans)
+        .describe("Only human players can release the trigger.")
+        .defaultValues(false);
+    LoadParam(root, "onlyNPCs", this, ApproachTrigger, setOnlyNPCs)
+        .describe("Only NPCs can release the trigger.")
+        .defaultValues(false);
+}
+
+#include "playable.h"
+#include "../npcs/generic_npc.h"
+
+bool ApproachTrigger::checkIsTriggered()
+{
+    WorldEntity* entity;
+    float distance;
+
+    // for all players
+    if (!this->onlyNPCs)
+    {
+        for (ObjectList<Playable>::const_iterator it = Playable::objectList().begin();
+            it != Playable::objectList().end();
+            ++it)
+        {
+            entity = (*it);
+            distance = (this->getAbsCoor() - entity->getAbsCoor()).len();
+            if (distance <= this->radius
+                || (fabs(this->getAbsCoor().x - entity->getAbsCoor().x) <= this->distanceX
+                    && fabs(this->getAbsCoor().y - entity->getAbsCoor().y) <= this->distanceY
+                    && fabs(this->getAbsCoor().z - entity->getAbsCoor().z) <= this->distanceZ))
+                return true;
+        }
+    }
+
+    // for all npcs
+    if (!this->onlyHumans)
+    {
+        for (ObjectList<GenericNPC>::const_iterator it = GenericNPC::objectList().begin();
+            it != GenericNPC::objectList().end();
+            ++it)
+        {
+            entity = (*it);
+            distance = (this->getAbsCoor() - entity->getAbsCoor()).len();
+            if (distance <= this->radius
+                || (fabs(this->getAbsCoor().x - entity->getAbsCoor().x) <= this->distanceX
+                    && fabs(this->getAbsCoor().y - entity->getAbsCoor().y) <= this->distanceY
+                    && fabs(this->getAbsCoor().z - entity->getAbsCoor().z) <= this->distanceZ))
+                return true;
+        }
+    }
+    
+    return false;
+}
Index: /trunk/src/world_entities/environments/mover_trigger_approach.h
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_approach.h	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_approach.h	(revision 10696)
@@ -0,0 +1,36 @@
+/*!
+ * @file mover_trigger_approach.h
+ *  Gets triggered when a player enters a radius or a box.
+ */
+
+#ifndef _MOVER_TRIGGER_APPROACH_H
+#define _MOVER_TRIGGER_APPROACH_H
+
+#include "mover_trigger.h"
+
+
+class ApproachTrigger : public MoverTrigger
+{
+    ObjectListDeclaration(ApproachTrigger);
+
+    public:
+        ApproachTrigger(const TiXmlElement* root = NULL);
+        virtual void loadParams(const TiXmlElement* root);
+        void setRadius(float radius) { this->radius = radius; }
+        void setDistance(float x, float y, float z) { this->distanceX = x; this->distanceY = y; this->distanceZ = z; }
+        void setOnlyHumans(bool onlyHumans = true) { this->onlyHumans = onlyHumans; }
+        void setOnlyNPCs(bool onlyNPCs = true) { this->onlyNPCs = onlyNPCs; }
+
+    private:
+        virtual bool checkIsTriggered();
+        float radius;
+        float distanceX;
+        float distanceY;
+        float distanceZ;
+        bool onlyHumans;
+        bool onlyNPCs;
+};
+
+
+#endif
+
Index: /trunk/src/world_entities/environments/mover_trigger_delay_list.cc
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_delay_list.cc	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_delay_list.cc	(revision 10696)
@@ -0,0 +1,91 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2007 orx
+
+   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, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Fabian 'x3n' Landau
+   co-programmer:
+*/
+
+#include "mover_trigger_list.h"
+
+
+MoverTriggerDelayList::MoverTriggerDelayList()
+{
+    this->first = 0;
+}
+
+MoverTriggerDelayList::~MoverTriggerDelayList()
+{
+    while (this->first)
+        this->deleteFirstState();
+}
+
+void MoverTriggerDelayList::addState(bool state, bool oldState, float time)
+{
+    if (this->first == 0)
+        this->first = new MoverTriggerDelayListElement(state, oldState, time);
+    else
+    {
+        MoverTriggerDelayListElement *temp = this->first;
+        while (temp->next != 0)
+            temp = temp->next;
+            
+        temp->next = new MoverTriggerDelayListElement(state, oldState, time);
+    }
+}
+
+void MoverTriggerDelayList::deleteFirstState()
+{
+    if (this->first != 0)
+    {
+        MoverTriggerDelayListElement *temp = this->first->next;
+        delete this->first;
+        this->first = temp;
+    }
+}
+
+MoverTriggerDelayListElement *MoverTriggerDelayList::getFirstState()
+{
+    return this->first;
+}
+
+MoverTriggerDelayListElement *MoverTriggerDelayList::getLastState()
+{
+    MoverTriggerDelayListElement *temp = this->first;
+    while (temp != 0)
+    {
+        if (temp->next == 0)
+            return temp;
+            
+        temp = temp->next;
+    }
+            
+    return 0;
+}
+
+bool MoverTriggerDelayList::isEmpty()
+{
+    return (this->first == 0);
+}
+
+////////////////////////////////////////////////////////
+
+
+MoverTriggerDelayListElement::MoverTriggerDelayListElement(bool state, bool oldState, float time)
+{
+    this->state = state;
+    this->oldState = oldState;
+    this->time = time;
+    this->next = 0;
+}
+
+MoverTriggerDelayListElement::~MoverTriggerDelayListElement()
+{
+}
Index: /trunk/src/world_entities/environments/mover_trigger_delay_list.h
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_delay_list.h	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_delay_list.h	(revision 10696)
@@ -0,0 +1,40 @@
+/*!
+ * @file mover_trigger_delay_list.h
+ *  A list to delay trigger-state-changes.
+ */
+
+#ifndef _MOVER_TRIGGER_DELAY_LIST_H
+#define _MOVER_TRIGGER_DELAY_LIST_H
+
+
+class MoverTriggerDelayListElement
+{
+    public:
+        MoverTriggerDelayListElement(bool state, bool oldState, float time);
+        ~MoverTriggerDelayListElement();
+        
+        bool state;
+        bool oldState;
+        float time;
+        MoverTriggerDelayListElement *next;
+};
+
+
+class MoverTriggerDelayList
+{
+    public:
+        MoverTriggerDelayList();
+        ~MoverTriggerDelayList();
+
+        void addState(bool state, bool oldState, float time);
+        void deleteFirstState();
+        MoverTriggerDelayListElement *getFirstState();
+        MoverTriggerDelayListElement *getLastState();
+        bool isEmpty();
+
+    private:
+        MoverTriggerDelayListElement *first;
+};
+
+
+#endif
Index: /trunk/src/world_entities/environments/mover_trigger_event.cc
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_event.cc	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_event.cc	(revision 10696)
@@ -0,0 +1,75 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2007 orx
+
+   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, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Fabian 'x3n' Landau
+   co-programmer:
+*/
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "mover_trigger_event.h"
+#include "debug.h"
+
+ObjectListDefinition(EventTrigger);
+CREATE_FACTORY(EventTrigger);
+
+
+EventTrigger::EventTrigger(const TiXmlElement* root)
+{
+    PRINTF(0)("15_1 EventTrigger %p created\n", this);
+    this->registerObject(this, EventTrigger::_objectList);
+    this->toList(OM_ENVIRON);
+
+    this->eventName = "";
+    this->eventTriggers = 0;
+    this->bIsChecking = false;
+    
+    if (root != NULL)
+        this->loadParams(root);
+
+    this->init_post_params();
+}
+
+EventTrigger::~EventTrigger()
+{
+    delete this->eventTriggers;
+}
+
+void EventTrigger::loadParams(const TiXmlElement* root)
+{
+    MoverTrigger::loadParams(root);
+
+    LoadParam(root, "event", this, EventTrigger, setEvent)
+        .describe("The event that releases the trigger")
+        .defaultValues("");
+}
+
+bool EventTrigger::checkIsTriggered()
+{
+    if (this->bIsChecking)
+        return this->bIsTriggered; // to avoid event-loops
+        
+    if (!this->eventTriggers)
+    {
+        if (MoverTrigger::events)
+            this->eventTriggers = MoverTrigger::events->getPointerList(this->eventName);
+
+        if (!this->eventTriggers)
+            this->eventTriggers = new MoverTriggerPointerList();
+    }
+
+    this->bIsChecking = true;
+    bool isTriggered = this->eventTriggers->isTriggered();
+    this->bIsChecking = false;
+    
+    return isTriggered;
+}
+
Index: /trunk/src/world_entities/environments/mover_trigger_event.h
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_event.h	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_event.h	(revision 10696)
@@ -0,0 +1,31 @@
+/*!
+ * @file mover_trigger_event.h
+ *  Gets triggered when a specific event occurs.
+ */
+
+#ifndef _MOVER_TRIGGER_EVENT_H
+#define _MOVER_TRIGGER_EVENT_H
+
+#include "mover_trigger.h"
+
+
+class EventTrigger : public MoverTrigger
+{
+    ObjectListDeclaration(EventTrigger);
+
+    public:
+        EventTrigger(const TiXmlElement* root = NULL);
+        virtual ~EventTrigger();
+        virtual void loadParams(const TiXmlElement* root);
+        void setEvent(const std::string& eventName) { this->eventName = eventName; }
+
+    private:
+        virtual bool checkIsTriggered();
+        std::string                 eventName;
+        MoverTriggerPointerList     *eventTriggers;
+        bool                        bIsChecking;
+};
+
+
+#endif
+
Index: /trunk/src/world_entities/environments/mover_trigger_event_list.cc
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_event_list.cc	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_event_list.cc	(revision 10696)
@@ -0,0 +1,152 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2007 orx
+
+   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, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Fabian 'x3n' Landau
+   co-programmer:
+*/
+
+#include "mover_trigger_event_list.h"
+#include "debug.h"
+/*
+MoverTriggerEventList *listPointer = 0;
+
+MoverTriggerEventList::getListPointer()
+{
+    if (!this->listPointer)
+        this->listPointer = new MoverTriggerEventList();
+        
+    return this->listPointer;
+}
+*/
+MoverTriggerEventList::MoverTriggerEventList()
+{
+    this->first = 0;
+}
+
+
+MoverTriggerEventList::~MoverTriggerEventList()
+{
+    while (this->first != 0)
+    {
+        this->removeTrigger(this->first->trigger);
+    }
+}
+
+void MoverTriggerEventList::addTrigger(MoverTrigger *trigger)
+{
+    if (trigger)
+    {
+        if (!this->first)
+            this->first = new MoverTriggerEventListElement(trigger);
+        else
+        {
+            MoverTriggerEventListElement *temp = this->first;
+            while (temp->next != 0)
+                temp = temp->next;
+
+            temp->next = new MoverTriggerEventListElement(trigger);
+        }
+    }
+}
+
+void MoverTriggerEventList::removeTrigger(MoverTrigger *trigger)
+{
+    if (trigger)
+    {
+        if (this->first != 0)
+        {
+            if (this->first->trigger == trigger)
+            {
+                MoverTriggerEventListElement *temp = this->first->next;
+
+                delete this->first;
+                this->first = temp;
+            }
+            else
+            {
+                MoverTriggerEventListElement *temp = this->first;
+
+                while (temp != 0)
+                {
+                    if (temp->next && (temp->next->trigger == trigger))
+                    {
+                        MoverTriggerEventListElement *temp2 = temp->next->next;
+                        delete temp->next;
+                        temp->next = temp2;
+                    }
+
+                    temp = temp->next;
+                }
+            }
+        }
+    }
+}
+
+bool MoverTriggerEventList::isEmpty()
+{
+    return (this->first == 0);
+}
+
+bool MoverTriggerEventList::isTriggered(const std::string& triggerName)
+{
+    MoverTriggerEventListElement *temp = this->first;
+    bool isTriggered = false;
+    
+    while (temp != 0)
+    {
+        if (temp->trigger && (temp->trigger->getName() == triggerName))
+        {
+            if (temp->trigger->isTriggered())
+            {
+                isTriggered = true;
+            }
+            else
+            {
+                if (temp->trigger->isObligatory())
+                    return false;
+            }
+        }
+        
+        temp = temp->next;
+    }
+    
+    return isTriggered;
+}
+
+MoverTriggerPointerList *MoverTriggerEventList::getPointerList(const std::string& triggerName)
+{
+    MoverTriggerPointerList *list = new MoverTriggerPointerList();
+    MoverTriggerEventListElement *temp = this->first;
+
+    while (temp != 0)
+    {
+        if (temp->trigger && (temp->trigger->getName() == triggerName))
+            list->addTrigger(temp->trigger);
+
+        temp = temp->next;
+    }
+    
+    return list;
+}
+
+
+////////////////////////////////////////////////////////
+
+
+MoverTriggerEventListElement::MoverTriggerEventListElement(MoverTrigger *trigger)
+{
+    this->trigger = trigger;
+    this->next = 0;
+}
+
+MoverTriggerEventListElement::~MoverTriggerEventListElement()
+{
+}
Index: /trunk/src/world_entities/environments/mover_trigger_event_list.h
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_event_list.h	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_event_list.h	(revision 10696)
@@ -0,0 +1,48 @@
+/*!
+ * @file mover_trigger_event_list.h
+ *  A List to handle several events, caused by mover triggers.
+ */
+
+#ifndef _MOVER_TRIGGER_EVENT_LIST_H
+#define _MOVER_TRIGGER_EVENT_LIST_H
+
+#include "mover_trigger.h"
+#include "mover_trigger_pointer_list.h"
+
+
+class MoverTrigger;
+class MoverTriggerPointerList;
+
+class MoverTriggerEventListElement
+{
+    public:
+        MoverTriggerEventListElement(MoverTrigger *trigger);
+        ~MoverTriggerEventListElement();
+
+        MoverTrigger *trigger;
+        MoverTriggerEventListElement *next;
+};
+
+
+class MoverTriggerEventList
+{
+    public:
+//        static MoverTriggerEventList *getListPointer();
+        
+        void addTrigger(MoverTrigger *trigger);
+        void removeTrigger(MoverTrigger *trigger);
+        bool isEmpty();
+        bool isTriggered(const std::string& triggerName);
+        MoverTriggerPointerList *getPointerList(const std::string& triggerName);
+
+//    protected:
+        MoverTriggerEventList();
+        ~MoverTriggerEventList();
+
+    private:
+        MoverTriggerEventListElement *first;
+//        static MoverTriggerEventList *listPointer;
+};
+
+
+#endif
Index: /trunk/src/world_entities/environments/mover_trigger_intervisibility.cc
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_intervisibility.cc	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_intervisibility.cc	(revision 10696)
@@ -0,0 +1,54 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2007 orx
+
+   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, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Fabian 'x3n' Landau
+   co-programmer:
+*/
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "mover_trigger_intervisibility.h"
+
+ObjectListDefinition(IntervisibilityTrigger);
+CREATE_FACTORY(IntervisibilityTrigger);
+
+
+IntervisibilityTrigger::IntervisibilityTrigger(const TiXmlElement* root)
+{
+    this->registerObject(this, IntervisibilityTrigger::_objectList);
+    this->toList(OM_ENVIRON);
+
+    this->onlyHumans = false;
+    this->onlyNPCs =  false;
+
+    if (root != NULL)
+        this->loadParams(root);
+
+    this->init_post_params();
+}
+
+void IntervisibilityTrigger::loadParams(const TiXmlElement* root)
+{
+    MoverTrigger::loadParams(root);
+
+    LoadParam(root, "onlyHumans", this, IntervisibilityTrigger, setOnlyHumans)
+        .describe("Only human players can release the trigger.")
+        .defaultValues(false);
+    LoadParam(root, "onlyNPCs", this, IntervisibilityTrigger, setOnlyNPCs)
+        .describe("Only NPCs can release the trigger.")
+        .defaultValues(false);
+}
+
+bool IntervisibilityTrigger::checkIsTriggered()
+{
+    /* TODO */
+    return false;
+}
Index: /trunk/src/world_entities/environments/mover_trigger_intervisibility.h
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_intervisibility.h	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_intervisibility.h	(revision 10696)
@@ -0,0 +1,30 @@
+/*!
+ * @file mover_trigger_intervisibility.h
+ *  Gets triggered when the trigger "sees" the player.
+ */
+
+#ifndef _MOVER_TRIGGER_INTERVISIBILITY_H
+#define _MOVER_TRIGGER_INTERVISIBILITY_H
+
+#include "mover_trigger.h"
+
+
+class IntervisibilityTrigger : public MoverTrigger
+{
+    ObjectListDeclaration(IntervisibilityTrigger);
+
+    public:
+        IntervisibilityTrigger(const TiXmlElement* root = NULL);
+        virtual void loadParams(const TiXmlElement* root);
+        void setOnlyHumans(bool onlyHumans = true) { this->onlyHumans = onlyHumans; }
+        void setOnlyNPCs(bool onlyNPCs = true) { this->onlyNPCs = onlyNPCs; }
+
+    private:
+        virtual bool checkIsTriggered();
+        bool onlyHumans;
+        bool onlyNPCs;
+};
+
+
+#endif
+
Index: /trunk/src/world_entities/environments/mover_trigger_key.cc
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_key.cc	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_key.cc	(revision 10696)
@@ -0,0 +1,49 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2007 orx
+
+   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, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Fabian 'x3n' Landau
+   co-programmer:
+*/
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "mover_trigger_key.h"
+
+ObjectListDefinition(KeyTrigger);
+CREATE_FACTORY(KeyTrigger);
+
+
+KeyTrigger::KeyTrigger(const TiXmlElement* root)
+{
+    this->registerObject(this, KeyTrigger::_objectList);
+    this->toList(OM_ENVIRON);
+    this->keyName = "";
+
+    if (root != NULL)
+        this->loadParams(root);
+
+    this->init_post_params();
+}
+
+void KeyTrigger::loadParams(const TiXmlElement* root)
+{
+    MoverTrigger::loadParams(root);
+
+    LoadParam(root, "key", this, KeyTrigger, setKey)
+        .describe("The key that releases the trigger")
+        .defaultValues("");
+}
+
+bool KeyTrigger::checkIsTriggered()
+{
+    /* TODO */
+    return false;
+}
Index: /trunk/src/world_entities/environments/mover_trigger_key.h
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_key.h	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_key.h	(revision 10696)
@@ -0,0 +1,28 @@
+/*!
+ * @file mover_trigger_key.h
+ *  Gets triggered when player presses a key.
+ */
+
+#ifndef _MOVER_TRIGGER_KEY_H
+#define _MOVER_TRIGGER_KEY_H
+
+#include "mover_trigger.h"
+
+
+class KeyTrigger : public MoverTrigger
+{
+    ObjectListDeclaration(KeyTrigger);
+
+    public:
+        KeyTrigger(const TiXmlElement* root = NULL);
+        virtual void loadParams(const TiXmlElement* root);
+        void setKey(const std::string& keyName) { this->keyName = keyName; }
+
+    private:
+        virtual bool checkIsTriggered();
+        std::string keyName;
+};
+
+
+#endif
+
Index: /trunk/src/world_entities/environments/mover_trigger_list.cc
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_list.cc	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_list.cc	(revision 10696)
@@ -0,0 +1,126 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2007 orx
+
+   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, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Fabian 'x3n' Landau
+   co-programmer:
+*/
+
+#include "mover_trigger_list.h"
+#include "debug.h"
+
+
+MoverTriggerList::MoverTriggerList()
+{
+    PRINTF(0)("10_1 MoverTriggerList %p created\n", this);
+    this->first = 0;
+    PRINTF(0)("10_2 first element: %p\n", this->first);
+}
+
+MoverTriggerList::~MoverTriggerList()
+{
+    PRINTF(0)("13_1 MoverTriggerList %p destroyed\n", this);
+    MoverTriggerListElement *temp1 = this->first;
+    MoverTriggerListElement *temp2;
+    while (temp1 != 0)
+    {
+        temp2 = temp1->next;
+        delete temp1;
+        temp1 = temp2;
+    }
+}
+
+void MoverTriggerList::addTrigger(MoverTrigger *trigger)
+{
+    PRINTF(0)("11_1 added trigger %p to list %p\n", trigger, this);
+    if (trigger)
+    {
+        if (this->first == 0)
+        {
+            PRINTF(0)("11_2\n");
+            this->first = new MoverTriggerListElement(trigger);
+        }
+        else
+        {
+            PRINTF(0)("11_3\n");
+            MoverTriggerListElement *temp = this->first;
+            while (temp->next != 0)
+                temp = temp->next;
+
+            temp->next = new MoverTriggerListElement(trigger);
+            PRINTF(0)("11_4\n");
+        }
+    }
+    PRINTF(0)("11_5\n");
+}
+
+bool MoverTriggerList::isTriggered()
+{
+//    PRINTF(0)("16_1\n");
+    if (this->first == 0)
+    {
+//        PRINTF(0)("16_2\n");
+        return true;
+    }
+    else
+    {
+//        PRINTF(0)("16_3\n");
+        bool isTriggered = false;
+        MoverTriggerListElement *temp = this->first;
+
+        while (temp != 0)
+        {
+            if (temp->trigger->isTriggered())
+            {
+                isTriggered = true;
+            }
+            else
+            {
+                if (temp->trigger->isObligatory())
+                    return false;
+            }
+                    
+            temp = temp->next;
+        }
+
+//        PRINTF(0)("16_4\n");
+        return isTriggered;
+    }
+}
+
+void MoverTriggerList::setBaseCoor(Vector baseCoor)
+{
+//    PRINTF(0)("12_1 set base coor in %p\n", this);
+//    PRINTF(0)("12_2 first element: %p\n", this->first);
+    MoverTriggerListElement *temp = this->first;
+    while (temp != 0)
+    {
+//        PRINTF(0)("12_3\n");
+        temp->trigger->setBaseCoor(baseCoor);
+        temp = temp->next;
+    }
+//    PRINTF(0)("12_4\n");
+}
+
+
+////////////////////////////////////////////////////////
+
+
+MoverTriggerListElement::MoverTriggerListElement(MoverTrigger *trigger)
+{
+    this->trigger = trigger;
+    this->next = 0;
+}
+
+MoverTriggerListElement::~MoverTriggerListElement()
+{
+    if (this->trigger)
+        delete this->trigger;
+}
Index: /trunk/src/world_entities/environments/mover_trigger_list.h
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_list.h	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_list.h	(revision 10696)
@@ -0,0 +1,40 @@
+/*!
+ * @file mover_trigger_list.h
+ *  A list to store and handle several triggers.
+ */
+
+#ifndef _MOVER_TRIGGER_LIST_H
+#define _MOVER_TRIGGER_LIST_H
+
+#include "mover_trigger.h"
+
+
+class MoverTrigger;
+
+class MoverTriggerListElement
+{
+    public:
+        MoverTriggerListElement(MoverTrigger *trigger);
+        ~MoverTriggerListElement();
+        
+        MoverTrigger *trigger;
+        MoverTriggerListElement *next;
+};
+
+
+class MoverTriggerList
+{
+    public:
+        MoverTriggerList();
+        ~MoverTriggerList();
+
+        void addTrigger(MoverTrigger *trigger);
+        bool isTriggered();
+        void setBaseCoor(Vector baseCoor);
+
+    private:
+        MoverTriggerListElement *first;
+};
+
+
+#endif
Index: /trunk/src/world_entities/environments/mover_trigger_mapstart.cc
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_mapstart.cc	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_mapstart.cc	(revision 10696)
@@ -0,0 +1,53 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2007 orx
+
+   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, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Fabian 'x3n' Landau
+   co-programmer:
+*/
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "mover_trigger_mapstart.h"
+#include "debug.h"
+
+ObjectListDefinition(MapstartTrigger);
+CREATE_FACTORY(MapstartTrigger);
+
+
+MapstartTrigger::MapstartTrigger(const TiXmlElement* root)
+{
+    PRINTF(0)("13_1 MapstartTrigger %p created\n", this);
+    this->registerObject(this, MapstartTrigger::_objectList);
+    this->toList(OM_ENVIRON);
+
+    this->bInit = true;
+
+    if (root != NULL)
+        this->loadParams(root);
+
+    this->init_post_params();
+}
+
+void MapstartTrigger::loadParams(const TiXmlElement* root)
+{
+    MoverTrigger::loadParams(root);
+}
+
+bool MapstartTrigger::checkIsTriggered()
+{
+    if (this->bInit)
+    {
+        this->bInit = false;
+        return true;
+    }
+    
+    return false;
+}
Index: /trunk/src/world_entities/environments/mover_trigger_mapstart.h
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_mapstart.h	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_mapstart.h	(revision 10696)
@@ -0,0 +1,27 @@
+/*!
+ * @file mover_trigger_mapstart.h
+ *  Gets triggered when the map starts.
+ */
+
+#ifndef _MOVER_TRIGGER_MAPSTART_H
+#define _MOVER_TRIGGER_MAPSTART_H
+
+#include "mover_trigger.h"
+
+
+class MapstartTrigger : public MoverTrigger
+{
+    ObjectListDeclaration(MapstartTrigger);
+
+    public:
+        MapstartTrigger(const TiXmlElement* root = NULL);
+        virtual void loadParams(const TiXmlElement* root);
+
+    private:
+        virtual bool checkIsTriggered();
+        bool bInit;
+};
+
+
+#endif
+
Index: /trunk/src/world_entities/environments/mover_trigger_pointer_list.cc
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_pointer_list.cc	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_pointer_list.cc	(revision 10696)
@@ -0,0 +1,97 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2007 orx
+
+   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, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Fabian 'x3n' Landau
+   co-programmer:
+*/
+
+#include "mover_trigger_pointer_list.h"
+#include "debug.h"
+
+
+MoverTriggerPointerList::MoverTriggerPointerList()
+{
+    this->first = 0;
+}
+
+MoverTriggerPointerList::~MoverTriggerPointerList()
+{
+    MoverTriggerPointerListElement *temp1 = this->first;
+    MoverTriggerPointerListElement *temp2;
+    while (temp1 != 0)
+    {
+        temp2 = temp1->next;
+        delete temp1;
+        temp1 = temp2;
+    }
+}
+
+void MoverTriggerPointerList::addTrigger(MoverTrigger *trigger)
+{
+    if (trigger)
+    {
+        if (this->first == 0)
+        {
+            this->first = new MoverTriggerPointerListElement(trigger);
+        }
+        else
+        {
+            MoverTriggerPointerListElement *temp = this->first;
+            while (temp->next != 0)
+                temp = temp->next;
+
+            temp->next = new MoverTriggerPointerListElement(trigger);
+        }
+    }
+}
+
+bool MoverTriggerPointerList::isTriggered()
+{
+    if (this->first == 0)
+    {
+        return false;
+    }
+    else
+    {
+        bool isTriggered = false;
+        MoverTriggerPointerListElement *temp = this->first;
+
+        while (temp != 0)
+        {
+            if (temp->trigger->isTriggered())
+            {
+                isTriggered = true;
+            }
+            else
+            {
+                if (temp->trigger->isObligatory())
+                    return false;
+            }
+                    
+            temp = temp->next;
+        }
+
+        return isTriggered;
+    }
+}
+
+////////////////////////////////////////////////////////
+
+
+MoverTriggerPointerListElement::MoverTriggerPointerListElement(MoverTrigger *trigger)
+{
+    this->trigger = trigger;
+    this->next = 0;
+}
+
+MoverTriggerPointerListElement::~MoverTriggerPointerListElement()
+{
+}
Index: /trunk/src/world_entities/environments/mover_trigger_pointer_list.h
===================================================================
--- /trunk/src/world_entities/environments/mover_trigger_pointer_list.h	(revision 10696)
+++ /trunk/src/world_entities/environments/mover_trigger_pointer_list.h	(revision 10696)
@@ -0,0 +1,39 @@
+/*!
+ * @file mover_trigger_pointer_list.h
+ *  A list to store and handle several trigger pointers.
+ */
+
+#ifndef _MOVER_TRIGGER_POINTER_LIST_H
+#define _MOVER_TRIGGER_POINTER_LIST_H
+
+#include "mover_trigger.h"
+
+
+class MoverTrigger;
+
+class MoverTriggerPointerListElement
+{
+    public:
+        MoverTriggerPointerListElement(MoverTrigger *trigger);
+        ~MoverTriggerPointerListElement();
+        
+        MoverTrigger *trigger;
+        MoverTriggerPointerListElement *next;
+};
+
+
+class MoverTriggerPointerList
+{
+    public:
+        MoverTriggerPointerList();
+        ~MoverTriggerPointerList();
+
+        void addTrigger(MoverTrigger *trigger);
+        bool isTriggered();
+
+    private:
+        MoverTriggerPointerListElement *first;
+};
+
+
+#endif
