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_MAP_H
19 #define EP_GAME_MAP_H
20 
21 // Headers
22 #include <vector>
23 #include <string>
24 #include "system.h"
25 #include "game_commonevent.h"
26 #include "game_event.h"
27 #include "game_vehicle.h"
28 #include "game_player.h"
29 #include <lcf/rpg/fwd.h>
30 #include <lcf/rpg/encounter.h>
31 #include <lcf/rpg/map.h>
32 #include <lcf/rpg/mapinfo.h>
33 #include <lcf/rpg/savemapinfo.h>
34 #include <lcf/rpg/savepanorama.h>
35 #include <lcf/rpg/savepartylocation.h>
36 #include <lcf/rpg/savevehiclelocation.h>
37 #include <lcf/rpg/savecommonevent.h>
38 #include "async_op.h"
39 
40 class FileRequestAsync;
41 struct BattleArgs;
42 
43 // These are in sixteenths of a pixel.
44 constexpr int SCREEN_TILE_SIZE = 256;
45 constexpr int SCREEN_WIDTH = 20 * SCREEN_TILE_SIZE;
46 constexpr int SCREEN_HEIGHT = 15 * SCREEN_TILE_SIZE;
47 
48 class MapUpdateAsyncContext {
49 	public:
50 		MapUpdateAsyncContext() = default;
51 
52 		static MapUpdateAsyncContext FromCommonEvent(int ce, AsyncOp aop);
53 		static MapUpdateAsyncContext FromMapEvent(int ce, AsyncOp aop);
54 		static MapUpdateAsyncContext FromForegroundEvent(AsyncOp aop);
55 		static MapUpdateAsyncContext FromMessage(AsyncOp aop);
56 
57 		AsyncOp GetAsyncOp() const;
58 
59 		int GetParallelCommonEvent() const;
60 		int GetParallelMapEvent() const;
61 
62 		bool IsForegroundEvent() const;
63 		bool IsParallelCommonEvent() const;
64 		bool IsParallelMapEvent() const;
65 		bool IsMessage() const;
66 		bool IsActive() const;
67 	private:
68 		AsyncOp async_op = {};
69 		int common_event = 0;
70 		int map_event = 0;
71 		bool foreground_event = false;
72 		bool message = false;
73 };
74 
75 /**
76  * Game_Map namespace
77  */
78 namespace Game_Map {
79 	/**
80 	 * Initialize Game_Map.
81 	 */
82 	void Init();
83 
84 	/**
85 	 * Quits (frees) Game_Map.
86 	 */
87 	void Quit();
88 
89 	/** Disposes Game_Map.  */
90 	void Dispose();
91 
92 	/**
93 	 * Loads the map from disk
94 	 *
95 	 * @param map_id the id of the map to load
96 	 * @return the map, or nullptr if it couldn't be loaded
97 	 */
98 	std::unique_ptr<lcf::rpg::Map> loadMapFile(int map_id);
99 
100 	/**
101 	 * Setups a new map.
102 	 *
103 	 * @pre Main_Data::game_player->GetMapId() reflects the new map.
104 	 */
105 	void Setup(std::unique_ptr<lcf::rpg::Map> map);
106 
107 	/**
108 	 * Setups a map from a savegame.
109 	 *
110 	 * @param map - The map data
111 	 * @param save_map - The map state
112 	 * @param save_boat - The boat state
113 	 * @param save_ship - The ship state
114 	 * @param save_airship - The airship state
115 	 * @param save_fg_exec - The foreground interpreter state
116 	 * @param save_pan - The panorama state
117 	 * @param save_ce - The common event state
118 	 */
119 	void SetupFromSave(
120 			std::unique_ptr<lcf::rpg::Map> map,
121 			lcf::rpg::SaveMapInfo save_map,
122 			lcf::rpg::SaveVehicleLocation save_boat,
123 			lcf::rpg::SaveVehicleLocation save_ship,
124 			lcf::rpg::SaveVehicleLocation save_airship,
125 			lcf::rpg::SaveEventExecState save_fg_exec,
126 			lcf::rpg::SavePanorama save_pan,
127 			std::vector<lcf::rpg::SaveCommonEvent> save_ce);
128 
129 	/**
130 	 * Copies event data into lcf::rpg::Save data.
131 	 *
132 	 * @param save - save data to populate.
133 	 */
134 	void PrepareSave(lcf::rpg::Save& save);
135 
136 	/**
137 	 * Runs map.
138 	 */
139 	void PlayBgm();
140 
141 	/**
142 	 * Refreshes the map.
143 	 */
144 	void Refresh();
145 
146 	/** Actions to perform after finishing a battle */
147 	void OnContinueFromBattle();
148 
149 	/**
150 	 * Scrolls the map view in the given directions.
151 	 *
152 	 * @param dx amount to scroll along x-axis in 1/16th pixels
153 	 * @param dy amount to scroll along x-axis in 1/16th pixels
154 	 */
155 	void Scroll(int dx, int dy);
156 
157 	/**
158 	 * Adds inc, a distance in sixteenths of a pixel, to screen_x, the
159 	 * x-position of a screen. The sum is clamped (for non-looping maps)
160 	 * and wrapped (for looping maps) to fit in the map range. If the
161 	 * sum is clamped, inc is updated to be actual amount that it
162 	 * changed by.
163 	 */
164 	void AddScreenX(int& screen_x, int& inc);
165 
166 	/** Same as AddScreenX, but for the Y-direction. */
167 	void AddScreenY(int& screen_y, int& inc);
168 
169 	/**
170 	 * Gets if a tile coordinate is valid.
171 	 *
172 	 * @param x tile x.
173 	 * @param y tile y.
174 	 * @return whether is valid.
175 	 */
176 	bool IsValid(int x, int y);
177 
178 	/**
179 	 * Clears the way for a move by self to (x,y). Any events
180 	 * that block the way are updated early to give them a
181 	 * chance to move out of the way.
182 	 *
183 	 * Returns true if move is possible.
184 	 *
185 	 * @param self Character to move.
186 	 * @param from_x from tile x.
187 	 * @param from_y from tile y.
188 	 * @param to_x to new tile x.
189 	 * @param to_y to new tile y.
190 	 * @return whether is passable.
191 	 */
192 	bool MakeWay(const Game_Character& self,
193 			int from_x, int from_y,
194 			int to_x, int to_y);
195 
196 	/**
197 	 * Gets if possible to land the airship at (x,y)
198 	 *
199 	 * @param x tile x.
200 	 * @param y tile y.
201 	 * @return whether is posible to land airship
202 	 */
203 	bool CanLandAirship(int x, int y);
204 
205 	/**
206 	 * Gets if possible to embark the boat or ship at (x,y)
207 	 *
208 	 * @param player the player
209 	 * @param x tile x.
210 	 * @param y tile y.
211 	 * @return whether is posible to disembark the boat or ship
212 	 */
213 	bool CanEmbarkShip(Game_Player& player, int x, int y);
214 
215 	/**
216 	 * Gets if possible to disembark the boat or ship to (x,y)
217 	 *
218 	 * @param player the player
219 	 * @param x tile x.
220 	 * @param y tile y.
221 	 * @return whether is posible to disembark the boat or ship
222 	 */
223 	bool CanDisembarkShip(Game_Player& player, int x, int y);
224 
225 	/**
226 	 * Return the tiles array for the given tiles layer.
227 	 *
228 	 * @param layer which layer to return
229 	 */
230 	const std::vector<uint8_t>& GetTilesLayer(int layer);
231 
232 	/**
233 	 * Gets the bush depth at a certain tile.
234 	 *
235 	 * @param x tile x.
236 	 * @param y tile y.
237 	 * @return bush depth.
238 	 */
239 	int GetBushDepth(int x, int y);
240 
241 	/**
242 	 * Gets if a tile has counter flag.
243 	 *
244 	 * @param x tile x.
245 	 * @param y tile y.
246 	 * @return whether has the counter flag.
247 	 */
248 	bool IsCounter(int x, int y);
249 
250 	/**
251 	 * Gets designated tile terrain tag.
252 	 *
253 	 * @param x tile x.
254 	 * @param y tile y.
255 	 * @return terrain tag ID.
256 	 */
257 	int GetTerrainTag(int x, int y);
258 
259 	/**
260 	 * Gets designated position event.
261 	 *
262 	 * @param x : tile x
263 	 * @param y : tile y
264 	 * @return event id, 0 if no event found
265 	 */
266 	int CheckEvent(int x, int y);
267 
268 	/**
269 	 * Updates the map state.
270 	 *
271 	 * @param actx asynchronous operations context. In out param.
272 	 *        If IsActive() when passed in, will resume to that point.
273 	 *        If IsActive() after return in, will suspend from that point.
274 	 * @param is_preupdate Update only common events and map events
275 	 */
276 	void Update(MapUpdateAsyncContext& actx, bool is_preupdate = false);
277 
278 	/**
279 	 * Gets current map_info.
280 	 *
281 	 * @return current map_info.
282 	 */
283 	lcf::rpg::MapInfo const& GetMapInfo();
284 
285 	/**
286 	 * Gets current map.
287 	 *
288 	 * @return current map.
289 	 */
290 	lcf::rpg::Map const& GetMap();
291 
292 	/**
293 	 * Gets current map ID.
294 	 *
295 	 * @return current map ID.
296 	 */
297 	int GetMapId();
298 
299 	/**
300 	 * Gets current map width.
301 	 *
302 	 * @return current map width.
303 	 */
304 	int GetWidth();
305 
306 	/**
307 	 * Gets current map height.
308 	 *
309 	 * @return current map height.
310 	 */
311 	int GetHeight();
312 
313 	/**
314 	 * Gets battle encounters list.
315 	 *
316 	 * @return battle encounters list.
317 	 */
318 	std::vector<lcf::rpg::Encounter>& GetEncounterList();
319 
320 	/** @return original map battle encounter rate steps. */
321 	int GetOriginalEncounterRate();
322 
323 	/** @return battle encounter rate steps. */
324 	int GetEncounterRate();
325 
326 	/**
327 	 * Sets battle encounter rate.
328 	 *
329 	 * @param step encounter steps.
330 	 */
331 	void SetEncounterRate(int step);
332 
333 	/**
334 	 * Gets possible encounters at a location.
335 	 * Respects areas and terrain settings.
336 	 *
337 	 * @param x x position
338 	 * @param y y position
339 	 * @return Possible encounters
340 	 */
341 	std::vector<int> GetEncountersAt(int x, int y);
342 
343 	/**
344 	 * Updates all battle data based on the current player position and starts
345 	 * a random encounter.
346 	 *
347 	 * @param args the arguments to pass to battle scene.
348 	 *
349 	 * @return true if battle starts, false if no monsters are at the current
350 	 * map position or encounter rate is 0
351 	 */
352 	bool PrepareEncounter(BattleArgs& args);
353 
354 	/**
355 	 * Updates all battle data based on the current player position.
356 	 *
357 	 * @param args the arguments to pass to battle scene.
358 	 */
359 	void SetupBattle(BattleArgs& args);
360 
361 	/**
362 	 * Gets lower layer map data.
363 	 *
364 	 * @return lower layer map data.
365 	 */
366 	std::vector<short>& GetMapDataDown();
367 
368 	/**
369 	 * Gets upper layer map data.
370 	 *
371 	 * @return upper layer map data.
372 	 */
373 	std::vector<short>& GetMapDataUp();
374 
375 	/** @return original map chipset ID */
376 	int GetOriginalChipset();
377 
378 	/** @return current chipset ID */
379 	int GetChipset();
380 
381 	/** @return chipset filename.  */
382 	StringView GetChipsetName();
383 
384 	/**
385 	 * Gets the offset of the screen from the left edge
386 	 * of the map, ignoring screen shaking.
387 	 */
388 	int GetPositionX();
389 
390 	/**
391 	 * Gets the offset of the screen from the left edge
392 	 * of the map, taking shaking into account.
393 	 */
394 	int GetDisplayX();
395 
396 	/**
397 	 * Sets the offset of the screen from the left edge
398 	 * of the map, as given by GetPositionX.
399 	 *
400 	 * @param new_position_x new position x.
401 	 * @param reset_panorama whether to reset panorama
402 	 */
403 	void SetPositionX(int new_position_x, bool reset_panorama = true);
404 
405 	/**
406 	 * Gets display y.
407 	 */
408 	int GetPositionY();
409 
410 	/**
411 	 * Gets display y.
412 	 */
413 	int GetDisplayY();
414 
415 	/**
416 	 * Sets the offset of the screen from the top edge
417 	 * of the map.
418 	 *
419 	 * @param new_position_y new position y.
420 	 * @param reset_panorama whether to reset panorama
421 	 */
422 	void SetPositionY(int new_position_y, bool reset_panorama = true);
423 
424 	/**
425 	 * @return need refresh flag.
426 	 */
427 	bool GetNeedRefresh();
428 
429 	/**
430 	 * Gets the game interpreter.
431 	 *
432 	 * @return the game interpreter.
433 	 */
434 	Game_Interpreter_Map& GetInterpreter();
435 
436 	/**
437 	 * Sets the need refresh flag.
438 	 *
439 	 * @param refresh need refresh flag.
440 	 */
441 	void SetNeedRefresh(bool refresh);
442 
443 	/**
444 	 * Gets lower passages list.
445 	 *
446 	 * @return lower passages list.
447 	 */
448 	std::vector<unsigned char>& GetPassagesDown();
449 
450 	/**
451 	 * Gets upper passages list.
452 	 *
453 	 * @return upper passages list.
454 	 */
455 	std::vector<unsigned char>& GetPassagesUp();
456 
457 	/**
458 	 * Gets chipset animation type.
459 	 *
460 	 * @return chipset animation type.
461 	 */
462 	int GetAnimationType();
463 
464 	/**
465 	 * Gets chipset animation speed.
466 	 *
467 	 * @return chipset animation speed.
468 	 */
469 	int GetAnimationSpeed();
470 
471 	/**
472 	 * Gets events list.
473 	 *
474 	 * @return events list.
475 	 */
476 	std::vector<Game_Event>& GetEvents();
477 
478 	/** @return highest event id present on the map, or 0 if no events */
479 	int GetHighestEventId();
480 
481 	/**
482 	 * Gets pointer to event.
483 	 *
484 	 * @param event_id event ID
485 	 * @return pointer to event.
486 	 */
487 	Game_Event* GetEvent(int event_id);
488 
489 	/**
490 	 * Gets common events list.
491 	 *
492 	 * @return common events list.
493 	 */
494 	std::vector<Game_CommonEvent>& GetCommonEvents();
495 
496 	void GetEventsXY(std::vector<Game_Event*>& events, int x, int y);
497 
498 	/**
499 	 * @param x x position on the map
500 	 * @param y y position on the map
501 	 * @param require_active If true, ignore events which are not active.
502 	 * @return the event with the highest id at (x,y)
503 	 */
504 	Game_Event* GetEventAt(int x, int y, bool require_active);
505 
506 	bool LoopHorizontal();
507 	bool LoopVertical();
508 
509 	int RoundX(int x, int units = 1);
510 	int RoundY(int y, int units = 1);
511 
512 	int RoundDx(int x, int units = 1);
513 	int RoundDy(int y, int units = 1);
514 
515 	int XwithDirection(int x, int direction);
516 	int YwithDirection(int y, int direction);
517 
518 	/**
519 	 * Gets the map index from MapInfo vector using map ID.
520 	 *
521 	 * @param id map ID.
522 	 * @return map index from MapInfo vector.
523 	 */
524 	int GetMapIndex(int id);
525 
526 	/**
527 	 * Gets the map name from MapInfo vector using map ID.
528 	 *
529 	 * @param id map ID.
530 	 * @return map name from MapInfo vector.
531 	 */
532 	StringView GetMapName(int id);
533 
534 	/**
535 	 * Gets the type (1 = normal, 2 = area) of the map.
536 	 *
537 	 * @param map_id map id
538 	 * @return type of the map
539 	 */
540 	int GetMapType(int map_id);
541 
542 	/**
543 	 * Gets the ID of the parent map.
544 	 * The root of the tree has ID 0.
545 	 *
546 	 * @param map_id map id
547 	 * @return parent map id
548 	 */
549 	int GetParentId(int map_id);
550 
551 	/**
552 	 * Sets the chipset.
553 	 *
554 	 * @param id new chipset ID.
555 	 */
556 	void SetChipset(int id);
557 
558 	Game_Vehicle* GetVehicle(Game_Vehicle::Type which);
559 	int SubstituteDown(int old_id, int new_id);
560 	int SubstituteUp(int old_id, int new_id);
561 
562 	/**
563 	 * Checks if its possible to step onto the tile at (x,y)
564 	 * The check includes tile graphic events checks.
565 	 *
566 	 * Returns true if move is possible.
567 	 *
568 	 * @param self Character to move. If not nullptr, checks the vehicle type and performs vehicle specific checks if is vehicle.
569 	 *        Also ignores self in the event tile graphic checks if self is not nullptr.
570 	 * @param bit which direction bits to check
571 	 * @param x target tile x.
572 	 * @param y target tile y.
573 	 * @return whether is passable.
574 	 */
575 	bool IsPassableTile(const Game_Character* self, int bit, int x, int y);
576 
577 	/**
578 	 * Checks if the lower tile at (x,y) is passable by the player.
579 	 *
580 	 * Returns true if move is possible.
581 	 *
582 	 * @param bit which direction bits to check
583 	 * @param tile_index the tile index
584 	 * @return whether is passable.
585 	 */
586 	bool IsPassableLowerTile(int bit, int tile_index);
587 
588 	/**
589 	 * Gets whether there are any starting non-parallel event or common event.
590 	 * Used as a workaround for the Game Player.
591 	 *
592 	 * @return whether any starting non-parallel (common) event is starting
593 	 */
594 	bool IsAnyEventStarting();
595 
596 	/** @return the number of times this map was saved in the editor */
597 	int GetMapSaveCount();
598 
599 	/** @return true if any event on this map has an active move route */
600 	bool IsAnyMovePending();
601 
602 	/** Cancel active move routes for all events on this map */
603 	void RemoveAllPendingMoves();
604 
605 	void UpdateProcessedFlags(bool is_preupdate);
606 	bool UpdateCommonEvents(MapUpdateAsyncContext& actx);
607 	bool UpdateMapEvents(MapUpdateAsyncContext& actx);
608 	bool UpdateMessage(MapUpdateAsyncContext& actx);
609 	bool UpdateForegroundEvents(MapUpdateAsyncContext& actx);
610 
611 	/**
612 	 * Construct a map name, either for EasyRPG or RPG Maker projects
613 	 *
614 	 * @param map_id The ID of the map to construct
615 	 * @param isEasyRpg Is the an easyrpg (emu) project, or an RPG Maker (lmu) one?
616 	 * @return The map name, as Map<map_id>.<map_extension>
617 	 */
618 	std::string ConstructMapName(int map_id, bool isEasyRpg);
619 
620 	FileRequestAsync* RequestMap(int map_id);
621 
622 	namespace Parallax {
623 		struct Params {
624 			std::string name;
625 			bool scroll_horz;
626 			bool scroll_horz_auto;
627 			int scroll_horz_speed;
628 			bool scroll_vert;
629 			bool scroll_vert_auto;
630 			int scroll_vert_speed;
631 		};
632 
633 		/**
634 		 * The name of the current parallax graphic (or the empty string
635 		 * if none).
636 		 */
637 		std::string GetName();
638 
639 		/**
640 		 * Offset in pixels of the bitmap at the top-left of the screen.
641 		 * (If the screen is shaking, at the top-left of where the screen
642 		 * would be if it weren't.)
643 		 */
644 		int GetX();
645 
646 		/** Same a GetX(), but in the y-direction. */
647 		int GetY();
648 
649 		/** Call this when you find out the width and height of the BG. */
650 		void Initialize(int width, int height);
651 
652 		/** Reset the x position of the BG. */
653 		void ResetPositionX();
654 
655 		/** Reset the y position of the BG. */
656 		void ResetPositionY();
657 
658 		/**
659 		 * To be called when the map scrolls right.
660 		 *
661 		 * @param distance Amount of scroll in 1/16th pixels.
662 		 */
663 		void ScrollRight(int distance);
664 
665 		/**
666 		 * To be called when the map scrolls down.
667 		 *
668 		 * @param distance Amount of scroll in 1/16th pixels.
669 		 */
670 		void ScrollDown(int distance);
671 
672 		/** Update autoscrolling BG (call every frame). */
673 		void Update();
674 
675 		/** Change BG (eg. with a "Change Parallax BG" command). */
676 		void ChangeBG(const Params& params);
677 
678 		/**
679 		 * Remove any changed BG. The BG goes back to what was set in
680 		 * the map properties.
681 		 */
682 		void ClearChangedBG();
683 	}
684 }
685 
686 
GetAsyncOp()687 inline AsyncOp MapUpdateAsyncContext::GetAsyncOp() const {
688 	return async_op;
689 }
690 
FromCommonEvent(int ce,AsyncOp aop)691 inline MapUpdateAsyncContext MapUpdateAsyncContext::FromCommonEvent(int ce, AsyncOp aop) {
692 	MapUpdateAsyncContext actx;
693 	if (aop.IsActive()) {
694 		actx.async_op = aop;
695 		actx.common_event = ce;
696 	}
697 	return actx;
698 }
699 
FromMapEvent(int ev,AsyncOp aop)700 inline MapUpdateAsyncContext MapUpdateAsyncContext::FromMapEvent(int ev, AsyncOp aop) {
701 	MapUpdateAsyncContext actx;
702 	if (aop.IsActive()) {
703 		actx.async_op = aop;
704 		actx.map_event = ev;
705 	}
706 	return actx;
707 }
708 
FromForegroundEvent(AsyncOp aop)709 inline MapUpdateAsyncContext MapUpdateAsyncContext::FromForegroundEvent(AsyncOp aop) {
710 	MapUpdateAsyncContext actx;
711 	if (aop.IsActive()) {
712 		actx.async_op = aop;
713 		actx.foreground_event = true;
714 	}
715 	return actx;
716 }
717 
FromMessage(AsyncOp aop)718 inline MapUpdateAsyncContext MapUpdateAsyncContext::FromMessage(AsyncOp aop) {
719 	MapUpdateAsyncContext actx;
720 	if (aop.IsActive()) {
721 		actx.async_op = aop;
722 		actx.message = true;
723 	}
724 	return actx;
725 }
726 
GetParallelCommonEvent()727 inline int MapUpdateAsyncContext::GetParallelCommonEvent() const {
728 	return common_event;
729 }
730 
GetParallelMapEvent()731 inline int MapUpdateAsyncContext::GetParallelMapEvent() const {
732 	return map_event;
733 }
734 
IsForegroundEvent()735 inline bool MapUpdateAsyncContext::IsForegroundEvent() const {
736 	return foreground_event;
737 }
738 
IsParallelCommonEvent()739 inline bool MapUpdateAsyncContext::IsParallelCommonEvent() const {
740 	return common_event > 0;
741 }
742 
IsParallelMapEvent()743 inline bool MapUpdateAsyncContext::IsParallelMapEvent() const {
744 	return map_event > 0;
745 }
746 
IsMessage()747 inline bool MapUpdateAsyncContext::IsMessage() const {
748 	return message;
749 }
750 
IsActive()751 inline bool MapUpdateAsyncContext::IsActive() const {
752 	return GetAsyncOp().IsActive();
753 }
754 
755 #endif
756