/* 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; }