2009-05-08 13:28:41 +00:00
/*
* OpenClonk , http : //www.openclonk.org
*
2013-12-17 20:01:09 +00:00
* Copyright ( c ) 1998 - 2000 , Matthes Bender
* Copyright ( c ) 2008 - 2009 , RedWolf Design GmbH , http : //www.clonk.de/
* Copyright ( c ) 2009 - 2013 , The OpenClonk Team and contributors
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* Distributed under the terms of the ISC license ; see accompanying file
* " COPYING " for details .
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* " Clonk " is a registered trademark of Matthes Bender , used with permission .
* See accompanying file " TRADEMARK " for details .
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* To redistribute this file separately , substitute the full license texts
* for the above references .
2009-05-08 13:28:41 +00:00
*/
// Engine internal C4Menus: Main menu, Options, Player join, Hostility, etc.
# include <C4Include.h>
# include <C4MainMenu.h>
2015-01-02 20:13:26 +00:00
# include <C4Application.h>
2011-03-03 16:10:22 +00:00
# include <C4DefList.h>
2009-05-08 13:28:41 +00:00
# include <C4FullScreen.h>
# include <C4Viewport.h>
# include <C4Player.h>
# include <C4GameOverDlg.h>
2009-06-12 18:52:21 +00:00
# include <C4GraphicsResource.h>
# include <C4Game.h>
2009-06-12 23:09:32 +00:00
# include <C4PlayerList.h>
2009-06-15 21:47:26 +00:00
# include <C4GameObjects.h>
2009-06-15 22:06:37 +00:00
# include <C4Network2.h>
# include <C4GameControl.h>
2015-01-02 20:13:26 +00:00
# include <C4Def.h>
2009-05-08 13:28:41 +00:00
// -----------------------------------------------------------
// C4MainMenu
C4MainMenu : : C4MainMenu ( ) : C4Menu ( ) // will be re-adjusted later
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Clear ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MainMenu : : Default ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
C4Menu : : Default ( ) ;
Player = NO_OWNER ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2016-01-27 04:16:33 +00:00
bool C4MainMenu : : InitRefSym ( const C4Facet & fctSymbol , const char * szEmpty , int32_t iPlayer , int32_t iId , int32_t iStyle )
2010-03-28 18:58:01 +00:00
{
2016-01-27 04:16:33 +00:00
if ( ! DoInitRefSym ( fctSymbol , szEmpty , iId , iStyle ) ) return false ;
2009-05-08 13:28:41 +00:00
Player = iPlayer ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MainMenu : : ActivateNewPlayer ( int32_t iPlayer )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// league or replay game
if ( Game . Parameters . isLeague ( ) | | Game . C4S . Head . Replay ) return false ;
// Max player limit
2009-06-12 23:09:32 +00:00
if ( : : Players . GetCount ( ) > = Game . Parameters . MaxPlayers ) return false ;
2009-05-08 13:28:41 +00:00
// Menu symbol/init
if ( GfxR - > fctPlayerClr . Surface )
GfxR - > fctPlayerClr . Surface - > SetClr ( 0xff ) ;
2016-01-30 14:59:18 +00:00
InitRefSym ( GfxR - > fctPlayerClr , LoadResStr ( " IDS_MENU_CPNEWPLAYER " ) , iPlayer , 0 , C4MN_Style_Context ) ;
2009-05-08 13:28:41 +00:00
for ( DirectoryIterator iter ( Config . General . UserDataPath ) ; * iter ; + + iter )
2011-03-13 15:39:48 +00:00
if ( WildcardMatch ( " *.ocp " , * iter ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
char szFilename [ _MAX_PATH + 1 ] , szCommand [ _MAX_PATH + 30 + 1 ] ;
SCopy ( * iter , szFilename , _MAX_PATH ) ;
if ( DirectoryExists ( szFilename ) ) continue ;
2009-06-12 23:09:32 +00:00
if ( : : Players . FileInUse ( szFilename ) ) continue ;
2009-05-08 13:28:41 +00:00
// Open group
C4Group hGroup ;
if ( ! hGroup . Open ( szFilename ) ) continue ;
// Load player info
C4PlayerInfoCore C4P ;
if ( ! C4P . Load ( hGroup ) ) { hGroup . Close ( ) ; continue ; }
2016-01-30 14:59:18 +00:00
// Load custom portrait
C4FacetSurface fctSymbol ;
if ( ! fctSymbol . Load ( hGroup , C4CFN_BigIcon , C4FCT_Full , C4FCT_Full , false , true ) )
fctSymbol . Load ( hGroup , C4CFN_BigIcon , C4FCT_Full , C4FCT_Full , false , true ) ;
2009-05-08 13:28:41 +00:00
// Close group
hGroup . Close ( ) ;
// Add player item
sprintf ( szCommand , " JoinPlayer:%s " , szFilename ) ;
StdStrBuf sItemText ;
sItemText . Format ( LoadResStr ( " IDS_MENU_NEWPLAYER " ) , C4P . PrefName ) ;
2016-01-30 14:59:18 +00:00
// No custom portrait: use default player image
if ( ! fctSymbol . Surface )
{
fctSymbol . Create ( C4SymbolSize , C4SymbolSize ) ;
GfxR - > fctPlayerClr . DrawClr ( fctSymbol , true , C4P . PrefColorDw ) ;
}
2009-05-08 13:28:41 +00:00
// Add menu item
Add ( sItemText . getData ( ) , fctSymbol , szCommand ) ;
// Reset symbol facet (menu holds on to the surface)
fctSymbol . Default ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Alignment
SetAlignment ( C4MN_Align_Left | C4MN_Align_Bottom ) ;
// Go back to options menu on close
SetCloseCommand ( " ActivateMenu:Main " ) ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MainMenu : : DoRefillInternal ( bool & rfRefilled )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Variables
C4FacetSurface fctSymbol ;
C4Player * pPlayer ;
C4IDList ListItems ;
C4Facet fctTarget ;
bool fWasEmpty = ! GetItemCount ( ) ;
// Refill
switch ( Identification )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2010-03-28 18:58:01 +00:00
case C4MN_Hostility :
{
// Clear items
ClearItems ( ) ;
// Refill player
if ( ! ( pPlayer = : : Players . Get ( Player ) ) ) return false ;
// Refill items
C4Player * pPlr ; int32_t iIndex ;
for ( iIndex = 0 ; ( pPlr = : : Players . GetByIndex ( iIndex ) ) ; iIndex + + )
// Ignore player self and invisible
if ( pPlr ! = pPlayer ) if ( ! pPlr - > IsInvisible ( ) )
{
2009-05-08 13:28:41 +00:00
// Symbol
fctSymbol . Create ( C4SymbolSize , C4SymbolSize ) ;
pPlayer - > DrawHostility ( fctSymbol , iIndex ) ;
// Message
StdStrBuf sMsg ;
2010-01-25 15:57:57 +00:00
bool isFriendly = pPlayer - > Hostility . find ( pPlr ) = = pPlayer - > Hostility . end ( ) ;
if ( isFriendly )
2009-05-08 13:28:41 +00:00
sMsg . Format ( LoadResStr ( " IDS_MENU_ATTACK " ) , pPlr - > GetName ( ) ) ;
else
sMsg . Format ( LoadResStr ( " IDS_MENU_NOATTACK " ) , pPlr - > GetName ( ) ) ;
// Command
char szCommand [ 1000 ] ;
sprintf ( szCommand , " SetHostility:%i " , pPlr - > Number ) ;
// Info caption
char szInfoCaption [ C4MaxTitle + 1 ] , szFriendly [ 50 ] , szNot [ 30 ] = " " ;
2010-01-25 15:57:57 +00:00
SCopy ( LoadResStr ( isFriendly ? " IDS_MENU_ATTACKHOSTILE " : " IDS_MENU_ATTACKFRIENDLY " ) , szFriendly ) ;
if ( ! isFriendly ) SCopy ( LoadResStr ( " IDS_MENU_ATTACKNOT " ) , szNot ) ;
2009-05-08 13:28:41 +00:00
sprintf ( szInfoCaption , LoadResStr ( " IDS_MENU_ATTACKINFO " ) , pPlr - > GetName ( ) , szFriendly , szNot ) ;
if ( iIndex = = pPlayer - > Number ) SCopy ( LoadResStr ( " IDS_MENU_ATTACKSELF " ) , szInfoCaption ) ;
// Add item
2016-01-27 04:16:33 +00:00
Add ( sMsg . getData ( ) , fctSymbol , szCommand , szInfoCaption ) ;
2009-05-08 13:28:41 +00:00
fctSymbol . Default ( ) ;
2010-03-28 18:58:01 +00:00
}
break ;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case C4MN_TeamSelection :
case C4MN_TeamSwitch :
{
// Clear items
ClearItems ( ) ;
// add all teams as menu items
// 2do: Icon
C4Team * pTeam ; int32_t i = 0 ; bool fAddNewTeam = Game . Teams . IsAutoGenerateTeams ( ) ;
for ( ; ; )
{
pTeam = Game . Teams . GetTeamByIndex ( i ) ;
if ( pTeam )
{
// next regular team
+ + i ;
// do not add a new team if an empty team exists
if ( ! pTeam - > GetPlayerCount ( ) ) fAddNewTeam = false ;
}
else if ( fAddNewTeam )
{
// join new team
fAddNewTeam = false ;
}
else
{
// all teams done
2009-05-08 13:28:41 +00:00
break ;
}
2010-03-28 18:58:01 +00:00
// create team symbol: Icon spec if specified; otherwise flag for empty and crew for nonempty team
fctSymbol . Create ( C4SymbolSize , C4SymbolSize ) ;
const char * szIconSpec = pTeam ? pTeam - > GetIconSpec ( ) : NULL ;
bool fHasIcon = false ;
if ( szIconSpec & & * szIconSpec )
2009-05-08 13:28:41 +00:00
{
2012-01-10 21:40:46 +00:00
fHasIcon = Game . DrawTextSpecImage ( fctSymbol , szIconSpec , NULL , pTeam - > GetColor ( ) ) ;
2010-03-28 18:58:01 +00:00
}
if ( ! fHasIcon )
{
if ( pTeam & & pTeam - > GetPlayerCount ( ) )
: : GraphicsResource . fctCrewClr . DrawClr ( fctSymbol , true , pTeam - > GetColor ( ) ) ;
2009-05-08 13:28:41 +00:00
else
2010-03-28 18:58:01 +00:00
C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_Team ) . Draw ( fctSymbol , true ) ;
2009-05-08 13:28:41 +00:00
}
2010-03-28 18:58:01 +00:00
StdStrBuf sTeamName ;
if ( pTeam )
2009-05-08 13:28:41 +00:00
{
2010-03-28 18:58:01 +00:00
sTeamName . Take ( pTeam - > GetNameWithParticipants ( ) ) ;
2009-05-08 13:28:41 +00:00
}
2010-03-28 18:58:01 +00:00
else
sTeamName . Ref ( LoadResStr ( " IDS_PRC_NEWTEAM " ) ) ;
const char * szOperation = ( Identification = = C4MN_TeamSwitch ) ? " TeamSwitch " : " TeamSel " ;
Add ( sTeamName . getData ( ) , fctSymbol , FormatString ( " %s:%d " , szOperation , pTeam ? pTeam - > GetID ( ) : TEAMID_New ) . getData ( ) ,
2016-01-27 04:16:33 +00:00
FormatString ( LoadResStr ( " IDS_MSG_JOINTEAM " ) , sTeamName . getData ( ) ) . getData ( ) ) ;
2010-03-28 18:58:01 +00:00
fctSymbol . Default ( ) ;
2009-05-08 13:28:41 +00:00
}
2010-03-28 18:58:01 +00:00
break ;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case C4MN_Observer : // observer menu
{
// Clear items
ClearItems ( ) ;
// Check validity
2010-09-29 01:44:05 +00:00
C4Viewport * pVP = : : Viewports . GetViewport ( NO_OWNER ) ;
2010-03-28 18:58:01 +00:00
if ( ! pVP ) return false ;
int32_t iInitialSelection = 0 ;
// Add free view
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_MSG_FREEVIEW " ) , C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_Star ) , " Observe:Free " , LoadResStr ( " IDS_MSG_FREELYSCROLLAROUNDTHEMAP " ) ) ;
2010-03-28 18:58:01 +00:00
// Add players
C4Player * pPlr ; int32_t iIndex ;
for ( iIndex = 0 ; ( pPlr = : : Players . GetByIndex ( iIndex ) ) ; iIndex + + )
{
// Ignore invisible
if ( ! pPlr - > IsInvisible ( ) )
{
// Symbol
fctSymbol . Create ( C4SymbolSize , C4SymbolSize ) ;
: : GraphicsResource . fctPlayerClr . DrawClr ( fctSymbol , true , pPlr - > ColorDw ) ;
// Message
StdStrBuf sMsg ;
DWORD dwClr = pPlr - > ColorDw ;
2010-04-28 21:43:25 +00:00
sMsg . Format ( " <c %x>%s</c> " , ( unsigned int ) C4GUI : : MakeColorReadableOnBlack ( dwClr ) , pPlr - > GetName ( ) ) ;
2010-03-28 18:58:01 +00:00
// Command
StdStrBuf sCommand ;
sCommand . Format ( " Observe:%d " , ( int ) pPlr - > Number ) ;
// Info caption
StdStrBuf sInfo ;
sInfo . Format ( LoadResStr ( " IDS_TEXT_FOLLOWVIEWOFPLAYER " ) , pPlr - > GetName ( ) ) ;
// Add item
2016-01-27 04:16:33 +00:00
Add ( sMsg . getData ( ) , fctSymbol , sCommand . getData ( ) , sInfo . getData ( ) ) ;
2010-03-28 18:58:01 +00:00
fctSymbol . Default ( ) ;
// check if this is the currently selected player
if ( pVP - > GetPlayer ( ) = = pPlr - > Number ) iInitialSelection = GetItemCount ( ) - 1 ;
}
// Initial selection on followed player
if ( fWasEmpty ) SetSelection ( iInitialSelection , false , true ) ;
}
}
break ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
default :
// No internal refill needed
return true ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
}
2009-05-08 13:28:41 +00:00
// Successfull internal refill
rfRefilled = true ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MainMenu : : OnSelectionChanged ( int32_t iNewSelection )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// immediate player highlight in observer menu
if ( Identification = = C4MN_Observer )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
C4MenuItem * pItem = GetSelectedItem ( ) ;
if ( pItem )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
if ( SEqual2 ( pItem - > GetCommand ( ) , " Observe: " ) )
MenuCommand ( pItem - > GetCommand ( ) , false ) ;
}
}
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MainMenu : : OnUserSelectItem ( int32_t Player , int32_t iIndex )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// direct selection for non-sync-menus
SetSelection ( iIndex , true , true ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2016-01-27 03:19:27 +00:00
void C4MainMenu : : OnUserEnter ( int32_t Player , int32_t iIndex )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// direct menu control
// but ensure selection is Okay before
SetSelection ( iIndex , true , false ) ;
2016-01-27 03:19:27 +00:00
Enter ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MainMenu : : OnUserClose ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// just close
TryClose ( false , true ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MainMenu : : ActivateGoals ( int32_t iPlayer , bool fDoActivate )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
C4FacetSurface fctSymbol ;
C4Facet fctGF ; // goal fulfilled facet
if ( fDoActivate )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Menu symbol/init
InitRefSym ( GfxR - > fctMenu . GetPhase ( 4 ) , LoadResStr ( " IDS_MENU_CPGOALS " ) , iPlayer ) ;
SetAlignment ( C4MN_Align_Left | C4MN_Align_Bottom ) ;
SetPermanent ( false ) ;
2009-06-05 15:19:15 +00:00
fctGF . Set ( NULL , C4SymbolSize - : : GraphicsResource . fctCaptain . Wdt - 2 , 2 , : : GraphicsResource . fctCaptain . Wdt , : : GraphicsResource . fctCaptain . Hgt ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// determine if the goals are fulfilled - do the calls even if the menu is not to be opened to ensure synchronization
C4IDList GoalList , FulfilledGoalList ;
C4RoundResults : : EvaluateGoals ( GoalList , FulfilledGoalList , iPlayer ) ;
// Add Items
if ( fDoActivate )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
int32_t iNumGoals = GoalList . GetNumberOfIDs ( ) , cnt ;
C4ID idGoal ; C4Def * pDef ;
for ( int32_t i = 0 ; i < iNumGoals ; + + i )
2010-01-25 04:00:59 +00:00
if ( ( idGoal = GoalList . GetID ( i , & cnt ) ) )
if ( ( pDef = C4Id2Def ( idGoal ) ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
fctSymbol . Create ( C4SymbolSize , C4SymbolSize ) ;
// 2do: If an object instance is known, draw the object instead?
// this would allow us to do dynamic pictures and overlays; e.g. draw the actual, required settlement score
// for settlement score goals
// Same for pDef->GetName(), pDef->GetDesc()
pDef - > Draw ( fctSymbol ) ;
if ( FulfilledGoalList . GetIDCount ( idGoal ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
fctGF . Surface = fctSymbol . Surface ;
2009-06-05 15:19:15 +00:00
: : GraphicsResource . fctCaptain . Draw ( fctGF ) ;
2010-03-28 18:58:01 +00:00
}
2010-01-25 15:57:57 +00:00
StdStrBuf Command ; Command . Format ( " Player:Goal:%s " , idGoal . ToString ( ) ) ;
2016-01-27 04:16:33 +00:00
Add ( pDef - > GetName ( ) , fctSymbol , Command . getData ( ) , " " ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Go back to options menu on close
SetCloseCommand ( " ActivateMenu:Main " ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Done
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MainMenu : : ActivateRules ( int32_t iPlayer )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Menu symbol/init
char Command [ 256 ] ;
C4FacetSurface fctSymbol ;
InitRefSym ( GfxR - > fctMenu . GetPhase ( 5 ) , LoadResStr ( " IDS_MENU_CPRULES " ) , iPlayer ) ;
SetAlignment ( C4MN_Align_Left | C4MN_Align_Bottom ) ;
SetPermanent ( false ) ;
// Items
int32_t cnt ; C4ID idGoal ; C4Def * pDef ;
2010-08-05 18:48:22 +00:00
for ( cnt = 0 ; ( idGoal = : : Objects . GetListID ( C4D_Rule , cnt ) ) ; cnt + + )
2010-01-25 04:00:59 +00:00
if ( ( pDef = C4Id2Def ( idGoal ) ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
fctSymbol . Create ( C4SymbolSize , C4SymbolSize ) ; pDef - > Draw ( fctSymbol ) ;
2010-01-25 15:57:57 +00:00
sprintf ( Command , " Player:Rule:%s " , idGoal . ToString ( ) ) ;
2016-01-27 04:16:33 +00:00
Add ( pDef - > GetName ( ) , fctSymbol , Command , " " ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Go back to options menu on close
SetCloseCommand ( " ActivateMenu:Main " ) ;
// Done
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool LooksLikeInteger ( const char * szInt )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// safety
if ( ! szInt ) return false ;
// check sign
if ( * szInt = = ' + ' | | * szInt = = ' - ' ) + + szInt ;
// check int32_t length
if ( ! * szInt ) return false ;
// must contain only digits now
char c ;
2010-01-25 04:00:59 +00:00
while ( ( c = * ( szInt + + ) ) ) if ( ! Inside < char > ( c , ' 0 ' , ' 9 ' ) ) return false ;
2009-05-08 13:28:41 +00:00
// it's an int32_t
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MainMenu : : ActivateSavegame ( int32_t iPlayer )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Check if saving is possible
if ( ! Game . CanQuickSave ( ) ) return false ;
// Menu symbol/init
char DirPath [ _MAX_PATH + 1 ] ;
char ScenName [ _MAX_PATH + 1 ] ; * ScenName = 0 ;
InitRefSym ( GfxR - > fctMenu . GetPhase ( 0 ) , LoadResStr ( " IDS_MENU_CPSAVEGAME " ) , iPlayer ) ;
SetAlignment ( C4MN_Align_Left | C4MN_Align_Bottom ) ;
SetPermanent ( true ) ;
// target file name mask
// get folder & filename to store in
// some magic is needed to ensure savegames are stored properly into their folders
SCopy ( GetFilename ( Game . ScenarioFilename ) , DirPath ) ;
if ( DirPath [ strlen ( DirPath ) - 1 ] = = ' \\ ' ) DirPath [ strlen ( DirPath ) - 1 ] = 0 ;
RemoveExtension ( DirPath ) ;
if ( LooksLikeInteger ( DirPath ) )
2010-03-28 18:58:01 +00:00
{
2011-03-13 15:38:33 +00:00
// ScenTitle.ocf\%d.ocs-names (old-style savegames)
2009-05-08 13:28:41 +00:00
// get owning folder
if ( Game . pParentGroup )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// owning folder determines filename
SCopy ( GetFilenameOnly ( Game . pParentGroup - > GetName ( ) ) , ScenName ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
else
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// no owning folder known: too bad
// make a vague guess based on the scenario title
SCopy ( GetFilenameOnly ( Game . ScenarioFilename ) , ScenName ) ;
}
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
else
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// DirPath is a valid filename for now...
SCopy ( DirPath , ScenName ) ;
// but remove trailing numbers to adjust new-style savegames
char * pScenNameEnd = ScenName + SLen ( ScenName ) ;
while ( Inside < char > ( * - - pScenNameEnd , ' 0 ' , ' 9 ' ) )
if ( pScenNameEnd = = ScenName )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// should not happen: digit-only-filenames should have been caught earlier
SCopy ( " dbg_error! " , ScenName ) ;
pScenNameEnd = ScenName + SLen ( ScenName ) - 1 ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
pScenNameEnd [ 1 ] = 0 ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// New Style 2007:
2011-03-13 15:38:33 +00:00
// * scenarios are saved into ScenName.ocf/ScenName123.ocs to keep umlauts out of filenames
2009-05-08 13:28:41 +00:00
// * language titles are stored in folders as title component
StdStrBuf strFilename , strTitle ;
2011-03-13 15:38:33 +00:00
strFilename . Format ( " %s.ocf%c%s%%d.ocs " , ScenName , DirectorySeparator , ScenName ) ;
2009-05-08 13:28:41 +00:00
strTitle = Game . ScenarioTitle ;
// Create menu items
StdStrBuf strFilenameIndexed , strCommand , strCaption , strSavePath ;
for ( int32_t i = 1 ; i < = 10 ; i + + )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Index filename
strFilenameIndexed . Format ( strFilename . getData ( ) , i ) ;
// Compose commmand
strCommand . Format ( " Save:Game:%s:%s " , strFilenameIndexed . getData ( ) , strTitle . getData ( ) ) ; // Notice: the language title might contain ':' and thus confuse the segment list - but C4Menu::MenuCommand will try to handle this...
// Check free slot
2011-05-09 15:35:44 +00:00
strSavePath . Format ( " %s%c%s " , Config . AtUserDataPath ( C4CFN_Savegames ) , DirectorySeparator , strFilenameIndexed . getData ( ) ) ;
2009-05-08 13:28:41 +00:00
bool fFree = ! C4Group_IsGroup ( strSavePath . getData ( ) ) ;
// Item caption
strCaption = LoadResStr ( " IDS_MENU_CPSAVEGAME " ) ;
// add menu item
2016-01-27 04:16:33 +00:00
AddRefSym ( strCaption . getData ( ) , GfxR - > fctMenu . GetPhase ( i - 1 , fFree ? 2 : 1 ) , strCommand . getData ( ) , LoadResStr ( " IDS_MENU_CPSAVEGAMEINFO " ) ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Go back to options menu on close
SetCloseCommand ( " ActivateMenu:Main " ) ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MainMenu : : ActivateHost ( int32_t iPlayer )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Menu symbol/init
2016-01-27 04:16:33 +00:00
InitRefSym ( C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_Disconnect ) , LoadResStr ( " IDS_MENU_DISCONNECTCLIENT " ) , iPlayer , 0 , C4MN_Style_Context ) ;
2009-05-08 13:28:41 +00:00
SetAlignment ( C4MN_Align_Left | C4MN_Align_Bottom ) ;
SetPermanent ( true ) ;
// Clients
2009-06-05 15:19:46 +00:00
for ( C4Network2Client * pClient = : : Network . Clients . GetNextClient ( NULL ) ; pClient ; pClient = : : Network . Clients . GetNextClient ( pClient ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
bool fHost = ( pClient - > getID ( ) = = 0 ) ;
StdStrBuf strText , strCommand ;
strText . Format ( " %s (%s) " , pClient - > getName ( ) , pClient - > getCore ( ) . getNick ( ) ) ;
strCommand . Format ( " Host:Kick:%d " , pClient - > getID ( ) ) ;
C4GUI : : Icons iIcon = fHost ? C4GUI : : Ico_Host : ( pClient - > isActivated ( ) ? C4GUI : : Ico_Client : C4GUI : : Ico_ObserverClient ) ;
AddRefSym ( strText . getData ( ) , C4GUI : : Icon : : GetIconFacet ( iIcon ) , strCommand . getData ( ) ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Go back to options menu on close
SetCloseCommand ( " ActivateMenu:Main " ) ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MainMenu : : ActivateClient ( int32_t iPlayer )
2010-03-28 18:58:01 +00:00
{
2016-01-27 04:16:33 +00:00
InitRefSym ( C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_Disconnect ) , LoadResStr ( " IDS_MENU_DISCONNECTFROMSERVER " ) , iPlayer , 0 , C4MN_Style_Context ) ;
2009-05-08 13:28:41 +00:00
SetAlignment ( C4MN_Align_Left | C4MN_Align_Bottom ) ;
2016-01-30 01:19:36 +00:00
AddRefSym ( LoadResStr ( " IDS_BTN_YES " ) , GfxR - > fctOKCancel . GetPhase ( 3 , 0 ) , " Part " ) ;
AddRefSym ( LoadResStr ( " IDS_BTN_NO " ) , C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_Close ) , " " ) ;
2009-05-08 13:28:41 +00:00
SetCloseCommand ( " ActivateMenu:Main " ) ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MainMenu : : ActivateSurrender ( int32_t iPlayer )
2010-03-28 18:58:01 +00:00
{
2016-01-27 04:16:33 +00:00
InitRefSym ( C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_Surrender ) , LoadResStr ( " IDS_MENU_SURRENDER " ) , iPlayer , 0 , C4MN_Style_Context ) ;
2009-05-08 13:28:41 +00:00
SetAlignment ( C4MN_Align_Left | C4MN_Align_Bottom ) ;
2016-01-30 01:19:36 +00:00
AddRefSym ( LoadResStr ( " IDS_BTN_YES " ) , GfxR - > fctOKCancel . GetPhase ( 3 ) , " Surrender " ) ;
AddRefSym ( LoadResStr ( " IDS_BTN_NO " ) , C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_Close ) , " " ) ;
2009-05-08 13:28:41 +00:00
SetCloseCommand ( " ActivateMenu:Main " ) ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MainMenu : : ActivateOptions ( int32_t iPlayer , int32_t selection )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Menu symbol/init
2016-01-27 04:16:33 +00:00
InitRefSym ( GfxR - > fctOptions . GetPhase ( 0 ) , LoadResStr ( " IDS_MNU_OPTIONS " ) , iPlayer , 0 , C4MN_Style_Context ) ;
2009-05-08 13:28:41 +00:00
SetAlignment ( C4MN_Align_Left | C4MN_Align_Bottom ) ;
SetPermanent ( true ) ;
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_DLG_SOUND " ) , GfxR - > fctOptions . GetPhase ( 17 + Config . Sound . RXSound ) , " Options:Sound " ) ;
AddRefSym ( LoadResStr ( " IDS_MNU_MUSIC " ) , GfxR - > fctOptions . GetPhase ( 1 + Config . Sound . RXMusic ) , " Options:Music " ) ;
2016-01-30 01:19:36 +00:00
AddRefSym ( LoadResStr ( " IDS_MENU_DISPLAY " ) , C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_View ) , " ActivateMenu:Display " ) ;
2009-05-08 13:28:41 +00:00
// Restore selection
SetSelection ( selection , false , true ) ;
// Go back to main menu on close
SetCloseCommand ( " ActivateMenu:Main " ) ;
// Done
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MainMenu : : ActivateDisplay ( int32_t iPlayer , int32_t selection )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Menu symbol/init
2016-01-30 01:19:36 +00:00
InitRefSym ( C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_View ) , LoadResStr ( " IDS_MENU_DISPLAY " ) , iPlayer , 0 , C4MN_Style_Context ) ;
2009-05-08 13:28:41 +00:00
SetAlignment ( C4MN_Align_Left | C4MN_Align_Bottom ) ;
SetPermanent ( true ) ;
// Crew player names
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_MNU_PLAYERNAMES " ) , GfxR - > fctOptions . GetPhase ( 7 + Config . Graphics . ShowCrewNames ) , " Display:PlayerNames " , LoadResStr ( " IDS_MENU_PLAYERNAMES_DESC " ) ) ;
2009-05-08 13:28:41 +00:00
// Crew clonk names
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_MNU_CLONKNAMES " ) , GfxR - > fctOptions . GetPhase ( 9 + Config . Graphics . ShowCrewCNames ) , " Display:ClonkNames " , LoadResStr ( " IDS_MENU_CLONKNAMES_DESC " ) ) ;
2009-05-08 13:28:41 +00:00
// Upper Board
2010-09-28 18:16:33 +00:00
if ( ! Application . isEditor )
2010-03-28 18:58:01 +00:00
{
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_MNU_UPPERBOARD " ) , GfxR - > fctOptions . GetPhase ( 3 + Config . Graphics . UpperBoard ) , " Display:UpperBoard " ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// FPS
2010-09-28 18:16:33 +00:00
if ( ! Application . isEditor )
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_MNU_FPS " ) , GfxR - > fctOptions . GetPhase ( 5 + Config . General . FPS ) , " Display:FPS " ) ;
2009-05-08 13:28:41 +00:00
// Clock
2010-09-28 18:16:33 +00:00
if ( ! Application . isEditor )
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_MNU_CLOCK " ) , GfxR - > fctOptions . GetPhase ( 15 + Config . Graphics . ShowClock ) , " Display:Clock " ) ;
2009-05-08 13:28:41 +00:00
// Restore selection
SetSelection ( selection , false , true ) ;
// Go back to options menu on close
SetCloseCommand ( " ActivateMenu:Options " ) ;
// Done
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MainMenu : : ActivateMain ( int32_t iPlayer )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Determine player
2009-06-12 23:09:32 +00:00
C4Player * pPlr = : : Players . Get ( iPlayer ) ;
2009-05-08 13:28:41 +00:00
// Menu symbol/init
2016-01-30 01:19:36 +00:00
InitRefSym ( C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_Player ) , LoadResStr ( pPlr ? " IDS_MENU_CPMAIN " : " IDS_MENU_OBSERVER " ) , iPlayer , 0 , C4MN_Style_Context ) ;
2009-05-08 13:28:41 +00:00
SetAlignment ( C4MN_Align_Left | C4MN_Align_Bottom ) ;
// Goals+Rules (player menu only)
// Goal menu can't be shown because of script callbacks
// Rule menu could be shown, but rule activation would issue script callbacks and trigger client activation
// Showing rules but not showing goals would be strange anyway
if ( pPlr )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Goals
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_MENU_CPGOALS " ) , GfxR - > fctMenu . GetPhase ( 4 ) , " ActivateMenu:Goals " , LoadResStr ( " IDS_MENU_CPGOALSINFO " ) ) ;
2009-05-08 13:28:41 +00:00
// Rules
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_MENU_CPRULES " ) , GfxR - > fctMenu . GetPhase ( 5 ) , " ActivateMenu:Rules " , LoadResStr ( " IDS_MENU_CPRULESINFO " ) ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Observer menu in free viewport
if ( ! pPlr )
2010-03-28 18:58:01 +00:00
{
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_TEXT_VIEW " ) , C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_View ) , " ActivateMenu:Observer " , LoadResStr ( " IDS_TEXT_DETERMINEPLAYERVIEWTOFOLL " ) ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Hostility (player menu only)
2009-06-12 23:09:32 +00:00
if ( pPlr & & ( : : Players . GetCount ( ) > 1 ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
GfxR - > fctFlagClr . Surface - > SetClr ( 0xff0000 ) ;
2016-01-30 01:19:36 +00:00
AddRefSym ( LoadResStr ( " IDS_MENU_CPATTACK " ) , C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_MeleeLeague ) , " ActivateMenu:Hostility " , LoadResStr ( " IDS_MENU_CPATTACKINFO " ) ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Team change
if ( pPlr & & Game . Teams . IsTeamSwitchAllowed ( ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
C4Facet fctTeams ; fctTeams = C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_Team ) ;
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_MSG_SELTEAM " ) , fctTeams , " ActivateMenu:TeamSel " , LoadResStr ( " IDS_MSG_ALLOWSYOUTOJOINADIFFERENT " ) ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Player join
2009-06-12 23:09:32 +00:00
if ( ( : : Players . GetCount ( ) < Game . Parameters . MaxPlayers ) & & ! Game . Parameters . isLeague ( ) )
2010-03-28 18:58:01 +00:00
{
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_MENU_CPNEWPLAYER " ) , GfxR - > fctPlayerClr . GetPhase ( ) , " ActivateMenu:NewPlayer " , LoadResStr ( " IDS_MENU_CPNEWPLAYERINFO " ) ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Save game (player menu only - should we allow saving games with no players in it?)
2009-06-05 15:19:46 +00:00
if ( pPlr & & ( ! : : Network . isEnabled ( ) | | : : Network . isHost ( ) ) )
2010-03-28 18:58:01 +00:00
{
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_MENU_CPSAVEGAME " ) , GfxR - > fctMenu . GetPhase ( 0 ) , " ActivateMenu:Save:Game " , LoadResStr ( " IDS_MENU_CPSAVEGAMEINFO " ) ) ;
2011-03-27 16:22:55 +00:00
}
2009-05-08 13:28:41 +00:00
// Options
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_MNU_OPTIONS " ) , GfxR - > fctOptions . GetPhase ( 0 ) , " ActivateMenu:Options " , LoadResStr ( " IDS_MNU_OPTIONSINFO " ) ) ;
2009-05-08 13:28:41 +00:00
// Disconnect
2009-06-05 15:19:46 +00:00
if ( : : Network . isEnabled ( ) )
2009-05-08 13:28:41 +00:00
{
// Host
2010-03-28 18:58:01 +00:00
if ( : : Network . isHost ( ) & & Game . Clients . getClient ( NULL ) )
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_MENU_DISCONNECT " ) , C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_Disconnect ) , " ActivateMenu:Host " , LoadResStr ( " IDS_TEXT_KICKCERTAINCLIENTSFROMTHE " ) ) ;
2009-05-08 13:28:41 +00:00
// Client
2009-06-05 15:19:46 +00:00
if ( ! : : Network . isHost ( ) )
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_MENU_DISCONNECT " ) , C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_Disconnect ) , " ActivateMenu:Client " , LoadResStr ( " IDS_TEXT_DISCONNECTTHEGAMEFROMTHES " ) ) ;
2009-05-08 13:28:41 +00:00
}
// Surrender (player menu only)
if ( pPlr )
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_MENU_CPSURRENDER " ) , C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_Surrender ) , " ActivateMenu:Surrender " , LoadResStr ( " IDS_MENU_CPSURRENDERINFO " ) ) ;
2009-05-08 13:28:41 +00:00
// Abort
2010-09-28 18:16:33 +00:00
if ( ! Application . isEditor )
2016-01-27 04:16:33 +00:00
AddRefSym ( LoadResStr ( " IDS_MENU_ABORT " ) , C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_Exit ) , " Abort " , LoadResStr ( " IDS_MENU_ABORT_DESC " ) ) ;
2009-05-08 13:28:41 +00:00
// No empty menus
if ( GetItemCount ( ) = = 0 ) Close ( false ) ;
// Done
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MainMenu : : ActivateHostility ( int32_t iPlayer )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Init menu
2016-01-30 01:19:36 +00:00
InitRefSym ( GfxR - > fctMenu . GetPhase ( 7 ) , LoadResStr ( " IDS_MENU_CPATTACK " ) , iPlayer , C4MN_Hostility ) ;
2009-05-08 13:28:41 +00:00
SetAlignment ( C4MN_Align_Left | C4MN_Align_Bottom ) ;
SetPermanent ( true ) ;
Refill ( ) ;
// Go back to options menu on close
SetCloseCommand ( " ActivateMenu:Main " ) ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MainMenu : : MenuCommand ( const char * szCommand , bool fIsCloseCommand )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Determine player
2009-06-12 23:09:32 +00:00
C4Player * pPlr = : : Players . Get ( Player ) ;
2009-05-08 13:28:41 +00:00
// Activate
if ( SEqual2 ( szCommand , " ActivateMenu: " ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
if ( C4GameOverDlg : : IsShown ( ) ) return false ; // no new menus during game over dlg
if ( SEqual ( szCommand + 13 , " Main " ) ) return ActivateMain ( Player ) ;
if ( SEqual ( szCommand + 13 , " Hostility " ) ) return ActivateHostility ( Player ) ;
if ( SEqual ( szCommand + 13 , " NewPlayer " ) ) return ActivateNewPlayer ( Player ) ;
if ( SEqual ( szCommand + 13 , " Goals " ) )
2010-03-28 18:58:01 +00:00
{
2013-09-02 20:22:29 +00:00
: : Control . DoInput ( CID_PlrAction , C4ControlPlayerAction : : ActivateGoalMenu ( : : Players . Get ( Player ) ) , CDT_Queue ) ;
2009-05-08 13:28:41 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
if ( SEqual ( szCommand + 13 , " Rules " ) ) return ActivateRules ( Player ) ;
if ( SEqual ( szCommand + 13 , " Host " ) ) return ActivateHost ( Player ) ;
if ( SEqual ( szCommand + 13 , " Client " ) ) return ActivateClient ( Player ) ;
if ( SEqual ( szCommand + 13 , " Options " ) ) return ActivateOptions ( Player ) ;
if ( SEqual ( szCommand + 13 , " Display " ) ) return ActivateDisplay ( Player ) ;
if ( SEqual ( szCommand + 13 , " Save:Game " ) ) return ActivateSavegame ( Player ) ;
if ( SEqual ( szCommand + 13 , " TeamSel " ) ) return pPlr ? pPlr - > ActivateMenuTeamSelection ( true ) : false ;
if ( SEqual ( szCommand + 13 , " Surrender " ) ) return ActivateSurrender ( Player ) ;
if ( SEqual ( szCommand + 13 , " Observer " ) ) return ActivateObserver ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// JoinPlayer
if ( SEqual2 ( szCommand , " JoinPlayer: " ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// not in league or replay mode
if ( Game . Parameters . isLeague ( ) | | Game . C4S . Head . Replay ) return false ;
// join player
2011-04-08 21:52:40 +00:00
// 2do: not for observers and such?
Players . JoinNew ( szCommand + 11 ) ;
2009-05-08 13:28:41 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// SetHostility
if ( SEqual2 ( szCommand , " SetHostility: " ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// only if allowed
if ( ! Game . Teams . IsHostilityChangeAllowed ( ) ) return false ;
2010-03-27 16:05:02 +00:00
int32_t iOpponent ; sscanf ( szCommand + 13 , " %i " , & iOpponent ) ;
2009-06-12 23:09:32 +00:00
C4Player * pOpponent = : : Players . Get ( iOpponent ) ;
2009-05-08 13:28:41 +00:00
if ( ! pOpponent | | pOpponent - > GetType ( ) ! = C4PT_User ) return false ;
2013-09-02 20:22:29 +00:00
: : Control . DoInput ( CID_PlrAction , C4ControlPlayerAction : : SetHostility ( : : Players . Get ( Player ) , pOpponent , ! : : Players . HostilityDeclared ( Player , pOpponent - > Number ) ) , CDT_Queue ) ;
2009-05-08 13:28:41 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Abort
if ( SEqual2 ( szCommand , " Abort " ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
FullScreen . ShowAbortDlg ( ) ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Surrender
if ( SEqual2 ( szCommand , " Surrender " ) )
2010-03-28 18:58:01 +00:00
{
2013-09-02 20:22:29 +00:00
: : Control . DoInput ( CID_PlrAction , C4ControlPlayerAction : : Surrender ( : : Players . Get ( Player ) ) , CDT_Queue ) ;
2009-05-08 13:28:41 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Save game
if ( SEqual2 ( szCommand , " Save:Game: " ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
char strFilename [ _MAX_PATH + 1 ] ; SCopySegment ( szCommand , 2 , strFilename , ' : ' , _MAX_PATH ) ;
char strTitle [ _MAX_PATH + 1 ] ; SCopy ( szCommand + SCharPos ( ' : ' , szCommand , 2 ) + 1 , strTitle , _MAX_PATH ) ;
Game . QuickSave ( strFilename , strTitle ) ;
ActivateSavegame ( Player ) ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Kick
if ( SEqual2 ( szCommand , " Host:Kick: " ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
int iClientID = atoi ( szCommand + 10 ) ;
2010-03-28 18:58:01 +00:00
if ( iClientID & & : : Network . isEnabled ( ) )
{
if ( Game . Parameters . isLeague ( ) & & : : Players . GetAtClient ( iClientID ) )
2009-06-05 15:19:46 +00:00
: : Network . Vote ( VT_Kick , true , iClientID ) ;
2009-05-08 13:28:41 +00:00
else
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
C4Client * pClient = Game . Clients . getClientByID ( iClientID ) ;
if ( pClient ) Game . Clients . CtrlRemove ( pClient , LoadResStr ( " IDS_MSG_KICKBYMENU " ) ) ;
Close ( true ) ;
2010-01-25 04:00:59 +00:00
}
2009-05-08 13:28:41 +00:00
}
2010-03-28 18:58:01 +00:00
return true ;
}
2009-05-08 13:28:41 +00:00
// Part
if ( SEqual2 ( szCommand , " Part " ) )
2010-03-28 18:58:01 +00:00
{
if ( : : Network . isEnabled ( ) )
2009-05-08 13:28:41 +00:00
{
2010-03-28 18:58:01 +00:00
if ( Game . Parameters . isLeague ( ) & & : : Players . GetLocalByIndex ( 0 ) )
2009-06-15 22:06:37 +00:00
: : Network . Vote ( VT_Kick , true , : : Control . ClientID ( ) ) ;
2009-05-08 13:28:41 +00:00
else
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Game . RoundResults . EvaluateNetwork ( C4RoundResults : : NR_NetError , LoadResStr ( " IDS_ERR_GAMELEFTVIAPLAYERMENU " ) ) ;
2009-06-05 15:19:46 +00:00
: : Network . Clear ( ) ;
2010-01-25 04:00:59 +00:00
}
2009-05-08 13:28:41 +00:00
}
2010-03-28 18:58:01 +00:00
return true ;
}
2009-05-08 13:28:41 +00:00
// Options
if ( SEqual2 ( szCommand , " Options: " ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Music
if ( SEqual ( szCommand + 8 , " Music " ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Application . MusicSystem . ToggleOnOff ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Sound
if ( SEqual ( szCommand + 8 , " Sound " ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
if ( Config . Sound . RXSound )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Application . SoundSystem . Clear ( ) ;
Config . Sound . RXSound = false ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
else
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Config . Sound . RXSound = true ;
if ( ! Application . SoundSystem . Init ( ) )
{ Log ( LoadResStr ( " IDS_PRC_NOSND " ) ) ; }
}
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Reopen with updated options
ActivateOptions ( Player , GetSelection ( ) ) ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Display
if ( SEqual2 ( szCommand , " Display: " ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Upper board
if ( SEqual ( szCommand + 8 , " UpperBoard " ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Config . Graphics . UpperBoard = ! Config . Graphics . UpperBoard ;
2010-09-29 01:44:05 +00:00
: : Viewports . RecalculateViewports ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// FPS
if ( SEqual ( szCommand + 8 , " FPS " ) ) Config . General . FPS = ! Config . General . FPS ;
// Player names
if ( SEqual ( szCommand + 8 , " PlayerNames " ) ) Config . Graphics . ShowCrewNames = ! Config . Graphics . ShowCrewNames ;
// Clonk names
if ( SEqual ( szCommand + 8 , " ClonkNames " ) ) Config . Graphics . ShowCrewCNames = ! Config . Graphics . ShowCrewCNames ;
// Clock
if ( SEqual ( szCommand + 8 , " Clock " ) ) Config . Graphics . ShowClock = ! Config . Graphics . ShowClock ;
// Reopen with updated options
ActivateDisplay ( Player , GetSelection ( ) ) ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Goal info
if ( SEqual2 ( szCommand , " Player:Goal: " ) | | SEqual2 ( szCommand , " Player:Rule: " ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
if ( ! ValidPlr ( Player ) ) return false ; // observers may not look at goal/rule info, because it requires queue activation
Close ( true ) ;
2013-03-03 18:25:18 +00:00
C4Object * pObj ; C4ID idItem ( szCommand + 12 ) ; C4Def * pDef = C4Id2Def ( idItem ) ;
if ( pDef & & ( pObj = : : Objects . Find ( pDef ) ) )
2013-09-02 20:22:29 +00:00
: : Control . DoInput ( CID_PlrAction , C4ControlPlayerAction : : ActivateGoal ( : : Players . Get ( Player ) , pObj ) , CDT_Queue ) ;
2009-05-08 13:28:41 +00:00
else
return false ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Team selection
if ( SEqual2 ( szCommand , " TeamSel: " ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Close ( true ) ;
int32_t idTeam = atoi ( szCommand + 8 ) ;
// OK, join this team
if ( pPlr ) pPlr - > DoTeamSelection ( idTeam ) ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Team switch
if ( SEqual2 ( szCommand , " TeamSwitch: " ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Close ( true ) ;
int32_t idTeam = atoi ( szCommand + 11 ) ;
// check if it's still allowed
if ( ! Game . Teams . IsTeamSwitchAllowed ( ) ) return false ;
// OK, join this team
2013-09-02 20:22:29 +00:00
: : Control . DoInput ( CID_PlrAction , C4ControlPlayerAction : : SetTeam ( : : Players . Get ( Player ) , idTeam ) , CDT_Queue ) ;
2009-05-08 13:28:41 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Observe
if ( SEqual2 ( szCommand , " Observe: " ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
const char * szObserverTarget = szCommand + 8 ;
2010-09-29 01:44:05 +00:00
C4Viewport * pVP = : : Viewports . GetViewport ( NO_OWNER ) ;
2009-05-08 13:28:41 +00:00
if ( pVP ) // viewport may have closed meanwhile
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
if ( SEqual ( szObserverTarget , " Free " ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// free view
pVP - > Init ( NO_OWNER , true ) ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
else
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// view following player
int32_t iPlr = atoi ( szObserverTarget ) ;
if ( ValidPlr ( iPlr ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
pVP - > Init ( iPlr , true ) ;
return true ;
}
}
}
2010-03-28 18:58:01 +00:00
return false ;
}
2009-05-08 13:28:41 +00:00
// No valid command
return false ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MainMenu : : ActivateCommand ( int32_t iPlayer , const char * szCommand )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// init menu for player and activate with command
Player = iPlayer ;
return MenuCommand ( szCommand , false ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MainMenu : : ActivateObserver ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Safety: Viewport lost?
2010-09-29 01:44:05 +00:00
if ( ! : : Viewports . GetViewport ( NO_OWNER ) ) return false ;
2009-05-08 13:28:41 +00:00
// Menu symbol/init
2016-01-27 04:16:33 +00:00
InitRefSym ( C4GUI : : Icon : : GetIconFacet ( C4GUI : : Ico_View ) , LoadResStr ( " IDS_TEXT_VIEW " ) , NO_OWNER , C4MN_Observer , C4MN_Style_Context ) ;
2009-05-08 13:28:41 +00:00
SetAlignment ( C4MN_Align_Left | C4MN_Align_Bottom ) ;
// Players added in Refill
Refill ( ) ;
// Go back to main menu on close
SetCloseCommand ( " ActivateMenu:Main " ) ;
return true ;
2010-03-28 18:58:01 +00:00
}