| [10423] | 1 | /* | 
|---|
 | 2 |    orxonox - the future of 3D-vertical-scrollers | 
|---|
 | 3 |  | 
|---|
 | 4 |    Copyright (C) 2004 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 | #include "util/loading/load_param.h" | 
|---|
 | 16 | #include "util/loading/factory.h" | 
|---|
 | 17 | #include "debug.h" | 
|---|
 | 18 |  | 
|---|
 | 19 | #include "mover.h" | 
|---|
 | 20 |  | 
|---|
 | 21 |  | 
|---|
 | 22 | ObjectListDefinition(Mover); | 
|---|
 | 23 | CREATE_FACTORY(Mover); | 
|---|
 | 24 |  | 
|---|
 | 25 | /** | 
|---|
 | 26 |  *  initializes the Mover from a XmlElement | 
|---|
 | 27 | */ | 
|---|
 | 28 | Mover::Mover(const TiXmlElement* root) | 
|---|
 | 29 | { | 
|---|
 | 30 |   this->registerObject(this, Mover::_objectList); | 
|---|
 | 31 |   this->toList(OM_GROUP_00); | 
|---|
 | 32 |    | 
|---|
 | 33 |   this->targetCoordinates = Vector(0, 0, 0); | 
|---|
 | 34 |   this->originCoordinates = Vector(0, 87, -256); | 
|---|
 | 35 |   this->actionRadius = 40.0; | 
|---|
 | 36 |   this->actionTime = 1.0; | 
|---|
 | 37 |  | 
|---|
 | 38 |   if (root != NULL) | 
|---|
 | 39 |     this->loadParams(root); | 
|---|
 | 40 |  | 
|---|
 | 41 |   this->updateNode(0.001); | 
|---|
 | 42 |   this->originCoordinates = this->getAbsCoor(); | 
|---|
 | 43 |   this->state = Closed; | 
|---|
 | 44 | } | 
|---|
 | 45 |  | 
|---|
 | 46 | Mover::~Mover() | 
|---|
 | 47 | { | 
|---|
 | 48 | } | 
|---|
 | 49 |  | 
|---|
 | 50 | /** | 
|---|
 | 51 |  * loads the Settings of the Mover from an XML-element. | 
|---|
 | 52 |  * @param root the XML-element to load the Movers's properties from | 
|---|
 | 53 |  */ | 
|---|
 | 54 | void Mover::loadParams(const TiXmlElement* root) | 
|---|
 | 55 | { | 
|---|
 | 56 |   WorldEntity::loadParams(root); | 
|---|
 | 57 |  | 
|---|
 | 58 |   LoadParam(root, "rel-target-coor", this, Mover, setTargetCoordinates) | 
|---|
 | 59 |       .describe("sets the relative target coordinates of the door"); | 
|---|
 | 60 |   LoadParam(root, "action-radius", this, Mover, setActionRadius) | 
|---|
 | 61 |       .describe("sets the action radius of the door") | 
|---|
 | 62 |       .defaultValues(40.0); | 
|---|
 | 63 |   LoadParam(root, "action-time", this, Mover, setActionTime) | 
|---|
 | 64 |       .describe("sets the action time of the door") | 
|---|
 | 65 |       .defaultValues(1.0); | 
|---|
 | 66 | } | 
|---|
 | 67 |  | 
|---|
 | 68 | /** | 
|---|
 | 69 |  * tick function | 
|---|
 | 70 |  */ | 
|---|
 | 71 | void Mover::tick(float dt) | 
|---|
 | 72 | { | 
|---|
 | 73 |     if (this->state == Closed) | 
|---|
 | 74 |     { | 
|---|
 | 75 |         if (this->checkPlayerInActionRadius()) | 
|---|
 | 76 |         { | 
|---|
 | 77 |             this->state = Opening; | 
|---|
 | 78 |         } | 
|---|
 | 79 |     } | 
|---|
 | 80 |     else if (this->state == Opening) | 
|---|
 | 81 |     { | 
|---|
 | 82 |         if (this->checkOpen(dt)) | 
|---|
 | 83 |         { | 
|---|
 | 84 |             this->state = Open; | 
|---|
 | 85 |             this->setAbsCoor(this->originCoordinates + this->targetCoordinates); | 
|---|
 | 86 |         } | 
|---|
 | 87 |     } | 
|---|
 | 88 |     else if (this->state == Open) | 
|---|
 | 89 |     { | 
|---|
 | 90 |         if (!this->checkPlayerInActionRadius()) | 
|---|
 | 91 |         { | 
|---|
 | 92 |             this->state = Closing; | 
|---|
 | 93 |         } | 
|---|
 | 94 |     } | 
|---|
 | 95 |     else if (this->state == Closing) | 
|---|
 | 96 |     { | 
|---|
 | 97 |         if (this->checkClosed(dt)) | 
|---|
 | 98 |         { | 
|---|
 | 99 |             this->state = Closed; | 
|---|
 | 100 |             this->setAbsCoor(this->originCoordinates); | 
|---|
 | 101 |         } | 
|---|
 | 102 |         if (this->checkPlayerInActionRadius()) | 
|---|
 | 103 |         { | 
|---|
 | 104 |             this->state = Opening; | 
|---|
 | 105 |         } | 
|---|
 | 106 |     } | 
|---|
 | 107 |  | 
|---|
 | 108 |     if (this->state == Opening) | 
|---|
 | 109 |     { | 
|---|
 | 110 |         this->shiftCoor(this->targetCoordinates / this->actionTime * dt); | 
|---|
 | 111 |     } | 
|---|
 | 112 |     else if (this->state == Closing) | 
|---|
 | 113 |     { | 
|---|
 | 114 |         this->shiftCoor(this->targetCoordinates * (-1) / this->actionTime * dt); | 
|---|
 | 115 |     } | 
|---|
 | 116 | } | 
