1 /***************************************************************************
2  *   Copyright (C) 2009 by Andrey Afletdinov <fheroes2@gmail.com>          *
3  *                                                                         *
4  *   Part of the Free Heroes2 Engine:                                      *
5  *   http://sourceforge.net/projects/fheroes2                              *
6  *                                                                         *
7  *   This program is free software; you can redistribute it and/or modify  *
8  *   it under the terms of the GNU General Public License as published by  *
9  *   the Free Software Foundation; either version 2 of the License, or     *
10  *   (at your option) any later version.                                   *
11  *                                                                         *
12  *   This program is distributed in the hope that it will be useful,       *
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
15  *   GNU General Public License for more details.                          *
16  *                                                                         *
17  *   You should have received a copy of the GNU General Public License     *
18  *   along with this program; if not, write to the                         *
19  *   Free Software Foundation, Inc.,                                       *
20  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
21  ***************************************************************************/
22 #ifndef H2WORLD_H
23 #define H2WORLD_H
24 
25 #include <string>
26 #include <vector>
27 
28 #include "artifact_ultimate.h"
29 #include "castle_heroes.h"
30 #include "kingdom.h"
31 #include "maps.h"
32 #include "maps_tiles.h"
33 #include "week.h"
34 #include "world_pathfinding.h"
35 #include "world_regions.h"
36 
37 class Recruits;
38 class MapObjectSimple;
39 class ActionSimple;
40 struct MapEvent;
41 
42 struct ListActions : public std::list<ActionSimple *>
43 {
44     ListActions() = default;
45     ListActions( const ListActions & other ) = default;
46     ListActions & operator=( const ListActions & other ) = delete;
47     ListActions( const ListActions && other ) = delete;
48     ListActions & operator=( const ListActions && other ) = delete;
49     ~ListActions();
50     void clear( void );
51 };
52 
53 struct MapObjects : public std::map<u32, MapObjectSimple *>
54 {
55     MapObjects() = default;
56     MapObjects( const MapObjects & other ) = delete;
57     MapObjects & operator=( const MapObjects & other ) = delete;
58     MapObjects( const MapObjects && other ) = delete;
59     MapObjects & operator=( const MapObjects && other ) = delete;
60     ~MapObjects();
61     void clear( void );
62     void add( MapObjectSimple * );
63     std::list<MapObjectSimple *> get( const fheroes2::Point & );
64     MapObjectSimple * get( u32 uid );
65     void remove( u32 uid );
66 };
67 
68 using MapActions = std::map<s32, ListActions>;
69 
70 struct CapturedObject
71 {
72     ObjectColor objcol;
73     Troop guardians;
74     int split;
75 
CapturedObjectCapturedObject76     CapturedObject()
77         : split( 1 )
78     {}
79 
GetSplitCapturedObject80     int GetSplit( void ) const
81     {
82         return split;
83     }
GetColorCapturedObject84     int GetColor( void ) const
85     {
86         return objcol.second;
87     }
GetTroopCapturedObject88     Troop & GetTroop( void )
89     {
90         return guardians;
91     }
92 
SetCapturedObject93     void Set( int obj, int col )
94     {
95         objcol = ObjectColor( obj, col );
96     }
SetColorCapturedObject97     void SetColor( int col )
98     {
99         objcol.second = col;
100     }
SetSplitCapturedObject101     void SetSplit( int spl )
102     {
103         split = spl;
104     }
105 };
106 
107 struct CapturedObjects : std::map<s32, CapturedObject>
108 {
109     void Set( s32, int, int );
110     void SetColor( s32, int );
111     void ClearFog( int );
112     void ResetColor( int );
113 
114     CapturedObject & Get( s32 );
115 
116     void tributeCapturedObjects( const int playerColorId, const int objectType, Funds & funds, int & objectCount );
117 
118     u32 GetCount( int, int ) const;
119     u32 GetCountMines( int, int ) const;
120     int GetColor( s32 ) const;
121 };
122 
123 struct EventDate
124 {
EventDateEventDate125     EventDate()
126         : first( 0 )
127         , subsequent( 0 )
128         , colors( 0 )
129         , computer( false )
130     {}
131 
132     void LoadFromMP2( StreamBuf );
133 
134     bool isAllow( int color, u32 date ) const;
135     bool isDeprecated( u32 date ) const;
136 
137     Funds resource;
138     u32 first;
139     u32 subsequent;
140     int colors;
141     bool computer;
142     std::string message;
143 
144     std::string title;
145 };
146 
147 StreamBase & operator<<( StreamBase &, const EventDate & );
148 StreamBase & operator>>( StreamBase &, EventDate & );
149 
150 using Rumors = std::list<std::string>;
151 using EventsDate = std::list<EventDate>;
152 using MapsTiles = std::vector<Maps::Tiles>;
153 
154 class World : protected fheroes2::Size
155 {
156 public:
157     World( const World & other ) = delete;
158     World & operator=( const World & other ) = delete;
159     World( const World && other ) = delete;
160     World & operator=( const World && other ) = delete;
~World()161     ~World()
162     {
163         Reset();
164     }
165 
166     bool LoadMapMP2( const std::string & );
167 
168     void NewMaps( int32_t, int32_t );
169 
170     static World & Get( void );
171 
w()172     int32_t w() const
173     {
174         return width;
175     }
176 
h()177     int32_t h() const
178     {
179         return height;
180     }
181 
182     const Maps::Tiles & GetTiles( const int32_t x, const int32_t y ) const;
183     Maps::Tiles & GetTiles( const int32_t x, const int32_t y );
184     const Maps::Tiles & GetTiles( const int32_t tileId ) const;
185     Maps::Tiles & GetTiles( const int32_t tileId );
186 
187     void InitKingdoms( void );
188 
189     Kingdom & GetKingdom( int color );
190     const Kingdom & GetKingdom( int color ) const;
191 
192     // Get castle based on its tile. If the tile is not a part of a castle return nullptr.
193     const Castle * getCastle( const fheroes2::Point & tilePosition ) const;
194     Castle * getCastle( const fheroes2::Point & tilePosition );
195 
196     // Get castle based on its entrance tile. If the tile is not castle's entrance return nullptr.
197     const Castle * getCastleEntrance( const fheroes2::Point & tilePosition ) const;
198     Castle * getCastleEntrance( const fheroes2::Point & tilePosition );
199 
200     const Heroes * GetHeroes( int id ) const;
201     Heroes * GetHeroes( int id );
202 
203     const Heroes * GetHeroes( const fheroes2::Point & ) const;
204     Heroes * GetHeroes( const fheroes2::Point & );
205 
206     Heroes * FromJailHeroes( s32 );
207     Heroes * GetFreemanHeroes( int race = 0 ) const;
208     Heroes * GetFreemanHeroesSpecial( int heroID ) const;
209 
210     const Heroes * GetHeroesCondWins( void ) const;
211     const Heroes * GetHeroesCondLoss( void ) const;
212 
213     CastleHeroes GetHeroes( const Castle & ) const;
214 
215     void RescanAllHeroesPathPassable() const;
216 
217     const UltimateArtifact & GetUltimateArtifact( void ) const;
218     bool DiggingForUltimateArtifact( const fheroes2::Point & );
219 
220     // overall number of cells of the world map: width * height
221     size_t getSize() const;
222     int GetDay( void ) const;
223     int GetWeek( void ) const;
224     int GetMonth( void ) const;
225     u32 CountDay( void ) const;
226     u32 CountWeek( void ) const;
227     bool BeginWeek( void ) const;
228     bool BeginMonth( void ) const;
229     bool LastDay( void ) const;
230     bool LastWeek( void ) const;
231     const Week & GetWeekType( void ) const;
232     std::string DateString( void ) const;
233 
234     void NewDay( void );
235     void NewWeek( void );
236     void NewMonth( void );
237 
238     const std::string & GetRumors( void );
239 
240     s32 NextTeleport( s32 ) const;
241     MapsIndexes GetTeleportEndPoints( s32 ) const;
242 
243     s32 NextWhirlpool( s32 ) const;
244     MapsIndexes GetWhirlpoolEndPoints( s32 ) const;
245 
246     void CaptureObject( s32, int col );
247     u32 CountCapturedObject( int obj, int col ) const;
248     u32 CountCapturedMines( int type, int col ) const;
249     u32 CountObeliskOnMaps( void );
250     int ColorCapturedObject( s32 ) const;
251     void ResetCapturedObjects( int );
252     CapturedObject & GetCapturedObject( s32 );
253     ListActions * GetListActions( s32 );
254 
255     void ActionForMagellanMaps( int color );
256     void ClearFog( int color );
257     void UpdateRecruits( Recruits & ) const;
258 
259     uint32_t CheckKingdomWins( const Kingdom & ) const;
260     bool KingdomIsWins( const Kingdom &, uint32_t wins ) const;
261     uint32_t CheckKingdomLoss( const Kingdom & ) const;
262     bool KingdomIsLoss( const Kingdom &, uint32_t loss ) const;
263 
264     void AddEventDate( const EventDate & );
265     EventsDate GetEventsDate( int color ) const;
266 
267     MapEvent * GetMapEvent( const fheroes2::Point & );
268     MapObjectSimple * GetMapObject( u32 uid );
269     void RemoveMapObject( const MapObjectSimple * );
270     const MapRegion & getRegion( size_t id ) const;
271     size_t getRegionCount() const;
272 
273     bool isTileBlocked( int toTile, bool fromWater ) const;
274     bool isValidPath( const int index, const int direction, const int heroColor ) const;
275     uint32_t getDistance( const Heroes & hero, int targetIndex );
276     std::list<Route::Step> getPath( const Heroes & hero, int targetIndex );
277     void resetPathfinder();
278 
279     void ComputeStaticAnalysis();
280     static u32 GetUniq( void );
281 
282     uint32_t GetMapSeed() const;
283 
284     bool isAnyKingdomVisited( const MP2::MapObjectType objectType, const int32_t dstIndex ) const;
285 
286 private:
World()287     World()
288         : fheroes2::Size( 0, 0 )
289         , _rumor( nullptr )
290         , _seed( 0 )
291     {}
292 
293     void Defaults( void );
294     void Reset( void );
295     void MonthOfMonstersAction( const Monster & );
296     void ProcessNewMap();
297     void PostLoad( const bool setTilePassabilities );
298     void pickRumor();
299 
300     bool isValidCastleEntrance( const fheroes2::Point & tilePosition ) const;
301 
302     friend class Radar;
303     friend StreamBase & operator<<( StreamBase &, const World & );
304     friend StreamBase & operator>>( StreamBase &, World & );
305 
306     MapsTiles vec_tiles;
307     AllHeroes vec_heroes;
308     AllCastles vec_castles;
309     Kingdoms vec_kingdoms;
310     Rumors vec_rumors;
311     const std::string * _rumor;
312     EventsDate vec_eventsday;
313 
314     // index, object, color
315     CapturedObjects map_captureobj;
316 
317     UltimateArtifact ultimate_artifact;
318 
319     uint32_t day = 0;
320     uint32_t week = 0;
321     uint32_t month = 0;
322 
323     Week week_current;
324     Week week_next;
325 
326     int heroes_cond_wins = Heroes::UNKNOWN;
327     int heroes_cond_loss = Heroes::UNKNOWN;
328 
329     MapActions map_actions;
330     MapObjects map_objects;
331 
332     // This data isn't serialized
333     Maps::Indexes _allTeleporters;
334     Maps::Indexes _whirlpoolTiles;
335     std::vector<MapRegion> _regions;
336     PlayerWorldPathfinder _pathfinder;
337 
338     uint32_t _seed{ 0 }; // global seed for the map
339     size_t _weekSeed{ 0 }; // global seed for the map, for this week
340 };
341 
342 StreamBase & operator<<( StreamBase &, const CapturedObject & );
343 StreamBase & operator>>( StreamBase &, CapturedObject & );
344 StreamBase & operator<<( StreamBase &, const World & );
345 StreamBase & operator>>( StreamBase &, World & );
346 
347 StreamBase & operator<<( StreamBase &, const ListActions & );
348 StreamBase & operator>>( StreamBase &, ListActions & );
349 
350 StreamBase & operator<<( StreamBase &, const MapObjects & );
351 StreamBase & operator>>( StreamBase &, MapObjects & );
352 
353 extern World & world;
354 
355 #endif
356