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 
23 #include "mp2.h"
24 #include "direction.h"
25 #include "icn.h"
26 #include "logging.h"
27 #include "settings.h"
28 #include "translations.h"
29 
30 #include <cassert>
31 
GetICNObject(const uint8_t tileset)32 int MP2::GetICNObject( const uint8_t tileset )
33 {
34     switch ( tileset >> 2 ) {
35     // reserverd
36     case 0:
37         return ICN::UNKNOWN;
38     // custom: boat sprite
39     case 6:
40         return ICN::BOAT32;
41     // artifact
42     case 11:
43         return ICN::OBJNARTI;
44     // monster
45     case 12:
46         return ICN::MONS32;
47     // castle flags
48     case 14:
49         return ICN::FLAG32;
50     // heroes
51     case 21:
52         return ICN::MINIHERO;
53     // mountains: snow
54     case 22:
55         return ICN::MTNSNOW;
56     // mountains: swamp
57     case 23:
58         return ICN::MTNSWMP;
59     // mountains: lava
60     case 24:
61         return ICN::MTNLAVA;
62     // mountains: desert
63     case 25:
64         return ICN::MTNDSRT;
65     // mountains: dirt
66     case 26:
67         return ICN::MTNDIRT;
68     // mountains: all terrains
69     case 27:
70         return ICN::MTNMULT;
71     // mines
72     case 29:
73         return ICN::EXTRAOVR;
74     // road
75     case 30:
76         return ICN::ROAD;
77     // relief: crck
78     case 31:
79         return ICN::MTNCRCK;
80     // relief: gras
81     case 32:
82         return ICN::MTNGRAS;
83     // trees jungle
84     case 33:
85         return ICN::TREJNGL;
86     // trees evil
87     case 34:
88         return ICN::TREEVIL;
89     // castle and town sprites
90     case 35:
91         return ICN::OBJNTOWN;
92     // castle base
93     case 36:
94         return ICN::OBJNTWBA;
95     // castle shadow
96     case 37:
97         return ICN::OBJNTWSH;
98     // random castle
99     case 38:
100         return ICN::OBJNTWRD;
101     // mine guardians (elementals)
102     case 39:
103         return ICN::OBJNXTRA;
104     // water object
105     case 40:
106         return ICN::OBJNWAT2;
107     // object other
108     case 41:
109         return ICN::OBJNMUL2;
110     // trees snow
111     case 42:
112         return ICN::TRESNOW;
113     // trees trefir
114     case 43:
115         return ICN::TREFIR;
116     // trees
117     case 44:
118         return ICN::TREFALL;
119     // river
120     case 45:
121         return ICN::STREAM;
122     // resource
123     case 46:
124         return ICN::OBJNRSRC;
125     // gras object
126     case 48:
127         return ICN::OBJNGRA2;
128     // trees tredeci
129     case 49:
130         return ICN::TREDECI;
131     // sea object
132     case 50:
133         return ICN::OBJNWATR;
134     // vegetation gras
135     case 51:
136         return ICN::OBJNGRAS;
137     // object on snow
138     case 52:
139         return ICN::OBJNSNOW;
140     // object on swamp
141     case 53:
142         return ICN::OBJNSWMP;
143     // object on lava
144     case 54:
145         return ICN::OBJNLAVA;
146     // object on desert
147     case 55:
148         return ICN::OBJNDSRT;
149     // object on dirt
150     case 56:
151         return ICN::OBJNDIRT;
152     // object on crck
153     case 57:
154         return ICN::OBJNCRCK;
155     // object on lava
156     case 58:
157         return ICN::OBJNLAV3;
158     // object on earth
159     case 59:
160         return ICN::OBJNMULT;
161     //  object on lava
162     case 60:
163         return ICN::OBJNLAV2;
164     // extra objects for loyalty version
165     case 61:
166         if ( Settings::Get().isPriceOfLoyaltySupported() )
167             return ICN::X_LOC1;
168         break;
169     // extra objects for loyalty version
170     case 62:
171         if ( Settings::Get().isPriceOfLoyaltySupported() )
172             return ICN::X_LOC2;
173         break;
174     // extra objects for loyalty version
175     case 63:
176         if ( Settings::Get().isPriceOfLoyaltySupported() )
177             return ICN::X_LOC3;
178         break;
179     default:
180         break;
181     }
182 
183     DEBUG_LOG( DBG_GAME, DBG_WARN, "unknown type: " << static_cast<int>( tileset ) );
184 
185     return ICN::UNKNOWN;
186 }
187 
isHiddenForPuzzle(uint8_t tileset,uint8_t index)188 bool MP2::isHiddenForPuzzle( uint8_t tileset, uint8_t index )
189 {
190     const int icnID = tileset >> 2;
191     return ( icnID < 22 || icnID == 46 || ( icnID == 56 && index == 140 ) );
192 }
193 
StringObject(const MapObjectType objectType)194 const char * MP2::StringObject( const MapObjectType objectType )
195 {
196     switch ( objectType ) {
197     case OBJ_ZERO:
198         return _( "No object" );
199     case OBJN_ALCHEMYLAB:
200     case OBJ_ALCHEMYLAB:
201         return _( "Alchemist Lab" );
202     case OBJN_DAEMONCAVE:
203     case OBJ_DAEMONCAVE:
204         return _( "Daemon Cave" );
205     case OBJN_FAERIERING:
206     case OBJ_FAERIERING:
207         return _( "Faerie Ring" );
208     case OBJN_GRAVEYARD:
209     case OBJ_GRAVEYARD:
210         return _( "Graveyard" );
211     case OBJN_DRAGONCITY:
212     case OBJ_DRAGONCITY:
213         return _( "Dragon City" );
214     case OBJN_LIGHTHOUSE:
215     case OBJ_LIGHTHOUSE:
216         return _( "Lighthouse" );
217     case OBJN_WATERWHEEL:
218     case OBJ_WATERWHEEL:
219         return _( "Water Wheel" );
220     case OBJN_MINES:
221     case OBJ_MINES:
222         return _( "Mines" );
223     case OBJN_OBELISK:
224     case OBJ_OBELISK:
225         return _( "Obelisk" );
226     case OBJN_OASIS:
227     case OBJ_OASIS:
228         return _( "Oasis" );
229     case OBJN_SAWMILL:
230     case OBJ_SAWMILL:
231         return _( "Sawmill" );
232     case OBJN_ORACLE:
233     case OBJ_ORACLE:
234         return _( "Oracle" );
235     case OBJN_DESERTTENT:
236     case OBJ_DESERTTENT:
237         return _( "Desert Tent" );
238     case OBJN_CASTLE:
239     case OBJ_CASTLE:
240         return _( "Castle" );
241     case OBJN_WAGONCAMP:
242     case OBJ_WAGONCAMP:
243         return _( "Wagon Camp" );
244     case OBJN_WINDMILL:
245     case OBJ_WINDMILL:
246         return _( "Windmill" );
247     case OBJN_RNDTOWN:
248     case OBJ_RNDTOWN:
249         return _( "Random Town" );
250     case OBJN_RNDCASTLE:
251     case OBJ_RNDCASTLE:
252         return _( "Random Castle" );
253     case OBJN_WATCHTOWER:
254     case OBJ_WATCHTOWER:
255         return _( "Watch Tower" );
256     case OBJN_TREECITY:
257     case OBJ_TREECITY:
258         return _( "Tree City" );
259     case OBJN_TREEHOUSE:
260     case OBJ_TREEHOUSE:
261         return _( "Tree House" );
262     case OBJN_RUINS:
263     case OBJ_RUINS:
264         return _( "Ruins" );
265     case OBJN_FORT:
266     case OBJ_FORT:
267         return _( "Fort" );
268     case OBJN_TRADINGPOST:
269     case OBJ_TRADINGPOST:
270         return _( "Trading Post" );
271     case OBJN_ABANDONEDMINE:
272     case OBJ_ABANDONEDMINE:
273         return _( "Abandoned Mine" );
274     case OBJN_TREEKNOWLEDGE:
275     case OBJ_TREEKNOWLEDGE:
276         return _( "Tree of Knowledge" );
277     case OBJN_DOCTORHUT:
278     case OBJ_DOCTORHUT:
279         return _( "Witch Doctor's Hut" );
280     case OBJN_TEMPLE:
281     case OBJ_TEMPLE:
282         return _( "Temple" );
283     case OBJN_HILLFORT:
284     case OBJ_HILLFORT:
285         return _( "Hill Fort" );
286     case OBJN_HALFLINGHOLE:
287     case OBJ_HALFLINGHOLE:
288         return _( "Halfling Hole" );
289     case OBJN_MERCENARYCAMP:
290     case OBJ_MERCENARYCAMP:
291         return _( "Mercenary Camp" );
292     case OBJN_PYRAMID:
293     case OBJ_PYRAMID:
294         return _( "Pyramid" );
295     case OBJN_CITYDEAD:
296     case OBJ_CITYDEAD:
297         return _( "City of the Dead" );
298     case OBJN_EXCAVATION:
299     case OBJ_EXCAVATION:
300         return _( "Excavation" );
301     case OBJN_SPHINX:
302     case OBJ_SPHINX:
303         return _( "Sphinx" );
304     case OBJN_TROLLBRIDGE:
305     case OBJ_TROLLBRIDGE:
306         return _( "Troll Bridge" );
307     case OBJN_WITCHSHUT:
308     case OBJ_WITCHSHUT:
309         return _( "Witch's Hut" );
310     case OBJN_XANADU:
311     case OBJ_XANADU:
312         return _( "Xanadu" );
313     case OBJN_CAVE:
314     case OBJ_CAVE:
315         return _( "Cave" );
316     case OBJN_MAGELLANMAPS:
317     case OBJ_MAGELLANMAPS:
318         return _( "Magellan's Maps" );
319     case OBJN_DERELICTSHIP:
320     case OBJ_DERELICTSHIP:
321         return _( "Derelict Ship" );
322     case OBJN_SHIPWRECK:
323     case OBJ_SHIPWRECK:
324         return _( "Shipwreck" );
325     case OBJN_OBSERVATIONTOWER:
326     case OBJ_OBSERVATIONTOWER:
327         return _( "Observation Tower" );
328     case OBJN_FREEMANFOUNDRY:
329     case OBJ_FREEMANFOUNDRY:
330         return _( "Freeman's Foundry" );
331     case OBJN_WATERINGHOLE:
332     case OBJ_WATERINGHOLE:
333         return _( "Watering Hole" );
334     case OBJN_ARTESIANSPRING:
335     case OBJ_ARTESIANSPRING:
336         return _( "Artesian Spring" );
337     case OBJN_GAZEBO:
338     case OBJ_GAZEBO:
339         return _( "Gazebo" );
340     case OBJN_ARCHERHOUSE:
341     case OBJ_ARCHERHOUSE:
342         return _( "Archer's House" );
343     case OBJN_PEASANTHUT:
344     case OBJ_PEASANTHUT:
345         return _( "Peasant Hut" );
346     case OBJN_DWARFCOTT:
347     case OBJ_DWARFCOTT:
348         return _( "Dwarf Cottage" );
349     case OBJN_STONELITHS:
350     case OBJ_STONELITHS:
351         return _( "Stone Liths" );
352     case OBJN_MAGICWELL:
353     case OBJ_MAGICWELL:
354         return _( "Magic Well" );
355     case OBJ_HEROES:
356         return _( "Heroes" );
357     case OBJ_SIGN:
358         return _( "Sign" );
359     case OBJ_NOTHINGSPECIAL:
360     case OBJ_NOTHINGSPECIAL2:
361         return _( "Nothing Special" );
362     case OBJ_TARPIT:
363         return _( "Tar Pit" );
364     case OBJ_COAST:
365         return _( "Beach" );
366     case OBJ_MOUND:
367         return _( "Mound" );
368     case OBJ_DUNE:
369         return _( "Dune" );
370     case OBJ_STUMP:
371         return _( "Stump" );
372     case OBJ_CACTUS:
373         return _( "Cactus" );
374     case OBJ_TREES:
375         return _( "Trees" );
376     case OBJ_DEADTREE:
377         return _( "Dead Tree" );
378     case OBJ_MOUNTS:
379         return _( "Mountains" );
380     case OBJ_VOLCANO:
381         return _( "Volcano" );
382     case OBJ_STONES:
383         return _( "Rock" );
384     case OBJ_FLOWERS:
385         return _( "Flowers" );
386     case OBJ_WATERLAKE:
387         return _( "Water Lake" );
388     case OBJ_MANDRAKE:
389         return _( "Mandrake" );
390     case OBJ_CRATER:
391         return _( "Crater" );
392     case OBJ_LAVAPOOL:
393         return _( "Lava Pool" );
394     case OBJ_SHRUB:
395         return _( "Shrub" );
396     case OBJ_BUOY:
397         return _( "Buoy" );
398     case OBJN_SKELETON:
399     case OBJ_SKELETON:
400         return _( "Skeleton" );
401     case OBJ_TREASURECHEST:
402         return _( "Treasure Chest" );
403     case OBJ_WATERCHEST:
404         return _( "Sea Chest" );
405     case OBJ_CAMPFIRE:
406         return _( "Campfire" );
407     case OBJ_FOUNTAIN:
408         return _( "Fountain" );
409     case OBJ_ANCIENTLAMP:
410         return _( "Genie Lamp" );
411     case OBJ_GOBLINHUT:
412         return _( "Goblin Hut" );
413     case OBJ_THATCHEDHUT:
414         return _( "Thatched Hut" );
415     case OBJ_MONSTER:
416         return _( "Monster" );
417     case OBJ_RESOURCE:
418         return _( "Resource" );
419     case OBJ_WHIRLPOOL:
420         return _( "Whirlpool" );
421     case OBJ_ARTIFACT:
422         return _( "Artifact" );
423     case OBJ_BOAT:
424         return _( "Boat" );
425     case OBJ_RNDARTIFACT:
426         return _( "Random Artifact" );
427     case OBJ_RNDRESOURCE:
428         return _( "Random Resource" );
429     case OBJ_RNDMONSTER1:
430         return _( "Random Monster - weak" );
431     case OBJ_RNDMONSTER2:
432         return _( "Random Monster - medium" );
433     case OBJ_RNDMONSTER3:
434         return _( "Random Monster - strong" );
435     case OBJ_RNDMONSTER4:
436         return _( "Random Monster - very strong" );
437     case OBJ_STANDINGSTONES:
438         return _( "Standing Stones" );
439     case OBJ_EVENT:
440         return _( "Event" );
441     case OBJ_RNDMONSTER:
442         return _( "Random Monster" );
443     case OBJ_RNDULTIMATEARTIFACT:
444         return _( "Random Ultimate Artifact" );
445     case OBJ_IDOL:
446         return _( "Idol" );
447     case OBJ_SHRINE1:
448         return _( "Shrine of the First Circle" );
449     case OBJ_SHRINE2:
450         return _( "Shrine of the Second Circle" );
451     case OBJ_SHRINE3:
452         return _( "Shrine of the Third Circle" );
453     case OBJ_WAGON:
454         return _( "Wagon" );
455     case OBJ_LEANTO:
456         return _( "Lean To" );
457     case OBJ_FLOTSAM:
458         return _( "Flotsam" );
459     case OBJ_SHIPWRECKSURVIROR:
460         return _( "Shipwreck Survivor" );
461     case OBJ_BOTTLE:
462         return _( "Bottle" );
463     case OBJ_MAGICGARDEN:
464         return _( "Magic Garden" );
465     case OBJ_RNDARTIFACT1:
466         return _( "Random Artifact - Treasure" );
467     case OBJ_RNDARTIFACT2:
468         return _( "Random Artifact - Minor" );
469     case OBJ_RNDARTIFACT3:
470         return _( "Random Artifact - Major" );
471     case OBJN_JAIL:
472     case OBJ_JAIL:
473         return _( "Jail" );
474     case OBJN_TRAVELLERTENT:
475     case OBJ_TRAVELLERTENT:
476         return _( "Traveller's Tent" );
477     case OBJ_BARRIER:
478         return _( "Barrier" );
479     case OBJN_FIREALTAR:
480     case OBJ_FIREALTAR:
481         return _( "Fire Summoning Altar" );
482     case OBJN_AIRALTAR:
483     case OBJ_AIRALTAR:
484         return _( "Air Summoning Altar" );
485     case OBJN_EARTHALTAR:
486     case OBJ_EARTHALTAR:
487         return _( "Earth Summoning Altar" );
488     case OBJN_WATERALTAR:
489     case OBJ_WATERALTAR:
490         return _( "Water Summoning Altar" );
491     case OBJN_BARROWMOUNDS:
492     case OBJ_BARROWMOUNDS:
493         return _( "Barrow Mounds" );
494     case OBJN_ARENA:
495     case OBJ_ARENA:
496         return _( "Arena" );
497     case OBJN_STABLES:
498     case OBJ_STABLES:
499         return _( "Stables" );
500     case OBJN_ALCHEMYTOWER:
501     case OBJ_ALCHEMYTOWER:
502         return _( "Alchemist's Tower" );
503     case OBJN_HUTMAGI:
504     case OBJ_HUTMAGI:
505         return _( "Hut of the Magi" );
506     case OBJN_EYEMAGI:
507     case OBJ_EYEMAGI:
508         return _( "Eye of the Magi" );
509     case OBJN_MERMAID:
510     case OBJ_MERMAID:
511         return _( "Mermaid" );
512     case OBJN_SIRENS:
513     case OBJ_SIRENS:
514         return _( "Sirens" );
515     case OBJ_REEFS:
516         return _( "Reefs" );
517     case OBJ_UNKNW_02:
518         return "OBJ_UNKNW_02";
519     case OBJ_UNKNW_03:
520         return "OBJ_UNKNW_03";
521     case OBJ_UNKNW_06:
522         return "OBJ_UNKNW_06";
523     case OBJ_UNKNW_08:
524         return "OBJ_UNKNW_08";
525     case OBJ_UNKNW_09:
526         return "OBJ_UNKNW_09";
527     case OBJ_UNKNW_0B:
528         return "OBJ_UNKNW_0B";
529     case OBJ_UNKNW_0E:
530         return "OBJ_UNKNW_0E";
531     case OBJ_UNKNW_11:
532         return "OBJ_UNKNW_11";
533     case OBJ_UNKNW_12:
534         return "OBJ_UNKNW_12";
535     case OBJ_UNKNW_13:
536         return "OBJ_UNKNW_13";
537     case OBJ_UNKNW_18:
538         return "OBJ_UNKNW_18";
539     case OBJ_UNKNW_1B:
540         return "OBJ_UNKNW_1B";
541     case OBJ_UNKNW_1F:
542         return "OBJ_UNKNW_1F";
543     case OBJ_UNKNW_21:
544         return "OBJ_UNKNW_21";
545     case OBJ_UNKNW_26:
546         return "OBJ_UNKNW_26";
547     case OBJ_UNKNW_27:
548         return "OBJ_UNKNW_27";
549     case OBJ_UNKNW_29:
550         return "OBJ_UNKNW_29";
551     case OBJ_UNKNW_2A:
552         return "OBJ_UNKNW_2A";
553     case OBJ_UNKNW_2B:
554         return "OBJ_UNKNW_2B";
555     case OBJ_UNKNW_2C:
556         return "OBJ_UNKNW_2C";
557     case OBJ_UNKNW_2D:
558         return "OBJ_UNKNW_2D";
559     case OBJ_UNKNW_2E:
560         return "OBJ_UNKNW_2E";
561     case OBJ_UNKNW_2F:
562         return "OBJ_UNKNW_2F";
563     case OBJ_UNKNW_32:
564         return "OBJ_UNKNW_32";
565     case OBJ_UNKNW_33:
566         return "OBJ_UNKNW_33";
567     case OBJ_UNKNW_34:
568         return "OBJ_UNKNW_34";
569     case OBJ_UNKNW_35:
570         return "OBJ_UNKNW_35";
571     case OBJ_UNKNW_36:
572         return "OBJ_UNKNW_36";
573     case OBJ_UNKNW_37:
574         return "OBJ_UNKNW_37";
575     case OBJ_UNKNW_41:
576         return "OBJ_UNKNW_41";
577     case OBJ_UNKNW_42:
578         return "OBJ_UNKNW_42";
579     case OBJ_UNKNW_43:
580         return "OBJ_UNKNW_43";
581     case OBJ_UNKNW_4A:
582         return "OBJ_UNKNW_4A";
583     case OBJ_UNKNW_4B:
584         return "OBJ_UNKNW_4B";
585     case OBJ_UNKNW_50:
586         return "OBJ_UNKNW_50";
587     case OBJ_UNKNW_58:
588         return "OBJ_UNKNW_58";
589     case OBJ_UNKNW_5A:
590         return "OBJ_UNKNW_5A";
591     case OBJ_UNKNW_5C:
592         return "OBJ_UNKNW_5C";
593     case OBJ_UNKNW_5D:
594         return "OBJ_UNKNW_5D";
595     case OBJ_UNKNW_5F:
596         return "OBJ_UNKNW_5F";
597     case OBJ_UNKNW_62:
598         return "OBJ_UNKNW_62";
599     case OBJ_UNKNW_79:
600         return "OBJ_UNKNW_79";
601     case OBJ_UNKNW_7A:
602         return "OBJ_UNKNW_7A";
603     case OBJ_UNKNW_91:
604         return "OBJ_UNKNW_91";
605     case OBJ_UNKNW_92:
606         return "OBJ_UNKNW_92";
607     case OBJ_UNKNW_A1:
608         return "OBJ_UNKNW_A1";
609     case OBJ_UNKNW_A6:
610         return "OBJ_UNKNW_A6";
611     case OBJ_UNKNW_AA:
612         return "OBJ_UNKNW_AA";
613     case OBJ_UNKNW_B2:
614         return "OBJ_UNKNW_B2";
615     case OBJ_UNKNW_B8:
616         return "OBJ_UNKNW_B8";
617     case OBJ_UNKNW_B9:
618         return "OBJ_UNKNW_B9";
619     case OBJ_UNKNW_D1:
620         return "OBJ_UNKNW_D1";
621     case OBJ_UNKNW_E2:
622         return "OBJ_UNKNW_E2";
623     case OBJ_UNKNW_E3:
624         return "OBJ_UNKNW_E3";
625     case OBJ_UNKNW_E4:
626         return "OBJ_UNKNW_E4";
627     case OBJ_UNKNW_E5:
628         return "OBJ_UNKNW_E5";
629     case OBJ_UNKNW_E6:
630         return "OBJ_UNKNW_E6";
631     case OBJ_UNKNW_E7:
632         return "OBJ_UNKNW_E7";
633     case OBJ_UNKNW_E8:
634         return "OBJ_UNKNW_E8";
635     case OBJ_UNKNW_F9:
636         return "OBJ_UNKNW_F9";
637     case OBJ_UNKNW_FA:
638         return "OBJ_UNKNW_FA";
639     default:
640         DEBUG_LOG( DBG_GAME, DBG_WARN, "unknown object: " << static_cast<int>( objectType ) );
641         break;
642     }
643 
644     return nullptr;
645 }
646 
getPluralObjectName(const MapObjectType objectType,const size_t count)647 const char * MP2::getPluralObjectName( const MapObjectType objectType, const size_t count )
648 {
649     switch ( objectType ) {
650     case OBJ_WATERWHEEL:
651         return _n( "Water Wheel", "Water Wheels", count );
652     case OBJ_WINDMILL:
653         return _n( "Windmill", "Windmills", count );
654     case OBJ_MAGICGARDEN:
655         return _n( "Magic Garden", "Magic Gardens", count );
656     default:
657         break;
658     }
659 
660     return StringObject( objectType );
661 }
662 
isDayLife(const MapObjectType objectType)663 bool MP2::isDayLife( const MapObjectType objectType )
664 {
665     // TODO: list day object life
666     switch ( objectType ) {
667     case OBJ_MAGICWELL:
668         return true;
669 
670     default:
671         break;
672     }
673 
674     return false;
675 }
676 
isWeekLife(const MapObjectType objectType)677 bool MP2::isWeekLife( const MapObjectType objectType )
678 {
679     // TODO: list week object life
680     switch ( objectType ) {
681     case OBJ_STABLES:
682     case OBJ_MAGICGARDEN:
683     case OBJ_WATERWHEEL:
684     case OBJ_WINDMILL:
685     case OBJ_ARTESIANSPRING:
686     // join army
687     case OBJ_WATCHTOWER:
688     case OBJ_EXCAVATION:
689     case OBJ_CAVE:
690     case OBJ_TREEHOUSE:
691     case OBJ_ARCHERHOUSE:
692     case OBJ_GOBLINHUT:
693     case OBJ_DWARFCOTT:
694     case OBJ_HALFLINGHOLE:
695     case OBJ_PEASANTHUT:
696     case OBJ_THATCHEDHUT:
697     // recruit army
698     case OBJ_RUINS:
699     case OBJ_TREECITY:
700     case OBJ_WAGONCAMP:
701     case OBJ_DESERTTENT:
702     case OBJ_WATERALTAR:
703     case OBJ_AIRALTAR:
704     case OBJ_FIREALTAR:
705     case OBJ_EARTHALTAR:
706     case OBJ_BARROWMOUNDS:
707     // battle and recruit army
708     case OBJ_DRAGONCITY:
709     case OBJ_CITYDEAD:
710     case OBJ_TROLLBRIDGE:
711     // for AI
712     case OBJ_COAST:
713     case OBJ_HEROES:
714         return true;
715     default:
716         break;
717     }
718 
719     return false;
720 }
721 
isMonthLife(const MapObjectType objectType)722 bool MP2::isMonthLife( const MapObjectType objectType )
723 {
724     return objectType == MP2::OBJ_CASTLE;
725 }
726 
isBattleLife(const MapObjectType objectType)727 bool MP2::isBattleLife( const MapObjectType objectType )
728 {
729     switch ( objectType ) {
730     // luck modificators
731     case OBJ_IDOL:
732     case OBJ_FOUNTAIN:
733     case OBJ_FAERIERING:
734     case OBJ_PYRAMID:
735     // morale modificators
736     case OBJ_BUOY:
737     case OBJ_OASIS:
738     case OBJ_TEMPLE:
739     case OBJ_WATERINGHOLE:
740     case OBJ_GRAVEYARD:
741     case OBJ_DERELICTSHIP:
742     case OBJ_SHIPWRECK:
743     case OBJ_MERMAID:
744         return true;
745     default:
746         break;
747     }
748 
749     return false;
750 }
751 
isActionObject(const MapObjectType objectType,const bool locatesOnWater)752 bool MP2::isActionObject( const MapObjectType objectType, const bool locatesOnWater )
753 {
754     if ( locatesOnWater ) {
755         return isWaterActionObject( objectType );
756     }
757 
758     return isActionObject( objectType );
759 }
760 
isWaterActionObject(const MapObjectType objectType)761 bool MP2::isWaterActionObject( const MapObjectType objectType )
762 {
763     switch ( objectType ) {
764     case OBJ_WATERCHEST:
765     case OBJ_DERELICTSHIP:
766     case OBJ_SHIPWRECK:
767     case OBJ_WHIRLPOOL:
768     case OBJ_BUOY:
769     case OBJ_BOTTLE:
770     case OBJ_SHIPWRECKSURVIROR:
771     case OBJ_FLOTSAM:
772     case OBJ_MAGELLANMAPS:
773     case OBJ_COAST:
774     case OBJ_MERMAID:
775     case OBJ_SIRENS:
776     case OBJ_BARRIER:
777     case OBJ_MONSTER:
778     case OBJ_ARTIFACT:
779     case OBJ_RESOURCE:
780         return true;
781     case OBJ_CASTLE:
782     case OBJ_BOAT:
783         return false;
784     default:
785         break;
786     }
787 
788     // price loyalty: editor allow place other objects
789     return Settings::Get().isPriceOfLoyaltySupported() ? isActionObject( objectType ) : false;
790 }
791 
isActionObject(const MapObjectType objectType)792 bool MP2::isActionObject( const MapObjectType objectType )
793 {
794     // check if first bit is set
795     if ( objectType < 128 ) {
796         return false;
797     }
798     switch ( objectType ) {
799     case OBJ_EVENT:
800     case OBJN_STABLES:
801     case OBJN_ALCHEMYTOWER:
802     case OBJ_UNKNW_E2:
803     case OBJ_UNKNW_E3:
804     case OBJ_UNKNW_E4:
805     case OBJ_UNKNW_E5:
806     case OBJ_UNKNW_E6:
807     case OBJ_UNKNW_E7:
808     case OBJ_UNKNW_E8:
809     case OBJ_UNKNW_F9:
810     case OBJ_UNKNW_FA:
811     case OBJ_UNKNW_91:
812     case OBJ_UNKNW_92:
813     case OBJ_UNKNW_9C:
814     case OBJ_UNKNW_A1:
815     case OBJ_UNKNW_AA:
816     case OBJ_UNKNW_B2:
817     case OBJ_UNKNW_B8:
818     case OBJ_UNKNW_B9:
819     case OBJ_UNKNW_D1:
820     case OBJ_REEFS:
821         return false;
822     default:
823         break;
824     }
825 
826     return true;
827 }
828 
getBaseActionObjectType(const MapObjectType objectType)829 MP2::MapObjectType MP2::getBaseActionObjectType( const MapObjectType objectType )
830 {
831     switch ( objectType ) {
832     case OBJN_ALCHEMYLAB:
833         return OBJ_ALCHEMYLAB;
834     case OBJN_SKELETON:
835         return OBJ_SKELETON;
836     case OBJN_DAEMONCAVE:
837         return OBJ_DAEMONCAVE;
838     case OBJN_FAERIERING:
839         return OBJ_FAERIERING;
840     case OBJN_GAZEBO:
841         return OBJ_GAZEBO;
842     case OBJN_GRAVEYARD:
843         return OBJ_GRAVEYARD;
844     case OBJN_ARCHERHOUSE:
845         return OBJ_ARCHERHOUSE;
846     case OBJN_DWARFCOTT:
847         return OBJ_DWARFCOTT;
848     case OBJN_PEASANTHUT:
849         return OBJ_PEASANTHUT;
850     case OBJN_DRAGONCITY:
851         return OBJ_DRAGONCITY;
852     case OBJN_LIGHTHOUSE:
853         return OBJ_LIGHTHOUSE;
854     case OBJN_WATERWHEEL:
855         return OBJ_WATERWHEEL;
856     case OBJN_MINES:
857         return OBJ_MINES;
858     case OBJN_OBELISK:
859         return OBJ_OBELISK;
860     case OBJN_OASIS:
861         return OBJ_OASIS;
862     case OBJN_SAWMILL:
863         return OBJ_SAWMILL;
864     case OBJN_ORACLE:
865         return OBJ_ORACLE;
866     case OBJN_SHIPWRECK:
867         return OBJ_SHIPWRECK;
868     case OBJN_DESERTTENT:
869         return OBJ_DESERTTENT;
870     case OBJN_CASTLE:
871         return OBJ_CASTLE;
872     case OBJN_STONELITHS:
873         return OBJ_STONELITHS;
874     case OBJN_WAGONCAMP:
875         return OBJ_WAGONCAMP;
876     case OBJN_WINDMILL:
877         return OBJ_WINDMILL;
878     case OBJN_RNDTOWN:
879         return OBJ_RNDTOWN;
880     case OBJN_RNDCASTLE:
881         return OBJ_RNDCASTLE;
882     case OBJN_WATCHTOWER:
883         return OBJ_WATCHTOWER;
884     case OBJN_TREEHOUSE:
885         return OBJ_TREEHOUSE;
886     case OBJN_TREECITY:
887         return OBJ_TREECITY;
888     case OBJN_RUINS:
889         return OBJ_RUINS;
890     case OBJN_FORT:
891         return OBJ_FORT;
892     case OBJN_TRADINGPOST:
893         return OBJ_TRADINGPOST;
894     case OBJN_ABANDONEDMINE:
895         return OBJ_ABANDONEDMINE;
896     case OBJN_TREEKNOWLEDGE:
897         return OBJ_TREEKNOWLEDGE;
898     case OBJN_DOCTORHUT:
899         return OBJ_DOCTORHUT;
900     case OBJN_TEMPLE:
901         return OBJ_TEMPLE;
902     case OBJN_HILLFORT:
903         return OBJ_HILLFORT;
904     case OBJN_HALFLINGHOLE:
905         return OBJ_HALFLINGHOLE;
906     case OBJN_MERCENARYCAMP:
907         return OBJ_MERCENARYCAMP;
908     case OBJN_PYRAMID:
909         return OBJ_PYRAMID;
910     case OBJN_CITYDEAD:
911         return OBJ_CITYDEAD;
912     case OBJN_EXCAVATION:
913         return OBJ_EXCAVATION;
914     case OBJN_SPHINX:
915         return OBJ_SPHINX;
916     case OBJN_ARTESIANSPRING:
917         return OBJ_ARTESIANSPRING;
918     case OBJN_TROLLBRIDGE:
919         return OBJ_TROLLBRIDGE;
920     case OBJN_WATERINGHOLE:
921         return OBJ_WATERINGHOLE;
922     case OBJN_WITCHSHUT:
923         return OBJ_WITCHSHUT;
924     case OBJN_XANADU:
925         return OBJ_XANADU;
926     case OBJN_CAVE:
927         return OBJ_CAVE;
928     case OBJN_MAGELLANMAPS:
929         return OBJ_MAGELLANMAPS;
930     case OBJN_DERELICTSHIP:
931         return OBJ_DERELICTSHIP;
932     case OBJN_MAGICWELL:
933         return OBJ_MAGICWELL;
934     case OBJN_OBSERVATIONTOWER:
935         return OBJ_OBSERVATIONTOWER;
936     case OBJN_FREEMANFOUNDRY:
937         return OBJ_FREEMANFOUNDRY;
938     case OBJN_ARENA:
939         return OBJ_ARENA;
940     case OBJN_BARROWMOUNDS:
941         return OBJ_BARROWMOUNDS;
942     case OBJN_MERMAID:
943         return OBJ_MERMAID;
944     case OBJN_SIRENS:
945         return OBJ_SIRENS;
946     case OBJN_HUTMAGI:
947         return OBJ_HUTMAGI;
948     case OBJN_EYEMAGI:
949         return OBJ_EYEMAGI;
950     case OBJN_TRAVELLERTENT:
951         return OBJ_TRAVELLERTENT;
952     case OBJN_JAIL:
953         return OBJ_JAIL;
954     case OBJN_FIREALTAR:
955         return OBJ_FIREALTAR;
956     case OBJN_AIRALTAR:
957         return OBJ_AIRALTAR;
958     case OBJN_EARTHALTAR:
959         return OBJ_EARTHALTAR;
960     case OBJN_WATERALTAR:
961         return OBJ_WATERALTAR;
962     case OBJN_ALCHEMYTOWER:
963         return OBJ_ALCHEMYTOWER;
964     case OBJN_STABLES:
965         return OBJ_STABLES;
966     default:
967         break;
968     }
969 
970     return objectType;
971 }
972 
isQuantityObject(const MapObjectType objectType)973 bool MP2::isQuantityObject( const MapObjectType objectType )
974 {
975     switch ( objectType ) {
976     case OBJ_SKELETON:
977     case OBJ_WAGON:
978     case OBJ_MAGICGARDEN:
979     case OBJ_WATERWHEEL:
980     case OBJ_WINDMILL:
981     case OBJ_LEANTO:
982     case OBJ_CAMPFIRE:
983     case OBJ_FLOTSAM:
984     case OBJ_SHIPWRECKSURVIROR:
985     case OBJ_WATERCHEST:
986     case OBJ_DERELICTSHIP:
987     case OBJ_SHIPWRECK:
988     case OBJ_GRAVEYARD:
989     case OBJ_PYRAMID:
990     case OBJ_DAEMONCAVE:
991     case OBJ_ABANDONEDMINE:
992         return true;
993     default:
994         break;
995     }
996 
997     if ( isPickupObject( objectType ) )
998         return true;
999 
1000     return false;
1001 }
1002 
isCaptureObject(const MapObjectType objectType)1003 bool MP2::isCaptureObject( const MapObjectType objectType )
1004 {
1005     switch ( objectType ) {
1006     case OBJ_MINES:
1007     case OBJ_ABANDONEDMINE:
1008     case OBJ_ALCHEMYLAB:
1009     case OBJ_SAWMILL:
1010     case OBJ_LIGHTHOUSE:
1011     case OBJ_CASTLE:
1012         return true;
1013     case OBJ_WATERWHEEL:
1014     case OBJ_WINDMILL:
1015     case OBJ_MAGICGARDEN:
1016         return Settings::Get().ExtWorldExtObjectsCaptured();
1017     default:
1018         break;
1019     }
1020 
1021     return false;
1022 }
1023 
isPickupObject(const MapObjectType objectType)1024 bool MP2::isPickupObject( const MapObjectType objectType )
1025 {
1026     switch ( objectType ) {
1027     case OBJ_WATERCHEST:
1028     case OBJ_SHIPWRECKSURVIROR:
1029     case OBJ_FLOTSAM:
1030     case OBJ_BOTTLE:
1031     case OBJ_TREASURECHEST:
1032     case OBJ_ANCIENTLAMP:
1033     case OBJ_CAMPFIRE:
1034     case OBJ_RESOURCE:
1035     case OBJ_ARTIFACT:
1036         return true;
1037     default:
1038         break;
1039     }
1040 
1041     return false;
1042 }
1043 
isArtifactObject(const MapObjectType objectType)1044 bool MP2::isArtifactObject( const MapObjectType objectType )
1045 {
1046     switch ( objectType ) {
1047     case OBJ_ARTIFACT:
1048     case OBJ_WAGON:
1049     case OBJ_SKELETON:
1050     case OBJ_DAEMONCAVE:
1051     case OBJ_WATERCHEST:
1052     case OBJ_TREASURECHEST:
1053     case OBJ_SHIPWRECKSURVIROR:
1054     case OBJ_SHIPWRECK:
1055     case OBJ_GRAVEYARD:
1056         return true;
1057     default:
1058         break;
1059     }
1060 
1061     return false;
1062 }
1063 
isHeroUpgradeObject(const MapObjectType objectType)1064 bool MP2::isHeroUpgradeObject( const MapObjectType objectType )
1065 {
1066     switch ( objectType ) {
1067     case OBJ_GAZEBO:
1068     case OBJ_TREEKNOWLEDGE:
1069     case OBJ_MERCENARYCAMP:
1070     case OBJ_FORT:
1071     case OBJ_STANDINGSTONES:
1072     case OBJ_DOCTORHUT:
1073     case OBJ_SHRINE1:
1074     case OBJ_SHRINE2:
1075     case OBJ_SHRINE3:
1076     case OBJ_WITCHSHUT:
1077     case OBJ_XANADU:
1078         return true;
1079     default:
1080         break;
1081     }
1082 
1083     return false;
1084 }
1085 
isMonsterDwelling(const MapObjectType objectType)1086 bool MP2::isMonsterDwelling( const MapObjectType objectType )
1087 {
1088     switch ( objectType ) {
1089     case OBJ_WATCHTOWER:
1090     case OBJ_EXCAVATION:
1091     case OBJ_CAVE:
1092     case OBJ_TREEHOUSE:
1093     case OBJ_ARCHERHOUSE:
1094     case OBJ_GOBLINHUT:
1095     case OBJ_DWARFCOTT:
1096     case OBJ_HALFLINGHOLE:
1097     case OBJ_PEASANTHUT:
1098     case OBJ_THATCHEDHUT:
1099     case OBJ_RUINS:
1100     case OBJ_TREECITY:
1101     case OBJ_WAGONCAMP:
1102     case OBJ_DESERTTENT:
1103     case OBJ_WATERALTAR:
1104     case OBJ_AIRALTAR:
1105     case OBJ_FIREALTAR:
1106     case OBJ_EARTHALTAR:
1107     case OBJ_BARROWMOUNDS:
1108     case OBJ_CITYDEAD:
1109     case OBJ_TROLLBRIDGE:
1110     case OBJ_DRAGONCITY:
1111         return true;
1112     default:
1113         break;
1114     }
1115 
1116     return false;
1117 }
1118 
isProtectedObject(const MapObjectType objectType)1119 bool MP2::isProtectedObject( const MapObjectType objectType )
1120 {
1121     switch ( objectType ) {
1122     case OBJ_MONSTER:
1123     case OBJ_ARTIFACT:
1124     case OBJ_DERELICTSHIP:
1125     case OBJ_SHIPWRECK:
1126     case OBJ_GRAVEYARD:
1127     case OBJ_PYRAMID:
1128     case OBJ_DAEMONCAVE:
1129     case OBJ_ABANDONEDMINE:
1130     case OBJ_CITYDEAD:
1131     case OBJ_TROLLBRIDGE:
1132     case OBJ_DRAGONCITY:
1133         return true;
1134     default:
1135         break;
1136     }
1137 
1138     return isCaptureObject( objectType );
1139 }
1140 
isAbandonedMine(const MapObjectType objectType)1141 bool MP2::isAbandonedMine( const MapObjectType objectType )
1142 {
1143     return objectType == MP2::OBJN_ABANDONEDMINE || objectType == MP2::OBJ_ABANDONEDMINE;
1144 }
1145 
isRemoveObject(const MapObjectType objectType)1146 bool MP2::isRemoveObject( const MapObjectType objectType )
1147 {
1148     switch ( objectType ) {
1149     case OBJ_MONSTER:
1150     case OBJ_BARRIER:
1151         return true;
1152     default:
1153         break;
1154     }
1155 
1156     return isPickupObject( objectType );
1157 }
1158 
isNeedStayFront(const MapObjectType objectType)1159 bool MP2::isNeedStayFront( const MapObjectType objectType )
1160 {
1161     switch ( objectType ) {
1162     case OBJ_MONSTER:
1163     case OBJ_HEROES:
1164     case OBJ_BOAT:
1165     case OBJ_BARRIER:
1166     case OBJ_JAIL:
1167     case OBJ_BUOY:
1168     case OBJ_SKELETON:
1169     case OBJ_MERMAID:
1170     case OBJ_SIRENS:
1171     case OBJ_SHIPWRECK:
1172         return true;
1173     default:
1174         break;
1175     }
1176 
1177     return isPickupObject( objectType );
1178 }
1179 
isAccessibleFromBeach(const MapObjectType objectType)1180 bool MP2::isAccessibleFromBeach( const MapObjectType objectType )
1181 {
1182     switch ( objectType ) {
1183     case OBJ_MONSTER:
1184     case OBJ_HEROES:
1185     case OBJ_BOAT:
1186     case OBJ_SHIPWRECK:
1187         return true;
1188     default:
1189         break;
1190     }
1191 
1192     return false;
1193 }
1194 
getActionObjectDirection(const MapObjectType objectType)1195 int MP2::getActionObjectDirection( const MapObjectType objectType )
1196 {
1197     switch ( objectType ) {
1198     case OBJ_JAIL:
1199     case OBJ_BARRIER:
1200     case OBJ_ARTIFACT:
1201     case OBJ_RESOURCE:
1202     case OBJ_TREASURECHEST:
1203     case OBJ_MONSTER:
1204     case OBJ_ANCIENTLAMP:
1205     case OBJ_CAMPFIRE:
1206     case OBJ_SHIPWRECKSURVIROR:
1207     case OBJ_FLOTSAM:
1208     case OBJ_WATERCHEST:
1209     case OBJ_BUOY:
1210     case OBJ_WHIRLPOOL:
1211     case OBJ_BOTTLE:
1212     case OBJ_COAST:
1213     case OBJ_BOAT:
1214     case OBJ_HEROES:
1215         return DIRECTION_ALL;
1216     case OBJ_DERELICTSHIP:
1217     case OBJ_TROLLBRIDGE:
1218     case OBJ_ARCHERHOUSE:
1219     case OBJ_DOCTORHUT:
1220     case OBJ_DWARFCOTT:
1221     case OBJ_THATCHEDHUT:
1222     case OBJ_FOUNTAIN:
1223     case OBJ_IDOL:
1224     case OBJ_LIGHTHOUSE:
1225     case OBJ_OBELISK:
1226     case OBJ_SIGN:
1227     case OBJ_WATCHTOWER:
1228     case OBJ_WITCHSHUT:
1229     case OBJ_GAZEBO:
1230     case OBJ_MAGICWELL:
1231     case OBJ_OBSERVATIONTOWER:
1232     case OBJ_PEASANTHUT:
1233     case OBJ_STONELITHS:
1234     case OBJ_STANDINGSTONES:
1235     case OBJ_GOBLINHUT:
1236     case OBJ_SHRINE1:
1237     case OBJ_SHRINE2:
1238     case OBJ_SHRINE3:
1239     case OBJ_TREEHOUSE:
1240     case OBJ_ARTESIANSPRING:
1241     case OBJ_SKELETON:
1242     case OBJ_TREEKNOWLEDGE:
1243     case OBJ_ORACLE:
1244     case OBJ_OASIS:
1245     case OBJ_LEANTO:
1246     case OBJ_MAGICGARDEN:
1247     case OBJ_WAGON:
1248     case OBJ_TRAVELLERTENT:
1249     case OBJ_ALCHEMYTOWER:
1250     case OBJ_HUTMAGI:
1251     case OBJ_EYEMAGI:
1252     case OBJ_MERCENARYCAMP:
1253     case OBJ_WINDMILL:
1254     case OBJ_WATERINGHOLE:
1255     case OBJ_TRADINGPOST:
1256     case OBJ_EXCAVATION:
1257     case OBJ_DESERTTENT:
1258     case OBJ_DAEMONCAVE:
1259     case OBJ_PYRAMID:
1260     case OBJ_FORT:
1261     case OBJ_RUINS:
1262     case OBJ_HILLFORT:
1263     case OBJ_FREEMANFOUNDRY:
1264     case OBJ_SAWMILL:
1265     case OBJ_TREECITY:
1266     case OBJ_SPHINX:
1267     case OBJ_TEMPLE:
1268     case OBJ_FAERIERING:
1269     case OBJ_BARROWMOUNDS:
1270     case OBJ_STABLES:
1271     case OBJ_ABANDONEDMINE:
1272     case OBJ_MINES:
1273     case OBJ_ALCHEMYLAB:
1274     case OBJ_CAVE:
1275     case OBJ_CITYDEAD:
1276     case OBJ_GRAVEYARD:
1277     case OBJ_DRAGONCITY:
1278     case OBJ_XANADU:
1279     case OBJ_HALFLINGHOLE:
1280     case OBJ_WAGONCAMP:
1281     case OBJ_WATERALTAR:
1282     case OBJ_AIRALTAR:
1283     case OBJ_FIREALTAR:
1284     case OBJ_EARTHALTAR:
1285     case OBJ_ARENA:
1286     case OBJ_SIRENS:
1287     case OBJ_MERMAID:
1288     case OBJ_WATERWHEEL:
1289     case OBJ_MAGELLANMAPS:
1290     case OBJ_SHIPWRECK:
1291         return DIRECTION_CENTER_ROW | DIRECTION_BOTTOM_ROW;
1292     case OBJ_CASTLE:
1293         return Direction::CENTER | Direction::BOTTOM;
1294     default:
1295         // Did you add a new action object? Please add its passability!
1296         assert( 0 );
1297         break;
1298     }
1299 
1300     return Direction::UNKNOWN;
1301 }
1302