1 /*
2  * This file is part of EasyRPG Player.
3  *
4  * EasyRPG Player is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * EasyRPG Player is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef EP_GAME_EVENT_H
19 #define EP_GAME_EVENT_H
20 
21 // Headers
22 #include <string>
23 #include <vector>
24 #include "game_character.h"
25 #include <lcf/rpg/event.h>
26 #include <lcf/rpg/savemapevent.h>
27 #include "game_interpreter_map.h"
28 #include "async_op.h"
29 
30 using Game_EventBase = Game_CharacterDataStorage<lcf::rpg::SaveMapEvent>;
31 
32 /**
33  * Game_Event class.
34  */
35 class Game_Event : public Game_EventBase {
36 public:
37 	/**
38 	 * Constructor.
39 	 */
40 	Game_Event(int map_id, const lcf::rpg::Event* event);
41 
42 	/** Load from saved game */
43 	void SetSaveData(lcf::rpg::SaveMapEvent save);
44 
45 	/** @return save game data */
46 	lcf::rpg::SaveMapEvent GetSaveData() const;
47 
48 	/**
49 	 * Implementation of abstract methods
50 	 */
51 	/** @{ */
52 	bool Move(int dir) override;
53 	void UpdateNextMovementAction() override;
54 	bool IsVisible() const override;
55 	/** @} */
56 
57 	/**
58 	 * Re-checks active pages and sets up new page on change.
59 	 */
60 	void RefreshPage();
61 
62 	/**
63 	 * Gets event ID.
64 	 *
65 	 * @return event ID.
66 	 */
67 	int GetId() const;
68 
69 	/**
70 	 * Gets event name.
71 	 *
72 	 * @return event name.
73 	 */
74 	StringView GetName() const;
75 
76 	/** Clears waiting_execution flag */
77 	void ClearWaitingForegroundExecution();
78 
79 	/** @return waiting_execution flag.  */
80 	bool IsWaitingForegroundExecution() const;
81 
82 	/**
83 	 * If the event is starting, whether or not it was started
84 	 * by pushing the decision key.
85 	 *
86 	 * @return started by decision key
87 	 */
88 	bool WasStartedByDecisionKey() const;
89 
90 	/**
91 	 * Gets trigger condition.
92 	 *
93 	 * @return trigger condition.
94 	 */
95 	lcf::rpg::EventPage::Trigger GetTrigger() const;
96 
97 	/**
98 	 * Gets event commands list.
99 	 *
100 	 * @return event commands list.
101 	 */
102 	const std::vector<lcf::rpg::EventCommand>& GetList() const;
103 
104 	/**
105 	 * Event returns to its original direction before talking to the hero.
106 	 */
107 	void OnFinishForegroundEvent();
108 
109 	/**
110 	 * Schedule the event for execution on the map's foreground interpreter.
111 	 *
112 	 * @param triggered_by_decision_key set whether this was triggered by decision key
113 	 * @param face_hero if scheduled, event faces the player.
114 	 *
115 	 * @return true if event was scheduled.
116 	 */
117 	bool ScheduleForegroundExecution(bool triggered_by_decision_key, bool face_player);
118 
119 	/**
120 	 * Update this for the current frame
121 	 *
122 	 * @param resume_async If we're resuming from an async operation.
123 	 * @return async operation if we should suspend, otherwise returns AsyncOp::eNone
124 	 */
125 	AsyncOp Update(bool resume_async);
126 
127 	bool AreConditionsMet(const lcf::rpg::EventPage& page);
128 
129 	/**
130 	 * Returns current index of a "Movement Type Custom" move route.
131 	 *
132 	 * @return current original move route index
133 	 */
134 	int GetOriginalMoveRouteIndex() const;
135 
136 	/**
137 	 * Sets current index of a "Movement Type Custom" move route.
138 	 *
139 	 * @param new_index New move route index
140 	 */
141 	void SetOriginalMoveRouteIndex(int new_index);
142 
143 	/**
144 	 * Returns the event page or nullptr is page does not exist.
145 	 *
146 	 * @param page Page number (starting from 1)
147 	 *
148 	 * @return page or nullptr
149 	 */
150 	const lcf::rpg::EventPage* GetPage(int page) const;
151 
152 	/**
153 	 * Returns the active event page or nullptr if no page is active.
154 	 *
155 	 * @return active page or nullptr
156 	 */
157 	const lcf::rpg::EventPage* GetActivePage() const;
158 
159 	/** @returns the number of pages this event has */
160 	int GetNumPages() const;
161 
162 protected:
163 	/** Check for and fix incorrect data after loading save game */
164 	void SanitizeData();
165 private:
166 	bool CheckEventAutostart();
167 	bool CheckEventCollision();
168 	void SetMaxStopCountForRandom();
169 
170 	/**
171 	 * Moves on a random route.
172 	 */
173 	void MoveTypeRandom();
174 
175 	/**
176 	 * Cycles between moving in default_dir and its opposite.
177 	 * Tries to move in the event's movement direction, or
178 	 * default_dir if this is along the wrong axis. Reverses
179 	 * directions when encountering an obstacle.
180 	 */
181 	void MoveTypeCycle(int default_dir);
182 
183 	/**
184 	 * Cycles left and right.
185 	 */
186 	void MoveTypeCycleLeftRight();
187 
188 	/**
189 	 * Cycles up and down.
190 	 */
191 	void MoveTypeCycleUpDown();
192 
193 	/**
194 	 * Implementation method for walking to
195 	 * or from the player
196 	 */
197 	void MoveTypeTowardsOrAwayPlayer(bool towards);
198 
199 	/**
200 	 * Walks to the player.
201 	 */
202 	void MoveTypeTowardsPlayer();
203 
204 	/**
205 	 * Walks away from the player.
206 	 */
207 	void MoveTypeAwayFromPlayer();
208 
209 	void CheckCollisonOnMoveFailure();
210 
211 	const lcf::rpg::Event* event = nullptr;
212 	const lcf::rpg::EventPage* page = nullptr;
213 	std::unique_ptr<Game_Interpreter_Map> interpreter;
214 };
215 
GetNumPages()216 inline int Game_Event::GetNumPages() const {
217 	return event->pages.size();
218 }
219 
IsVisible()220 inline bool Game_Event::IsVisible() const {
221 	return GetActivePage() != nullptr && Game_Character::IsVisible();
222 }
223 
224 #endif
225