1 /***************************************************************************
2  *   Copyright (C) 2005-2019 by the FIFE team                              *
3  *   http://www.fifengine.net                                              *
4  *   This file is part of FIFE.                                            *
5  *                                                                         *
6  *   FIFE is free software; you can redistribute it and/or                 *
7  *   modify it under the terms of the GNU Lesser General Public            *
8  *   License as published by the Free Software Foundation; either          *
9  *   version 2.1 of the License, or (at your option) any later version.    *
10  *                                                                         *
11  *   This library is distributed in the hope that it will be useful,       *
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
14  *   Lesser General Public License for more details.                       *
15  *                                                                         *
16  *   You should have received a copy of the GNU Lesser General Public      *
17  *   License along with this library; if not, write to the                 *
18  *   Free Software Foundation, Inc.,                                       *
19  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
20  ***************************************************************************/
21 
22 #ifndef FIFE_TRIGGER_H
23 #define FIFE_TRIGGER_H
24 
25 // Standard C++ library includes
26 #include <vector>
27 #include <string>
28 
29 // 3rd party library includes
30 
31 // FIFE includes
32 // These includes are split up in two parts, separated by one empty line
33 // First block: files included from the FIFE root src directory
34 // Second block: files included from the same folder
35 #include "util/base/fifeclass.h"
36 
37 namespace FIFE {
38 	class Cell;
39 	class Layer;
40 	class Instance;
41 	class TriggerChangeListener;
42 
43 	class ITriggerListener {
44 	public:
~ITriggerListener()45 		virtual ~ITriggerListener() {};
46 
47 		virtual void onTriggered() = 0;
48 	};
49 
50 	enum TriggerCondition {
51 		// cell conditions
52 		CELL_TRIGGER_ENTER = 0,
53 		CELL_TRIGGER_EXIT,
54 		CELL_TRIGGER_BLOCKING_CHANGE,
55 		// instance conditions
56 		INSTANCE_TRIGGER_LOCATION,
57 		INSTANCE_TRIGGER_ROTATION,
58 		INSTANCE_TRIGGER_SPEED,
59 		INSTANCE_TRIGGER_ACTION,
60 		INSTANCE_TRIGGER_TIME_MULTIPLIER,
61 		INSTANCE_TRIGGER_SAYTEXT,
62 		INSTANCE_TRIGGER_BLOCK,
63 		INSTANCE_TRIGGER_CELL,
64 		INSTANCE_TRIGGER_TRANSPARENCY,
65 		INSTANCE_TRIGGER_VISIBLE,
66 		INSTANCE_TRIGGER_STACKPOS,
67 		INSTANCE_TRIGGER_VISUAL,
68 		INSTANCE_TRIGGER_DELETE
69 	};
70 
71 	// FORWARD REFERENCES
72 
73 	/**  Trigger get triggered when a specific set of criteria are met.
74 	 *
75 	 * Currently these can be added directly to Layers.  In order to extend
76 	 * their use we might consider abstracting them from the Layer and adding
77 	 * a trigger manager of some sort which will then add the appropriate
78 	 * listeners to the layer and any other object that might need to
79 	 * trip a trigger.
80 	 *
81 	 * @see Layer
82 	 */
83 	class Trigger : public FifeClass {
84 	public:
85 
86 	// LIFECYCLE
87 
88 		/** Default constructor.
89 		 *
90 		 * TODO (fixme)
91          * I'm not sure if I actually want to be able to call the default constructor.
92          * Triggers should always be given a name.
93          * The maps trigger controller should guarantee the uniqueness of the name.
94 		 */
95 		Trigger();
96 
97 		/** Constructor with name
98 		 *
99 		 * Triggers should be created with a name as that is how they will
100 		 * be referred to in the map file.
101 		 *
102 		 */
103 		Trigger(const std::string& name);
104 
105 		/** Destructor.
106 		 */
107 		virtual ~Trigger();
108 
109 		/** Add a listener to the trigger.
110 		 *
111 		 * When a trigger gets triggered it will call the onTriggered()
112 		 * function of the listener.
113 		 *
114 		 * The Trigger does NOT take ownership of the listener so clients
115 		 * must be sure to free their memory after the trigger has been
116 		 * deleted.
117 		 *
118 		 * @see ITriggerListener
119 		 */
120 		void addTriggerListener(ITriggerListener* listener);
121 
122 		/** Removes a listener from the trigger.
123 		 *
124 		 * This listener will no longer get called.  The Trigger does
125 		 * NOT free the listener so you must be sure to do this.
126 		 */
127 		void removeTriggerListener(ITriggerListener* listener);
128 
129 		/** Reset trigger
130 		 *
131 		 * Resets the status of the trigger so it can be triggered again.
132 		 *
133 		 */
134 		void reset();
135 
136 		/** Gets the name of the trigger.
137 		 *
138 		 * @return name of the trigger.
139 		 */
getName()140 		const std::string& getName() const { return m_name; };
141 
142 		/** Returns if the trigger has been triggered
143 		 *
144 		 *  Triggers will only trigger once unless they are reset.
145 		 * @return bool true if the trigger has been triggered, false
146 		 * otherwise.
147 		 */
isTriggered()148 		bool isTriggered() { return m_triggered; };
149 
150 		/** Sets the trigger to triggered and calls ITriggerListener->onTriggered()
151 		 */
152 		void setTriggered();
153 
154 		/** Adds trigger condition.
155 		 *
156 		 * @param type The trigger condition.
157 		 */
158 		void addTriggerCondition(TriggerCondition type);
159 
160 		/** Returns trigger conditions in an vector.
161 		 */
162 		const std::vector<TriggerCondition>& getTriggerConditions();
163 
164 		/** Removes trigger condition.
165 		 *
166 		 * @param type The trigger condition.
167 		 */
168 		void removeTriggerCondition(TriggerCondition type);
169 
170 		/** Enables trigger for given instance.
171 		 *
172 		 * @param instance The instance which is enabled for the trigger.
173 		 */
174 		void enableForInstance(Instance* instance);
175 
176 		/** Returns instance which the trigger is enabled for.
177 		 */
178 		const std::vector<Instance*>& getEnabledInstances();
179 
180 		/** Disables trigger for given instance.
181 		 *
182 		 * @param instance The instance which is disabled for the trigger.
183 		 */
184 		void disableForInstance(Instance* instance);
185 
186 		/** Enables trigger for all instances.
187 		 */
188 		void enableForAllInstances();
189 
190 		/** Returns if trigger is enabled for all instances.
191 		 */
192 		bool isEnabledForAllInstances();
193 
194 		/** Disables trigger for all instances.
195 		 */
196 		void disableForAllInstances();
197 
198 		/** Assigns trigger on given layer and position.
199 		 *
200 		 * @param layer A pointer to the layer in which to add the Trigger to.
201 		 * @param pt The ModelCoordinate where the Trigger should be added.
202 		 */
203 		void assign(Layer* layer, const ModelCoordinate& pt);
204 
205 		/** Removes trigger from given layer and position.
206 		 *
207 		 * @param layer A pointer to the layer in which to remove the Trigger from.
208 		 * @param pt The ModelCoordinate where the Trigger should be removed.
209 		 */
210 		void remove(Layer* layer, const ModelCoordinate& pt);
211 
212 		/** Assigns trigger on given cell.
213 		 *
214 		 * @param cell A pointer to the cell in which to add the Trigger to.
215 		 */
216 		void assign(Cell* cell);
217 
218 		/** Removes trigger from given cell.
219 		 *
220 		 * @param cell A pointer to the cell in which to remove the Trigger from.
221 		 */
222 		void remove(Cell* cell);
223 
224 		/** Returns vector with the cells where the trigger is assigned to.
225 		 */
226 		const std::vector<Cell*>& getAssignedCells();
227 
228 		/** Attaches the trigger to the given instance. So the trigger moves with the instance.
229 		 *
230 		 * @param instance A pointer to the instance which the Trigger is attached to.
231 		 */
232 		void attach(Instance* instance);
233 
234 		/** Detaches trigger from instance.
235 		 */
236 		void detach();
237 
238 		/** Returns pointer to instance where the trigger is attached to.
239 		 * Note: Returns Null if no instance is attached.
240 		 */
getAttached()241 		Instance* getAttached() { return m_attached; }
242 
243 		/** Callback for TriggerChangeListener.
244 		 */
245 		void move();
246 
247 		/** Moves the trigger from the old position to the new position.
248 		 *
249 		 * @param newPos The old position as ModelCoordinate.
250 		 * @param oldPos The old position as ModelCoordinate.
251 		 */
252 		void moveTo(const ModelCoordinate& newPos, const ModelCoordinate& oldPos);
253 
254 	private:
255 		//! name of the trigger.  This should be unique per Map.
256 		std::string m_name;
257 
258 		//! true if this trigger has been triggered
259 		bool m_triggered;
260 
261 		//! true if the trigger is enabled for all instances
262 		bool m_enabledAll;
263 
264 		//! Vector of the listeners that get called
265 		std::vector<ITriggerListener*> m_triggerListeners;
266 
267 		//! main change listener (cell and instance listener)
268 		TriggerChangeListener* m_changeListener;
269 
270 		//! cells in which the trigger is assigned
271 		std::vector<Cell*> m_assigned;
272 
273 		//! all trigger conditions
274 		std::vector<TriggerCondition> m_triggerConditions;
275 
276 		//! all enabled instances
277 		std::vector<Instance*> m_enabledInstances;
278 
279 		//! instance where the trigger is attached to
280 		Instance* m_attached;
281 	};
282 } //FIFE
283 
284 #endif
285