2017-07-13 10:26:03 +02:00
/*
* CGameState . 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
*
*/
2011-12-14 00:23:17 +03:00
# pragma once
2010-12-20 23:22:53 +02:00
# include "CCreatureHandler.h"
2009-05-20 13:08:56 +03:00
# include "VCMI_Lib.h"
2010-05-02 21:20:26 +03:00
2010-02-10 04:56:00 +02:00
# include "HeroBonus.h"
2010-05-02 21:20:26 +03:00
# include "CCreatureSet.h"
2010-12-20 15:04:24 +02:00
# include "ConstTransitivePtr.h"
2011-05-10 01:20:47 +03:00
# include "IGameCallback.h"
2011-07-05 09:14:07 +03:00
# include "ResourceSet.h"
2011-12-14 00:23:17 +03:00
# include "int3.h"
2014-03-17 22:51:07 +03:00
# include "CRandomGenerator.h"
2014-06-25 17:11:07 +03:00
# include "CGameStateFwd.h"
2015-10-27 02:34:47 +02:00
# include "CPathfinder.h"
2010-05-02 21:20:26 +03:00
2022-07-26 15:07:42 +02:00
namespace boost
{
class shared_mutex ;
}
VCMI_LIB_NAMESPACE_BEGIN
2008-12-27 03:01:59 +02:00
class CTown ;
2010-06-07 08:28:12 +03:00
class IGameCallback ;
2008-12-27 03:01:59 +02:00
class CCreatureSet ;
2012-05-16 20:29:05 +03:00
class CQuest ;
2008-12-27 03:01:59 +02:00
class CGHeroInstance ;
class CGTownInstance ;
class CArmedInstance ;
2009-10-24 22:21:32 +03:00
class CGDwelling ;
2008-12-27 03:01:59 +02:00
class CObjectScript ;
class CGObjectInstance ;
class CCreature ;
2012-11-03 22:31:16 +03:00
class CMap ;
2008-12-27 03:01:59 +02:00
struct StartInfo ;
struct SetObjectProperty ;
struct MetaString ;
2009-03-07 00:25:19 +02:00
struct CPack ;
2009-05-07 18:19:52 +03:00
class CSpell ;
2009-08-30 15:47:40 +03:00
struct TerrainTile ;
2010-02-07 17:06:14 +02:00
class CHeroClass ;
2010-05-08 21:56:38 +03:00
class CCampaign ;
2010-08-04 14:18:13 +03:00
class CCampaignState ;
2010-11-10 02:06:25 +02:00
class IModableArt ;
2011-05-03 06:14:18 +03:00
class CGGarrison ;
2012-05-16 20:29:05 +03:00
struct QuestInfo ;
2012-07-07 11:45:45 +03:00
class CQuest ;
2013-12-20 16:07:58 +03:00
class CCampaignScenario ;
2013-12-29 18:48:56 +03:00
struct EventCondition ;
2014-01-03 19:36:22 +03:00
class CScenarioTravel ;
2017-07-20 06:08:49 +02:00
class IMapService ;
2008-12-27 03:01:59 +02:00
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
2018-01-05 19:21:07 +02:00
template < typename T > class CApplier ;
class CBaseForGSApply ;
2011-12-14 00:23:17 +03:00
struct DLL_LINKAGE SThievesGuildInfo
2010-02-01 19:51:33 +02:00
{
2013-03-03 20:06:03 +03:00
std : : vector < PlayerColor > playerColors ; //colors of players that are in-game
2010-02-01 19:51:33 +02:00
2013-03-03 20:06:03 +03:00
std : : vector < std : : vector < PlayerColor > > numOfTowns , numOfHeroes , gold , woodOre , mercSulfCrystGems , obelisks , artifacts , army , income ; // [place] -> [colours of players]
2010-02-01 19:51:33 +02:00
2013-03-03 20:06:03 +03:00
std : : map < PlayerColor , InfoAboutHero > colorToBestHero ; //maps player's color to his best heros'
2010-02-01 19:51:33 +02:00
2013-03-03 20:06:03 +03:00
std : : map < PlayerColor , EAiTactic : : EAiTactic > personality ; // color to personality // ai tactic
std : : map < PlayerColor , si32 > bestCreature ; // color to ID // id or -1 if not known
2010-02-06 15:49:14 +02:00
2017-07-31 15:35:42 +02:00
// template <typename Handler> void serialize(Handler &h, const int version)
// {
// h & playerColors;
// h & numOfTowns;
// h & numOfHeroes;
// h & gold;
// h & woodOre;
// h & mercSulfCrystGems;
// h & obelisks;
// h & artifacts;
// h & army;
// h & income;
// h & colorToBestHero;
// h & personality;
// h & bestCreature;
// }
2010-02-01 19:51:33 +02:00
} ;
2015-11-30 23:44:58 +02:00
struct DLL_LINKAGE RumorState
{
enum ERumorType : ui8
{
2015-12-04 21:58:14 +02:00
TYPE_NONE = 0 , TYPE_RAND , TYPE_SPECIAL , TYPE_MAP
} ;
enum ERumorTypeSpecial : ui8
{
RUMOR_OBELISKS = 208 ,
RUMOR_ARTIFACTS = 209 ,
RUMOR_ARMY = 210 ,
RUMOR_INCOME = 211 ,
RUMOR_GRAIL = 212
2015-11-30 23:44:58 +02:00
} ;
ERumorType type ;
std : : map < ERumorType , std : : pair < int , int > > last ;
2015-12-23 16:23:56 +02:00
RumorState ( ) { type = TYPE_NONE ; } ;
2015-12-01 03:57:52 +02:00
bool update ( int id , int extra ) ;
2015-11-30 23:44:58 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & type ;
h & last ;
2015-11-30 23:44:58 +02:00
}
} ;
2008-12-27 03:01:59 +02:00
struct UpgradeInfo
{
2013-02-11 02:24:57 +03:00
CreatureID oldID ; //creature to be upgraded
std : : vector < CreatureID > newID ; //possible upgrades
2011-07-05 09:14:07 +03:00
std : : vector < TResources > cost ; // cost[upgrade_serial] -> set of pairs<resource_ID,resource_amount>; cost is for single unit (not entire stack)
2013-02-07 20:34:50 +03:00
UpgradeInfo ( ) { oldID = CreatureID : : NONE ; } ;
2008-12-27 03:01:59 +02:00
} ;
2017-07-20 06:08:49 +02:00
class BattleInfo ;
2010-12-25 21:23:30 +02:00
2013-11-17 20:57:04 +03:00
DLL_LINKAGE std : : ostream & operator < < ( std : : ostream & os , const EVictoryLossCheckResult & victoryLossCheckResult ) ;
2011-12-14 00:23:17 +03:00
class DLL_LINKAGE CGameState : public CNonConstInfoCallback
2008-12-27 03:01:59 +02:00
{
2009-03-07 00:11:17 +02:00
public :
2013-11-17 20:57:04 +03:00
struct DLL_LINKAGE HeroesPool
{
std : : map < ui32 , ConstTransitivePtr < CGHeroInstance > > heroesPool ; //[subID] - heroes available to buy; nullptr if not available
std : : map < ui32 , ui8 > pavailable ; // [subid] -> which players can recruit hero (binary flags)
2023-03-13 23:26:44 +02:00
CGHeroInstance * pickHeroFor ( bool native ,
const PlayerColor & player ,
const CTown * town ,
std : : map < ui32 , ConstTransitivePtr < CGHeroInstance > > & available ,
CRandomGenerator & rand ,
const CHeroClass * bannedClass = nullptr ) const ;
2013-11-17 20:57:04 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & heroesPool ;
h & pavailable ;
2009-01-06 20:42:20 +02:00
}
2008-12-27 03:01:59 +02:00
} hpool ; //we have here all heroes available on this map that are not hired
2013-12-18 21:18:12 +03:00
CGameState ( ) ;
virtual ~ CGameState ( ) ;
2011-05-10 01:20:47 +03:00
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
void preInit ( Services * services ) ;
2017-07-20 06:08:49 +02:00
void init ( const IMapService * mapService , StartInfo * si , bool allowSavingRandomMap = false ) ;
2018-01-05 19:21:07 +02:00
void updateOnLoad ( StartInfo * si ) ;
2012-07-26 03:48:44 +03:00
2013-12-18 21:18:12 +03:00
ConstTransitivePtr < StartInfo > scenarioOps , initialOpts ; //second one is a copy of settings received from pregame (not randomized)
PlayerColor currentPlayer ; //ID of player currently having turn
ConstTransitivePtr < BattleInfo > curB ; //current battle
ui32 day ; //total number of days in game
ConstTransitivePtr < CMap > map ;
std : : map < PlayerColor , PlayerState > players ;
std : : map < TeamID , TeamState > teams ;
CBonusSystemNode globalEffects ;
2015-11-30 23:44:58 +02:00
RumorState rumor ;
2013-12-18 21:18:12 +03:00
2017-06-14 06:59:41 +02:00
static boost : : shared_mutex mutex ;
2013-12-18 21:18:12 +03:00
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
void updateEntity ( Metatype metatype , int32_t index , const JsonNode & data ) override ;
2023-03-18 22:58:39 +02:00
bool giveHeroArtifact ( CGHeroInstance * h , const ArtifactID & aid ) ;
2012-02-17 22:30:40 +03:00
2009-03-07 00:25:19 +02:00
void apply ( CPack * pack ) ;
2022-06-22 10:41:02 +02:00
BattleField battleGetBattlefieldType ( int3 tile , CRandomGenerator & rand ) ;
2022-12-07 21:50:45 +02:00
2022-12-25 14:03:43 +02:00
void fillUpgradeInfo ( const CArmedInstance * obj , SlotID stackPos , UpgradeInfo & out ) const override ;
2022-12-07 21:50:45 +02:00
PlayerRelations : : PlayerRelations getPlayerRelations ( PlayerColor color1 , PlayerColor color2 ) const override ;
2009-08-30 15:47:40 +03:00
bool checkForVisitableDir ( const int3 & src , const int3 & dst ) const ; //check if src tile is visitable from dst tile
2022-12-07 21:50:45 +02:00
void calculatePaths ( const CGHeroInstance * hero , CPathsInfo & out ) override ; //calculates possible paths for hero, by default uses current hero position and movement left; returns pointer to newly allocated CPath or nullptr if path does not exists
2023-03-13 23:26:44 +02:00
void calculatePaths ( const std : : shared_ptr < PathfinderConfig > & config ) override ;
2022-05-19 14:14:50 +02:00
int3 guardingCreaturePosition ( int3 pos ) const override ;
2012-11-15 00:19:32 +03:00
std : : vector < CGObjectInstance * > guardingCreatures ( int3 pos ) const ;
2015-11-30 23:44:58 +02:00
void updateRumor ( ) ;
2013-12-29 14:27:38 +03:00
// ----- victory, loss condition checks -----
2023-03-13 23:26:44 +02:00
EVictoryLossCheckResult checkForVictoryAndLoss ( const PlayerColor & player ) const ;
bool checkForVictory ( const PlayerColor & player , const EventCondition & condition ) const ; //checks if given player is winner
2013-12-29 14:27:38 +03:00
PlayerColor checkForStandardWin ( ) const ; //returns color of player that accomplished standard victory conditions or 255 (NEUTRAL) if no winner
2023-03-13 23:26:44 +02:00
bool checkForStandardLoss ( const PlayerColor & player ) const ; //checks if given player lost the game
2013-11-17 20:57:04 +03:00
void obtainPlayersStats ( SThievesGuildInfo & tgi , int level ) ; //fills tgi with info about other players that is available at given level of thieves' guild
std : : map < ui32 , ConstTransitivePtr < CGHeroInstance > > unusedHeroesFromPool ( ) ; //heroes pool without heroes that are available in taverns
2022-12-07 21:50:45 +02:00
2023-03-13 23:26:44 +02:00
bool isVisible ( int3 pos , const boost : : optional < PlayerColor > & player ) const override ;
bool isVisible ( const CGObjectInstance * obj , const boost : : optional < PlayerColor > & player ) const override ;
2009-07-30 15:49:45 +03:00
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
int getDate ( Date : : EDateType mode = Date : : DAY ) const override ; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
2013-12-18 21:18:12 +03:00
2014-03-17 22:51:07 +03:00
// ----- getters, setters -----
2016-09-09 19:30:36 +02:00
/// This RNG should only be used inside GS or CPackForClient-derived applyGs
/// If this doesn't work for your code that mean you need a new netpack
///
/// Client-side must use CRandomGenerator::getDefault which is not serialized
///
/// CGameHandler have it's own getter for CRandomGenerator::getDefault
/// Any server-side code outside of GH must use CRandomGenerator::getDefault
2014-03-17 22:51:07 +03:00
CRandomGenerator & getRandomGenerator ( ) ;
2008-12-27 03:01:59 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & scenarioOps ;
h & initialOpts ;
h & currentPlayer ;
h & day ;
h & map ;
h & players ;
h & teams ;
h & hpool ;
h & globalEffects ;
h & rand ;
2022-06-20 16:39:50 +02:00
h & rumor ;
2015-11-30 23:44:58 +02:00
2011-02-23 05:57:45 +02:00
BONUS_TREE_DESERIALIZATION_FIX
2008-12-27 03:01:59 +02:00
}
2013-11-17 20:57:04 +03:00
private :
2014-01-30 21:56:31 +03:00
struct CrossoverHeroesList
{
std : : vector < CGHeroInstance * > heroesFromPreviousScenario , heroesFromAnyPreviousScenarios ;
void addHeroToBothLists ( CGHeroInstance * hero ) ;
void removeHeroFromBothLists ( CGHeroInstance * hero ) ;
} ;
struct CampaignHeroReplacement
{
2023-03-13 23:26:44 +02:00
CampaignHeroReplacement ( CGHeroInstance * hero , const ObjectInstanceID & heroPlaceholderId ) ;
2014-01-30 21:56:31 +03:00
CGHeroInstance * hero ;
ObjectInstanceID heroPlaceholderId ;
} ;
2013-12-20 16:07:58 +03:00
// ----- initialization -----
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
void preInitAuto ( ) ;
2017-07-20 06:08:49 +02:00
void initNewGame ( const IMapService * mapService , bool allowSavingRandomMap ) ;
2018-01-05 19:21:07 +02:00
void initCampaign ( ) ;
2013-12-18 21:18:12 +03:00
void checkMapChecksum ( ) ;
2023-02-19 20:42:51 +02:00
void initGlobalBonuses ( ) ;
2013-12-18 21:18:12 +03:00
void initGrailPosition ( ) ;
void initRandomFactionsForPlayers ( ) ;
void randomizeMapObjects ( ) ;
void randomizeObject ( CGObjectInstance * cur ) ;
void initPlayerStates ( ) ;
2013-12-28 15:47:55 +03:00
void placeCampaignHeroes ( ) ;
2014-01-30 21:56:31 +03:00
CrossoverHeroesList getCrossoverHeroesFromPreviousScenarios ( ) const ;
2014-01-03 19:36:22 +03:00
/// returns heroes and placeholders in where heroes will be put
2014-01-30 21:56:31 +03:00
std : : vector < CampaignHeroReplacement > generateCampaignHeroesToReplace ( CrossoverHeroesList & crossoverHeroes ) ;
/// gets prepared and copied hero instances with crossover heroes from prev. scenario and travel options from current scenario
2016-09-09 19:30:36 +02:00
void prepareCrossoverHeroes ( std : : vector < CampaignHeroReplacement > & campaignHeroReplacements , const CScenarioTravel & travelOptions ) ;
2013-12-20 16:07:58 +03:00
2014-01-30 21:56:31 +03:00
void replaceHeroesPlaceholders ( const std : : vector < CampaignHeroReplacement > & campaignHeroReplacements ) ;
2013-12-18 21:18:12 +03:00
void placeStartingHeroes ( ) ;
2023-03-13 23:26:44 +02:00
void placeStartingHero ( const PlayerColor & playerColor , const HeroTypeID & heroTypeId , int3 townPos ) ;
2013-12-18 21:18:12 +03:00
void initStartingResources ( ) ;
void initHeroes ( ) ;
2022-12-05 13:02:55 +02:00
void placeHeroesInTowns ( ) ;
2013-12-18 21:18:12 +03:00
void giveCampaignBonusToHero ( CGHeroInstance * hero ) ;
void initFogOfWar ( ) ;
void initStartingBonus ( ) ;
void initTowns ( ) ;
void initMapObjects ( ) ;
void initVisitingAndGarrisonedHeroes ( ) ;
2013-12-20 16:07:58 +03:00
// ----- bonus system handling -----
2013-12-18 21:18:12 +03:00
void buildBonusSystemTree ( ) ;
void attachArmedObjects ( ) ;
void buildGlobalTeamPlayerTree ( ) ;
void deserializationFix ( ) ;
2013-12-20 16:07:58 +03:00
// ---- misc helpers -----
2023-03-13 23:26:44 +02:00
CGHeroInstance * getUsedHero ( const HeroTypeID & hid ) const ;
bool isUsedHero ( const HeroTypeID & hid ) const ; //looks in heroes and prisons
2013-12-18 21:18:12 +03:00
std : : set < HeroTypeID > getUnusedAllowedHeroes ( bool alsoIncludeNotAllowed = false ) const ;
std : : pair < Obj , int > pickObject ( CGObjectInstance * obj ) ; //chooses type of object to be randomized, returns <type, subtype>
2023-03-13 23:26:44 +02:00
int pickUnusedHeroTypeRandomly ( const PlayerColor & owner ) ; // picks a unused hero type randomly
int pickNextHeroType ( const PlayerColor & owner ) ; // picks next free hero type of the H3 hero init sequence -> chosen starting hero, then unused hero type randomly
2022-12-25 14:03:43 +02:00
UpgradeInfo fillUpgradeInfo ( const CStackInstance & stack ) const ;
2014-03-17 22:51:07 +03:00
// ---- data -----
2018-01-05 19:21:07 +02:00
std : : shared_ptr < CApplier < CBaseForGSApply > > applier ;
2014-03-17 22:51:07 +03:00
CRandomGenerator rand ;
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
Services * services ;
2013-12-18 21:18:12 +03:00
friend class IGameCallback ;
friend class CMapHandler ;
friend class CGameHandler ;
2008-12-27 03:01:59 +02:00
} ;
2022-07-26 15:07:42 +02:00
VCMI_LIB_NAMESPACE_END