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