|---|
 | 117 |  | 
|---|
 | 118 | /** | 
|---|
 | 119 |  * checks if the door is open | 
|---|
 | 120 |  */ | 
|---|
 | 121 | bool Mover::checkOpen(float dt) | 
|---|
 | 122 | { | 
|---|
 | 123 |     if (fabs((this->originCoordinates - (this->getAbsCoor() - this->targetCoordinates)).len()) < fabs(2 * (this->targetCoordinates / this->actionTime * dt).len())) | 
|---|
 | 124 |         return true; | 
|---|
 | 125 |      | 
|---|
 | 126 |     return false; | 
|---|
 | 127 | } | 
|---|
 | 128 |  | 
|---|
 | 129 | /** | 
|---|
 | 130 |  * checks if the door is closed | 
|---|
 | 131 |  */ | 
|---|
 | 132 | bool Mover::checkClosed(float dt) | 
|---|
 | 133 | { | 
|---|
 | 134 |     if (fabs((this->getAbsCoor() - this->originCoordinates).len()) < fabs(2 * (this->targetCoordinates / this->actionTime * dt).len())) | 
|---|
 | 135 |         return true; | 
|---|
 | 136 |  | 
|---|
 | 137 |     return false; | 
|---|
 | 138 | } | 
|---|
 | 139 |  | 
|---|
 | 140 | #include "playable.h" | 
|---|
 | 141 | #include "generic_npc.h" | 
|---|
 | 142 | /** | 
|---|
 | 143 |  * checks if the player is within the action radius | 
|---|
 | 144 |  */ | 
|---|
 | 145 | bool Mover::checkPlayerInActionRadius() | 
|---|
 | 146 | { | 
|---|
 | 147 |  | 
|---|
 | 148 |   WorldEntity* entity; | 
|---|
 | 149 |   Vector vDistance; | 
|---|
 | 150 |   float powerDistance; | 
|---|
 | 151 |  | 
|---|
 | 152 |   for (ObjectList<Playable>::const_iterator it = Playable::objectList().begin(); | 
|---|
 | 153 |        it != Playable::objectList().end(); | 
|---|
 | 154 |        ++it) | 
|---|
 | 155 |   // for all players | 
|---|
 | 156 |   { | 
|---|
 | 157 |     entity = (*it); | 
|---|
 | 158 |  | 
|---|
 | 159 |     vDistance = this->originCoordinates - entity->getAbsCoor(); | 
|---|
 | 160 |     powerDistance = vDistance.x * vDistance.x + vDistance.z * vDistance.z; | 
|---|
 | 161 |  | 
|---|
 | 162 |     if( powerDistance < (this->actionRadius * this->actionRadius)) | 
|---|
 | 163 |       return true; | 
|---|
 | 164 |   } | 
|---|
 | 165 |  | 
|---|
 | 166 |  | 
|---|
 | 167 |  | 
|---|
 | 168 |   for (ObjectList<GenericNPC>::const_iterator it = GenericNPC::objectList().begin(); | 
|---|
 | 169 |        it != GenericNPC::objectList().end(); | 
|---|
 | 170 |        ++it) | 
|---|
 | 171 |   { | 
|---|
 | 172 |     entity = (*it); | 
|---|
 | 173 |  | 
|---|
 | 174 |     vDistance = this->originCoordinates - entity->getAbsCoor(); | 
|---|
 | 175 |     powerDistance = vDistance.x * vDistance.x + vDistance.z * vDistance.z; | 
|---|
 | 176 |  | 
|---|
 | 177 |     if( powerDistance < (this->actionRadius * this->actionRadius)) | 
|---|
 | 178 |       return true; | 
|---|
 | 179 |   } | 
|---|
 | 180 |  | 
|---|
 | 181 |   return false; | 
|---|
 | 182 | } | 
|---|