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