| 1 | /* | 
|---|
| 2 |    orxonox - the future of 3D-vertical-scrollers | 
|---|
| 3 |  | 
|---|
| 4 |    Copyright (C) 2007 orx | 
|---|
| 5 |  | 
|---|
| 6 |    This program is free software; you can redistribute it and/or modify | 
|---|
| 7 |    it under the terms of the GNU General Public License as published by | 
|---|
| 8 |    the Free Software Foundation; either version 2, or (at your option) | 
|---|
| 9 |    any later version. | 
|---|
| 10 |  | 
|---|
| 11 |    ### File Specific: | 
|---|
| 12 |    main-programmer: Fabian 'x3n' Landau | 
|---|
| 13 |    co-programmer: | 
|---|
| 14 | */ | 
|---|
| 15 |  | 
|---|
| 16 | #include "util/loading/load_param_xml.h" | 
|---|
| 17 | #include "util/loading/load_param.h" | 
|---|
| 18 | #include "util/loading/factory.h" | 
|---|
| 19 | #include "mover_trigger.h" | 
|---|
| 20 | #include "mover_trigger_approach.h" | 
|---|
| 21 | #include "mover_trigger_mapstart.h" | 
|---|
| 22 | #include "mover_trigger_key.h" | 
|---|
| 23 | #include "mover_trigger_event.h" | 
|---|
| 24 | #include "mover_trigger_intervisibility.h" | 
|---|
| 25 | #include <string.h> | 
|---|
| 26 |  | 
|---|
| 27 | MoverTriggerEventList *MoverTrigger::events = 0; | 
|---|
| 28 |  | 
|---|
| 29 | ObjectListDefinition(MoverTrigger); | 
|---|
| 30 | CREATE_FACTORY(MoverTrigger); | 
|---|
| 31 |  | 
|---|
| 32 |  | 
|---|
| 33 | MoverTrigger::MoverTrigger(const TiXmlElement* root) | 
|---|
| 34 | { | 
|---|
| 35 |     PRINTF(0)("5_1 MoverTrigger %p created\n", this); | 
|---|
| 36 |     this->registerObject(this, MoverTrigger::_objectList); | 
|---|
| 37 |     this->toList(OM_ENVIRON); | 
|---|
| 38 |  | 
|---|
| 39 |     PRINTF(0)("5_2\n"); | 
|---|
| 40 |     this->init_prae_params(); | 
|---|
| 41 |     PRINTF(0)("5_3\n"); | 
|---|
| 42 |  | 
|---|
| 43 |     if (root != NULL) | 
|---|
| 44 |         this->loadParams(root); | 
|---|
| 45 |  | 
|---|
| 46 |     PRINTF(0)("5_4\n"); | 
|---|
| 47 |     this->init_post_params(); | 
|---|
| 48 |     PRINTF(0)("5_5\n"); | 
|---|
| 49 | } | 
|---|
| 50 |  | 
|---|
| 51 | MoverTrigger::~MoverTrigger() | 
|---|
| 52 | { | 
|---|
| 53 |     PRINTF(0)("14_1 MoverTrigger %p destroyed\n", this); | 
|---|
| 54 |     if (this->triggers) | 
|---|
| 55 |         delete this->triggers; | 
|---|
| 56 |          | 
|---|
| 57 |     PRINTF(0)("14_2\n"); | 
|---|
| 58 |     if (this->delaylist) | 
|---|
| 59 |         delete this->delaylist; | 
|---|
| 60 |      | 
|---|
| 61 |     PRINTF(0)("14_3\n"); | 
|---|
| 62 |     if (MoverTrigger::events) | 
|---|
| 63 |     { | 
|---|
| 64 |         PRINTF(0)("14_4\n"); | 
|---|
| 65 |         MoverTrigger::events->removeTrigger(this); | 
|---|
| 66 |         if (MoverTrigger::events->isEmpty()) | 
|---|
| 67 |         { | 
|---|
| 68 |             PRINTF(0)("14_5\n"); | 
|---|
| 69 |             delete MoverTrigger::events; | 
|---|
| 70 |             MoverTrigger::events = 0; | 
|---|
| 71 |         } | 
|---|
| 72 |     } | 
|---|
| 73 |     PRINTF(0)("14_6\n"); | 
|---|
| 74 | } | 
|---|
| 75 |  | 
|---|
| 76 | void MoverTrigger::init_prae_params() | 
|---|
| 77 | { | 
|---|
| 78 |     PRINTF(0)("6_1\n"); | 
|---|
| 79 |     this->bIsTriggered = false; | 
|---|
| 80 |     this->delay = 0; | 
|---|
| 81 |     this->bIsWaitingForDelay = false; | 
|---|
| 82 |     this->relCoor = Vector(0, 0, 0); | 
|---|
| 83 |     this->bStayTriggered = false; | 
|---|
| 84 |     this->bTriggerOnceOnly = false; | 
|---|
| 85 |     this->bInvert = false; | 
|---|
| 86 |     this->bSwitch = false; | 
|---|
| 87 |     this->bObligatory = false; | 
|---|
| 88 |     this->bFirstRelease = true; | 
|---|
| 89 |     this->oldState = false; | 
|---|
| 90 |     this->time = 0; | 
|---|
| 91 |      | 
|---|
| 92 |     this->triggers = 0; | 
|---|
| 93 |     this->delaylist = 0; | 
|---|
| 94 |      | 
|---|
| 95 | //    if (!this->delaylist) | 
|---|
| 96 |         this->delaylist = new MoverTriggerDelayList(); | 
|---|
| 97 |  | 
|---|
| 98 | //    if (!this->triggers) | 
|---|
| 99 |         this->triggers = new MoverTriggerList(); | 
|---|
| 100 |  | 
|---|
| 101 |     PRINTF(0)("6_2\n"); | 
|---|
| 102 |  | 
|---|
| 103 |     if (!MoverTrigger::events) | 
|---|
| 104 |         MoverTrigger::events = new MoverTriggerEventList(); | 
|---|
| 105 |          | 
|---|
| 106 |     PRINTF(0)("6_3\n"); | 
|---|
| 107 | } | 
|---|
| 108 |  | 
|---|
| 109 | void MoverTrigger::init_post_params() | 
|---|
| 110 | { | 
|---|
| 111 |     PRINTF(0)("6_4\n"); | 
|---|
| 112 |     this->updateNode(0.001); | 
|---|
| 113 |     this->setBaseCoor(this->getAbsCoor()); | 
|---|
| 114 |  | 
|---|
| 115 | //    PRINTF(0)("6_5 MoverTrigger abs-coor: %f, %f, %f\n", this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z); | 
|---|
| 116 |  | 
|---|
| 117 |     PRINTF(0)("6_5\n"); | 
|---|
| 118 |     if (this->getName() != "") | 
|---|
| 119 |         MoverTrigger::events->addTrigger(this); | 
|---|
| 120 |          | 
|---|
| 121 |     PRINTF(0)("6_6\n"); | 
|---|
| 122 | } | 
|---|
| 123 |  | 
|---|
| 124 | void MoverTrigger::loadParams(const TiXmlElement* root) | 
|---|
| 125 | { | 
|---|
| 126 |     PRINTF(0)("7_1 MoverTrigger loadParams for trigger %p\n", this); | 
|---|
| 127 |     WorldEntity::loadParams(root); | 
|---|
| 128 |  | 
|---|
| 129 |     LoadParam(root, "rel-coor", this, MoverTrigger, setRelCoor) | 
|---|
| 130 |         .describe("The relative position to the mover.") | 
|---|
| 131 |         .defaultValues(0, 0, 0); | 
|---|
| 132 |     LoadParam(root, "delay", this, MoverTrigger, setDelay) | 
|---|
| 133 |         .describe("The delay of the trigger.") | 
|---|
| 134 |         .defaultValues(0); | 
|---|
| 135 |     LoadParam(root, "bStayTriggered", this, MoverTrigger, setStayTriggered) | 
|---|
| 136 |         .describe("If the trigger gets released, he stays triggered forever.") | 
|---|
| 137 |         .defaultValues(false); | 
|---|
| 138 |     LoadParam(root, "bTriggerOnceOnly", this, MoverTrigger, setTriggerOnceOnly) | 
|---|
| 139 |         .describe("The trigger can only be released once.") | 
|---|
| 140 |         .defaultValues(false); | 
|---|
| 141 |     LoadParam(root, "bInvert", this, MoverTrigger, setInvert) | 
|---|
| 142 |         .describe("Inverts the state of the trigger.") | 
|---|
| 143 |         .defaultValues(false); | 
|---|
| 144 |     LoadParam(root, "bSwitch", this, MoverTrigger, setSwitch) | 
|---|
| 145 |         .describe("Each time the trigger gets triggered again, he switches his state.") | 
|---|
| 146 |         .defaultValues(false); | 
|---|
| 147 |     LoadParam(root, "bObligatory", this, MoverTrigger, setObligatory) | 
|---|
| 148 |         .describe("A obligatory trigger MUST be triggered to create an event.") | 
|---|
| 149 |         .defaultValues(false); | 
|---|
| 150 |     LoadParamXML(root, "triggers", this, MoverTrigger, setTriggers) | 
|---|
| 151 |         .describe("Adds a trigger that triggers the trigger."); | 
|---|
| 152 | } | 
|---|
| 153 |  | 
|---|
| 154 | void MoverTrigger::setBaseCoor(Vector baseCoor) | 
|---|
| 155 | { | 
|---|
| 156 | //    PRINTF(0)("13_1\n"); | 
|---|
| 157 |     this->setAbsCoor(baseCoor + this->relCoor); | 
|---|
| 158 | //    PRINTF(0)("13_2\n"); | 
|---|
| 159 |     if (this->triggers) | 
|---|
| 160 |         this->triggers->setBaseCoor(baseCoor); | 
|---|
| 161 | //    PRINTF(0)("13_3\n"); | 
|---|
| 162 | } | 
|---|
| 163 |  | 
|---|
| 164 | void MoverTrigger::setTriggers(const TiXmlElement* root) | 
|---|
| 165 | { | 
|---|
| 166 |     PRINTF(0)("8_1\n"); | 
|---|
| 167 |     if (!this->triggers) | 
|---|
| 168 |         this->triggers = new MoverTriggerList(); | 
|---|
| 169 |          | 
|---|
| 170 |     const TiXmlElement* element = root->FirstChildElement(); | 
|---|
| 171 |  | 
|---|
| 172 |     PRINTF(0)("8_2\n"); | 
|---|
| 173 |     while (element != NULL) | 
|---|
| 174 |     { | 
|---|
| 175 |         PRINTF(0)("8_3\n"); | 
|---|
| 176 |         BaseObject *newObj = Factory::fabricate(element); | 
|---|
| 177 | //        MoverTrigger *newTrigger = ((MoverTrigger*)(&newObj)); | 
|---|
| 178 |         MoverTrigger *newTrigger = (dynamic_cast< MoverTrigger *> ( newObj )); | 
|---|
| 179 |         this->triggers->addTrigger(newTrigger); | 
|---|
| 180 | //        this->triggers->addTrigger(MoverTrigger::createTrigger(element)); | 
|---|
| 181 |         PRINTF(0)("8_4\n"); | 
|---|
| 182 |         element = element->NextSiblingElement(); | 
|---|
| 183 |     } | 
|---|
| 184 |     PRINTF(0)("8_5\n"); | 
|---|
| 185 | } | 
|---|
| 186 | /* | 
|---|
| 187 | MoverTrigger *MoverTrigger::createTrigger(const TiXmlElement* root) | 
|---|
| 188 | { | 
|---|
| 189 |     PRINTF(0)("9_1\n"); | 
|---|
| 190 |     PRINTF(0)("root->Value(): %s\n", root->Value()); | 
|---|
| 191 |     if (strcmp(root->Value(), "MoverTrigger") == 0) | 
|---|
| 192 |     { | 
|---|
| 193 |         PRINTF(0)("9_2\n"); | 
|---|
| 194 |         return new MoverTrigger(root); | 
|---|
| 195 |     } | 
|---|
| 196 |     else if (strcmp(root->Value(), "ApproachTrigger") == 0) | 
|---|
| 197 |     { | 
|---|
| 198 |         PRINTF(0)("9_3\n"); | 
|---|
| 199 |         return new ApproachTrigger(root); | 
|---|
| 200 |     } | 
|---|
| 201 |     else if (strcmp(root->Value(), "MapstartTrigger") == 0) | 
|---|
| 202 |         return new MapstartTrigger(root); | 
|---|
| 203 |     else if (strcmp(root->Value(), "EventTrigger") == 0) | 
|---|
| 204 |         return new EventTrigger(root); | 
|---|
| 205 |     else if (strcmp(root->Value(), "KeyTrigger") == 0) | 
|---|
| 206 |         return new KeyTrigger(root); | 
|---|
| 207 |     else if (strcmp(root->Value(), "IntervisibilityTrigger") == 0) | 
|---|
| 208 |         return new IntervisibilityTrigger(root); | 
|---|
| 209 |     else | 
|---|
| 210 |     { | 
|---|
| 211 |         PRINTF(0)("9_4\n"); | 
|---|
| 212 |         return new MoverTrigger(root); | 
|---|
| 213 |     } | 
|---|
| 214 | } | 
|---|
| 215 | */ | 
|---|
| 216 | void MoverTrigger::tick(float dt) | 
|---|
| 217 | { | 
|---|
| 218 |     this->time += dt; | 
|---|
| 219 |      | 
|---|
| 220 |     if (this->delaylist && this->delaylist->isEmpty()) | 
|---|
| 221 |         this->time = 0; | 
|---|
| 222 | } | 
|---|
| 223 |  | 
|---|
| 224 | bool MoverTrigger::isTriggered() | 
|---|
| 225 | { | 
|---|
| 226 | //    PRINTF(0)("17_1\n"); | 
|---|
| 227 |     if (!this->bIsTriggered && this->bTriggerOnceOnly && !this->bFirstRelease) | 
|---|
| 228 |         return this->bInvert; // yes this makes sense... just think about it ;) | 
|---|
| 229 |  | 
|---|
| 230 | //    PRINTF(0)("17_2\n"); | 
|---|
| 231 |     if (!this->bStayTriggered || !this->bIsTriggered) | 
|---|
| 232 |     { | 
|---|
| 233 | //        PRINTF(0)("17_3\n"); | 
|---|
| 234 |         if (this->triggers && this->delaylist) | 
|---|
| 235 |         { | 
|---|
| 236 | //            PRINTF(0)("17_4\n"); | 
|---|
| 237 |             if (this->triggers->isTriggered()) | 
|---|
| 238 |             { | 
|---|
| 239 | //                PRINTF(0)("17_5\n"); | 
|---|
| 240 |                 bool tempIsTriggered = this->checkIsTriggered(); | 
|---|
| 241 |                 if (this->delaylist->isEmpty()) | 
|---|
| 242 |                 { | 
|---|
| 243 |                     if (!this->bSwitch) | 
|---|
| 244 |                     { | 
|---|
| 245 |                         if (tempIsTriggered != this->bIsTriggered) | 
|---|
| 246 |                             this->delaylist->addState(tempIsTriggered, this->oldState, this->time + this->delay); | 
|---|
| 247 |                     } | 
|---|
| 248 |                     else | 
|---|
| 249 |                     { | 
|---|
| 250 |                         if (tempIsTriggered != this->oldState) | 
|---|
| 251 |                             this->delaylist->addState(tempIsTriggered, this->oldState, this->time + this->delay); | 
|---|
| 252 |                     } | 
|---|
| 253 |                 } | 
|---|
| 254 |                 else | 
|---|
| 255 |                 { | 
|---|
| 256 |                     if (!this->bSwitch) | 
|---|
| 257 |                     { | 
|---|
| 258 |                         if (tempIsTriggered != this->delaylist->getLastState()->state) | 
|---|
| 259 |                             this->delaylist->addState(tempIsTriggered, this->oldState, this->time + this->delay); | 
|---|
| 260 |                     } | 
|---|
| 261 |                     else | 
|---|
| 262 |                     { | 
|---|
| 263 |                         if (tempIsTriggered != this->delaylist->getLastState()->oldState) | 
|---|
| 264 |                             this->delaylist->addState(tempIsTriggered, this->oldState, this->time + this->delay); | 
|---|
| 265 |                     } | 
|---|
| 266 |                 } | 
|---|
| 267 |             } | 
|---|
| 268 |  | 
|---|
| 269 | //            PRINTF(0)("17_6\n"); | 
|---|
| 270 |             while (!this->delaylist->isEmpty()) | 
|---|
| 271 |             { | 
|---|
| 272 |                 MoverTriggerDelayListElement *element = this->delaylist->getFirstState(); | 
|---|
| 273 |  | 
|---|
| 274 |                 if (element && (this->time >= element->time)) | 
|---|
| 275 |                 { | 
|---|
| 276 |                     if (!this->bSwitch) | 
|---|
| 277 |                     { | 
|---|
| 278 |                         this->bIsTriggered = element->state; | 
|---|
| 279 |                     } | 
|---|
| 280 |                     else | 
|---|
| 281 |                     { | 
|---|
| 282 |                         if (element->state && !this->oldState) | 
|---|
| 283 |                             this->bIsTriggered = !this->bIsTriggered; | 
|---|
| 284 |  | 
|---|
| 285 |                         this->oldState = element->state; | 
|---|
| 286 |                     } | 
|---|
| 287 |  | 
|---|
| 288 |                     this->delaylist->deleteFirstState(); | 
|---|
| 289 |  | 
|---|
| 290 |                     if (this->delaylist->isEmpty()) | 
|---|
| 291 |                     { | 
|---|
| 292 |                         this->time = 0; | 
|---|
| 293 |                         break; | 
|---|
| 294 |                     } | 
|---|
| 295 |                      | 
|---|
| 296 |                     continue; | 
|---|
| 297 |                 } | 
|---|
| 298 |                  | 
|---|
| 299 |                 break; | 
|---|
| 300 |             } | 
|---|
| 301 |         } | 
|---|
| 302 |         else | 
|---|
| 303 |             this->bIsTriggered = false; | 
|---|
| 304 |     } | 
|---|
| 305 |  | 
|---|
| 306 | //    PRINTF(0)("17_7\n"); | 
|---|
| 307 |     if (this->bIsTriggered && this->bTriggerOnceOnly && this->bFirstRelease) | 
|---|
| 308 |         this->bFirstRelease = false; | 
|---|
| 309 |  | 
|---|
| 310 | //    PRINTF(0)("17_8\n"); | 
|---|
| 311 |     if (this->bInvert) | 
|---|
| 312 |         return (!this->bIsTriggered); | 
|---|
| 313 |     else | 
|---|
| 314 |         return this->bIsTriggered; | 
|---|
| 315 | } | 
|---|
| 316 |  | 
|---|
| 317 | bool MoverTrigger::isObligatory() | 
|---|
| 318 | { | 
|---|
| 319 |     return this->bObligatory; | 
|---|
| 320 | } | 
|---|
| 321 |  | 
|---|
| 322 | bool MoverTrigger::checkIsTriggered() | 
|---|
| 323 | { | 
|---|
| 324 |     return true; | 
|---|
| 325 | } | 
|---|
| 326 |  | 
|---|
| 327 |  | 
|---|