2013-08-17 15:46:48 +03:00
/*
* CRmgTemplateZone . h , part of VCMI engine
*
* Authors : listed in file AUTHORS in main folder
*
* License : GNU General Public License v2 .0 or later
* Full text of license available in license . txt file , in main folder
*
*/
# pragma once
# include "../GameConstants.h"
2014-05-22 20:25:17 +03:00
# include "CMapGenerator.h"
2014-05-24 13:42:06 +03:00
# include "float3.h"
2014-05-30 17:50:06 +03:00
# include "../int3.h"
2018-03-05 16:05:17 +02:00
# include "CRmgTemplate.h"
2014-07-08 21:13:51 +03:00
# include "../mapObjects/ObjectTemplate.h"
2016-12-15 13:58:16 +02:00
# include <boost/heap/priority_queue.hpp> //A*
2022-06-20 16:39:50 +02:00
# include "Terrain.h"
2014-05-22 20:25:17 +03:00
2014-05-30 17:50:06 +03:00
class CMapGenerator ;
class CTileInfo ;
class int3 ;
class CGObjectInstance ;
2014-06-28 10:46:32 +03:00
class ObjectTemplate ;
2013-08-17 15:46:48 +03:00
2016-07-12 11:42:03 +02:00
namespace EObjectPlacingResult
{
enum EObjectPlacingResult
{
SUCCESS ,
CANNOT_FIT ,
SEALED_OFF
} ;
}
2014-05-30 17:50:06 +03:00
class DLL_LINKAGE CTileInfo
2013-08-17 15:46:48 +03:00
{
2014-05-30 17:50:06 +03:00
public :
CTileInfo ( ) ;
2014-07-25 18:10:16 +03:00
float getNearestObjectDistance ( ) const ;
void setNearestObjectDistance ( float value ) ;
2014-05-30 17:50:06 +03:00
bool isBlocked ( ) const ;
bool shouldBeBlocked ( ) const ;
bool isPossible ( ) const ;
bool isFree ( ) const ;
2014-07-04 00:11:24 +03:00
bool isUsed ( ) const ;
2016-02-15 12:34:37 +02:00
bool isRoad ( ) const ;
2014-05-30 17:50:06 +03:00
void setOccupied ( ETileType : : ETileType value ) ;
2022-06-20 16:39:50 +02:00
Terrain getTerrainType ( ) const ;
2015-01-16 10:40:11 +02:00
ETileType : : ETileType getTileType ( ) const ;
2022-06-20 16:39:50 +02:00
void setTerrainType ( Terrain value ) ;
2016-02-15 12:34:37 +02:00
2022-06-20 16:39:50 +02:00
void setRoadType ( const std : : string & value ) ;
2014-05-30 17:50:06 +03:00
private :
2014-07-25 18:10:16 +03:00
float nearestObjectDistance ;
2014-05-30 17:50:06 +03:00
ETileType : : ETileType occupied ;
2022-06-20 16:39:50 +02:00
Terrain terrain ;
std : : string roadType ;
2013-08-17 15:46:48 +03:00
} ;
2014-06-04 20:08:04 +03:00
struct DLL_LINKAGE ObjectInfo
{
2014-07-08 21:13:51 +03:00
ObjectTemplate templ ;
2014-06-04 20:08:04 +03:00
ui32 value ;
ui16 probability ;
2014-07-15 23:33:51 +03:00
ui32 maxPerZone ;
2016-11-25 15:47:16 +02:00
//ui32 maxPerMap; //unused
2014-06-04 20:08:04 +03:00
std : : function < CGObjectInstance * ( ) > generateObject ;
2014-07-08 21:13:51 +03:00
2022-06-20 16:39:50 +02:00
void setTemplate ( si32 type , si32 subtype , Terrain terrain ) ;
2014-07-15 23:33:51 +03:00
2016-11-25 15:47:16 +02:00
ObjectInfo ( ) ;
2014-07-15 23:33:51 +03:00
bool operator = = ( const ObjectInfo & oi ) const { return ( templ = = oi . templ ) ; }
2014-07-08 21:13:51 +03:00
} ;
struct DLL_LINKAGE CTreasurePileInfo
{
2014-07-09 10:22:50 +03:00
std : : set < int3 > visitableFromBottomPositions ; //can be visited only from bottom or side
2014-07-08 21:13:51 +03:00
std : : set < int3 > visitableFromTopPositions ; //they can be visited from any direction
2014-07-09 10:22:50 +03:00
std : : set < int3 > blockedPositions ;
std : : set < int3 > occupiedPositions ; //blocked + visitable
2014-07-08 21:13:51 +03:00
int3 nextTreasurePos ;
2014-06-04 20:08:04 +03:00
} ;
2013-08-17 15:46:48 +03:00
/// The CRmgTemplateZone describes a zone in a template.
2018-03-05 16:05:17 +02:00
class DLL_LINKAGE CRmgTemplateZone : public rmg : : ZoneOptions
2013-08-17 15:46:48 +03:00
{
public :
2022-05-28 15:03:50 +02:00
CRmgTemplateZone ( CMapGenerator * Gen ) ;
2013-08-17 15:46:48 +03:00
2022-05-31 11:25:39 +02:00
void setOptions ( const rmg : : ZoneOptions & options ) ;
2022-05-28 15:03:50 +02:00
bool isUnderground ( ) const ;
2014-05-24 13:42:06 +03:00
float3 getCenter ( ) const ;
2014-05-30 17:50:06 +03:00
void setCenter ( const float3 & f ) ;
int3 getPos ( ) const ;
2014-05-25 12:02:15 +03:00
void setPos ( const int3 & pos ) ;
2022-05-31 11:25:39 +02:00
bool isAccessibleFromSomewhere ( ObjectTemplate & appearance , const int3 & tile ) const ;
int3 getAccessibleOffset ( ObjectTemplate & appearance , const int3 & tile ) const ;
2014-05-24 13:42:06 +03:00
2022-05-31 11:25:39 +02:00
void addTile ( const int3 & pos ) ;
void removeTile ( const int3 & pos ) ;
2017-11-03 22:03:51 +02:00
void initFreeTiles ( ) ;
2016-08-13 19:48:44 +02:00
std : : set < int3 > getTileInfo ( ) const ;
std : : set < int3 > getPossibleTiles ( ) const ;
2022-05-31 11:25:39 +02:00
std : : set < int3 > collectDistantTiles ( float distance ) const ;
2015-01-16 20:28:27 +02:00
void clearTiles ( ) ;
2014-05-31 11:56:14 +03:00
2014-06-01 17:31:15 +03:00
void addRequiredObject ( CGObjectInstance * obj , si32 guardStrength = 0 ) ;
2014-12-20 23:13:10 +02:00
void addCloseObject ( CGObjectInstance * obj , si32 guardStrength = 0 ) ;
2022-05-23 12:08:36 +02:00
void addNearbyObject ( CGObjectInstance * obj , CGObjectInstance * nearbyTarget ) ;
2022-05-31 11:25:39 +02:00
void addObjectAtPosition ( CGObjectInstance * obj , const int3 & position , si32 guardStrength = 0 ) ;
2015-06-04 09:02:56 +02:00
void addToConnectLater ( const int3 & src ) ;
2017-11-03 22:03:51 +02:00
bool addMonster ( int3 & pos , si32 strength , bool clearSurroundingTiles = true , bool zoneGuard = false ) ;
bool createTreasurePile ( int3 & pos , float minDistance , const CTreasureInfo & treasureInfo ) ;
bool fill ( ) ;
bool placeMines ( ) ;
void initTownType ( ) ;
2022-06-20 16:39:50 +02:00
void paintZoneTerrain ( Terrain terrainType ) ;
2022-05-28 15:03:50 +02:00
void randomizeTownType ( bool matchUndergroundType = false ) ; //helper function
2017-11-03 22:03:51 +02:00
void initTerrainType ( ) ;
void createBorder ( ) ;
void fractalize ( ) ;
void connectLater ( ) ;
2022-05-31 11:25:39 +02:00
EObjectPlacingResult : : EObjectPlacingResult tryToPlaceObjectAndConnectToPath ( CGObjectInstance * obj , const int3 & pos ) ; //return true if the position can be connected
2017-11-03 22:03:51 +02:00
bool createRequiredObjects ( ) ;
2022-05-31 11:25:39 +02:00
bool createShipyard ( const int3 & pos , si32 guardStrength = 0 ) ;
int3 createShipyard ( const std : : set < int3 > & lake , si32 guardStrength = 0 ) ;
bool makeBoat ( TRmgTemplateZoneId land , const int3 & coast ) ;
int3 makeBoat ( TRmgTemplateZoneId land , const std : : set < int3 > & lake ) ;
2017-11-03 22:03:51 +02:00
void createTreasures ( ) ;
2022-05-31 11:25:39 +02:00
void createWater ( EWaterContent : : EWaterContent waterContent , bool debug = false ) ;
void waterInitFreeTiles ( ) ;
void waterConnection ( CRmgTemplateZone & dst ) ;
bool waterKeepConnection ( TRmgTemplateZoneId zoneA , TRmgTemplateZoneId zoneB ) ;
const std : : set < int3 > & getCoastTiles ( ) const ;
bool isWaterConnected ( TRmgTemplateZoneId zone , const int3 & tile ) const ;
//void computeCoastTiles();
2017-11-03 22:03:51 +02:00
void createObstacles1 ( ) ;
void createObstacles2 ( ) ;
bool crunchPath ( const int3 & src , const int3 & dst , bool onlyStraight , std : : set < int3 > * clearedTiles = nullptr ) ;
bool connectPath ( const int3 & src , bool onlyStraight ) ;
2022-05-31 11:25:39 +02:00
bool connectWithCenter ( const int3 & src , bool onlyStraight , bool passTroughBlocked = false ) ;
2017-11-03 22:03:51 +02:00
void updateDistances ( const int3 & pos ) ;
std : : vector < int3 > getAccessibleOffsets ( const CGObjectInstance * object ) ;
2022-05-31 11:25:39 +02:00
bool areAllTilesAvailable ( CGObjectInstance * obj , int3 & tile , const std : : set < int3 > & tilesBlockedByObject ) const ;
2013-08-17 15:46:48 +03:00
2018-03-09 20:11:20 +02:00
void setQuestArtZone ( std : : shared_ptr < CRmgTemplateZone > otherZone ) ;
2014-06-18 10:57:36 +03:00
std : : set < int3 > * getFreePaths ( ) ;
2022-05-31 11:25:39 +02:00
void addFreePath ( const int3 & ) ;
2014-05-24 13:42:06 +03:00
2017-11-03 22:03:51 +02:00
ObjectInfo getRandomObject ( CTreasurePileInfo & info , ui32 desiredValue , ui32 maxValue , ui32 currentValue ) ;
2014-06-04 20:08:04 +03:00
2017-11-03 22:03:51 +02:00
void placeSubterraneanGate ( int3 pos , si32 guardStrength ) ;
void placeObject ( CGObjectInstance * object , const int3 & pos , bool updateDistance = true ) ;
bool guardObject ( CGObjectInstance * object , si32 str , bool zoneGuard = false , bool addToFreePaths = false ) ;
void placeAndGuardObject ( CGObjectInstance * object , const int3 & pos , si32 str , bool zoneGuard = false ) ;
2015-01-18 15:19:00 +02:00
void addRoadNode ( const int3 & node ) ;
2017-11-03 22:03:51 +02:00
void connectRoads ( ) ; //fills "roads" according to "roadNodes"
2014-07-03 18:24:28 +03:00
2016-12-15 13:58:16 +02:00
//A* priority queue
typedef std : : pair < int3 , float > TDistance ;
struct NodeComparer
{
bool operator ( ) ( const TDistance & lhs , const TDistance & rhs ) const
{
return ( rhs . second < lhs . second ) ;
}
} ;
2020-10-01 10:38:06 +02:00
boost : : heap : : priority_queue < TDistance , boost : : heap : : compare < NodeComparer > > createPriorityQueue ( ) ;
2016-12-15 13:58:16 +02:00
2013-08-17 15:46:48 +03:00
private :
2022-05-31 11:25:39 +02:00
//subclass to store disconnected parts of water zone
struct Lake
{
std : : set < int3 > tiles ;
std : : set < int3 > coast ;
std : : map < int3 , int > distance ;
std : : set < TRmgTemplateZoneId > connectedZones ;
std : : set < TRmgTemplateZoneId > keepConnections ;
} ;
2017-11-03 22:03:51 +02:00
CMapGenerator * gen ;
2022-05-31 11:25:39 +02:00
2014-05-24 13:42:06 +03:00
//template info
2014-06-14 18:14:59 +03:00
si32 townType ;
2022-06-20 16:39:50 +02:00
Terrain terrainType ;
2018-03-09 20:11:20 +02:00
std : : weak_ptr < CRmgTemplateZone > questArtZone ; //artifacts required for Seer Huts will be placed here - or not if null
2014-05-22 20:25:17 +03:00
2014-06-04 20:08:04 +03:00
std : : vector < ObjectInfo > possibleObjects ;
2014-12-26 17:17:39 +02:00
int minGuardedValue ;
2022-05-28 15:03:50 +02:00
2014-05-24 13:42:06 +03:00
//content info
2014-06-01 17:31:15 +03:00
std : : vector < std : : pair < CGObjectInstance * , ui32 > > requiredObjects ;
2014-12-20 23:13:10 +02:00
std : : vector < std : : pair < CGObjectInstance * , ui32 > > closeObjects ;
2022-05-31 11:25:39 +02:00
std : : vector < std : : pair < CGObjectInstance * , int3 > > instantObjects ;
2022-05-23 12:08:36 +02:00
std : : vector < std : : pair < CGObjectInstance * , CGObjectInstance * > > nearbyObjects ;
2014-05-22 20:25:17 +03:00
std : : vector < CGObjectInstance * > objects ;
2022-05-31 11:25:39 +02:00
std : : map < CGObjectInstance * , int3 > requestedPositions ;
2014-05-22 20:25:17 +03:00
2014-05-24 13:42:06 +03:00
//placement info
int3 pos ;
float3 center ;
2014-05-30 22:23:41 +03:00
std : : set < int3 > tileinfo ; //irregular area assined to zone
2014-07-24 20:16:49 +03:00
std : : set < int3 > possibleTiles ; //optimization purposes for treasure generation
2014-06-18 10:57:36 +03:00
std : : set < int3 > freePaths ; //core paths of free tiles that all other objects will be linked to
2022-05-31 11:25:39 +02:00
std : : set < int3 > coastTiles ; //tiles bordered to water
2016-02-15 12:34:37 +02:00
2015-01-18 15:19:00 +02:00
std : : set < int3 > roadNodes ; //tiles to be connected with roads
std : : set < int3 > roads ; //all tiles with roads
2015-06-04 09:02:56 +02:00
std : : set < int3 > tilesToConnectLater ; //will be connected after paths are fractalized
2022-05-31 11:25:39 +02:00
std : : vector < Lake > lakes ; //disconnected parts of zone. Used to work with water zones
std : : map < int3 , int > lakeMap ; //map tile on lakeId which is position of lake in lakes array +1
2017-11-03 22:03:51 +02:00
bool createRoad ( const int3 & src , const int3 & dst ) ;
void drawRoads ( ) ; //actually updates tiles
2014-05-24 13:42:06 +03:00
2014-05-22 20:25:17 +03:00
bool pointIsIn ( int x , int y ) ;
2017-11-03 22:03:51 +02:00
void addAllPossibleObjects ( ) ; //add objects, including zone-specific, to possibleObjects
bool findPlaceForObject ( CGObjectInstance * obj , si32 min_dist , int3 & pos ) ;
bool findPlaceForTreasurePile ( float min_dist , int3 & pos , int value ) ;
bool canObstacleBePlacedHere ( ObjectTemplate & temp , int3 & pos ) ;
void setTemplateForObject ( CGObjectInstance * obj ) ;
void checkAndPlaceObject ( CGObjectInstance * object , const int3 & pos ) ;
2022-06-20 16:39:50 +02:00
int chooseRandomAppearance ( si32 ObjID ) const ;
2022-05-31 11:25:39 +02:00
bool isGuardNeededForTreasure ( int value ) ;
2013-08-17 15:46:48 +03:00
} ;