Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc @ 7163

Last change on this file since 7163 was 7163, checked in by dafrick, 14 years ago

Merged presentation3 branch into trunk.

  • Property svn:eol-style set to native
File size: 5.9 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Damian 'Mozork' Frick
24 *   Co-authors:
25 *      ...
26 *
27*/
28
29/**
30    @file DistanceMultiTrigger.cc
31    @brief Implementation of the DistanceMultiTrigger class.
32*/
33
34#include "DistanceMultiTrigger.h"
35
36#include "core/CoreIncludes.h"
37#include "core/XMLPort.h"
38#include "DistanceTriggerBeacon.h"
39
40namespace orxonox
41{
42
43    CreateFactory(DistanceMultiTrigger);
44
45    /**
46    @brief
47        Default Constructor. Registers the object and initializes default values.
48    */
49    DistanceMultiTrigger::DistanceMultiTrigger(BaseObject* creator) : MultiTrigger(creator)
50    {
51        RegisterObject(DistanceMultiTrigger);
52
53        this->distance_ = 100.0f;
54        this->targetName_ = BLANKSTRING;
55        this->singleTargetMode_ = false;
56    }
57
58    /**
59    @brief
60        Destructor.
61    */
62    DistanceMultiTrigger::~DistanceMultiTrigger()
63    {
64    }
65
66    /**
67    @brief
68        Method for creating a DistanceMultiTrigger object through XML.
69    */
70    void DistanceMultiTrigger::XMLPort(Element& xmlelement, XMLPort::Mode mode)
71    {
72        SUPER(DistanceMultiTrigger, XMLPort, xmlelement, mode);
73
74        XMLPortParam(DistanceMultiTrigger, "distance", setDistance, getDistance, xmlelement, mode);
75        XMLPortParam(DistanceMultiTrigger, "targetname", setTargetName, getTargetName, xmlelement, mode);
76    }
77
78    /**
79    @brief
80        This method is called by the MultiTrigger to get information about new trigger events that need to be looked at.
81
82        In this implementation we iterate through all possible objects and check whether the fact that they are in range or not has changed and fire and hand a state ofer to the MultiTrigger if so.
83    */
84    std::queue<MultiTriggerState*>* DistanceMultiTrigger::letTrigger(void)
85    {
86
87        std::queue<MultiTriggerState*>* queue = NULL;
88
89        // Check for objects that were in range but no longer are. Iterate through all objects, that are in range.
90        for(std::map<WorldEntity*, WeakPtr<WorldEntity>* >::iterator it = this->range_.begin(); it != this->range_.end(); )
91        {
92            WorldEntity* entity = it->second->get();
93            WorldEntity* key = it->first;
94            if(entity == NULL)
95            {
96                ++it;
97                this->removeFromRange(key);
98                continue;
99            }
100
101            Vector3 distanceVec = entity->getWorldPosition() - this->getWorldPosition();
102            // If the object is no longer in range.
103            if (distanceVec.length() > this->distance_)
104            {
105                if(!this->removeFromRange(key))
106                {
107                    ++it;
108                    continue;
109                }
110
111                // If no queue has been created, yet.
112                if(queue == NULL)
113                    queue = new std::queue<MultiTriggerState*>();
114
115                // Create a state and append it to the queue.
116                MultiTriggerState* state = new MultiTriggerState;
117                state->bTriggered = false;
118                state->originator = entity;
119                queue->push(state);
120            }
121            else
122                ++it;
123        }
124
125        ClassTreeMask& targetMask = this->getTargetMask();
126
127        // Check for new objects that are in range
128        for(ClassTreeMaskObjectIterator it = targetMask.begin(); it != targetMask.end(); ++it)
129        {
130            WorldEntity* entity = static_cast<WorldEntity*>(*it);
131            if (entity == NULL) //If the object is no WorldEntity or is already in range.
132                continue;
133
134            // If the DistanceMultiTrigger is in single-target-mode.
135            if(this->singleTargetMode_)
136            {
137                // If the object that is a target is no DistanceTriggerBeacon, then the DistanceMultiTrigger can't be in single-target-mode.
138                if(!(*it)->isA(ClassIdentifier<DistanceTriggerBeacon>::getIdentifier()))
139                    this->singleTargetMode_ = false;
140                // If the target name and the name of the DistancTriggreBeacon don't match.
141                else if(entity->getName().compare(this->targetName_) != 0)
142                    continue;
143            }
144
145            Vector3 distanceVec = entity->getWorldPosition() - this->getWorldPosition();
146            // If the object is in range.
147            if (distanceVec.length() <= this->distance_)
148            {
149                // Add the object to the objects that are in range.
150                if(!this->addToRange(entity))
151                    continue;
152
153                // Change the entity to the parent of the DistanceTriggerBeacon (if in single-target-mode), which is the entity to which the beacon is attached.
154                if(this->singleTargetMode_)
155                    entity = entity->getParent();
156
157                // If no queue has been created, yet.
158                if(queue == NULL)
159                    queue = new std::queue<MultiTriggerState*>();
160
161                // Create a state and append it to the queue.
162                MultiTriggerState* state = new MultiTriggerState;
163                state->bTriggered = true;
164                state->originator = entity;
165                queue->push(state);
166            }
167        }
168
169        return queue;
170    }
171
172}
Note: See TracBrowser for help on using the repository browser.