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::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::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 + +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 +