2017-07-13 10:26:03 +02:00
/*
* CAdvmapInterface . cpp , 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
# include "StdInc.h"
2007-08-04 00:47:34 +03:00
# include "CAdvmapInterface.h"
2011-12-14 00:23:17 +03:00
2008-08-20 22:02:48 +03:00
# include "CCastleInterface.h"
2008-11-09 00:29:19 +02:00
# include "CHeroWindow.h"
2010-01-25 23:25:14 +02:00
# include "CKingdomInterface.h"
2009-05-20 13:08:56 +03:00
# include "CSpellWindow.h"
2014-07-13 20:53:37 +03:00
# include "CTradeWindow.h"
2022-09-18 14:47:49 +02:00
# include "GUIClasses.h"
# include "InfoWindows.h"
2014-07-13 20:53:37 +03:00
# include "../CBitmapHandler.h"
# include "../CGameInfo.h"
# include "../CMessage.h"
# include "../CMusicHandler.h"
# include "../CPlayerInterface.h"
2018-01-05 19:21:07 +02:00
# include "../mainmenu/CMainMenu.h"
2022-04-26 13:14:31 +02:00
# include "../lobby/CSelectionBase.h"
# include "../lobby/CCampaignInfoScreen.h"
2018-01-05 19:21:07 +02:00
# include "../lobby/CSavingScreen.h"
# include "../lobby/CScenarioInfoScreen.h"
2014-07-13 20:53:37 +03:00
# include "../Graphics.h"
# include "../mapHandler.h"
2015-01-31 00:37:28 +02:00
# include "../gui/CAnimation.h"
2014-07-13 20:53:37 +03:00
# include "../gui/CCursorHandler.h"
# include "../gui/CGuiHandler.h"
# include "../gui/SDL_Extensions.h"
# include "../widgets/MiscWidgets.h"
# include "../../CCallback.h"
# include "../../lib/CConfigHandler.h"
# include "../../lib/CGameState.h"
# include "../../lib/CGeneralTextHandler.h"
# include "../../lib/CHeroHandler.h"
# include "../../lib/CSoundBase.h"
2015-02-02 10:25:26 +02:00
# include "../../lib/spells/CSpellHandler.h"
2014-07-13 20:53:37 +03:00
# include "../../lib/CTownHandler.h"
# include "../../lib/JsonNode.h"
# include "../../lib/mapObjects/CGHeroInstance.h"
# include "../../lib/mapping/CMap.h"
# include "../../lib/UnlockGuard.h"
# include "../../lib/VCMI_Lib.h"
2018-01-05 19:21:07 +02:00
# include "../../lib/StartInfo.h"
2022-04-26 13:14:31 +02:00
# include "../../lib/mapping/CMapInfo.h"
2008-12-21 21:17:35 +02:00
# ifdef _MSC_VER
# pragma warning (disable : 4355)
# endif
2008-11-12 20:26:23 +02:00
# define ADVOPT (conf.go()->ac)
2007-08-12 20:48:05 +03:00
using namespace CSDL_Ext ;
2009-07-30 15:49:45 +03:00
2018-07-25 00:36:48 +02:00
std : : shared_ptr < CAdvMapInt > adventureInt ;
2010-02-20 15:24:38 +02:00
2016-10-17 12:44:47 +02:00
static void setScrollingCursor ( ui8 direction )
{
if ( direction & CAdvMapInt : : RIGHT )
{
if ( direction & CAdvMapInt : : UP )
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 33 ) ;
else if ( direction & CAdvMapInt : : DOWN )
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 35 ) ;
else
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 34 ) ;
}
else if ( direction & CAdvMapInt : : LEFT )
{
if ( direction & CAdvMapInt : : UP )
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 39 ) ;
else if ( direction & CAdvMapInt : : DOWN )
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 37 ) ;
else
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 38 ) ;
}
else if ( direction & CAdvMapInt : : UP )
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 32 ) ;
else if ( direction & CAdvMapInt : : DOWN )
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 36 ) ;
}
2009-01-12 22:05:56 +02:00
CTerrainRect : : CTerrainRect ( )
2015-10-31 19:23:13 +02:00
: fadeSurface ( nullptr ) ,
2016-11-27 18:00:16 +02:00
lastRedrawStatus ( EMapAnimRedrawStatus : : OK ) ,
2018-04-07 13:34:11 +02:00
fadeAnim ( std : : make_shared < CFadeAnimation > ( ) ) ,
2015-10-31 19:23:13 +02:00
curHoveredTile ( - 1 , - 1 , - 1 ) ,
2015-01-31 00:37:28 +02:00
currentPath ( nullptr )
2007-08-17 20:42:21 +03:00
{
2009-06-14 18:10:59 +03:00
tilesw = ( ADVOPT . advmapW + 31 ) / 32 ;
tilesh = ( ADVOPT . advmapH + 31 ) / 32 ;
2008-11-28 03:36:34 +02:00
pos . x = ADVOPT . advmapX ;
pos . y = ADVOPT . advmapY ;
2009-06-14 18:10:59 +03:00
pos . w = ADVOPT . advmapW ;
pos . h = ADVOPT . advmapH ;
2008-10-17 19:30:56 +03:00
moveX = moveY = 0 ;
2017-06-07 22:42:41 +02:00
addUsedEvents ( LCLICK | RCLICK | MCLICK | HOVER | MOVE ) ;
2007-08-17 20:42:21 +03:00
}
2012-06-02 18:16:54 +03:00
2015-01-31 00:37:28 +02:00
CTerrainRect : : ~ CTerrainRect ( )
{
2018-04-07 13:34:11 +02:00
if ( fadeSurface )
2015-01-31 00:37:28 +02:00
SDL_FreeSurface ( fadeSurface ) ;
}
2007-08-04 22:01:22 +03:00
void CTerrainRect : : deactivate ( )
{
2012-06-02 18:16:54 +03:00
CIntObject : : deactivate ( ) ;
2009-11-13 23:01:33 +02:00
curHoveredTile = int3 ( - 1 , - 1 , - 1 ) ; //we lost info about hovered tile when disabling
2011-02-23 20:21:51 +02:00
}
2012-06-02 18:16:54 +03:00
2009-08-11 19:05:33 +03:00
void CTerrainRect : : clickLeft ( tribool down , bool previousState )
2007-09-22 04:16:31 +03:00
{
2017-05-25 19:57:20 +02:00
if ( adventureInt - > mode = = EAdvMapMode : : WORLD_VIEW )
2015-01-13 21:57:41 +02:00
return ;
2017-05-25 19:57:20 +02:00
if ( indeterminate ( down ) )
2007-09-22 04:16:31 +03:00
return ;
2010-03-21 00:17:19 +02:00
2021-03-13 13:08:13 +02:00
# if defined(VCMI_ANDROID) || defined(VCMI_IOS)
2017-05-25 19:57:20 +02:00
if ( adventureInt - > swipeEnabled )
{
2019-01-24 17:34:58 +02:00
if ( handleSwipeStateChange ( ( bool ) down = = true ) )
2017-05-25 19:57:20 +02:00
{
return ; // if swipe is enabled, we don't process "down" events and wait for "up" (to make sure this wasn't a swiping gesture)
}
}
else
{
# endif
if ( down = = false )
return ;
2021-03-13 13:08:13 +02:00
# if defined(VCMI_ANDROID) || defined(VCMI_IOS)
2017-05-25 19:57:20 +02:00
}
# endif
2008-08-28 20:36:34 +03:00
int3 mp = whichTileIsIt ( ) ;
2017-05-25 19:57:20 +02:00
if ( mp . x < 0 | | mp . y < 0 | | mp . x > = LOCPLINT - > cb - > getMapSize ( ) . x | | mp . y > = LOCPLINT - > cb - > getMapSize ( ) . y )
2008-08-28 20:36:34 +03:00
return ;
2009-04-21 01:57:07 +03:00
2010-03-21 00:17:19 +02:00
adventureInt - > tileLClicked ( mp ) ;
2007-09-22 04:16:31 +03:00
}
2012-06-02 18:16:54 +03:00
2009-08-11 19:05:33 +03:00
void CTerrainRect : : clickRight ( tribool down , bool previousState )
2007-09-22 04:16:31 +03:00
{
2021-03-13 13:08:13 +02:00
# if defined(VCMI_ANDROID) || defined(VCMI_IOS)
2017-05-25 19:57:20 +02:00
if ( adventureInt - > swipeEnabled & & isSwiping )
return ;
# endif
if ( adventureInt - > mode = = EAdvMapMode : : WORLD_VIEW )
2015-01-13 21:57:41 +02:00
return ;
2009-01-14 21:01:20 +02:00
int3 mp = whichTileIsIt ( ) ;
2009-10-22 05:25:12 +03:00
2017-05-25 19:57:20 +02:00
if ( CGI - > mh - > map - > isInTheMap ( mp ) & & down )
2011-05-26 01:44:02 +03:00
adventureInt - > tileRClicked ( mp ) ;
2007-09-22 04:16:31 +03:00
}
2011-05-26 01:44:02 +03:00
2017-06-07 22:42:41 +02:00
void CTerrainRect : : clickMiddle ( tribool down , bool previousState )
{
2019-01-24 17:30:09 +02:00
handleSwipeStateChange ( ( bool ) down = = true ) ;
2017-06-07 22:42:41 +02:00
}
2015-11-18 02:14:58 +02:00
void CTerrainRect : : mouseMoved ( const SDL_MouseMotionEvent & sEvent )
2007-09-22 04:16:31 +03:00
{
2017-05-25 19:57:20 +02:00
handleHover ( sEvent ) ;
2017-06-07 22:42:41 +02:00
if ( ! adventureInt - > swipeEnabled )
2017-05-25 19:57:20 +02:00
return ;
handleSwipeMove ( sEvent ) ;
}
void CTerrainRect : : handleSwipeMove ( const SDL_MouseMotionEvent & sEvent )
{
2021-03-13 13:08:13 +02:00
# if defined(VCMI_ANDROID) || defined(VCMI_IOS)
if ( sEvent . state = = 0 ) // any "button" is enough on mobile
# else
2017-06-07 22:42:41 +02:00
if ( ( sEvent . state & SDL_BUTTON_MMASK ) = = 0 ) // swipe only works with middle mouse on other platforms
2021-03-13 13:08:13 +02:00
# endif
2017-06-07 22:42:41 +02:00
{
return ;
}
2017-05-25 19:57:20 +02:00
if ( ! isSwiping )
{
// try to distinguish if this touch was meant to be a swipe or just fat-fingering press
if ( abs ( sEvent . x - swipeInitialRealPos . x ) > SwipeTouchSlop | |
abs ( sEvent . y - swipeInitialRealPos . y ) > SwipeTouchSlop )
{
isSwiping = true ;
}
}
if ( isSwiping )
{
adventureInt - > swipeTargetPosition . x =
swipeInitialMapPos . x + static_cast < si32 > ( swipeInitialRealPos . x - sEvent . x ) / 32 ;
adventureInt - > swipeTargetPosition . y =
swipeInitialMapPos . y + static_cast < si32 > ( swipeInitialRealPos . y - sEvent . y ) / 32 ;
adventureInt - > swipeMovementRequested = true ;
}
}
2017-06-07 22:42:41 +02:00
bool CTerrainRect : : handleSwipeStateChange ( bool btnPressed )
{
if ( btnPressed )
{
swipeInitialRealPos = int3 ( GH . current - > motion . x , GH . current - > motion . y , 0 ) ;
swipeInitialMapPos = int3 ( adventureInt - > position ) ;
return true ;
}
else if ( isSwiping ) // only accept this touch if it wasn't a swipe
{
isSwiping = false ;
return true ;
}
return false ;
}
2017-05-25 19:57:20 +02:00
void CTerrainRect : : handleHover ( const SDL_MouseMotionEvent & sEvent )
{
int3 tHovered = whichTileIsIt ( sEvent . x , sEvent . y ) ;
2010-02-20 15:24:38 +02:00
int3 pom = adventureInt - > verifyPos ( tHovered ) ;
2009-09-24 16:23:52 +03:00
if ( tHovered ! = pom ) //tile outside the map
{
2012-12-14 18:32:53 +03:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 0 ) ;
2009-09-24 16:23:52 +03:00
return ;
}
if ( pom ! = curHoveredTile )
2017-05-25 19:57:20 +02:00
{
2015-11-18 02:14:58 +02:00
curHoveredTile = pom ;
2017-05-25 19:57:20 +02:00
adventureInt - > tileHovered ( pom ) ;
}
2007-09-22 04:16:31 +03:00
}
2017-05-25 19:57:20 +02:00
2007-10-07 17:51:09 +03:00
void CTerrainRect : : hover ( bool on )
{
if ( ! on )
2009-05-02 01:08:03 +03:00
{
2018-08-26 18:09:56 +02:00
adventureInt - > statusbar - > clear ( ) ;
2012-12-14 18:32:53 +03:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 0 ) ;
2009-05-02 01:08:03 +03:00
}
2009-08-11 19:05:33 +03:00
//Hoverable::hover(on);
2007-10-07 17:51:09 +03:00
}
2009-11-14 22:14:15 +02:00
void CTerrainRect : : showPath ( const SDL_Rect * extRect , SDL_Surface * to )
2007-08-04 22:01:22 +03:00
{
2011-05-21 11:44:02 +03:00
const static int pns [ 9 ] [ 9 ] = {
{ 16 , 17 , 18 , 7 , - 1 , 19 , 6 , 5 , - 1 } ,
{ 8 , 9 , 18 , 7 , - 1 , 19 , 6 , - 1 , 20 } ,
{ 8 , 1 , 10 , 7 , - 1 , 19 , - 1 , 21 , 20 } ,
{ 24 , 17 , 18 , 15 , - 1 , - 1 , 6 , 5 , 4 } ,
{ - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 } ,
{ 8 , 1 , 2 , - 1 , - 1 , 11 , 22 , 21 , 20 } ,
{ 24 , 17 , - 1 , 23 , - 1 , 3 , 14 , 5 , 4 } ,
{ 24 , - 1 , 2 , 23 , - 1 , 3 , 22 , 13 , 4 } ,
{ - 1 , 1 , 2 , 23 , - 1 , 3 , 22 , 21 , 12 }
} ; //table of magic values TODO meaning, change variable name
2022-06-20 16:39:50 +02:00
for ( int i = 0 ; i < - 1 + ( int ) currentPath - > nodes . size ( ) ; + + i )
2007-08-17 20:42:21 +03:00
{
2011-09-19 23:50:25 +03:00
const int3 & curPos = currentPath - > nodes [ i ] . coord , & nextPos = currentPath - > nodes [ i + 1 ] . coord ;
if ( curPos . z ! = adventureInt - > position . z )
continue ;
2007-12-22 16:40:27 +02:00
int pn = - 1 ; //number of picture
if ( i = = 0 ) //last tile
{
2011-09-19 23:50:25 +03:00
int x = 32 * ( curPos . x - adventureInt - > position . x ) + CGI - > mh - > offsetX + pos . x ,
y = 32 * ( curPos . y - adventureInt - > position . y ) + CGI - > mh - > offsetY + pos . y ;
2007-12-22 16:40:27 +02:00
if ( x < 0 | | y < 0 | | x > pos . w | | y > pos . h )
continue ;
pn = 0 ;
}
else
2007-08-17 20:42:21 +03:00
{
2011-09-19 23:50:25 +03:00
const int3 & prevPos = currentPath - > nodes [ i - 1 ] . coord ;
std : : vector < CGPathNode > & cv = currentPath - > nodes ;
2011-05-21 04:10:41 +03:00
/* Vector directions
* 0 1 2
2012-01-12 18:23:00 +03:00
* \ | /
2011-05-21 04:10:41 +03:00
* 3 - 4 - 5
* / | \
* 6 7 8
* For example :
* |
* | __ \
* /
* is id1 = 7 , id2 = 5 ( pns [ 7 ] [ 5 ] )
2012-01-12 18:23:00 +03:00
*/
2011-09-19 23:50:25 +03:00
bool pathContinuous = curPos . areNeighbours ( nextPos ) & & curPos . areNeighbours ( prevPos ) ;
2015-11-08 03:01:58 +02:00
if ( pathContinuous & & cv [ i ] . action ! = CGPathNode : : EMBARK & & cv [ i ] . action ! = CGPathNode : : DISEMBARK )
2011-09-19 23:50:25 +03:00
{
int id1 = ( curPos . x - nextPos . x + 1 ) + 3 * ( curPos . y - nextPos . y + 1 ) ; //Direction of entering vector
int id2 = ( cv [ i - 1 ] . coord . x - curPos . x + 1 ) + 3 * ( cv [ i - 1 ] . coord . y - curPos . y + 1 ) ; //Direction of exiting vector
pn = pns [ id1 ] [ id2 ] ;
}
else //path discontinuity or sea/land transition (eg. when moving through Subterranean Gate or Boat)
{
pn = 0 ;
}
2007-12-22 16:40:27 +02:00
}
2009-09-07 05:29:44 +03:00
if ( currentPath - > nodes [ i ] . turns )
2007-12-22 16:40:27 +02:00
pn + = 25 ;
if ( pn > = 0 )
{
2018-03-30 13:02:04 +02:00
const auto arrow = graphics - > heroMoveArrows - > getImage ( pn ) ;
2016-10-18 09:31:31 +02:00
2011-09-19 23:50:25 +03:00
int x = 32 * ( curPos . x - adventureInt - > position . x ) + CGI - > mh - > offsetX + pos . x ,
y = 32 * ( curPos . y - adventureInt - > position . y ) + CGI - > mh - > offsetY + pos . y ;
2012-05-15 11:47:11 +03:00
if ( x < - 32 | | y < - 32 | | x > pos . w | | y > pos . h )
2007-12-22 16:40:27 +02:00
continue ;
2016-10-18 09:31:31 +02:00
int hvx = ( x + arrow - > width ( ) ) - ( pos . x + pos . w ) ,
hvy = ( y + arrow - > height ( ) ) - ( pos . y + pos . h ) ;
2009-01-09 15:03:47 +02:00
2009-01-09 20:12:36 +02:00
SDL_Rect prevClip ;
2009-11-14 22:14:15 +02:00
SDL_GetClipRect ( to , & prevClip ) ;
SDL_SetClipRect ( to , extRect ) ; //preventing blitting outside of that rect
2009-01-09 15:03:47 +02:00
if ( ADVOPT . smoothMove ) //version for smooth hero move, with pos shifts
2007-12-22 16:40:27 +02:00
{
2009-01-09 15:03:47 +02:00
if ( hvx < 0 & & hvy < 0 )
{
2016-10-18 09:31:31 +02:00
arrow - > draw ( to , x + moveX , y + moveY ) ;
2009-01-09 15:03:47 +02:00
}
else if ( hvx < 0 )
{
2016-10-18 09:31:31 +02:00
Rect srcRect = genRect ( arrow - > height ( ) - hvy , arrow - > width ( ) , 0 , 0 ) ;
arrow - > draw ( to , x + moveX , y + moveY , & srcRect ) ;
2009-01-09 15:03:47 +02:00
}
else if ( hvy < 0 )
{
2016-10-18 09:31:31 +02:00
Rect srcRect = genRect ( arrow - > height ( ) , arrow - > width ( ) - hvx , 0 , 0 ) ;
arrow - > draw ( to , x + moveX , y + moveY , & srcRect ) ;
2009-01-09 15:03:47 +02:00
}
else
{
2016-10-18 09:31:31 +02:00
Rect srcRect = genRect ( arrow - > height ( ) - hvy , arrow - > width ( ) - hvx , 0 , 0 ) ;
arrow - > draw ( to , x + moveX , y + moveY , & srcRect ) ;
2009-01-09 15:03:47 +02:00
}
2007-08-17 20:42:21 +03:00
}
2009-01-09 15:03:47 +02:00
else //standard version
2008-02-10 19:44:51 +02:00
{
2009-01-09 15:03:47 +02:00
if ( hvx < 0 & & hvy < 0 )
{
2016-10-18 09:31:31 +02:00
arrow - > draw ( to , x , y ) ;
2009-01-09 15:03:47 +02:00
}
else if ( hvx < 0 )
{
2016-10-18 09:31:31 +02:00
Rect srcRect = genRect ( arrow - > height ( ) - hvy , arrow - > width ( ) , 0 , 0 ) ;
arrow - > draw ( to , x , y , & srcRect ) ;
2009-01-09 15:03:47 +02:00
}
else if ( hvy < 0 )
{
2016-10-18 09:31:31 +02:00
Rect srcRect = genRect ( arrow - > height ( ) , arrow - > width ( ) - hvx , 0 , 0 ) ;
arrow - > draw ( to , x , y , & srcRect ) ;
2009-01-09 15:03:47 +02:00
}
else
{
2016-10-18 09:31:31 +02:00
Rect srcRect = genRect ( arrow - > height ( ) - hvy , arrow - > width ( ) - hvx , 0 , 0 ) ;
arrow - > draw ( to , x , y , & srcRect ) ;
2009-01-09 15:03:47 +02:00
}
2008-02-10 19:44:51 +02:00
}
2009-11-14 22:14:15 +02:00
SDL_SetClipRect ( to , & prevClip ) ;
2007-12-22 16:40:27 +02:00
}
} //for (int i=0;i<currentPath->nodes.size()-1;i++)
}
2012-06-02 18:16:54 +03:00
2009-04-14 15:47:09 +03:00
void CTerrainRect : : show ( SDL_Surface * to )
2007-12-22 16:40:27 +02:00
{
2015-01-13 21:57:41 +02:00
if ( adventureInt - > mode = = EAdvMapMode : : NORMAL )
{
2022-09-18 16:39:10 +02:00
MapDrawingInfo info ( adventureInt - > position , LOCPLINT - > cb - > getVisibilityMap ( ) , & pos ) ;
2015-01-18 19:53:40 +02:00
info . otherheroAnim = true ;
info . anim = adventureInt - > anim ;
info . heroAnim = adventureInt - > heroAnim ;
2015-01-13 21:57:41 +02:00
if ( ADVOPT . smoothMove )
2015-01-18 19:53:40 +02:00
info . movement = int3 ( moveX , moveY , 0 ) ;
2015-10-31 19:23:13 +02:00
2015-01-31 00:37:28 +02:00
lastRedrawStatus = CGI - > mh - > drawTerrainRectNew ( to , & info ) ;
if ( fadeAnim - > isFading ( ) )
{
Rect r ( pos ) ;
fadeAnim - > update ( ) ;
fadeAnim - > draw ( to , nullptr , & r ) ;
}
2012-01-12 18:23:00 +03:00
2015-01-13 21:57:41 +02:00
if ( currentPath /* && adventureInt->position.z==currentPath->startPos().z*/ ) //drawing path
{
showPath ( & pos , to ) ;
}
}
}
void CTerrainRect : : showAll ( SDL_Surface * to )
{
// world view map is static and doesn't need redraw every frame
if ( adventureInt - > mode = = EAdvMapMode : : WORLD_VIEW )
2015-01-18 19:53:40 +02:00
{
2022-09-18 16:39:10 +02:00
MapDrawingInfo info ( adventureInt - > position , LOCPLINT - > cb - > getVisibilityMap ( ) , & pos , adventureInt - > worldViewIcons ) ;
2015-01-18 19:53:40 +02:00
info . scaled = true ;
info . scale = adventureInt - > worldViewScale ;
2015-02-02 14:02:27 +02:00
adventureInt - > worldViewOptions . adjustDrawingInfo ( info ) ;
2015-01-18 19:53:40 +02:00
CGI - > mh - > drawTerrainRectNew ( to , & info ) ;
}
2007-08-04 22:01:22 +03:00
}
2007-08-06 07:03:34 +03:00
2015-01-31 00:37:28 +02:00
void CTerrainRect : : showAnim ( SDL_Surface * to )
2015-10-31 19:23:13 +02:00
{
2015-01-31 00:37:28 +02:00
if ( fadeAnim - > isFading ( ) )
show ( to ) ;
else if ( lastRedrawStatus = = EMapAnimRedrawStatus : : REDRAW_REQUESTED )
2015-01-31 19:36:57 +02:00
show ( to ) ; // currently the same; maybe we should pass some flag to map handler so it redraws ONLY tiles that need redraw instead of full
2015-01-31 00:37:28 +02:00
}
2016-01-09 14:32:42 +02:00
int3 CTerrainRect : : whichTileIsIt ( const int x , const int y )
2007-10-07 17:51:09 +03:00
{
int3 ret ;
2016-01-09 14:32:42 +02:00
ret . x = adventureInt - > position . x + ( ( x - CGI - > mh - > offsetX - pos . x ) / 32 ) ;
ret . y = adventureInt - > position . y + ( ( y - CGI - > mh - > offsetY - pos . y ) / 32 ) ;
2010-02-20 15:24:38 +02:00
ret . z = adventureInt - > position . z ;
2007-10-07 17:51:09 +03:00
return ret ;
}
2012-06-02 18:16:54 +03:00
2007-10-07 17:51:09 +03:00
int3 CTerrainRect : : whichTileIsIt ( )
{
2016-01-09 14:32:42 +02:00
if ( GH . current )
return whichTileIsIt ( GH . current - > motion . x , GH . current - > motion . y ) ;
else
return int3 ( - 1 ) ;
2007-10-07 17:51:09 +03:00
}
2009-01-12 22:05:56 +02:00
2015-01-13 21:57:41 +02:00
int3 CTerrainRect : : tileCountOnScreen ( )
{
switch ( adventureInt - > mode )
{
default :
2017-08-11 13:38:10 +02:00
logGlobal - > error ( " Unknown map mode %d " , ( int ) adventureInt - > mode ) ;
2015-01-13 21:57:41 +02:00
return int3 ( ) ;
case EAdvMapMode : : NORMAL :
return int3 ( tilesw , tilesh , 1 ) ;
case EAdvMapMode : : WORLD_VIEW :
2020-10-01 10:38:06 +02:00
return int3 ( ( si32 ) ( tilesw / adventureInt - > worldViewScale ) , ( si32 ) ( tilesh / adventureInt - > worldViewScale ) , 1 ) ;
2015-01-13 21:57:41 +02:00
}
}
2015-01-31 00:37:28 +02:00
void CTerrainRect : : fadeFromCurrentView ( )
{
2015-02-02 20:38:30 +02:00
if ( ! ADVOPT . screenFading )
return ;
2015-01-31 00:37:28 +02:00
if ( adventureInt - > mode = = EAdvMapMode : : WORLD_VIEW )
return ;
2015-10-31 19:23:13 +02:00
2015-01-31 00:37:28 +02:00
if ( ! fadeSurface )
fadeSurface = CSDL_Ext : : newSurface ( pos . w , pos . h ) ;
SDL_BlitSurface ( screen , & pos , fadeSurface , nullptr ) ;
2015-02-02 18:42:42 +02:00
fadeAnim - > init ( CFadeAnimation : : EMode : : OUT , fadeSurface ) ;
2015-01-31 00:37:28 +02:00
}
bool CTerrainRect : : needsAnimUpdate ( )
{
return fadeAnim - > isFading ( ) | | lastRedrawStatus = = EMapAnimRedrawStatus : : REDRAW_REQUESTED ;
}
2009-08-11 19:05:33 +03:00
void CResDataBar : : clickRight ( tribool down , bool previousState )
2007-09-16 20:21:23 +03:00
{
}
2012-06-02 18:16:54 +03:00
2018-04-07 13:34:11 +02:00
CResDataBar : : CResDataBar ( const std : : string & defname , int x , int y , int offx , int offy , int resdist , int datedist )
2008-12-08 00:38:04 +02:00
{
2018-04-07 13:34:11 +02:00
pos . x + = x ;
pos . y + = y ;
OBJECT_CONSTRUCTION_CAPTURING ( 255 - DISPOSE ) ;
background = std : : make_shared < CPicture > ( defname , 0 , 0 ) ;
background - > colorize ( LOCPLINT - > playerID ) ;
pos . w = background - > bg - > w ;
pos . h = background - > bg - > h ;
2008-12-08 00:38:04 +02:00
txtpos . resize ( 8 ) ;
for ( int i = 0 ; i < 8 ; i + + )
{
txtpos [ i ] . first = pos . x + offx + resdist * i ;
txtpos [ i ] . second = pos . y + offy ;
}
txtpos [ 7 ] . first = txtpos [ 6 ] . first + datedist ;
2012-01-12 18:23:00 +03:00
datetext = CGI - > generaltexth - > allTexts [ 62 ] + " : %s, " + CGI - > generaltexth - > allTexts [ 63 ]
2008-12-08 00:38:04 +02:00
+ " : %s, " + CGI - > generaltexth - > allTexts [ 64 ] + " : %s " ;
2012-06-02 18:16:54 +03:00
addUsedEvents ( RCLICK ) ;
2008-12-08 00:38:04 +02:00
}
2012-06-02 18:16:54 +03:00
2007-09-16 20:21:23 +03:00
CResDataBar : : CResDataBar ( )
{
2018-04-07 13:34:11 +02:00
pos . x + = ADVOPT . resdatabarX ;
pos . y + = ADVOPT . resdatabarY ;
OBJECT_CONSTRUCTION_CAPTURING ( 255 - DISPOSE ) ;
background = std : : make_shared < CPicture > ( ADVOPT . resdatabarG , 0 , 0 ) ;
background - > colorize ( LOCPLINT - > playerID ) ;
pos . w = background - > bg - > w ;
pos . h = background - > bg - > h ;
2007-09-16 20:21:23 +03:00
2008-11-28 03:36:34 +02:00
txtpos . resize ( 8 ) ;
for ( int i = 0 ; i < 8 ; i + + )
{
txtpos [ i ] . first = pos . x + ADVOPT . resOffsetX + ADVOPT . resDist * i ;
txtpos [ i ] . second = pos . y + ADVOPT . resOffsetY ;
}
txtpos [ 7 ] . first = txtpos [ 6 ] . first + ADVOPT . resDateDist ;
2012-01-12 18:23:00 +03:00
datetext = CGI - > generaltexth - > allTexts [ 62 ] + " : %s, " + CGI - > generaltexth - > allTexts [ 63 ]
2008-11-28 03:36:34 +02:00
+ " : %s, " + CGI - > generaltexth - > allTexts [ 64 ] + " : %s " ;
2007-09-16 20:21:23 +03:00
}
2008-12-08 00:38:04 +02:00
2018-04-07 13:34:11 +02:00
CResDataBar : : ~ CResDataBar ( ) = default ;
2009-04-14 15:47:09 +03:00
void CResDataBar : : draw ( SDL_Surface * to )
2007-09-16 20:21:23 +03:00
{
2018-04-07 13:34:11 +02:00
//TODO: all this should be labels, but they require proper text update on change
2013-02-09 15:56:35 +03:00
for ( auto i = Res : : WOOD ; i < = Res : : GOLD ; vstd : : advance ( i , 1 ) )
2007-09-16 20:21:23 +03:00
{
2012-12-19 20:24:53 +03:00
std : : string text = boost : : lexical_cast < std : : string > ( LOCPLINT - > cb - > getResourceAmount ( i ) ) ;
graphics - > fonts [ FONT_SMALL ] - > renderTextLeft ( to , text , Colors : : WHITE , Point ( txtpos [ i ] . first , txtpos [ i ] . second ) ) ;
2007-09-16 20:21:23 +03:00
}
2007-09-18 16:30:26 +03:00
std : : vector < std : : string > temp ;
2012-12-19 20:24:53 +03:00
2013-02-02 11:29:57 +03:00
temp . push_back ( boost : : lexical_cast < std : : string > ( LOCPLINT - > cb - > getDate ( Date : : MONTH ) ) ) ;
temp . push_back ( boost : : lexical_cast < std : : string > ( LOCPLINT - > cb - > getDate ( Date : : WEEK ) ) ) ;
temp . push_back ( boost : : lexical_cast < std : : string > ( LOCPLINT - > cb - > getDate ( Date : : DAY_OF_WEEK ) ) ) ;
2012-12-19 20:24:53 +03:00
graphics - > fonts [ FONT_SMALL ] - > renderTextLeft ( to , processStr ( datetext , temp ) , Colors : : WHITE , Point ( txtpos [ 7 ] . first , txtpos [ 7 ] . second ) ) ;
2007-09-16 20:21:23 +03:00
}
2009-08-11 19:05:33 +03:00
2011-12-22 16:05:19 +03:00
void CResDataBar : : show ( SDL_Surface * to )
2009-08-11 19:05:33 +03:00
{
}
2011-04-07 20:54:08 +03:00
2011-12-22 16:05:19 +03:00
void CResDataBar : : showAll ( SDL_Surface * to )
2011-04-07 20:54:08 +03:00
{
2018-04-07 13:34:11 +02:00
CIntObject : : showAll ( to ) ;
2011-04-07 20:54:08 +03:00
draw ( to ) ;
}
2012-06-13 16:04:06 +03:00
CAdvMapInt : : CAdvMapInt ( ) :
2015-01-13 21:57:41 +02:00
mode ( EAdvMapMode : : NORMAL ) ,
2016-08-17 08:49:43 +02:00
worldViewScale ( 0.0f ) , //actual init later in changeMode
2015-01-13 21:57:41 +02:00
minimap ( Rect ( ADVOPT . minimapX , ADVOPT . minimapY , ADVOPT . minimapW , ADVOPT . minimapH ) ) ,
2018-08-26 18:09:56 +02:00
statusbar ( CGStatusBar : : create ( ADVOPT . statusbarX , ADVOPT . statusbarY , ADVOPT . statusbarG ) ) ,
2015-01-19 22:48:52 +02:00
heroList ( ADVOPT . hlistSize , Point ( ADVOPT . hlistX , ADVOPT . hlistY ) , ADVOPT . hlistAU , ADVOPT . hlistAD ) ,
townList ( ADVOPT . tlistSize , Point ( ADVOPT . tlistX , ADVOPT . tlistY ) , ADVOPT . tlistAU , ADVOPT . tlistAD ) ,
2016-10-22 10:18:57 +02:00
infoBar ( Rect ( ADVOPT . infoboxX , ADVOPT . infoboxY , 192 , 192 ) ) , state ( NA ) ,
2018-04-07 13:34:11 +02:00
spellBeingCasted ( nullptr ) , position ( int3 ( 0 , 0 , 0 ) ) , selection ( nullptr ) ,
updateScreen ( false ) , anim ( 0 ) , animValHitCount ( 0 ) , heroAnim ( 0 ) , heroAnimValHitCount ( 0 ) ,
2017-08-10 18:39:27 +02:00
activeMapPanel ( nullptr ) , duringAITurn ( false ) , scrollingDir ( 0 ) , scrollingState ( false ) ,
2017-06-07 22:42:41 +02:00
swipeEnabled ( settings [ " general " ] [ " swipe " ] . Bool ( ) ) , swipeMovementRequested ( false ) ,
2017-05-25 19:57:20 +02:00
swipeTargetPosition ( int3 ( - 1 , - 1 , - 1 ) )
2007-08-06 07:03:34 +03:00
{
2009-08-18 11:22:56 +03:00
pos . x = pos . y = 0 ;
pos . w = screen - > w ;
pos . h = screen - > h ;
2019-12-26 20:10:39 +02:00
strongInterest = true ; // handle all mouse move events to prevent dead mouse move space in fullscreen mode
2014-08-04 21:33:59 +03:00
townList . onSelect = std : : bind ( & CAdvMapInt : : selectionChanged , this ) ;
2008-11-12 20:26:23 +02:00
bg = BitmapHandler : : loadBitmap ( ADVOPT . mainGraphic ) ;
2016-10-02 22:05:53 +02:00
if ( ADVOPT . worldViewGraphic ! = " " )
{
bgWorldView = BitmapHandler : : loadBitmap ( ADVOPT . worldViewGraphic ) ;
}
else
{
bgWorldView = nullptr ;
2016-10-03 20:32:01 +02:00
logGlobal - > warn ( " ADVOPT.worldViewGraphic is empty => bitmap not loaded " ) ;
2016-10-02 22:05:53 +02:00
}
2015-01-13 21:57:41 +02:00
if ( ! bgWorldView )
{
logGlobal - > warn ( " bgWorldView not defined in resolution config; fallback to VWorld.bmp " ) ;
bgWorldView = BitmapHandler : : loadBitmap ( " VWorld.bmp " ) ;
}
2016-10-18 04:46:07 +02:00
worldViewIcons = std : : make_shared < CAnimation > ( " VwSymbol " ) ; //todo: customize with ADVOPT
2018-04-07 13:34:11 +02:00
worldViewIcons - > preload ( ) ;
2016-10-18 04:46:07 +02:00
2018-04-07 13:34:11 +02:00
for ( int g = 0 ; g < ADVOPT . gemG . size ( ) ; + + g )
2010-08-04 14:18:13 +03:00
{
2018-04-07 13:34:11 +02:00
gems . push_back ( std : : make_shared < CAnimImage > ( ADVOPT . gemG [ g ] , 0 , 0 , ADVOPT . gemX [ g ] , ADVOPT . gemY [ g ] ) ) ;
2010-08-04 14:18:13 +03:00
}
2010-07-29 01:24:16 +03:00
2018-04-07 13:34:11 +02:00
auto makeButton = [ & ] ( int textID , std : : function < void ( ) > callback , config : : ButtonInfo info , int key ) - > std : : shared_ptr < CButton >
2014-08-03 14:16:19 +03:00
{
2018-04-07 13:34:11 +02:00
auto button = std : : make_shared < CButton > ( Point ( info . x , info . y ) , info . defName , CGI - > generaltexth - > zelp [ textID ] , callback , key , info . playerColoured ) ;
for ( auto image : info . additionalDefs )
2014-08-03 14:16:19 +03:00
button - > addImage ( image ) ;
return button ;
} ;
2014-08-09 15:14:31 +03:00
kingOverview = makeButton ( 293 , std : : bind ( & CAdvMapInt : : fshowOverview , this ) , ADVOPT . kingOverview , SDLK_k ) ;
underground = makeButton ( 294 , std : : bind ( & CAdvMapInt : : fswitchLevel , this ) , ADVOPT . underground , SDLK_u ) ;
questlog = makeButton ( 295 , std : : bind ( & CAdvMapInt : : fshowQuestlog , this ) , ADVOPT . questlog , SDLK_q ) ;
sleepWake = makeButton ( 296 , std : : bind ( & CAdvMapInt : : fsleepWake , this ) , ADVOPT . sleepWake , SDLK_w ) ;
moveHero = makeButton ( 297 , std : : bind ( & CAdvMapInt : : fmoveHero , this ) , ADVOPT . moveHero , SDLK_m ) ;
spellbook = makeButton ( 298 , std : : bind ( & CAdvMapInt : : fshowSpellbok , this ) , ADVOPT . spellbook , SDLK_c ) ;
advOptions = makeButton ( 299 , std : : bind ( & CAdvMapInt : : fadventureOPtions , this ) , ADVOPT . advOptions , SDLK_a ) ;
sysOptions = makeButton ( 300 , std : : bind ( & CAdvMapInt : : fsystemOptions , this ) , ADVOPT . sysOptions , SDLK_o ) ;
nextHero = makeButton ( 301 , std : : bind ( & CAdvMapInt : : fnextHero , this ) , ADVOPT . nextHero , SDLK_h ) ;
endTurn = makeButton ( 302 , std : : bind ( & CAdvMapInt : : fendTurn , this ) , ADVOPT . endTurn , SDLK_e ) ;
2010-07-29 01:24:16 +03:00
2015-01-29 19:39:46 +02:00
int panelSpaceBottom = screen - > h - resdatabar . pos . h - 4 ;
2015-10-31 19:23:13 +02:00
2018-04-07 13:34:11 +02:00
panelMain = std : : make_shared < CAdvMapPanel > ( nullptr , Point ( 0 , 0 ) ) ;
2015-01-29 19:39:46 +02:00
// TODO correct drawing position
2018-04-07 13:34:11 +02:00
panelWorldView = std : : make_shared < CAdvMapWorldViewPanel > ( worldViewIcons , bgWorldView , Point ( heroList . pos . x - 2 , 195 ) , panelSpaceBottom , LOCPLINT - > playerID ) ;
2015-01-15 01:22:20 +02:00
panelMain - > addChildColorableButton ( kingOverview ) ;
panelMain - > addChildColorableButton ( underground ) ;
panelMain - > addChildColorableButton ( questlog ) ;
panelMain - > addChildColorableButton ( sleepWake ) ;
panelMain - > addChildColorableButton ( moveHero ) ;
panelMain - > addChildColorableButton ( spellbook ) ;
panelMain - > addChildColorableButton ( advOptions ) ;
panelMain - > addChildColorableButton ( sysOptions ) ;
panelMain - > addChildColorableButton ( nextHero ) ;
panelMain - > addChildColorableButton ( endTurn ) ;
2015-01-13 21:57:41 +02:00
// TODO move configs to resolutions.json, similarly to previous buttons
config : : ButtonInfo worldViewBackConfig = config : : ButtonInfo ( ) ;
worldViewBackConfig . defName = " IOK6432.DEF " ;
worldViewBackConfig . x = screen - > w - 73 ;
worldViewBackConfig . y = 343 + 195 ;
worldViewBackConfig . playerColoured = false ;
2015-01-15 01:22:20 +02:00
panelWorldView - > addChildToPanel (
makeButton ( 288 , std : : bind ( & CAdvMapInt : : fworldViewBack , this ) , worldViewBackConfig , SDLK_ESCAPE ) , ACTIVATE | DEACTIVATE ) ;
2015-01-13 21:57:41 +02:00
2015-01-19 21:46:03 +02:00
config : : ButtonInfo worldViewPuzzleConfig = config : : ButtonInfo ( ) ;
worldViewPuzzleConfig . defName = " VWPUZ.DEF " ;
worldViewPuzzleConfig . x = screen - > w - 188 ;
worldViewPuzzleConfig . y = 343 + 195 ;
worldViewPuzzleConfig . playerColoured = false ;
panelWorldView - > addChildToPanel ( // no help text for this one
2018-04-07 13:34:11 +02:00
std : : make_shared < CButton > ( Point ( worldViewPuzzleConfig . x , worldViewPuzzleConfig . y ) , worldViewPuzzleConfig . defName , std : : pair < std : : string , std : : string > ( ) ,
2015-01-19 21:46:03 +02:00
std : : bind ( & CPlayerInterface : : showPuzzleMap , LOCPLINT ) , SDLK_p , worldViewPuzzleConfig . playerColoured ) , ACTIVATE | DEACTIVATE ) ;
2015-01-13 21:57:41 +02:00
config : : ButtonInfo worldViewScale1xConfig = config : : ButtonInfo ( ) ;
worldViewScale1xConfig . defName = " VWMAG1.DEF " ;
worldViewScale1xConfig . x = screen - > w - 191 ;
worldViewScale1xConfig . y = 23 + 195 ;
worldViewScale1xConfig . playerColoured = false ;
2015-01-19 21:46:03 +02:00
panelWorldView - > addChildToPanel ( // help text is wrong for this button
2015-01-17 14:41:59 +02:00
makeButton ( 291 , std : : bind ( & CAdvMapInt : : fworldViewScale1x , this ) , worldViewScale1xConfig , SDLK_1 ) , ACTIVATE | DEACTIVATE ) ;
2015-01-13 21:57:41 +02:00
config : : ButtonInfo worldViewScale2xConfig = config : : ButtonInfo ( ) ;
worldViewScale2xConfig . defName = " VWMAG2.DEF " ;
worldViewScale2xConfig . x = screen - > w - 191 + 63 ;
worldViewScale2xConfig . y = 23 + 195 ;
worldViewScale2xConfig . playerColoured = false ;
2015-01-19 21:46:03 +02:00
panelWorldView - > addChildToPanel ( // help text is wrong for this button
2015-01-17 14:41:59 +02:00
makeButton ( 291 , std : : bind ( & CAdvMapInt : : fworldViewScale2x , this ) , worldViewScale2xConfig , SDLK_2 ) , ACTIVATE | DEACTIVATE ) ;
2015-01-13 21:57:41 +02:00
config : : ButtonInfo worldViewScale4xConfig = config : : ButtonInfo ( ) ;
worldViewScale4xConfig . defName = " VWMAG4.DEF " ;
worldViewScale4xConfig . x = screen - > w - 191 + 126 ;
worldViewScale4xConfig . y = 23 + 195 ;
worldViewScale4xConfig . playerColoured = false ;
2015-01-19 21:46:03 +02:00
panelWorldView - > addChildToPanel ( // help text is wrong for this button
2015-01-17 14:41:59 +02:00
makeButton ( 291 , std : : bind ( & CAdvMapInt : : fworldViewScale4x , this ) , worldViewScale4xConfig , SDLK_4 ) , ACTIVATE | DEACTIVATE ) ;
2015-01-13 21:57:41 +02:00
config : : ButtonInfo worldViewUndergroundConfig = config : : ButtonInfo ( ) ;
worldViewUndergroundConfig . defName = " IAM010.DEF " ;
worldViewUndergroundConfig . additionalDefs . push_back ( " IAM003.DEF " ) ;
worldViewUndergroundConfig . x = screen - > w - 115 ;
worldViewUndergroundConfig . y = 343 + 195 ;
worldViewUndergroundConfig . playerColoured = true ;
2015-01-17 12:56:12 +02:00
worldViewUnderground = makeButton ( 294 , std : : bind ( & CAdvMapInt : : fswitchLevel , this ) , worldViewUndergroundConfig , SDLK_u ) ;
2015-01-15 01:22:20 +02:00
panelWorldView - > addChildColorableButton ( worldViewUnderground ) ;
2015-01-13 21:57:41 +02:00
2010-07-29 01:24:16 +03:00
setPlayer ( LOCPLINT - > playerID ) ;
2015-01-13 21:57:41 +02:00
int iconColorMultiplier = player . getNum ( ) * 19 ;
2015-01-15 01:22:20 +02:00
int wvLeft = heroList . pos . x - 2 ; // TODO correct drawing position
2016-10-18 04:46:07 +02:00
//int wvTop = 195;
2015-01-13 21:57:41 +02:00
for ( int i = 0 ; i < 5 ; + + i )
{
2016-10-18 04:46:07 +02:00
panelWorldView - > addChildIcon ( std : : pair < int , Point > ( i , Point ( 5 , 58 + i * 20 ) ) , iconColorMultiplier ) ;
2018-04-07 13:34:11 +02:00
panelWorldView - > addChildToPanel ( std : : make_shared < CLabel > ( wvLeft + 45 , 263 + i * 20 , EFonts : : FONT_SMALL , EAlignment : : TOPLEFT ,
2015-01-13 21:57:41 +02:00
Colors : : WHITE , CGI - > generaltexth - > allTexts [ 612 + i ] ) ) ;
}
for ( int i = 0 ; i < 7 ; + + i )
{
2016-10-18 04:46:07 +02:00
panelWorldView - > addChildIcon ( std : : pair < int , Point > ( i + 5 , Point ( 5 , 182 + i * 20 ) ) , iconColorMultiplier ) ;
panelWorldView - > addChildIcon ( std : : pair < int , Point > ( i + 12 , Point ( 160 , 182 + i * 20 ) ) , iconColorMultiplier ) ;
2018-04-07 13:34:11 +02:00
panelWorldView - > addChildToPanel ( std : : make_shared < CLabel > ( wvLeft + 45 , 387 + i * 20 , EFonts : : FONT_SMALL , EAlignment : : TOPLEFT ,
2015-01-13 21:57:41 +02:00
Colors : : WHITE , CGI - > generaltexth - > allTexts [ 619 + i ] ) ) ;
}
2018-04-07 13:34:11 +02:00
panelWorldView - > addChildToPanel ( std : : make_shared < CLabel > ( wvLeft + 5 , 367 , EFonts : : FONT_SMALL , EAlignment : : TOPLEFT ,
2015-01-13 21:57:41 +02:00
Colors : : WHITE , CGI - > generaltexth - > allTexts [ 617 ] ) ) ;
2018-04-07 13:34:11 +02:00
panelWorldView - > addChildToPanel ( std : : make_shared < CLabel > ( wvLeft + 45 , 367 , EFonts : : FONT_SMALL , EAlignment : : TOPLEFT ,
2015-01-13 21:57:41 +02:00
Colors : : WHITE , CGI - > generaltexth - > allTexts [ 618 ] ) ) ;
2015-01-15 01:22:20 +02:00
activeMapPanel = panelMain ;
2015-10-31 19:23:13 +02:00
2015-01-19 22:48:52 +02:00
changeMode ( EAdvMapMode : : NORMAL ) ;
2015-01-13 21:57:41 +02:00
2014-08-03 14:16:19 +03:00
underground - > block ( ! CGI - > mh - > map - > twoLevel ) ;
2015-02-13 23:52:00 +02:00
questlog - > block ( ! CGI - > mh - > map - > quests . size ( ) ) ;
2015-01-13 21:57:41 +02:00
worldViewUnderground - > block ( ! CGI - > mh - > map - > twoLevel ) ;
2015-02-16 22:45:16 +02:00
addUsedEvents ( MOVE ) ;
2007-08-06 07:03:34 +03:00
}
2009-01-12 22:05:56 +02:00
CAdvMapInt : : ~ CAdvMapInt ( )
{
SDL_FreeSurface ( bg ) ;
}
2007-08-06 07:03:34 +03:00
void CAdvMapInt : : fshowOverview ( )
{
2018-07-25 00:36:48 +02:00
GH . pushIntT < CKingdomInterface > ( ) ;
2007-08-06 07:03:34 +03:00
}
2015-01-13 21:57:41 +02:00
void CAdvMapInt : : fworldViewBack ( )
{
changeMode ( EAdvMapMode : : NORMAL ) ;
CGI - > mh - > discardWorldViewCache ( ) ;
2015-01-17 14:41:59 +02:00
auto hero = curHero ( ) ;
if ( hero )
centerOn ( hero ) ;
2015-01-13 21:57:41 +02:00
}
void CAdvMapInt : : fworldViewScale1x ( )
{
// TODO set corresponding scale button to "selected" mode
2015-01-17 12:56:12 +02:00
changeMode ( EAdvMapMode : : WORLD_VIEW , 0.22f ) ;
2015-01-13 21:57:41 +02:00
}
void CAdvMapInt : : fworldViewScale2x ( )
{
2015-01-17 12:56:12 +02:00
changeMode ( EAdvMapMode : : WORLD_VIEW , 0.36f ) ;
2015-01-13 21:57:41 +02:00
}
void CAdvMapInt : : fworldViewScale4x ( )
{
2015-01-17 12:56:12 +02:00
changeMode ( EAdvMapMode : : WORLD_VIEW , 0.5f ) ;
2015-01-13 21:57:41 +02:00
}
2015-01-17 12:56:12 +02:00
void CAdvMapInt : : fswitchLevel ( )
2015-01-13 21:57:41 +02:00
{
2015-01-17 12:56:12 +02:00
// with support for future multi-level maps :)
2022-09-18 16:39:10 +02:00
int maxLevels = CGI - > mh - > map - > levels ( ) ;
2015-01-17 12:56:12 +02:00
if ( maxLevels < 2 )
2015-01-13 21:57:41 +02:00
return ;
2015-01-17 12:56:12 +02:00
position . z = ( position . z + 1 ) % maxLevels ;
underground - > setIndex ( position . z , true ) ;
underground - > redraw ( ) ;
worldViewUnderground - > setIndex ( position . z , true ) ;
worldViewUnderground - > redraw ( ) ;
2015-01-13 21:57:41 +02:00
2007-08-06 07:03:34 +03:00
updateScreen = true ;
2012-06-13 16:04:06 +03:00
minimap . setLevel ( position . z ) ;
2015-01-17 12:56:12 +02:00
if ( mode = = EAdvMapMode : : WORLD_VIEW )
terrain . redraw ( ) ;
2007-08-06 07:03:34 +03:00
}
void CAdvMapInt : : fshowQuestlog ( )
{
2012-07-06 22:12:04 +03:00
LOCPLINT - > showQuestLog ( ) ;
2007-08-06 07:03:34 +03:00
}
void CAdvMapInt : : fsleepWake ( )
{
2011-09-24 19:46:23 +03:00
const CGHeroInstance * h = curHero ( ) ;
if ( ! h )
return ;
bool newSleep = ! isHeroSleeping ( h ) ;
setHeroSleeping ( h , newSleep ) ;
updateSleepWake ( h ) ;
if ( newSleep )
2011-10-04 22:43:49 +03:00
{
2011-09-24 19:46:23 +03:00
fnextHero ( ) ;
2011-10-04 22:43:49 +03:00
2012-01-12 18:23:00 +03:00
//moveHero.block(true);
2011-10-04 22:43:49 +03:00
//uncomment to enable original HoMM3 behaviour:
//move button is disabled for hero going to sleep, even though it's enabled when you reselect him
}
2007-08-06 07:03:34 +03:00
}
2011-09-24 19:46:23 +03:00
2007-08-06 07:03:34 +03:00
void CAdvMapInt : : fmoveHero ( )
2012-01-12 18:23:00 +03:00
{
2010-03-21 00:17:19 +02:00
const CGHeroInstance * h = curHero ( ) ;
2015-02-09 17:03:24 +02:00
if ( ! h | | ! terrain . currentPath | | ! CGI - > mh - > canStartHeroMovement ( ) )
2007-10-14 00:27:03 +03:00
return ;
2009-04-21 01:57:07 +03:00
2010-03-21 00:17:19 +02:00
LOCPLINT - > moveHero ( h , * terrain . currentPath ) ;
2007-08-06 07:03:34 +03:00
}
2009-06-11 20:21:06 +03:00
2007-08-06 07:03:34 +03:00
void CAdvMapInt : : fshowSpellbok ( )
{
2010-03-21 00:17:19 +02:00
if ( ! curHero ( ) ) //checking necessary values
2008-09-10 15:19:48 +03:00
return ;
2010-03-21 00:17:19 +02:00
centerOn ( selection ) ;
2012-01-12 18:23:00 +03:00
2018-07-25 00:36:48 +02:00
GH . pushIntT < CSpellWindow > ( curHero ( ) , LOCPLINT , false ) ;
2007-08-06 07:03:34 +03:00
}
2009-06-11 20:21:06 +03:00
2007-08-06 07:03:34 +03:00
void CAdvMapInt : : fadventureOPtions ( )
{
2018-07-25 00:36:48 +02:00
GH . pushIntT < CAdventureOptions > ( ) ;
2007-08-06 07:03:34 +03:00
}
2009-06-11 20:21:06 +03:00
2007-08-06 07:03:34 +03:00
void CAdvMapInt : : fsystemOptions ( )
{
2018-07-25 00:36:48 +02:00
GH . pushIntT < CSystemOptionsWindow > ( ) ;
2007-08-06 07:03:34 +03:00
}
2009-06-11 20:21:06 +03:00
2007-08-06 07:03:34 +03:00
void CAdvMapInt : : fnextHero ( )
{
2012-06-13 16:04:06 +03:00
auto hero = dynamic_cast < const CGHeroInstance * > ( selection ) ;
int next = getNextHeroIndex ( vstd : : find_pos ( LOCPLINT - > wanderingHeroes , hero ) ) ;
2011-10-04 22:43:49 +03:00
if ( next < 0 )
return ;
2012-06-13 16:04:06 +03:00
select ( LOCPLINT - > wanderingHeroes [ next ] , true ) ;
2007-08-06 07:03:34 +03:00
}
2009-06-11 20:21:06 +03:00
2007-08-06 07:03:34 +03:00
void CAdvMapInt : : fendTurn ( )
{
2011-05-30 02:49:25 +03:00
if ( ! LOCPLINT - > makingTurn )
return ;
2011-09-24 19:46:23 +03:00
2018-02-24 15:49:42 +02:00
if ( settings [ " adventure " ] [ " heroReminder " ] . Bool ( ) )
2012-01-12 18:23:00 +03:00
{
2018-02-24 15:49:42 +02:00
for ( auto hero : LOCPLINT - > wanderingHeroes )
{
if ( ! isHeroSleeping ( hero ) & & hero - > movement > 0 )
2012-01-12 18:23:00 +03:00
{
2018-02-24 15:49:42 +02:00
// Only show hero reminder if conditions met:
// - There still movement points
// - Hero don't have a path or there not points for first step on path
auto path = LOCPLINT - > getAndVerifyPath ( hero ) ;
if ( ! path | | path - > nodes . size ( ) < 2 | | ! path - > nodes [ path - > nodes . size ( ) - 2 ] . turns )
{
2018-04-07 13:34:11 +02:00
LOCPLINT - > showYesNoDialog ( CGI - > generaltexth - > allTexts [ 55 ] , std : : bind ( & CAdvMapInt : : endingTurn , this ) , nullptr ) ;
2018-02-24 15:49:42 +02:00
return ;
}
2012-01-12 18:23:00 +03:00
}
2018-02-24 15:49:42 +02:00
}
2012-01-12 18:23:00 +03:00
}
2011-09-24 19:46:23 +03:00
endingTurn ( ) ;
}
void CAdvMapInt : : updateSleepWake ( const CGHeroInstance * h )
{
2014-08-03 14:16:19 +03:00
sleepWake - > block ( ! h ) ;
2011-09-24 19:46:23 +03:00
if ( ! h )
2012-01-12 18:23:00 +03:00
return ;
2011-09-24 19:46:23 +03:00
bool state = isHeroSleeping ( h ) ;
2014-08-03 14:16:19 +03:00
sleepWake - > setIndex ( state ? 1 : 0 , true ) ;
sleepWake - > assignedKeys . clear ( ) ;
sleepWake - > assignedKeys . insert ( state ? SDLK_w : SDLK_z ) ;
2007-08-06 07:03:34 +03:00
}
2011-10-04 22:43:49 +03:00
void CAdvMapInt : : updateMoveHero ( const CGHeroInstance * h , tribool hasPath )
{
2016-01-15 18:30:43 +02:00
if ( ! h )
2011-10-04 22:43:49 +03:00
{
2014-08-03 14:16:19 +03:00
moveHero - > block ( true ) ;
2011-10-04 22:43:49 +03:00
return ;
}
2016-01-15 18:30:43 +02:00
//default value is for everywhere but CPlayerInterface::moveHero, because paths are not updated from there immediately
if ( boost : : logic : : indeterminate ( hasPath ) )
hasPath = LOCPLINT - > paths [ h ] . nodes . size ( ) ? true : false ;
2019-01-24 16:45:40 +02:00
moveHero - > block ( ! ( bool ) hasPath | | ( h - > movement = = 0 ) ) ;
2011-10-04 22:43:49 +03:00
}
2015-12-06 02:12:39 +02:00
void CAdvMapInt : : updateSpellbook ( const CGHeroInstance * h )
{
spellbook - > block ( ! h ) ;
}
2011-10-04 22:43:49 +03:00
int CAdvMapInt : : getNextHeroIndex ( int startIndex )
{
if ( LOCPLINT - > wanderingHeroes . size ( ) = = 0 )
return - 1 ;
if ( startIndex < 0 )
startIndex = 0 ;
int i = startIndex ;
2012-01-12 18:23:00 +03:00
do
2011-10-04 22:43:49 +03:00
{
i + + ;
if ( i > = LOCPLINT - > wanderingHeroes . size ( ) )
i = 0 ;
2012-01-12 18:23:00 +03:00
}
2011-10-04 22:43:49 +03:00
while ( ( ( LOCPLINT - > wanderingHeroes [ i ] - > movement = = 0 ) | | isHeroSleeping ( LOCPLINT - > wanderingHeroes [ i ] ) ) & & ( i ! = startIndex ) ) ;
2011-11-27 21:55:11 +03:00
if ( ( LOCPLINT - > wanderingHeroes [ i ] - > movement ! = 0 ) & & ! isHeroSleeping ( LOCPLINT - > wanderingHeroes [ i ] ) )
2011-10-04 22:43:49 +03:00
return i ;
else
return - 1 ;
}
void CAdvMapInt : : updateNextHero ( const CGHeroInstance * h )
{
2012-06-13 16:04:06 +03:00
int start = vstd : : find_pos ( LOCPLINT - > wanderingHeroes , h ) ;
2011-10-04 22:43:49 +03:00
int next = getNextHeroIndex ( start ) ;
if ( next < 0 )
{
2014-08-03 14:16:19 +03:00
nextHero - > block ( true ) ;
2011-10-04 22:43:49 +03:00
return ;
}
const CGHeroInstance * nextH = LOCPLINT - > wanderingHeroes [ next ] ;
bool noActiveHeroes = ( next = = start ) & & ( ( nextH - > movement = = 0 ) | | isHeroSleeping ( nextH ) ) ;
2014-08-03 14:16:19 +03:00
nextHero - > block ( noActiveHeroes ) ;
2011-10-04 22:43:49 +03:00
}
2008-01-20 14:34:39 +02:00
void CAdvMapInt : : activate ( )
{
2012-06-02 18:16:54 +03:00
CIntObject : : activate ( ) ;
2012-06-17 01:40:28 +03:00
if ( ! ( active & KEYBOARD ) )
2012-10-06 23:35:04 +03:00
CIntObject : : activate ( KEYBOARD ) ;
2012-02-22 16:41:27 +03:00
2009-05-25 02:21:55 +03:00
screenBuf = screen ;
2018-08-26 18:09:56 +02:00
GH . statusbar = statusbar ;
2022-10-05 17:04:51 +02:00
if ( LOCPLINT )
LOCPLINT - > cingconsole - > activate ( ) ;
2012-02-22 16:41:27 +03:00
if ( ! duringAITurn )
{
2015-01-15 01:22:20 +02:00
activeMapPanel - > activate ( ) ;
2015-01-13 21:57:41 +02:00
if ( mode = = EAdvMapMode : : NORMAL )
{
heroList . activate ( ) ;
townList . activate ( ) ;
infoBar . activate ( ) ;
}
2012-02-22 16:41:27 +03:00
minimap . activate ( ) ;
terrain . activate ( ) ;
GH . fakeMouseMove ( ) ; //to restore the cursor
}
2008-01-20 14:34:39 +02:00
}
2015-01-13 21:57:41 +02:00
2008-01-20 14:34:39 +02:00
void CAdvMapInt : : deactivate ( )
{
2012-06-02 18:16:54 +03:00
CIntObject : : deactivate ( ) ;
2012-02-22 16:41:27 +03:00
if ( ! duringAITurn )
{
scrollingDir = 0 ;
2010-02-24 15:03:36 +02:00
2012-12-14 18:32:53 +03:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 0 ) ;
2015-01-15 01:22:20 +02:00
activeMapPanel - > deactivate ( ) ;
2015-01-13 21:57:41 +02:00
if ( mode = = EAdvMapMode : : NORMAL )
{
heroList . deactivate ( ) ;
townList . deactivate ( ) ;
infoBar . deactivate ( ) ;
}
2012-02-22 16:41:27 +03:00
minimap . deactivate ( ) ;
terrain . deactivate ( ) ;
}
2008-01-20 14:34:39 +02:00
}
2015-01-13 21:57:41 +02:00
2011-12-22 16:05:19 +03:00
void CAdvMapInt : : showAll ( SDL_Surface * to )
2007-08-04 22:01:22 +03:00
{
2009-04-14 15:47:09 +03:00
blitAt ( bg , 0 , 0 , to ) ;
2010-02-20 15:24:38 +02:00
if ( state ! = INGAME )
return ;
2015-01-13 21:57:41 +02:00
switch ( mode )
{
case EAdvMapMode : : NORMAL :
heroList . showAll ( to ) ;
townList . showAll ( to ) ;
infoBar . showAll ( to ) ;
break ;
case EAdvMapMode : : WORLD_VIEW :
terrain . showAll ( to ) ;
break ;
}
2015-01-15 01:22:20 +02:00
activeMapPanel - > showAll ( to ) ;
2009-04-14 15:47:09 +03:00
2008-08-28 20:36:34 +03:00
updateScreen = true ;
2015-01-13 21:57:41 +02:00
minimap . showAll ( to ) ;
2009-04-14 15:47:09 +03:00
show ( to ) ;
2007-08-20 00:12:55 +03:00
2015-01-13 21:57:41 +02:00
2018-04-07 13:34:11 +02:00
resdatabar . showAll ( to ) ;
2007-09-16 20:21:23 +03:00
2018-08-26 18:09:56 +02:00
statusbar - > show ( to ) ;
2007-08-07 14:54:50 +03:00
2015-11-08 21:16:58 +02:00
LOCPLINT - > cingconsole - > show ( to ) ;
2007-08-04 22:01:22 +03:00
}
2011-09-24 19:46:23 +03:00
bool CAdvMapInt : : isHeroSleeping ( const CGHeroInstance * hero )
{
if ( ! hero )
return false ;
return vstd : : contains ( LOCPLINT - > sleepingHeroes , hero ) ;
}
void CAdvMapInt : : setHeroSleeping ( const CGHeroInstance * hero , bool sleep )
{
if ( sleep )
2014-10-03 23:34:13 +03:00
LOCPLINT - > sleepingHeroes . push_back ( hero ) ; //FIXME: should we check for existence?
2011-09-24 19:46:23 +03:00
else
LOCPLINT - > sleepingHeroes - = hero ;
2013-06-26 14:18:27 +03:00
updateNextHero ( nullptr ) ;
2011-09-24 19:46:23 +03:00
}
2011-12-22 16:05:19 +03:00
void CAdvMapInt : : show ( SDL_Surface * to )
2007-08-04 22:01:22 +03:00
{
2010-02-20 15:24:38 +02:00
if ( state ! = INGAME )
return ;
2008-08-28 20:36:34 +03:00
+ + animValHitCount ; //for animations
2019-05-26 17:11:57 +02:00
if ( animValHitCount % 2 = = 0 )
{
+ + heroAnim ;
}
2008-08-28 20:36:34 +03:00
if ( animValHitCount = = 8 )
{
2008-11-30 16:08:07 +02:00
CGI - > mh - > updateWater ( ) ;
2008-08-28 20:36:34 +03:00
animValHitCount = 0 ;
+ + anim ;
updateScreen = true ;
}
2009-02-11 19:03:30 +02:00
2017-05-25 19:57:20 +02:00
if ( swipeEnabled )
2008-08-28 20:36:34 +03:00
{
2017-05-25 19:57:20 +02:00
handleSwipeUpdate ( ) ;
}
2021-03-13 13:08:13 +02:00
# if defined(VCMI_ANDROID) || defined(VCMI_IOS) // on mobile, map-moving mode is exclusive (TODO technically it might work with both enabled; to be checked)
2017-05-25 19:57:20 +02:00
else
2021-03-13 13:08:13 +02:00
# endif
2017-05-25 19:57:20 +02:00
{
handleMapScrollingUpdate ( ) ;
2008-08-28 20:36:34 +03:00
}
2017-05-25 19:57:20 +02:00
2016-10-18 03:09:52 +02:00
for ( int i = 0 ; i < 4 ; i + + )
2017-06-03 07:25:10 +02:00
{
if ( settings [ " session " ] [ " spectate " ] . Bool ( ) )
gems [ i ] - > setFrame ( PlayerColor ( 1 ) . getNum ( ) ) ;
else
gems [ i ] - > setFrame ( LOCPLINT - > playerID . getNum ( ) ) ;
}
2008-08-28 20:36:34 +03:00
if ( updateScreen )
2008-11-30 16:08:07 +02:00
{
2013-12-20 18:00:48 +03:00
int3 betterPos = LOCPLINT - > repairScreenPos ( position ) ;
if ( betterPos ! = position )
{
2017-08-10 18:39:27 +02:00
logGlobal - > warn ( " Incorrect position for adventure map! " ) ;
2013-12-20 18:00:48 +03:00
position = betterPos ;
}
2009-04-14 15:47:09 +03:00
terrain . show ( to ) ;
2016-10-18 03:09:52 +02:00
for ( int i = 0 ; i < 4 ; i + + )
gems [ i ] - > showAll ( to ) ;
2012-01-12 18:23:00 +03:00
updateScreen = false ;
2015-11-08 21:16:58 +02:00
LOCPLINT - > cingconsole - > show ( to ) ;
2008-08-28 20:36:34 +03:00
}
2015-01-31 00:37:28 +02:00
else if ( terrain . needsAnimUpdate ( ) )
{
terrain . showAnim ( to ) ;
2016-10-18 03:09:52 +02:00
for ( int i = 0 ; i < 4 ; i + + )
gems [ i ] - > showAll ( to ) ;
2015-01-31 00:37:28 +02:00
}
2015-10-31 19:23:13 +02:00
2012-06-13 16:04:06 +03:00
infoBar . show ( to ) ;
2018-08-26 18:09:56 +02:00
statusbar - > showAll ( to ) ;
2007-09-14 16:11:10 +03:00
}
2017-05-25 19:57:20 +02:00
void CAdvMapInt : : handleMapScrollingUpdate ( )
{
2020-10-01 10:38:06 +02:00
int scrollSpeed = static_cast < int > ( settings [ " adventure " ] [ " scrollSpeed " ] . Float ( ) ) ;
2017-05-25 19:57:20 +02:00
//if advmap needs updating AND (no dialog is shown OR ctrl is pressed)
if ( ( animValHitCount % ( 4 / scrollSpeed ) ) = = 0
2018-07-25 00:36:48 +02:00
& & ( ( GH . topInt ( ) . get ( ) = = this ) | | isCtrlKeyDown ( ) ) )
2017-05-25 19:57:20 +02:00
{
if ( ( scrollingDir & LEFT ) & & ( position . x > - CGI - > mh - > frameW ) )
position . x - - ;
if ( ( scrollingDir & RIGHT ) & & ( position . x < CGI - > mh - > map - > width - CGI - > mh - > tilesW + CGI - > mh - > frameW ) )
position . x + + ;
if ( ( scrollingDir & UP ) & & ( position . y > - CGI - > mh - > frameH ) )
position . y - - ;
if ( ( scrollingDir & DOWN ) & & ( position . y < CGI - > mh - > map - > height - CGI - > mh - > tilesH + CGI - > mh - > frameH ) )
position . y + + ;
if ( scrollingDir )
{
setScrollingCursor ( scrollingDir ) ;
scrollingState = true ;
updateScreen = true ;
minimap . redraw ( ) ;
if ( mode = = EAdvMapMode : : WORLD_VIEW )
terrain . redraw ( ) ;
}
else if ( scrollingState )
{
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 0 ) ;
scrollingState = false ;
}
}
}
void CAdvMapInt : : handleSwipeUpdate ( )
{
if ( swipeMovementRequested )
{
2017-06-07 22:42:41 +02:00
auto fixedPos = LOCPLINT - > repairScreenPos ( swipeTargetPosition ) ;
position . x = fixedPos . x ;
position . y = fixedPos . y ;
2017-05-25 19:57:20 +02:00
CCS - > curh - > changeGraphic ( ECursor : : DEFAULT , 0 ) ;
updateScreen = true ;
minimap . redraw ( ) ;
swipeMovementRequested = false ;
}
}
2008-01-31 23:35:30 +02:00
void CAdvMapInt : : selectionChanged ( )
{
2012-06-13 16:04:06 +03:00
const CGTownInstance * to = LOCPLINT - > towns [ townList . getSelectedIndex ( ) ] ;
2012-09-05 15:49:23 +03:00
if ( selection ! = to )
select ( to ) ;
2008-01-31 23:35:30 +02:00
}
2014-09-18 17:53:41 +03:00
2017-07-15 13:08:20 +02:00
void CAdvMapInt : : centerOn ( int3 on , bool fade )
2007-09-14 16:11:10 +03:00
{
2012-06-13 16:04:06 +03:00
bool switchedLevels = on . z ! = position . z ;
2015-10-31 19:23:13 +02:00
2015-02-02 18:42:42 +02:00
if ( fade )
2015-01-31 00:37:28 +02:00
{
terrain . fadeFromCurrentView ( ) ;
}
2012-06-13 16:04:06 +03:00
2015-01-17 14:41:59 +02:00
switch ( mode )
{
default :
case EAdvMapMode : : NORMAL :
on . x - = CGI - > mh - > frameW ; // is this intentional? frame size doesn't really have to correspond to camera size...
on . y - = CGI - > mh - > frameH ;
break ;
case EAdvMapMode : : WORLD_VIEW :
2020-10-01 10:38:06 +02:00
on . x - = static_cast < si32 > ( CGI - > mh - > tilesW / 2 / worldViewScale ) ;
on . y - = static_cast < si32 > ( CGI - > mh - > tilesH / 2 / worldViewScale ) ;
2015-01-17 14:41:59 +02:00
break ;
}
2012-01-12 18:23:00 +03:00
2009-02-02 15:05:19 +02:00
on = LOCPLINT - > repairScreenPos ( on ) ;
2007-09-14 16:11:10 +03:00
2012-06-13 16:04:06 +03:00
position = on ;
updateScreen = true ;
2014-08-03 14:16:19 +03:00
underground - > setIndex ( on . z , true ) ; //change underground switch button image
underground - > redraw ( ) ;
2015-01-17 14:41:59 +02:00
worldViewUnderground - > setIndex ( on . z , true ) ;
worldViewUnderground - > redraw ( ) ;
2012-06-13 16:04:06 +03:00
if ( switchedLevels )
minimap . setLevel ( position . z ) ;
2014-09-18 17:53:41 +03:00
minimap . redraw ( ) ;
2015-01-13 21:57:41 +02:00
if ( mode = = EAdvMapMode : : WORLD_VIEW )
terrain . redraw ( ) ;
2007-09-14 16:11:10 +03:00
}
2010-03-21 00:17:19 +02:00
2017-07-15 13:08:20 +02:00
void CAdvMapInt : : centerOn ( const CGObjectInstance * obj , bool fade )
2010-03-21 00:17:19 +02:00
{
2015-02-02 18:42:42 +02:00
centerOn ( obj - > getSightCenter ( ) , fade ) ;
2010-03-21 00:17:19 +02:00
}
2008-10-19 16:17:32 +03:00
void CAdvMapInt : : keyPressed ( const SDL_KeyboardEvent & key )
{
2015-01-17 14:41:59 +02:00
if ( mode = = EAdvMapMode : : WORLD_VIEW )
return ;
2009-09-07 05:29:44 +03:00
ui8 Dir = 0 ;
2015-06-21 00:38:05 +02:00
SDL_Keycode k = key . keysym . sym ;
2010-03-21 00:17:19 +02:00
const CGHeroInstance * h = curHero ( ) ; //selected hero
const CGTownInstance * t = curTown ( ) ; //selected town
2009-09-07 05:29:44 +03:00
switch ( k )
2008-10-19 16:17:32 +03:00
{
2012-04-08 04:15:18 +03:00
case SDLK_g :
if ( key . state ! = SDL_PRESSED | | GH . topInt ( ) - > type & BLOCK_ADV_HOTKEYS )
return ;
{
//find first town with tavern
2013-06-26 14:18:27 +03:00
auto itr = range : : find_if ( LOCPLINT - > towns , [ ] ( const CGTownInstance * town )
{
return town - > hasBuilt ( BuildingID : : TAVERN ) ;
} ) ;
2012-04-08 04:15:18 +03:00
if ( itr ! = LOCPLINT - > towns . end ( ) )
LOCPLINT - > showThievesGuildWindow ( * itr ) ;
else
2022-09-18 14:39:08 +02:00
LOCPLINT - > showInfoDialog ( CGI - > generaltexth - > localizedTexts [ " adventureMap " ] [ " noTownWithTavern " ] . String ( ) ) ;
2012-04-08 04:15:18 +03:00
}
return ;
2012-01-12 18:23:00 +03:00
case SDLK_i :
2009-12-28 06:08:24 +02:00
if ( isActive ( ) )
2009-08-27 11:04:32 +03:00
CAdventureOptions : : showScenarioInfo ( ) ;
return ;
2012-04-09 05:53:50 +03:00
case SDLK_l :
if ( isActive ( ) )
LOCPLINT - > proposeLoadingGame ( ) ;
return ;
2012-01-12 18:23:00 +03:00
case SDLK_s :
2016-01-28 09:26:40 +02:00
if ( isActive ( ) & & key . type = = SDL_KEYUP )
2018-07-25 00:36:48 +02:00
GH . pushIntT < CSavingScreen > ( ) ;
2009-08-27 11:04:32 +03:00
return ;
2012-01-12 18:23:00 +03:00
case SDLK_d :
2010-03-01 21:04:07 +02:00
{
2022-09-29 14:52:28 +02:00
if ( h & & isActive ( ) & & LOCPLINT - > makingTurn & & key . state = = SDL_PRESSED )
2010-03-01 21:04:07 +02:00
LOCPLINT - > tryDiggging ( h ) ;
return ;
}
2012-01-12 18:23:00 +03:00
case SDLK_p :
2010-03-01 21:04:07 +02:00
if ( isActive ( ) )
LOCPLINT - > showPuzzleMap ( ) ;
return ;
2015-01-31 11:57:13 +02:00
case SDLK_v :
if ( isActive ( ) )
LOCPLINT - > viewWorldMap ( ) ;
return ;
2012-04-08 06:06:27 +03:00
case SDLK_r :
if ( isActive ( ) & & LOCPLINT - > ctrlPressed ( ) )
{
2022-09-18 14:39:08 +02:00
LOCPLINT - > showYesNoDialog ( CGI - > generaltexth - > localizedTexts [ " adventureMap " ] [ " confirmRestartGame " ] . String ( ) ,
2018-04-07 13:34:11 +02:00
[ ] ( ) { LOCPLINT - > sendCustomEvent ( EUserEvent : : RESTART_GAME ) ; } , nullptr ) ;
2012-04-08 06:06:27 +03:00
}
return ;
2009-03-27 01:05:40 +02:00
case SDLK_SPACE : //space - try to revisit current object with selected hero
{
2012-01-12 18:23:00 +03:00
if ( ! isActive ( ) )
2009-05-22 22:20:30 +03:00
return ;
2009-03-27 01:05:40 +02:00
if ( h & & key . state = = SDL_PRESSED )
{
2016-11-25 21:12:22 +02:00
auto unlockPim = vstd : : makeUnlockGuard ( * CPlayerInterface : : pim ) ;
2013-05-27 13:53:28 +03:00
//TODO!!!!!!! possible freeze, when GS mutex is locked and network thread can't apply package
2015-01-13 21:57:41 +02:00
//this thread leaves scope and tries to lock pim while holding gs,
2013-05-27 13:53:28 +03:00
//network thread tries to lock gs (appluy cl) while holding pim
//this thread should first lock pim, however gs locking/unlocking is done inside cb
2009-03-27 01:05:40 +02:00
LOCPLINT - > cb - > moveHero ( h , h - > pos ) ;
}
}
return ;
2009-05-30 19:00:26 +03:00
case SDLK_RETURN :
{
2012-01-12 18:23:00 +03:00
if ( ! isActive ( ) | | ! selection | | key . state ! = SDL_PRESSED )
2009-05-30 19:00:26 +03:00
return ;
2010-03-21 00:17:19 +02:00
if ( h )
LOCPLINT - > openHeroWindow ( h ) ;
else if ( t )
LOCPLINT - > openTownWindow ( t ) ;
2009-05-30 19:00:26 +03:00
return ;
}
2010-06-01 00:14:15 +03:00
case SDLK_ESCAPE :
{
2018-07-25 00:36:48 +02:00
if ( isActive ( ) | | GH . topInt ( ) . get ( ) ! = this | | ! spellBeingCasted | | key . state ! = SDL_PRESSED )
2010-06-01 00:14:15 +03:00
return ;
leaveCastingMode ( ) ;
return ;
}
2009-07-01 10:04:21 +03:00
case SDLK_t :
{
//act on key down if marketplace windows is not already opened
2012-04-08 04:15:18 +03:00
if ( key . state ! = SDL_PRESSED | | GH . topInt ( ) - > type & BLOCK_ADV_HOTKEYS )
return ;
2009-07-01 10:04:21 +03:00
2012-04-08 04:15:18 +03:00
if ( LOCPLINT - > ctrlPressed ( ) ) //CTRL + T => open marketplace
2010-05-18 10:01:54 +03:00
{
2012-04-08 04:15:18 +03:00
//check if we have any marketplace
2013-06-26 14:18:27 +03:00
const CGTownInstance * townWithMarket = nullptr ;
2013-06-29 16:05:48 +03:00
for ( const CGTownInstance * t : LOCPLINT - > cb - > getTownsInfo ( ) )
2010-05-18 10:01:54 +03:00
{
2013-02-11 02:24:57 +03:00
if ( t - > hasBuilt ( BuildingID : : MARKETPLACE ) )
2012-04-08 04:15:18 +03:00
{
townWithMarket = t ;
break ;
}
2010-05-18 10:01:54 +03:00
}
2009-07-01 10:04:21 +03:00
2012-04-08 04:15:18 +03:00
if ( townWithMarket ) //if any town has marketplace, open window
2018-07-25 00:36:48 +02:00
GH . pushIntT < CMarketplaceWindow > ( townWithMarket ) ;
2012-04-08 04:15:18 +03:00
else //if not - complain
2022-09-18 14:39:08 +02:00
LOCPLINT - > showInfoDialog ( CGI - > generaltexth - > localizedTexts [ " adventureMap " ] [ " noTownWithMarket " ] . String ( ) ) ;
2012-04-08 04:15:18 +03:00
}
else if ( isActive ( ) ) //no ctrl, advmapint is on the top => switch to town
{
townList . selectNext ( ) ;
}
2009-07-01 10:04:21 +03:00
return ;
}
2012-01-12 18:23:00 +03:00
default :
2009-09-07 05:29:44 +03:00
{
static const int3 directions [ ] = { int3 ( - 1 , + 1 , 0 ) , int3 ( 0 , + 1 , 0 ) , int3 ( + 1 , + 1 , 0 ) ,
int3 ( - 1 , 0 , 0 ) , int3 ( 0 , 0 , 0 ) , int3 ( + 1 , 0 , 0 ) ,
int3 ( - 1 , - 1 , 0 ) , int3 ( 0 , - 1 , 0 ) , int3 ( + 1 , - 1 , 0 ) } ;
//numpad arrow
2015-06-21 00:38:05 +02:00
if ( CGuiHandler : : isArrowKey ( k ) )
k = CGuiHandler : : arrowToNum ( k ) ;
2015-01-13 21:57:41 +02:00
2014-05-23 20:40:13 +03:00
k - = SDLK_KP_1 ;
2015-06-21 00:13:45 +02:00
2012-05-15 11:47:11 +03:00
if ( k < 0 | | k > 8 )
2009-09-07 05:29:44 +03:00
return ;
2015-06-21 00:13:45 +02:00
2015-02-09 17:03:24 +02:00
if ( ! CGI - > mh - > canStartHeroMovement ( ) )
return ;
2009-09-07 05:29:44 +03:00
2012-05-15 11:47:11 +03:00
int3 dir = directions [ k ] ;
if ( ! isActive ( ) | | LOCPLINT - > ctrlPressed ( ) ) //ctrl makes arrow move screen, not hero
{
Dir = ( dir . x < 0 ? LEFT : 0 ) |
( dir . x > 0 ? RIGHT : 0 ) |
( dir . y < 0 ? UP : 0 ) |
( dir . y > 0 ? DOWN : 0 ) ;
break ;
}
if ( ! h | | key . state ! = SDL_PRESSED )
2010-03-21 00:17:19 +02:00
break ;
2009-09-07 05:29:44 +03:00
if ( k = = 4 )
{
2010-03-21 00:17:19 +02:00
centerOn ( h ) ;
2009-09-07 05:29:44 +03:00
return ;
}
2010-02-20 15:24:38 +02:00
CGPath & path = LOCPLINT - > paths [ h ] ;
2009-09-07 05:29:44 +03:00
terrain . currentPath = & path ;
2015-02-22 09:05:24 +02:00
int3 dst = h - > getPosition ( false ) + dir ;
2015-11-02 10:14:32 +02:00
if ( dst ! = verifyPos ( dst ) | | ! LOCPLINT - > cb - > getPathsInfo ( h ) - > getPath ( path , dst ) )
2009-09-07 05:29:44 +03:00
{
2013-06-26 14:18:27 +03:00
terrain . currentPath = nullptr ;
2009-09-07 05:29:44 +03:00
return ;
}
2012-05-15 11:47:11 +03:00
if ( path . nodes . size ( ) > 2 )
updateMoveHero ( h ) ;
else
2009-09-07 05:29:44 +03:00
if ( ! path . nodes [ 0 ] . turns )
LOCPLINT - > moveHero ( h , path ) ;
}
2008-10-19 16:17:32 +03:00
return ;
}
2009-09-07 05:29:44 +03:00
if ( Dir & & key . state = = SDL_PRESSED //arrow is pressed
2009-11-29 04:46:30 +02:00
& & LOCPLINT - > ctrlPressed ( )
2009-02-11 19:03:30 +02:00
)
scrollingDir | = Dir ;
else
scrollingDir & = ~ Dir ;
2008-10-19 16:17:32 +03:00
}
2010-03-21 00:17:19 +02:00
void CAdvMapInt : : handleRightClick ( std : : string text , tribool down )
2008-08-02 18:08:03 +03:00
{
2010-03-21 00:17:19 +02:00
if ( down )
2007-10-13 23:31:50 +03:00
{
2010-03-21 00:17:19 +02:00
CRClickPopup : : createAndPush ( text ) ;
2007-10-13 23:31:50 +03:00
}
}
2007-10-07 17:51:09 +03:00
int3 CAdvMapInt : : verifyPos ( int3 ver )
{
if ( ver . x < 0 )
ver . x = 0 ;
if ( ver . y < 0 )
ver . y = 0 ;
if ( ver . z < 0 )
ver . z = 0 ;
if ( ver . x > = CGI - > mh - > sizes . x )
ver . x = CGI - > mh - > sizes . x - 1 ;
if ( ver . y > = CGI - > mh - > sizes . y )
ver . y = CGI - > mh - > sizes . y - 1 ;
if ( ver . z > = CGI - > mh - > sizes . z )
ver . z = CGI - > mh - > sizes . z - 1 ;
return ver ;
2008-08-02 18:08:03 +03:00
}
2008-08-28 20:36:34 +03:00
2017-07-15 13:08:20 +02:00
void CAdvMapInt : : select ( const CArmedInstance * sel , bool centerView )
2008-08-28 20:36:34 +03:00
{
2010-05-08 21:56:38 +03:00
assert ( sel ) ;
2014-09-21 16:42:08 +03:00
LOCPLINT - > setSelection ( sel ) ;
2008-08-28 20:36:34 +03:00
selection = sel ;
2013-06-26 14:18:27 +03:00
if ( LOCPLINT - > battleInt = = nullptr & & LOCPLINT - > makingTurn )
2012-07-15 18:34:00 +03:00
{
auto pos = sel - > visitablePos ( ) ;
auto tile = LOCPLINT - > cb - > getTile ( pos ) ;
if ( tile )
2022-09-21 11:34:23 +02:00
CCS - > musich - > playMusicFromSet ( " terrain " , tile - > terType - > name , true ) ;
2012-07-15 18:34:00 +03:00
}
2010-03-21 00:17:19 +02:00
if ( centerView )
centerOn ( sel ) ;
2009-06-11 20:21:06 +03:00
2013-06-26 14:18:27 +03:00
terrain . currentPath = nullptr ;
2012-09-23 21:01:04 +03:00
if ( sel - > ID = = Obj : : TOWN )
2008-08-28 20:36:34 +03:00
{
2012-06-13 16:04:06 +03:00
auto town = dynamic_cast < const CGTownInstance * > ( sel ) ;
2012-06-22 14:40:16 +03:00
infoBar . showTownSelection ( town ) ;
2012-06-13 16:04:06 +03:00
townList . select ( town ) ;
heroList . select ( nullptr ) ;
2013-06-26 14:18:27 +03:00
updateSleepWake ( nullptr ) ;
updateMoveHero ( nullptr ) ;
2015-12-06 02:12:39 +02:00
updateSpellbook ( nullptr ) ;
2008-08-28 20:36:34 +03:00
}
2009-06-11 20:21:06 +03:00
else //hero selected
2009-04-14 17:26:58 +03:00
{
2012-06-13 16:04:06 +03:00
auto hero = dynamic_cast < const CGHeroInstance * > ( sel ) ;
2012-06-22 14:40:16 +03:00
infoBar . showHeroSelection ( hero ) ;
2012-06-13 16:04:06 +03:00
heroList . select ( hero ) ;
townList . select ( nullptr ) ;
2009-06-11 20:21:06 +03:00
2012-06-13 16:04:06 +03:00
terrain . currentPath = LOCPLINT - > getAndVerifyPath ( hero ) ;
2011-10-04 22:43:49 +03:00
2012-06-13 16:04:06 +03:00
updateSleepWake ( hero ) ;
updateMoveHero ( hero ) ;
2015-12-06 02:12:39 +02:00
updateSpellbook ( hero ) ;
2009-04-14 17:26:58 +03:00
}
2012-06-13 16:04:06 +03:00
townList . redraw ( ) ;
heroList . redraw ( ) ;
2009-06-07 01:47:23 +03:00
}
2009-08-07 01:36:51 +03:00
void CAdvMapInt : : mouseMoved ( const SDL_MouseMotionEvent & sEvent )
{
2021-03-13 13:08:13 +02:00
# if defined(VCMI_ANDROID) || defined(VCMI_IOS)
2017-05-25 19:57:20 +02:00
if ( swipeEnabled )
return ;
# endif
2015-01-13 21:57:41 +02:00
// adventure map scrolling with mouse
2015-01-15 01:22:20 +02:00
// currently disabled in world view mode (as it is in OH3), but should work correctly if mode check is removed
2020-01-05 08:45:33 +02:00
// don't scroll if there is no window in focus - these events don't seem to correspond to the actual mouse movement
if ( ! isCtrlKeyDown ( ) & & isActive ( ) & & sEvent . windowID ! = 0 & & mode = = EAdvMapMode : : NORMAL )
2009-08-07 01:36:51 +03:00
{
if ( sEvent . x < 15 )
{
scrollingDir | = LEFT ;
}
else
{
scrollingDir & = ~ LEFT ;
}
if ( sEvent . x > screen - > w - 15 )
{
scrollingDir | = RIGHT ;
}
else
{
scrollingDir & = ~ RIGHT ;
}
if ( sEvent . y < 15 )
{
scrollingDir | = UP ;
}
else
{
scrollingDir & = ~ UP ;
}
if ( sEvent . y > screen - > h - 15 )
{
scrollingDir | = DOWN ;
}
else
{
scrollingDir & = ~ DOWN ;
}
}
2009-08-27 11:04:32 +03:00
}
2009-12-28 06:08:24 +02:00
bool CAdvMapInt : : isActive ( )
{
2009-12-29 03:07:17 +02:00
return active & ~ CIntObject : : KEYBOARD ;
2009-12-28 06:08:24 +02:00
}
2013-03-03 20:06:03 +03:00
void CAdvMapInt : : startHotSeatWait ( PlayerColor Player )
2010-01-02 03:48:44 +02:00
{
2010-02-20 15:24:38 +02:00
state = WAITING ;
}
2010-01-02 03:48:44 +02:00
2013-03-03 20:06:03 +03:00
void CAdvMapInt : : setPlayer ( PlayerColor Player )
2010-02-20 15:24:38 +02:00
{
player = Player ;
graphics - > blueToPlayersAdv ( bg , player ) ;
2015-01-15 01:22:20 +02:00
panelMain - > setPlayerColor ( player ) ;
panelWorldView - > setPlayerColor ( player ) ;
2016-10-18 04:46:07 +02:00
panelWorldView - > recolorIcons ( player , player . getNum ( ) * 19 ) ;
2018-04-07 13:34:11 +02:00
resdatabar . background - > colorize ( player ) ;
2010-02-20 15:24:38 +02:00
}
void CAdvMapInt : : startTurn ( )
{
state = INGAME ;
2017-06-03 07:25:10 +02:00
if ( LOCPLINT - > cb - > getCurrentPlayer ( ) = = LOCPLINT - > playerID
| | settings [ " session " ] [ " spectate " ] . Bool ( ) )
2012-02-22 16:41:27 +03:00
{
adjustActiveness ( false ) ;
2012-06-13 16:04:06 +03:00
minimap . setAIRadar ( false ) ;
2012-02-22 16:41:27 +03:00
}
2010-01-02 03:48:44 +02:00
}
2011-09-24 19:46:23 +03:00
void CAdvMapInt : : endingTurn ( )
{
2017-06-03 07:25:10 +02:00
if ( settings [ " session " ] [ " spectate " ] . Bool ( ) )
return ;
2011-09-24 19:46:23 +03:00
LOCPLINT - > makingTurn = false ;
LOCPLINT - > cb - > endTurn ( ) ;
2017-09-13 02:35:58 +02:00
CCS - > soundh - > ambientStopAllChannels ( ) ;
2011-09-24 19:46:23 +03:00
}
2014-07-01 17:19:08 +03:00
const CGObjectInstance * CAdvMapInt : : getActiveObject ( const int3 & mapPos )
2010-03-21 00:17:19 +02:00
{
2012-05-14 19:29:06 +03:00
std : : vector < const CGObjectInstance * > bobjs = LOCPLINT - > cb - > getBlockingObjs ( mapPos ) ; //blocking objects at tile
if ( bobjs . empty ( ) )
return nullptr ;
2011-05-03 06:14:18 +03:00
2014-07-01 17:19:08 +03:00
return * boost : : range : : max_element ( bobjs , & CMapHandler : : compareObjectBlitOrder ) ;
/*
2012-09-23 21:01:04 +03:00
if ( bobjs . back ( ) - > ID = = Obj : : HERO )
2012-05-14 19:29:06 +03:00
return bobjs . back ( ) ;
else
2014-07-01 17:19:08 +03:00
return bobjs . front ( ) ; */
2012-05-14 19:29:06 +03:00
}
void CAdvMapInt : : tileLClicked ( const int3 & mapPos )
{
2015-01-13 21:57:41 +02:00
if ( mode ! = EAdvMapMode : : NORMAL )
return ;
2012-05-14 19:29:06 +03:00
if ( ! LOCPLINT - > cb - > isVisible ( mapPos ) | | ! LOCPLINT - > makingTurn )
return ;
2011-08-18 00:48:12 +03:00
2012-05-14 19:29:06 +03:00
const TerrainTile * tile = LOCPLINT - > cb - > getTile ( mapPos ) ;
2010-03-21 00:17:19 +02:00
2014-07-01 17:19:08 +03:00
const CGObjectInstance * topBlocking = getActiveObject ( mapPos ) ;
2010-03-21 00:17:19 +02:00
int3 selPos = selection - > getSightCenter ( ) ;
2012-05-14 19:29:06 +03:00
if ( spellBeingCasted & & isInScreenRange ( selPos , mapPos ) )
2010-03-21 00:17:19 +02:00
{
2011-05-10 01:20:47 +03:00
const TerrainTile * heroTile = LOCPLINT - > cb - > getTile ( selPos ) ;
2010-03-21 00:17:19 +02:00
switch ( spellBeingCasted - > id )
{
2013-02-11 02:24:57 +03:00
case SpellID : : SCUTTLE_BOAT : //Scuttle Boat
2013-01-31 23:11:25 +03:00
if ( topBlocking & & topBlocking - > ID = = Obj : : BOAT )
2012-05-14 19:29:06 +03:00
leaveCastingMode ( true , mapPos ) ;
2010-03-21 00:17:19 +02:00
break ;
2013-02-11 02:24:57 +03:00
case SpellID : : DIMENSION_DOOR :
2010-03-21 00:17:19 +02:00
if ( ! tile | | tile - > isClear ( heroTile ) )
2012-05-14 19:29:06 +03:00
leaveCastingMode ( true , mapPos ) ;
2010-03-21 00:17:19 +02:00
break ;
}
return ;
}
2010-08-13 13:46:08 +03:00
//check if we can select this object
2012-09-23 21:01:04 +03:00
bool canSelect = topBlocking & & topBlocking - > ID = = Obj : : HERO & & topBlocking - > tempOwner = = LOCPLINT - > playerID ;
canSelect | = topBlocking & & topBlocking - > ID = = Obj : : TOWN & & LOCPLINT - > cb - > getPlayerRelations ( LOCPLINT - > playerID , topBlocking - > tempOwner ) ;
2010-03-21 00:17:19 +02:00
2016-01-17 06:48:21 +02:00
if ( selection - > ID ! = Obj : : HERO ) //hero is not selected (presumably town)
2010-03-21 00:17:19 +02:00
{
assert ( ! terrain . currentPath ) ; //path can be active only when hero is selected
if ( selection = = topBlocking ) //selected town clicked
LOCPLINT - > openTownWindow ( static_cast < const CGTownInstance * > ( topBlocking ) ) ;
2016-01-17 06:48:21 +02:00
else if ( canSelect )
select ( static_cast < const CArmedInstance * > ( topBlocking ) , false ) ;
2010-07-26 18:37:58 +03:00
return ;
2010-03-21 00:17:19 +02:00
}
else if ( const CGHeroInstance * currentHero = curHero ( ) ) //hero is selected
{
2014-09-21 16:42:08 +03:00
const CGPathNode * pn = LOCPLINT - > cb - > getPathsInfo ( currentHero ) - > getPathInfo ( mapPos ) ;
2010-03-21 00:17:19 +02:00
if ( currentHero = = topBlocking ) //clicked selected hero
{
LOCPLINT - > openHeroWindow ( currentHero ) ;
2010-07-13 08:25:40 +03:00
return ;
2010-03-21 00:17:19 +02:00
}
2010-08-13 13:46:08 +03:00
else if ( canSelect & & pn - > turns = = 255 ) //selectable object at inaccessible tile
2010-03-21 00:17:19 +02:00
{
select ( static_cast < const CArmedInstance * > ( topBlocking ) , false ) ;
2010-07-13 08:25:40 +03:00
return ;
2010-03-21 00:17:19 +02:00
}
else //still here? we need to move hero if we clicked end of already selected path or calculate a new path otherwise
{
2016-01-17 06:48:21 +02:00
if ( terrain . currentPath & & terrain . currentPath - > endPos ( ) = = mapPos ) //we'll be moving
2010-03-21 00:17:19 +02:00
{
2016-01-17 06:48:21 +02:00
if ( CGI - > mh - > canStartHeroMovement ( ) )
LOCPLINT - > moveHero ( currentHero , * terrain . currentPath ) ;
2010-07-13 08:25:40 +03:00
return ;
2010-03-21 00:17:19 +02:00
}
2016-01-17 06:48:21 +02:00
else //remove old path and find a new one if we clicked on accessible tile
2010-03-21 00:17:19 +02:00
{
CGPath & path = LOCPLINT - > paths [ currentHero ] ;
2016-01-17 06:48:21 +02:00
CGPath newpath ;
bool gotPath = LOCPLINT - > cb - > getPathsInfo ( currentHero ) - > getPath ( newpath , mapPos ) ; //try getting path, erase if failed
if ( gotPath & & newpath . nodes . size ( ) )
path = newpath ;
if ( path . nodes . size ( ) )
terrain . currentPath = & path ;
2010-07-13 08:25:40 +03:00
else
2016-01-17 06:48:21 +02:00
LOCPLINT - > eraseCurrentPathOf ( currentHero ) ;
updateMoveHero ( currentHero ) ;
2010-03-21 00:17:19 +02:00
}
}
} //end of hero is selected "case"
else
{
2012-04-22 10:32:45 +03:00
throw std : : runtime_error ( " Nothing is selected... " ) ;
2010-03-21 00:17:19 +02:00
}
2010-07-13 08:25:40 +03:00
if ( const IShipyard * shipyard = ourInaccessibleShipyard ( topBlocking ) )
{
LOCPLINT - > showShipyardDialogOrProblemPopup ( shipyard ) ;
}
2010-03-21 00:17:19 +02:00
}
2012-05-14 19:29:06 +03:00
void CAdvMapInt : : tileHovered ( const int3 & mapPos )
2010-03-21 00:17:19 +02:00
{
2015-11-08 02:33:01 +02:00
if ( mode ! = EAdvMapMode : : NORMAL //disable in world view
| | ! selection ) //may occur just at the start of game (fake move before full intiialization)
2015-01-13 21:57:41 +02:00
return ;
2012-05-14 19:29:06 +03:00
if ( ! LOCPLINT - > cb - > isVisible ( mapPos ) )
2011-05-03 06:14:18 +03:00
{
2012-12-14 18:32:53 +03:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 0 ) ;
2018-08-26 18:09:56 +02:00
statusbar - > clear ( ) ;
2011-05-03 06:14:18 +03:00
return ;
}
2015-11-08 02:10:48 +02:00
auto objRelations = PlayerRelations : : ALLIES ;
2015-11-08 02:33:01 +02:00
const CGObjectInstance * objAtTile = getActiveObject ( mapPos ) ;
2015-11-08 02:10:48 +02:00
if ( objAtTile )
2010-03-21 00:17:19 +02:00
{
2015-11-08 02:10:48 +02:00
objRelations = LOCPLINT - > cb - > getPlayerRelations ( LOCPLINT - > playerID , objAtTile - > tempOwner ) ;
2014-06-24 20:39:36 +03:00
std : : string text = curHero ( ) ? objAtTile - > getHoverText ( curHero ( ) ) : objAtTile - > getHoverText ( LOCPLINT - > playerID ) ;
2012-05-14 19:29:06 +03:00
boost : : replace_all ( text , " \n " , " " ) ;
2018-08-26 18:09:56 +02:00
statusbar - > setText ( text ) ;
2010-03-21 00:17:19 +02:00
}
else
{
std : : string hlp ;
2012-05-14 19:29:06 +03:00
CGI - > mh - > getTerrainDescr ( mapPos , hlp , false ) ;
2018-08-26 18:09:56 +02:00
statusbar - > setText ( hlp ) ;
2010-03-21 00:17:19 +02:00
}
if ( spellBeingCasted )
{
switch ( spellBeingCasted - > id )
{
2013-02-11 02:24:57 +03:00
case SpellID : : SCUTTLE_BOAT :
2012-09-23 21:01:04 +03:00
if ( objAtTile & & objAtTile - > ID = = Obj : : BOAT )
2012-12-14 18:32:53 +03:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 42 ) ;
2010-03-21 00:17:19 +02:00
else
2012-12-14 18:32:53 +03:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 0 ) ;
2010-03-21 00:17:19 +02:00
return ;
2013-02-11 02:24:57 +03:00
case SpellID : : DIMENSION_DOOR :
2010-03-21 00:17:19 +02:00
{
2015-11-08 02:33:01 +02:00
const TerrainTile * t = LOCPLINT - > cb - > getTile ( mapPos , false ) ;
2010-03-21 00:17:19 +02:00
int3 hpos = selection - > getSightCenter ( ) ;
2015-11-08 02:33:01 +02:00
if ( ( ! t | | t - > isClear ( LOCPLINT - > cb - > getTile ( hpos ) ) ) & & isInScreenRange ( hpos , mapPos ) )
2012-12-14 18:32:53 +03:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 41 ) ;
2010-03-21 00:17:19 +02:00
else
2012-12-14 18:32:53 +03:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 0 ) ;
2010-03-21 00:17:19 +02:00
return ;
}
}
}
2012-09-23 21:01:04 +03:00
if ( selection - > ID = = Obj : : TOWN )
2010-03-21 00:17:19 +02:00
{
2010-08-13 13:46:08 +03:00
if ( objAtTile )
2010-03-21 00:17:19 +02:00
{
2015-11-08 02:33:01 +02:00
if ( objAtTile - > ID = = Obj : : TOWN & & objRelations ! = PlayerRelations : : ENEMIES )
2012-12-14 18:32:53 +03:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 3 ) ;
2015-11-08 02:33:01 +02:00
else if ( objAtTile - > ID = = Obj : : HERO & & objRelations = = PlayerRelations : : SAME_PLAYER )
2012-12-14 18:32:53 +03:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 2 ) ;
2012-02-28 14:26:08 +03:00
else
2012-12-14 18:32:53 +03:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 0 ) ;
2010-03-21 00:17:19 +02:00
}
else
2012-12-14 18:32:53 +03:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 0 ) ;
2010-03-21 00:17:19 +02:00
}
2015-11-08 02:33:01 +02:00
else if ( const CGHeroInstance * h = curHero ( ) )
2010-03-21 00:17:19 +02:00
{
2022-09-20 13:52:43 +02:00
const CGPathNode * pnode = LOCPLINT - > cb - > getPathsInfo ( h ) - > getPathInfo ( mapPos ) ;
2015-10-31 19:23:13 +02:00
assert ( pnode ) ;
2014-09-21 16:42:08 +03:00
int turns = pnode - > turns ;
vstd : : amin ( turns , 3 ) ;
2015-11-08 02:10:48 +02:00
switch ( pnode - > action )
2010-03-21 00:17:19 +02:00
{
2015-11-08 02:10:48 +02:00
case CGPathNode : : NORMAL :
2015-12-11 08:42:30 +02:00
case CGPathNode : : TELEPORT_NORMAL :
2015-11-08 02:10:48 +02:00
if ( pnode - > layer = = EPathfindingLayer : : LAND )
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 4 + turns * 6 ) ;
else
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 28 + turns ) ;
break ;
2010-03-21 00:17:19 +02:00
2015-11-08 02:10:48 +02:00
case CGPathNode : : VISIT :
case CGPathNode : : BLOCKING_VISIT :
2015-12-11 08:42:30 +02:00
case CGPathNode : : TELEPORT_BLOCKING_VISIT :
2015-11-17 06:09:01 +02:00
if ( objAtTile & & objAtTile - > ID = = Obj : : HERO )
2010-03-21 00:17:19 +02:00
{
2015-11-08 02:10:48 +02:00
if ( selection = = objAtTile )
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 2 ) ;
2012-01-12 18:23:00 +03:00
else
2015-11-08 02:10:48 +02:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 8 + turns * 6 ) ;
2010-05-06 15:13:31 +03:00
}
2015-11-08 02:10:48 +02:00
else if ( pnode - > layer = = EPathfindingLayer : : LAND )
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 9 + turns * 6 ) ;
2010-03-21 00:17:19 +02:00
else
2015-11-08 02:10:48 +02:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 28 + turns ) ;
break ;
case CGPathNode : : BATTLE :
2015-12-11 08:42:30 +02:00
case CGPathNode : : TELEPORT_BATTLE :
2015-11-08 02:10:48 +02:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 5 + turns * 6 ) ;
break ;
case CGPathNode : : EMBARK :
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 6 + turns * 6 ) ;
break ;
case CGPathNode : : DISEMBARK :
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 7 + turns * 6 ) ;
break ;
default :
if ( objAtTile & & objRelations ! = PlayerRelations : : ENEMIES )
2010-03-21 00:17:19 +02:00
{
2015-11-08 02:10:48 +02:00
if ( objAtTile - > ID = = Obj : : TOWN )
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 3 ) ;
else if ( objAtTile - > ID = = Obj : : HERO & & objRelations = = PlayerRelations : : SAME_PLAYER )
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 2 ) ;
2019-05-03 07:20:32 +02:00
else
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 0 ) ;
2010-03-21 00:17:19 +02:00
}
else
2012-12-14 18:32:53 +03:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 0 ) ;
2015-11-08 02:10:48 +02:00
break ;
2010-03-21 00:17:19 +02:00
}
}
2010-07-13 08:25:40 +03:00
2011-02-20 11:24:53 +02:00
if ( ourInaccessibleShipyard ( objAtTile ) )
2010-07-13 08:25:40 +03:00
{
2012-12-14 18:32:53 +03:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 6 ) ;
2010-07-13 08:25:40 +03:00
}
2010-03-21 00:17:19 +02:00
}
2012-05-14 19:29:06 +03:00
void CAdvMapInt : : tileRClicked ( const int3 & mapPos )
2010-03-21 00:17:19 +02:00
{
2015-01-13 21:57:41 +02:00
if ( mode ! = EAdvMapMode : : NORMAL )
return ;
2010-03-21 00:17:19 +02:00
if ( spellBeingCasted )
{
leaveCastingMode ( ) ;
return ;
}
2012-05-14 19:29:06 +03:00
if ( ! LOCPLINT - > cb - > isVisible ( mapPos ) )
2011-05-03 06:14:18 +03:00
{
CRClickPopup : : createAndPush ( VLC - > generaltexth - > allTexts [ 61 ] ) ; //Uncharted Territory
return ;
}
2010-03-21 00:17:19 +02:00
2014-07-01 17:19:08 +03:00
const CGObjectInstance * obj = getActiveObject ( mapPos ) ;
2012-05-14 19:29:06 +03:00
if ( ! obj )
2010-03-21 00:17:19 +02:00
{
// Bare or undiscovered terrain
2012-05-14 19:29:06 +03:00
const TerrainTile * tile = LOCPLINT - > cb - > getTile ( mapPos ) ;
2012-01-12 18:23:00 +03:00
if ( tile )
2010-03-21 00:17:19 +02:00
{
std : : string hlp ;
2012-05-14 19:29:06 +03:00
CGI - > mh - > getTerrainDescr ( mapPos , hlp , true ) ;
2010-03-21 00:17:19 +02:00
CRClickPopup : : createAndPush ( hlp ) ;
}
return ;
}
CRClickPopup : : createAndPush ( obj , GH . current - > motion , CENTER ) ;
}
void CAdvMapInt : : enterCastingMode ( const CSpell * sp )
{
2013-02-11 02:24:57 +03:00
assert ( sp - > id = = SpellID : : SCUTTLE_BOAT | | sp - > id = = SpellID : : DIMENSION_DOOR ) ;
2010-03-21 00:17:19 +02:00
spellBeingCasted = sp ;
deactivate ( ) ;
terrain . activate ( ) ;
GH . fakeMouseMove ( ) ;
}
2017-07-15 13:08:20 +02:00
void CAdvMapInt : : leaveCastingMode ( bool cast , int3 dest )
2010-03-21 00:17:19 +02:00
{
assert ( spellBeingCasted ) ;
2013-02-11 02:24:57 +03:00
SpellID id = spellBeingCasted - > id ;
2013-06-26 14:18:27 +03:00
spellBeingCasted = nullptr ;
2010-03-21 00:17:19 +02:00
terrain . deactivate ( ) ;
activate ( ) ;
2010-06-01 00:14:15 +03:00
if ( cast )
LOCPLINT - > cb - > castSpell ( curHero ( ) , id , dest ) ;
2012-01-12 18:23:00 +03:00
else
2010-06-01 00:14:15 +03:00
LOCPLINT - > showInfoDialog ( CGI - > generaltexth - > allTexts [ 731 ] ) ; //Spell cancelled
2010-03-21 00:17:19 +02:00
}
const CGHeroInstance * CAdvMapInt : : curHero ( ) const
{
2012-09-23 21:01:04 +03:00
if ( selection & & selection - > ID = = Obj : : HERO )
2010-03-21 00:17:19 +02:00
return static_cast < const CGHeroInstance * > ( selection ) ;
else
2013-06-26 14:18:27 +03:00
return nullptr ;
2010-03-21 00:17:19 +02:00
}
const CGTownInstance * CAdvMapInt : : curTown ( ) const
{
2012-09-23 21:01:04 +03:00
if ( selection & & selection - > ID = = Obj : : TOWN )
2010-03-21 00:17:19 +02:00
return static_cast < const CGTownInstance * > ( selection ) ;
else
2013-06-26 14:18:27 +03:00
return nullptr ;
2010-03-21 00:17:19 +02:00
}
2010-07-13 08:25:40 +03:00
const IShipyard * CAdvMapInt : : ourInaccessibleShipyard ( const CGObjectInstance * obj ) const
{
const IShipyard * ret = IShipyard : : castFrom ( obj ) ;
2012-12-14 18:32:53 +03:00
if ( ! ret | | obj - > tempOwner ! = player | | CCS - > curh - > type | | ( CCS - > curh - > frame ! = 6 & & CCS - > curh - > frame ! = 0 ) )
2013-06-26 14:18:27 +03:00
return nullptr ;
2010-07-13 08:25:40 +03:00
return ret ;
}
2012-02-22 16:41:27 +03:00
void CAdvMapInt : : aiTurnStarted ( )
{
2017-06-03 07:25:10 +02:00
if ( settings [ " session " ] [ " spectate " ] . Bool ( ) )
return ;
2012-02-22 16:41:27 +03:00
adjustActiveness ( true ) ;
2012-08-06 10:34:37 +03:00
CCS - > musich - > playMusicFromSet ( " enemy-turn " , true ) ;
2012-06-13 16:04:06 +03:00
adventureInt - > minimap . setAIRadar ( true ) ;
adventureInt - > infoBar . startEnemyTurn ( LOCPLINT - > cb - > getCurrentPlayer ( ) ) ;
adventureInt - > infoBar . showAll ( screen ) ; //force refresh on inactive object
2012-02-22 16:41:27 +03:00
}
void CAdvMapInt : : adjustActiveness ( bool aiTurnStart )
{
bool wasActive = isActive ( ) ;
2015-01-13 21:57:41 +02:00
if ( wasActive )
2012-02-22 16:41:27 +03:00
deactivate ( ) ;
adventureInt - > duringAITurn = aiTurnStart ;
2015-01-13 21:57:41 +02:00
if ( wasActive )
2012-02-22 16:41:27 +03:00
activate ( ) ;
}
2012-04-08 04:15:18 +03:00
2016-01-10 17:00:24 +02:00
void CAdvMapInt : : quickCombatLock ( )
{
if ( ! duringAITurn )
deactivate ( ) ;
}
void CAdvMapInt : : quickCombatUnlock ( )
{
if ( ! duringAITurn )
activate ( ) ;
}
2017-07-15 13:08:20 +02:00
void CAdvMapInt : : changeMode ( EAdvMapMode newMode , float newScale )
2015-01-13 21:57:41 +02:00
{
if ( mode ! = newMode )
{
mode = newMode ;
switch ( mode )
{
case EAdvMapMode : : NORMAL :
2015-01-15 01:22:20 +02:00
panelMain - > activate ( ) ;
panelWorldView - > deactivate ( ) ;
activeMapPanel = panelMain ;
2015-01-13 21:57:41 +02:00
townList . activate ( ) ;
heroList . activate ( ) ;
infoBar . activate ( ) ;
2015-10-31 19:23:13 +02:00
2015-02-02 14:02:27 +02:00
worldViewOptions . clear ( ) ;
2015-10-31 19:23:13 +02:00
2015-01-13 21:57:41 +02:00
break ;
case EAdvMapMode : : WORLD_VIEW :
2015-01-15 01:22:20 +02:00
panelMain - > deactivate ( ) ;
panelWorldView - > activate ( ) ;
activeMapPanel = panelWorldView ;
2015-01-13 21:57:41 +02:00
townList . deactivate ( ) ;
heroList . deactivate ( ) ;
infoBar . showSelection ( ) ; // to prevent new day animation interfering world view mode
infoBar . deactivate ( ) ;
break ;
}
worldViewScale = newScale ;
redraw ( ) ;
}
else if ( worldViewScale ! = newScale ) // still in world view mode, but the scale changed
{
worldViewScale = newScale ;
2015-01-31 11:57:13 +02:00
redraw ( ) ;
2015-01-13 21:57:41 +02:00
}
}
2018-04-07 13:34:11 +02:00
CAdventureOptions : : CAdventureOptions ( )
: CWindowObject ( PLAYER_COLORED , " ADVOPTS " )
2009-08-27 11:04:32 +03:00
{
2018-04-07 13:34:11 +02:00
OBJECT_CONSTRUCTION_CAPTURING ( 255 - DISPOSE ) ;
2012-06-13 16:04:06 +03:00
2018-04-07 13:34:11 +02:00
viewWorld = std : : make_shared < CButton > ( Point ( 24 , 23 ) , " ADVVIEW.DEF " , CButton : : tooltip ( ) , [ & ] ( ) { close ( ) ; } , SDLK_v ) ;
2015-01-13 21:57:41 +02:00
viewWorld - > addCallback ( std : : bind ( & CPlayerInterface : : viewWorldMap , LOCPLINT ) ) ;
2018-04-07 13:34:11 +02:00
exit = std : : make_shared < CButton > ( Point ( 204 , 313 ) , " IOK6432.DEF " , CButton : : tooltip ( ) , std : : bind ( & CAdventureOptions : : close , this ) , SDLK_RETURN ) ;
2014-07-15 10:14:49 +03:00
exit - > assignedKeys . insert ( SDLK_ESCAPE ) ;
2018-04-07 13:34:11 +02:00
scenInfo = std : : make_shared < CButton > ( Point ( 24 , 198 ) , " ADVINFO.DEF " , CButton : : tooltip ( ) , [ & ] ( ) { close ( ) ; } , SDLK_i ) ;
2014-08-03 14:16:19 +03:00
scenInfo - > addCallback ( CAdventureOptions : : showScenarioInfo ) ;
2018-04-07 13:34:11 +02:00
puzzle = std : : make_shared < CButton > ( Point ( 24 , 81 ) , " ADVPUZ.DEF " , CButton : : tooltip ( ) , [ & ] ( ) { close ( ) ; } , SDLK_p ) ;
2014-08-09 15:14:31 +03:00
puzzle - > addCallback ( std : : bind ( & CPlayerInterface : : showPuzzleMap , LOCPLINT ) ) ;
2014-07-15 10:14:49 +03:00
2018-04-07 13:34:11 +02:00
dig = std : : make_shared < CButton > ( Point ( 24 , 139 ) , " ADVDIG.DEF " , CButton : : tooltip ( ) , [ & ] ( ) { close ( ) ; } , SDLK_d ) ;
2014-07-15 10:14:49 +03:00
if ( const CGHeroInstance * h = adventureInt - > curHero ( ) )
2014-08-09 15:14:31 +03:00
dig - > addCallback ( std : : bind ( & CPlayerInterface : : tryDiggging , LOCPLINT , h ) ) ;
2010-02-24 15:03:36 +02:00
else
dig - > block ( true ) ;
2009-08-27 11:04:32 +03:00
}
void CAdventureOptions : : showScenarioInfo ( )
{
2018-01-05 19:21:07 +02:00
if ( LOCPLINT - > cb - > getStartInfo ( ) - > campState )
2013-12-16 21:39:56 +03:00
{
2022-04-26 13:14:31 +02:00
GH . pushIntT < CCampaignInfoScreen > ( ) ;
2013-12-16 21:39:56 +03:00
}
else
{
2018-07-25 00:36:48 +02:00
GH . pushIntT < CScenarioInfoScreen > ( ) ;
2013-12-16 21:39:56 +03:00
}
2010-10-31 00:53:41 +03:00
}
2015-02-02 14:02:27 +02:00
CAdvMapInt : : WorldViewOptions : : WorldViewOptions ( )
{
clear ( ) ;
}
void CAdvMapInt : : WorldViewOptions : : clear ( )
{
2015-02-26 16:15:17 +02:00
showAllTerrain = false ;
2015-10-31 19:23:13 +02:00
2015-02-26 16:15:17 +02:00
iconPositions . clear ( ) ;
2015-02-02 14:02:27 +02:00
}
void CAdvMapInt : : WorldViewOptions : : adjustDrawingInfo ( MapDrawingInfo & info )
{
2015-02-26 16:15:17 +02:00
info . showAllTerrain = showAllTerrain ;
2015-02-02 14:02:27 +02:00
2015-10-31 19:23:13 +02:00
info . additionalIcons = & iconPositions ;
}