2005-07-24 14:12:37 +00:00
/* $Id$ */
2006-10-12 14:13:39 +00:00
# ifdef ENABLE_NETWORK
2007-01-02 17:34:03 +00:00
# include "../stdafx.h"
# include "../openttd.h"
2007-12-21 19:49:27 +00:00
# include "../strings_func.h"
2004-12-04 17:54:56 +00:00
# include "network.h"
2007-12-26 13:50:40 +00:00
# include "../date_func.h"
2007-01-02 17:34:03 +00:00
# include "../fios.h"
2004-12-04 17:54:56 +00:00
# include "network_data.h"
2006-06-11 16:00:56 +00:00
# include "network_client.h"
2006-10-12 14:13:39 +00:00
# include "network_gui.h"
2004-12-20 22:14:39 +00:00
# include "network_gamelist.h"
2007-01-02 17:34:03 +00:00
# include "../gui.h"
2007-12-19 20:45:46 +00:00
# include "../window_gui.h"
# include "../textbuf_gui.h"
2007-01-02 17:34:03 +00:00
# include "../variables.h"
2004-12-04 17:54:56 +00:00
# include "network_server.h"
# include "network_udp.h"
2007-01-02 17:34:03 +00:00
# include "../town.h"
# include "../newgrf.h"
2007-12-25 11:26:07 +00:00
# include "../functions.h"
# include "../window_func.h"
2008-01-07 14:02:26 +00:00
# include "../core/alloc_func.hpp"
2008-01-07 14:23:25 +00:00
# include "../string_func.h"
2008-01-09 09:45:45 +00:00
# include "../gfx_func.h"
2008-01-12 14:10:35 +00:00
# include "../player_func.h"
2008-01-13 14:37:30 +00:00
# include "../settings_type.h"
2008-01-14 16:10:58 +00:00
# include "../widgets/dropdown_func.h"
2004-08-09 17:04:08 +00:00
2008-01-13 01:21:35 +00:00
# include "table/strings.h"
# include "../table/sprites.h"
2004-08-09 17:04:08 +00:00
# define BGC 5
# define BTC 15
2006-01-26 16:19:24 +00:00
2007-12-19 20:45:46 +00:00
struct chatquerystr_d : public querystr_d {
2008-03-24 06:32:53 +00:00
DestType dtype ;
2007-12-19 20:45:46 +00:00
int dest ;
} ;
assert_compile ( WINDOW_CUSTOM_SIZE > = sizeof ( chatquerystr_d ) ) ;
2007-03-07 12:11:48 +00:00
struct network_d {
2006-04-29 14:31:16 +00:00
PlayerID company ; // select company in network lobby
2006-01-26 17:10:11 +00:00
byte field ; // select text-field in start-server and game-listing
2007-08-14 12:13:12 +00:00
byte widget_id ; ///< The widget that has the pop-up input menu
2006-01-26 17:10:11 +00:00
NetworkGameList * server ; // selected server in lobby and game-listing
FiosItem * map ; // selected map in start-server
2007-03-07 12:11:48 +00:00
} ;
2006-01-26 16:19:24 +00:00
assert_compile ( WINDOW_CUSTOM_SIZE > = sizeof ( network_d ) ) ;
2007-03-07 12:11:48 +00:00
struct network_ql_d {
2006-01-26 17:10:11 +00:00
network_d n ; // see above; general stuff
querystr_d q ; // text-input in start-server and game-listing
NetworkGameList * * sort_list ; // list of games (sorted)
list_d l ; // accompanying list-administration
2007-03-07 12:11:48 +00:00
} ;
2006-01-26 17:10:11 +00:00
assert_compile ( WINDOW_CUSTOM_SIZE > = sizeof ( network_ql_d ) ) ;
/* Global to remember sorting after window has been closed */
2006-09-03 23:27:38 +00:00
static Listing _ng_sorting ;
2006-01-26 16:19:24 +00:00
2008-03-24 06:38:20 +00:00
static char _edit_str_net_buf [ 150 ] ;
2006-08-20 10:51:27 +00:00
static bool _chat_tab_completion_active ;
2006-04-07 09:15:17 +00:00
2007-03-07 11:47:46 +00:00
static void ShowNetworkStartServerWindow ( ) ;
2006-01-26 16:19:24 +00:00
static void ShowNetworkLobbyWindow ( NetworkGameList * ngl ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 10:00:30 +00:00
extern void SwitchMode ( int new_mode ) ;
2004-08-09 17:04:08 +00:00
static const StringID _connection_types_dropdown [ ] = {
2004-12-15 21:54:07 +00:00
STR_NETWORK_LAN_INTERNET ,
STR_NETWORK_INTERNET_ADVERTISE ,
2004-08-09 17:04:08 +00:00
INVALID_STRING_ID
} ;
2004-12-22 18:42:56 +00:00
static const StringID _lan_internet_types_dropdown [ ] = {
STR_NETWORK_LAN ,
STR_NETWORK_INTERNET ,
INVALID_STRING_ID
} ;
2007-06-04 19:49:00 +00:00
static StringID _language_dropdown [ NETLANG_COUNT + 1 ] = { STR_NULL } ;
2007-06-04 16:07:22 +00:00
2007-07-25 00:16:30 +00:00
void SortNetworkLanguages ( )
{
2007-06-04 19:49:00 +00:00
/* Init the strings */
if ( _language_dropdown [ 0 ] = = STR_NULL ) {
for ( int i = 0 ; i < NETLANG_COUNT ; i + + ) _language_dropdown [ i ] = STR_NETWORK_LANG_ANY + i ;
_language_dropdown [ NETLANG_COUNT ] = INVALID_STRING_ID ;
2007-06-04 16:07:22 +00:00
}
2007-06-04 19:49:00 +00:00
/* Sort the strings (we don't move 'any' and the 'invalid' one) */
qsort ( & _language_dropdown [ 1 ] , NETLANG_COUNT - 1 , sizeof ( StringID ) , & StringIDSorter ) ;
2007-06-04 16:07:22 +00:00
}
2007-06-01 23:06:01 +00:00
2004-09-12 14:12:33 +00:00
enum {
2006-01-25 19:03:50 +00:00
NET_PRC__OFFSET_TOP_WIDGET = 54 ,
2006-01-26 16:19:24 +00:00
NET_PRC__OFFSET_TOP_WIDGET_COMPANY = 52 ,
2006-01-25 19:03:50 +00:00
NET_PRC__SIZE_OF_ROW = 14 ,
2004-09-12 14:12:33 +00:00
} ;
2006-11-06 00:14:36 +00:00
/** Update the network new window because a new server is
* found on the network .
* @ param unselect unselect the currently selected item */
2005-01-05 10:47:59 +00:00
void UpdateNetworkGameWindow ( bool unselect )
{
2006-11-06 00:14:36 +00:00
SendWindowMessage ( WC_NETWORK_WINDOW , 0 , unselect , 0 , 0 ) ;
2005-01-05 10:47:59 +00:00
}
2006-01-26 17:10:11 +00:00
static bool _internal_sort_order ; // Used for Qsort order-flipping
typedef int CDECL NGameNameSortFunction ( const void * , const void * ) ;
/** Qsort function to sort by name. */
static int CDECL NGameNameSorter ( const void * a , const void * b )
{
const NetworkGameList * cmp1 = * ( const NetworkGameList * * ) a ;
const NetworkGameList * cmp2 = * ( const NetworkGameList * * ) b ;
2006-01-26 17:32:49 +00:00
int r = strcasecmp ( cmp1 - > info . server_name , cmp2 - > info . server_name ) ;
2006-01-26 17:10:11 +00:00
2006-10-17 23:34:12 +00:00
return _internal_sort_order ? - r : r ;
2006-01-26 17:10:11 +00:00
}
/** Qsort function to sort by the amount of clients online on a
* server . If the two servers have the same amount , the one with the
* higher maximum is preferred . */
static int CDECL NGameClientSorter ( const void * a , const void * b )
{
const NetworkGameList * cmp1 = * ( const NetworkGameList * * ) a ;
const NetworkGameList * cmp2 = * ( const NetworkGameList * * ) b ;
/* Reverse as per default we are interested in most-clients first */
2006-07-30 14:57:28 +00:00
int r = cmp1 - > info . clients_on - cmp2 - > info . clients_on ;
2006-01-26 17:10:11 +00:00
if ( r = = 0 ) r = cmp1 - > info . clients_max - cmp2 - > info . clients_max ;
2006-01-29 20:24:18 +00:00
if ( r = = 0 ) r = strcasecmp ( cmp1 - > info . server_name , cmp2 - > info . server_name ) ;
2006-01-26 17:10:11 +00:00
2006-10-17 23:34:12 +00:00
return _internal_sort_order ? - r : r ;
2006-01-26 17:10:11 +00:00
}
/** Qsort function to sort by joinability. If both servers are the
* same , prefer the non - passworded server first . */
static int CDECL NGameAllowedSorter ( const void * a , const void * b )
{
const NetworkGameList * cmp1 = * ( const NetworkGameList * * ) a ;
const NetworkGameList * cmp2 = * ( const NetworkGameList * * ) b ;
2007-01-14 16:44:52 +00:00
/* The servers we do not know anything about (the ones that did not reply) should be at the bottom) */
int r = StrEmpty ( cmp1 - > info . server_revision ) - StrEmpty ( cmp2 - > info . server_revision ) ;
/* Reverse default as we are interested in version-compatible clients first */
if ( r = = 0 ) r = cmp2 - > info . version_compatible - cmp1 - > info . version_compatible ;
/* The version-compatible ones are then sorted with NewGRF compatible first, incompatible last */
if ( r = = 0 ) r = cmp2 - > info . compatible - cmp1 - > info . compatible ;
/* Passworded servers should be below unpassworded servers */
2006-01-26 17:10:11 +00:00
if ( r = = 0 ) r = cmp1 - > info . use_password - cmp2 - > info . use_password ;
2007-01-14 16:44:52 +00:00
/* Finally sort on the name of the server */
2006-01-29 20:24:18 +00:00
if ( r = = 0 ) r = strcasecmp ( cmp1 - > info . server_name , cmp2 - > info . server_name ) ;
2006-01-26 17:10:11 +00:00
2006-10-17 23:34:12 +00:00
return _internal_sort_order ? - r : r ;
2006-01-26 17:10:11 +00:00
}
/** (Re)build the network game list as its amount has changed because
* an item has been added or deleted for example
* @ param ngl list_d struct that contains all necessary information for sorting */
static void BuildNetworkGameList ( network_ql_d * nqld )
{
NetworkGameList * ngl_temp ;
uint n = 0 ;
if ( ! ( nqld - > l . flags & VL_REBUILD ) ) return ;
/* Count the number of games in the list */
for ( ngl_temp = _network_game_list ; ngl_temp ! = NULL ; ngl_temp = ngl_temp - > next ) n + + ;
if ( n = = 0 ) return ;
/* Create temporary array of games to use for listing */
free ( nqld - > sort_list ) ;
2007-01-11 17:29:39 +00:00
nqld - > sort_list = MallocT < NetworkGameList * > ( n ) ;
2006-01-26 17:10:11 +00:00
nqld - > l . list_length = n ;
for ( n = 0 , ngl_temp = _network_game_list ; ngl_temp ! = NULL ; ngl_temp = ngl_temp - > next ) {
nqld - > sort_list [ n + + ] = ngl_temp ;
}
/* Force resort */
nqld - > l . flags & = ~ VL_REBUILD ;
nqld - > l . flags | = VL_RESORT ;
}
static void SortNetworkGameList ( network_ql_d * nqld )
{
2006-07-26 03:33:12 +00:00
static NGameNameSortFunction * const ngame_sorter [ ] = {
2006-05-16 21:13:41 +00:00
& NGameNameSorter ,
& NGameClientSorter ,
& NGameAllowedSorter
} ;
2006-01-26 17:10:11 +00:00
NetworkGameList * item ;
uint i ;
if ( ! ( nqld - > l . flags & VL_RESORT ) ) return ;
2006-05-16 21:13:41 +00:00
if ( nqld - > l . list_length = = 0 ) return ;
2006-01-26 17:10:11 +00:00
2006-10-17 23:34:12 +00:00
_internal_sort_order = ! ! ( nqld - > l . flags & VL_DESC ) ;
2006-05-16 21:13:41 +00:00
qsort ( nqld - > sort_list , nqld - > l . list_length , sizeof ( nqld - > sort_list [ 0 ] ) , ngame_sorter [ nqld - > l . sort_type ] ) ;
2006-01-26 17:10:11 +00:00
/* After sorting ngl->sort_list contains the sorted items. Put these back
* into the original list . Basically nothing has changed , we are only
* shuffling the - > next pointers */
_network_game_list = nqld - > sort_list [ 0 ] ;
for ( item = _network_game_list , i = 1 ; i ! = nqld - > l . list_length ; i + + ) {
item - > next = nqld - > sort_list [ i ] ;
item = item - > next ;
}
item - > next = NULL ;
nqld - > l . flags & = ~ VL_RESORT ;
}
2007-11-24 21:41:59 +00:00
/** Enum for NetworkGameWindow, referring to _network_game_window_widgets */
enum NetworkGameWindowWidgets {
NGWW_CLOSE = 0 , ///< Close 'X' button
2008-01-17 20:00:13 +00:00
NGWW_CONN_BTN = 4 , ///< 'Connection' droplist button
NGWW_PLAYER = 5 , ///< Panel with editbox to set player name
2007-11-24 21:41:59 +00:00
2008-01-17 20:00:13 +00:00
NGWW_NAME = 6 , ///< 'Name' button
2007-11-24 21:41:59 +00:00
NGWW_CLIENTS , ///< 'Clients' button
NGWW_INFO , ///< Third button in the game list panel
2008-01-17 20:00:13 +00:00
NGWW_MATRIX = 9 , ///< Panel with list of games
2007-11-24 21:41:59 +00:00
2008-01-17 20:00:13 +00:00
NGWW_DETAILS = 11 , ///< Panel with game details
NGWW_JOIN = 12 , ///< 'Join game' button
NGWW_REFRESH = 13 , ///< 'Refresh server' button
NGWW_NEWGRF = 14 , ///< 'NewGRF Settings' button
2007-11-24 21:41:59 +00:00
2008-01-17 20:00:13 +00:00
NGWW_FIND = 15 , ///< 'Find server' button
2007-11-24 21:41:59 +00:00
NGWW_ADD , ///< 'Add server' button
NGWW_START , ///< 'Start server' button
NGWW_CANCEL , ///< 'Cancel' button
} ;
/**
* Handler of actions done in the NetworkStartServer window
*
* @ param w pointer to the Window structure
* @ param e pointer to window event
* @ note Uses network_ql_d ( network_d , querystr_d and list_d ) WP macro
* @ see struct _network_game_window_widgets
* @ see enum NetworkGameWindowWidgets
*/
2004-08-09 17:04:08 +00:00
static void NetworkGameWindowWndProc ( Window * w , WindowEvent * e )
{
2006-01-26 17:10:11 +00:00
network_d * nd = & WP ( w , network_ql_d ) . n ;
list_d * ld = & WP ( w , network_ql_d ) . l ;
2006-01-26 16:19:24 +00:00
2005-04-06 18:44:34 +00:00
switch ( e - > event ) {
2007-11-24 21:41:59 +00:00
case WE_CREATE : // Focus input box
2007-07-27 19:57:52 +00:00
w - > vscroll . cap = 13 ;
w - > resize . step_height = NET_PRC__SIZE_OF_ROW ;
2007-11-24 21:41:59 +00:00
nd - > field = NGWW_PLAYER ;
2006-01-26 16:19:24 +00:00
nd - > server = NULL ;
2006-01-26 17:10:11 +00:00
WP ( w , network_ql_d ) . sort_list = NULL ;
2007-01-10 18:56:51 +00:00
ld - > flags = VL_REBUILD | ( _ng_sorting . order ? VL_DESC : VL_NONE ) ;
2006-01-26 17:10:11 +00:00
ld - > sort_type = _ng_sorting . criteria ;
2005-04-06 18:44:34 +00:00
break ;
2005-11-13 13:43:55 +00:00
2004-08-09 17:04:08 +00:00
case WE_PAINT : {
2006-01-26 16:19:24 +00:00
const NetworkGameList * sel = nd - > server ;
2008-01-18 10:36:55 +00:00
const SortButtonState arrow = ( ld - > flags & VL_DESC ) ? SBS_DOWN : SBS_UP ;
2006-01-26 17:10:11 +00:00
if ( ld - > flags & VL_REBUILD ) {
BuildNetworkGameList ( & WP ( w , network_ql_d ) ) ;
SetVScrollCount ( w , ld - > list_length ) ;
}
if ( ld - > flags & VL_RESORT ) SortNetworkGameList ( & WP ( w , network_ql_d ) ) ;
2005-07-15 18:43:39 +00:00
2007-11-24 21:41:59 +00:00
/* 'Refresh' button invisible if no server selected */
2007-12-02 14:29:48 +00:00
w - > SetWidgetDisabledState ( NGWW_REFRESH , sel = = NULL ) ;
2007-11-24 21:41:59 +00:00
/* 'Join' button disabling conditions */
2007-12-02 14:29:48 +00:00
w - > SetWidgetDisabledState ( NGWW_JOIN , sel = = NULL | | // no Selected Server
2006-10-03 02:08:15 +00:00
! sel - > online | | // Server offline
sel - > info . clients_on > = sel - > info . clients_max | | // Server full
! sel - > info . compatible ) ; // Revision mismatch
2004-09-10 19:02:27 +00:00
2007-11-24 21:41:59 +00:00
/* 'NewGRF Settings' button invisible if no NewGRF is used */
2007-12-02 14:29:48 +00:00
w - > SetWidgetHiddenState ( NGWW_NEWGRF , sel = = NULL | |
2006-12-18 12:26:55 +00:00
! sel - > online | |
sel - > info . grfconfig = = NULL ) ;
2004-12-02 22:53:07 +00:00
SetDParam ( 0 , 0x00 ) ;
2007-08-14 10:46:38 +00:00
SetDParam ( 1 , _lan_internet_types_dropdown [ _network_lan_internet ] ) ;
2004-08-09 17:04:08 +00:00
DrawWindowWidgets ( w ) ;
2004-09-10 19:02:27 +00:00
2007-11-24 21:41:59 +00:00
/* Edit box to set player name */
DrawEditBox ( w , & WP ( w , network_ql_d ) . q , NGWW_PLAYER ) ;
2004-09-10 19:02:27 +00:00
2007-11-24 21:41:59 +00:00
DrawString ( w - > widget [ NGWW_PLAYER ] . left - 100 , 23 , STR_NETWORK_PLAYER_NAME , TC_GOLD ) ;
2004-08-09 17:04:08 +00:00
2006-01-26 17:10:11 +00:00
/* Sort based on widgets: name, clients, compatibility */
switch ( ld - > sort_type ) {
2008-01-18 10:36:55 +00:00
case NGWW_NAME - NGWW_NAME : DrawSortButtonState ( w , NGWW_NAME , arrow ) ; break ;
case NGWW_CLIENTS - NGWW_NAME : DrawSortButtonState ( w , NGWW_CLIENTS , arrow ) ; break ;
case NGWW_INFO - NGWW_NAME : DrawSortButtonState ( w , NGWW_INFO , arrow ) ; break ;
2006-01-26 17:10:11 +00:00
}
2004-09-12 14:12:33 +00:00
{ // draw list of games
uint16 y = NET_PRC__OFFSET_TOP_WIDGET + 3 ;
int32 n = 0 ;
2004-12-27 10:24:38 +00:00
int32 pos = w - > vscroll . pos ;
2007-11-24 21:41:59 +00:00
uint max_name_width = w - > widget [ NGWW_NAME ] . right - w - > widget [ NGWW_NAME ] . left - 5 ;
2004-12-04 17:54:56 +00:00
const NetworkGameList * cur_item = _network_game_list ;
2004-12-27 10:24:38 +00:00
while ( pos > 0 & & cur_item ! = NULL ) {
pos - - ;
2004-12-26 22:09:34 +00:00
cur_item = cur_item - > next ;
}
2004-12-27 10:24:38 +00:00
2004-09-12 14:12:33 +00:00
while ( cur_item ! = NULL ) {
2007-11-24 21:41:59 +00:00
/* show highlighted item with a different colour */
if ( cur_item = = sel ) GfxFillRect ( w - > widget [ NGWW_NAME ] . left + 1 , y - 2 , w - > widget [ NGWW_INFO ] . right - 1 , y + 9 , 10 ) ;
2004-09-12 14:12:33 +00:00
2005-07-17 16:01:26 +00:00
SetDParamStr ( 0 , cur_item - > info . server_name ) ;
2007-11-24 21:41:59 +00:00
DrawStringTruncated ( w - > widget [ NGWW_NAME ] . left + 5 , y , STR_02BD , TC_BLACK , max_name_width ) ;
2004-09-12 14:12:33 +00:00
2004-12-04 17:54:56 +00:00
SetDParam ( 0 , cur_item - > info . clients_on ) ;
SetDParam ( 1 , cur_item - > info . clients_max ) ;
2006-01-25 18:11:06 +00:00
SetDParam ( 2 , cur_item - > info . companies_on ) ;
SetDParam ( 3 , cur_item - > info . companies_max ) ;
2007-11-24 21:41:59 +00:00
DrawStringCentered ( w - > widget [ NGWW_CLIENTS ] . left + 39 , y , STR_NETWORK_GENERAL_ONLINE , TC_GOLD ) ;
2004-09-12 14:12:33 +00:00
2007-11-24 21:41:59 +00:00
/* only draw icons if the server is online */
2004-12-10 22:01:17 +00:00
if ( cur_item - > online ) {
2007-11-24 21:41:59 +00:00
/* draw a lock if the server is password protected */
if ( cur_item - > info . use_password ) DrawSprite ( SPR_LOCK , PAL_NONE , w - > widget [ NGWW_INFO ] . left + 5 , y - 1 ) ;
2004-12-10 22:01:17 +00:00
2007-11-24 21:41:59 +00:00
/* draw red or green icon, depending on compatibility with server */
DrawSprite ( SPR_BLOT , ( cur_item - > info . compatible ? PALETTE_TO_GREEN : ( cur_item - > info . version_compatible ? PALETTE_TO_YELLOW : PALETTE_TO_RED ) ) , w - > widget [ NGWW_INFO ] . left + 15 , y ) ;
2004-12-10 22:01:17 +00:00
2007-11-24 21:41:59 +00:00
/* draw flag according to server language */
DrawSprite ( SPR_FLAGS_BASE + cur_item - > info . server_lang , PAL_NONE , w - > widget [ NGWW_INFO ] . left + 25 , y ) ;
2004-12-09 23:16:52 +00:00
}
2004-12-10 22:01:17 +00:00
cur_item = cur_item - > next ;
y + = NET_PRC__SIZE_OF_ROW ;
2005-10-23 13:04:44 +00:00
if ( + + n = = w - > vscroll . cap ) break ; // max number of games in the window
2004-09-12 14:12:33 +00:00
}
}
2004-12-04 17:54:56 +00:00
2006-01-25 19:03:50 +00:00
/* Draw the right menu */
2007-11-24 21:41:59 +00:00
GfxFillRect ( w - > widget [ NGWW_DETAILS ] . left + 1 , 43 , w - > widget [ NGWW_DETAILS ] . right - 1 , 92 , 157 ) ;
2005-07-15 18:43:39 +00:00
if ( sel = = NULL ) {
2007-11-24 21:41:59 +00:00
DrawStringCentered ( w - > widget [ NGWW_DETAILS ] . left + 115 , 58 , STR_NETWORK_GAME_INFO , TC_FROMSTRING ) ;
2005-07-15 18:43:39 +00:00
} else if ( ! sel - > online ) {
SetDParamStr ( 0 , sel - > info . server_name ) ;
2007-11-24 21:41:59 +00:00
DrawStringCentered ( w - > widget [ NGWW_DETAILS ] . left + 115 , 68 , STR_ORANGE , TC_FROMSTRING ) ; // game name
2004-12-04 17:54:56 +00:00
2007-11-24 21:41:59 +00:00
DrawStringCentered ( w - > widget [ NGWW_DETAILS ] . left + 115 , 132 , STR_NETWORK_SERVER_OFFLINE , TC_FROMSTRING ) ; // server offline
2004-12-04 17:54:56 +00:00
} else { // show game info
2006-01-25 19:03:50 +00:00
uint16 y = 100 ;
2007-11-24 21:41:59 +00:00
const uint16 x = w - > widget [ NGWW_DETAILS ] . left + 5 ;
2004-12-04 17:54:56 +00:00
2007-11-24 21:41:59 +00:00
DrawStringCentered ( w - > widget [ NGWW_DETAILS ] . left + 115 , 48 , STR_NETWORK_GAME_INFO , TC_FROMSTRING ) ;
2004-12-04 17:54:56 +00:00
2005-07-14 09:43:59 +00:00
2005-07-15 18:43:39 +00:00
SetDParamStr ( 0 , sel - > info . server_name ) ;
2007-11-24 21:41:59 +00:00
DrawStringCenteredTruncated ( w - > widget [ NGWW_DETAILS ] . left , w - > widget [ NGWW_DETAILS ] . right , 62 , STR_ORANGE , TC_BLACK ) ; // game name
2004-12-04 17:54:56 +00:00
2005-07-15 18:43:39 +00:00
SetDParamStr ( 0 , sel - > info . map_name ) ;
2007-11-24 21:41:59 +00:00
DrawStringCenteredTruncated ( w - > widget [ NGWW_DETAILS ] . left , w - > widget [ NGWW_DETAILS ] . right , 74 , STR_02BD , TC_BLACK ) ; // map name
2004-12-04 17:54:56 +00:00
2005-07-15 18:43:39 +00:00
SetDParam ( 0 , sel - > info . clients_on ) ;
SetDParam ( 1 , sel - > info . clients_max ) ;
2006-01-25 18:11:06 +00:00
SetDParam ( 2 , sel - > info . companies_on ) ;
SetDParam ( 3 , sel - > info . companies_max ) ;
2007-11-04 00:08:57 +00:00
DrawString ( x , y , STR_NETWORK_CLIENTS , TC_GOLD ) ;
2005-11-14 19:48:04 +00:00
y + = 10 ;
2004-12-04 17:54:56 +00:00
2007-06-04 19:49:00 +00:00
SetDParam ( 0 , STR_NETWORK_LANG_ANY + sel - > info . server_lang ) ;
2007-11-04 00:08:57 +00:00
DrawString ( x , y , STR_NETWORK_LANGUAGE , TC_GOLD ) ; // server language
2005-11-14 19:48:04 +00:00
y + = 10 ;
2004-12-04 17:54:56 +00:00
2005-12-20 20:52:05 +00:00
SetDParam ( 0 , STR_TEMPERATE_LANDSCAPE + sel - > info . map_set ) ;
2007-11-04 00:08:57 +00:00
DrawString ( x , y , STR_NETWORK_TILESET , TC_GOLD ) ; // tileset
2005-11-14 19:48:04 +00:00
y + = 10 ;
2004-12-04 17:54:56 +00:00
2005-07-15 18:43:39 +00:00
SetDParam ( 0 , sel - > info . map_width ) ;
SetDParam ( 1 , sel - > info . map_height ) ;
2007-11-04 00:08:57 +00:00
DrawString ( x , y , STR_NETWORK_MAP_SIZE , TC_GOLD ) ; // map size
2005-11-14 19:48:04 +00:00
y + = 10 ;
2004-12-04 17:54:56 +00:00
2005-07-15 18:43:39 +00:00
SetDParamStr ( 0 , sel - > info . server_revision ) ;
2007-11-04 00:08:57 +00:00
DrawString ( x , y , STR_NETWORK_SERVER_VERSION , TC_GOLD ) ; // server version
2005-11-14 19:48:04 +00:00
y + = 10 ;
2004-12-04 17:54:56 +00:00
2005-07-15 18:43:39 +00:00
SetDParamStr ( 0 , sel - > info . hostname ) ;
SetDParam ( 1 , sel - > port ) ;
2007-11-04 00:08:57 +00:00
DrawString ( x , y , STR_NETWORK_SERVER_ADDRESS , TC_GOLD ) ; // server address
2005-11-14 19:48:04 +00:00
y + = 10 ;
2004-12-04 17:54:56 +00:00
2005-07-15 18:43:39 +00:00
SetDParam ( 0 , sel - > info . start_date ) ;
2007-11-04 00:08:57 +00:00
DrawString ( x , y , STR_NETWORK_START_DATE , TC_GOLD ) ; // start date
2005-11-14 19:48:04 +00:00
y + = 10 ;
2004-12-04 17:54:56 +00:00
2005-07-15 18:43:39 +00:00
SetDParam ( 0 , sel - > info . game_date ) ;
2007-11-04 00:08:57 +00:00
DrawString ( x , y , STR_NETWORK_CURRENT_DATE , TC_GOLD ) ; // current date
2005-11-14 19:48:04 +00:00
y + = 10 ;
2004-12-04 17:54:56 +00:00
2005-11-14 19:48:04 +00:00
y + = 2 ;
2004-12-13 14:57:58 +00:00
2006-01-25 19:03:50 +00:00
if ( ! sel - > info . compatible ) {
2007-11-24 21:41:59 +00:00
DrawStringCentered ( w - > widget [ NGWW_DETAILS ] . left + 115 , y , sel - > info . version_compatible ? STR_NETWORK_GRF_MISMATCH : STR_NETWORK_VERSION_MISMATCH , TC_FROMSTRING ) ; // server mismatch
2005-07-15 18:43:39 +00:00
} else if ( sel - > info . clients_on = = sel - > info . clients_max ) {
2007-11-24 21:41:59 +00:00
/* Show: server full, when clients_on == clients_max */
DrawStringCentered ( w - > widget [ NGWW_DETAILS ] . left + 115 , y , STR_NETWORK_SERVER_FULL , TC_FROMSTRING ) ; // server full
2005-11-14 19:48:04 +00:00
} else if ( sel - > info . use_password ) {
2007-11-24 21:41:59 +00:00
DrawStringCentered ( w - > widget [ NGWW_DETAILS ] . left + 115 , y , STR_NETWORK_PASSWORD , TC_FROMSTRING ) ; // password warning
2005-11-14 19:48:04 +00:00
}
2004-12-15 00:31:08 +00:00
2005-11-14 19:48:04 +00:00
y + = 10 ;
2004-12-04 17:54:56 +00:00
}
2007-04-18 22:41:53 +00:00
} break ;
2004-08-09 17:04:08 +00:00
case WE_CLICK :
2006-09-23 02:39:24 +00:00
nd - > field = e - > we . click . widget ;
switch ( e - > we . click . widget ) {
2007-11-24 21:41:59 +00:00
case NGWW_CANCEL : // Cancel button
2004-08-09 17:04:08 +00:00
DeleteWindowById ( WC_NETWORK_WINDOW , 0 ) ;
break ;
2008-01-17 20:00:13 +00:00
case NGWW_CONN_BTN : // 'Connection' droplist
2007-11-24 21:41:59 +00:00
ShowDropDownMenu ( w , _lan_internet_types_dropdown , _network_lan_internet , NGWW_CONN_BTN , 0 , 0 ) ; // do it for widget NSSW_CONN_BTN
2004-12-22 18:42:56 +00:00
break ;
2007-11-24 21:41:59 +00:00
case NGWW_NAME : // Sort by name
case NGWW_CLIENTS : // Sort by connected clients
case NGWW_INFO : // Connectivity (green dot)
if ( ld - > sort_type = = e - > we . click . widget - NGWW_NAME ) ld - > flags ^ = VL_DESC ;
2006-01-26 17:10:11 +00:00
ld - > flags | = VL_RESORT ;
2007-11-24 21:41:59 +00:00
ld - > sort_type = e - > we . click . widget - NGWW_NAME ;
2006-01-26 17:10:11 +00:00
_ng_sorting . order = ! ! ( ld - > flags & VL_DESC ) ;
_ng_sorting . criteria = ld - > sort_type ;
SetWindowDirty ( w ) ;
break ;
2007-11-24 21:41:59 +00:00
case NGWW_MATRIX : { // Matrix to show networkgames
2006-01-26 16:19:24 +00:00
NetworkGameList * cur_item ;
2006-09-23 02:39:24 +00:00
uint32 id_v = ( e - > we . click . pt . y - NET_PRC__OFFSET_TOP_WIDGET ) / NET_PRC__SIZE_OF_ROW ;
2004-09-12 14:12:33 +00:00
2005-10-23 13:04:44 +00:00
if ( id_v > = w - > vscroll . cap ) return ; // click out of bounds
2004-09-12 14:12:33 +00:00
id_v + = w - > vscroll . pos ;
2006-01-26 16:19:24 +00:00
cur_item = _network_game_list ;
for ( ; id_v > 0 & & cur_item ! = NULL ; id_v - - ) cur_item = cur_item - > next ;
2004-12-04 17:54:56 +00:00
2006-01-26 16:19:24 +00:00
nd - > server = cur_item ;
2004-12-04 17:54:56 +00:00
SetWindowDirty ( w ) ;
2004-09-12 14:12:33 +00:00
} break ;
2007-11-24 21:41:59 +00:00
case NGWW_FIND : // Find server automatically
2004-12-22 18:42:56 +00:00
switch ( _network_lan_internet ) {
case 0 : NetworkUDPSearchGame ( ) ; break ;
case 1 : NetworkUDPQueryMasterServer ( ) ; break ;
}
2004-09-12 14:12:33 +00:00
break ;
2007-11-24 21:41:59 +00:00
case NGWW_ADD : { // Add a server
ShowQueryString (
2005-07-14 09:43:59 +00:00
BindCString ( _network_default_ip ) ,
2004-12-04 17:54:56 +00:00
STR_NETWORK_ENTER_IP ,
31 | 0x1000 , // maximum number of characters OR
250 , // characters up to this width pixels, whichever is satisfied first
2006-12-30 01:17:53 +00:00
w , CS_ALPHANUMERAL ) ;
2004-12-04 17:54:56 +00:00
} break ;
2007-11-24 21:41:59 +00:00
case NGWW_START : // Start server
2004-12-04 17:54:56 +00:00
ShowNetworkStartServerWindow ( ) ;
break ;
2007-11-24 21:41:59 +00:00
case NGWW_JOIN : // Join Game
2006-01-26 16:19:24 +00:00
if ( nd - > server ! = NULL ) {
snprintf ( _network_last_host , sizeof ( _network_last_host ) , " %s " , inet_ntoa ( * ( struct in_addr * ) & nd - > server - > ip ) ) ;
_network_last_port = nd - > server - > port ;
ShowNetworkLobbyWindow ( nd - > server ) ;
2004-12-04 17:54:56 +00:00
}
break ;
2007-11-24 21:41:59 +00:00
case NGWW_REFRESH : // Refresh
2006-01-26 17:10:11 +00:00
if ( nd - > server ! = NULL )
2007-02-02 21:04:50 +00:00
NetworkUDPQueryServer ( nd - > server - > info . hostname , nd - > server - > port ) ;
2004-12-04 17:54:56 +00:00
break ;
2007-11-24 21:41:59 +00:00
case NGWW_NEWGRF : // NewGRF Settings
2006-12-21 10:29:16 +00:00
if ( nd - > server ! = NULL ) ShowNewGRFSettings ( false , false , false , & nd - > server - > info . grfconfig ) ;
2006-12-18 12:26:55 +00:00
break ;
2004-12-04 17:54:56 +00:00
2007-04-18 22:41:53 +00:00
} break ;
2004-09-06 22:46:02 +00:00
2007-11-24 21:41:59 +00:00
case WE_DROPDOWN_SELECT : // we have selected a dropdown item in the list
2006-09-23 02:39:24 +00:00
switch ( e - > we . dropdown . button ) {
2007-11-24 21:41:59 +00:00
case NGWW_CONN_BTN :
2006-09-23 02:39:24 +00:00
_network_lan_internet = e - > we . dropdown . index ;
2004-12-22 18:42:56 +00:00
break ;
2007-11-24 21:41:59 +00:00
default :
NOT_REACHED ( ) ;
2004-12-22 18:42:56 +00:00
}
SetWindowDirty ( w ) ;
break ;
2004-08-09 17:04:08 +00:00
case WE_MOUSELOOP :
2007-11-24 21:41:59 +00:00
if ( nd - > field = = NGWW_PLAYER ) HandleEditBox ( w , & WP ( w , network_ql_d ) . q , NGWW_PLAYER ) ;
2004-08-09 17:04:08 +00:00
break ;
2006-01-26 17:10:11 +00:00
case WE_MESSAGE :
2006-11-06 00:14:36 +00:00
if ( e - > we . message . msg ! = 0 ) nd - > server = NULL ;
2006-01-26 17:10:11 +00:00
ld - > flags | = VL_REBUILD ;
2006-01-25 19:03:50 +00:00
SetWindowDirty ( w ) ;
2006-01-26 17:10:11 +00:00
break ;
2006-01-25 19:03:50 +00:00
2004-08-09 17:04:08 +00:00
case WE_KEYPRESS :
2007-11-24 21:41:59 +00:00
if ( nd - > field ! = NGWW_PLAYER ) {
2006-01-26 16:19:24 +00:00
if ( nd - > server ! = NULL ) {
2007-11-24 21:41:59 +00:00
if ( e - > we . keypress . keycode = = WKC_DELETE ) { // Press 'delete' to remove servers
2006-01-26 16:19:24 +00:00
NetworkGameListRemoveItem ( nd - > server ) ;
2004-12-20 22:14:39 +00:00
NetworkRebuildHostList ( ) ;
2006-01-26 16:19:24 +00:00
nd - > server = NULL ;
2004-12-20 22:14:39 +00:00
}
}
2004-12-21 14:54:27 +00:00
break ;
}
2007-11-24 21:41:59 +00:00
if ( HandleEditBoxKey ( w , & WP ( w , network_ql_d ) . q , NGWW_PLAYER , e ) = = 1 ) break ; // enter pressed
2004-12-04 17:54:56 +00:00
2007-11-24 21:41:59 +00:00
/* The name is only allowed when it starts with a letter! */
2008-03-24 06:38:20 +00:00
if ( _edit_str_net_buf [ 0 ] ! = ' \0 ' & & _edit_str_net_buf [ 0 ] ! = ' ' ) {
ttd_strlcpy ( _network_player_name , _edit_str_net_buf , lengthof ( _network_player_name ) ) ;
2005-11-14 19:48:04 +00:00
} else {
2004-12-04 17:54:56 +00:00
ttd_strlcpy ( _network_player_name , " Player " , lengthof ( _network_player_name ) ) ;
2005-11-14 19:48:04 +00:00
}
2004-12-04 17:54:56 +00:00
2004-08-09 17:04:08 +00:00
break ;
2006-01-25 19:03:50 +00:00
case WE_ON_EDIT_TEXT :
2006-09-23 02:39:24 +00:00
NetworkAddServer ( e - > we . edittext . str ) ;
2004-12-20 22:14:39 +00:00
NetworkRebuildHostList ( ) ;
2006-01-25 19:03:50 +00:00
break ;
2006-01-26 17:10:11 +00:00
2007-07-27 19:57:52 +00:00
case WE_RESIZE : {
w - > vscroll . cap + = e - > we . sizing . diff . y / ( int ) w - > resize . step_height ;
2007-11-24 21:41:59 +00:00
w - > widget [ NGWW_MATRIX ] . data = ( w - > vscroll . cap < < 8 ) + 1 ;
2007-07-27 19:57:52 +00:00
2007-11-25 15:17:16 +00:00
SetVScrollCount ( w , ld - > list_length ) ;
2007-11-24 21:41:59 +00:00
int widget_width = w - > widget [ NGWW_FIND ] . right - w - > widget [ NGWW_FIND ] . left ;
2007-07-27 19:57:52 +00:00
int space = ( w - > width - 4 * widget_width - 25 ) / 3 ;
int offset = 10 ;
for ( uint i = 0 ; i < 4 ; i + + ) {
2007-11-24 21:41:59 +00:00
w - > widget [ NGWW_FIND + i ] . left = offset ;
2007-07-27 19:57:52 +00:00
offset + = widget_width ;
2007-11-24 21:41:59 +00:00
w - > widget [ NGWW_FIND + i ] . right = offset ;
2007-07-27 19:57:52 +00:00
offset + = space ;
}
} break ;
2007-11-24 21:41:59 +00:00
case WE_DESTROY : // Nicely clean up the sort-list
2006-01-26 17:10:11 +00:00
free ( WP ( w , network_ql_d ) . sort_list ) ;
break ;
2004-08-09 17:04:08 +00:00
}
}
static const Widget _network_game_window_widgets [ ] = {
2007-11-24 21:41:59 +00:00
/* TOP */
{ WWT_CLOSEBOX , RESIZE_NONE , BGC , 0 , 10 , 0 , 13 , STR_00C5 , STR_018B_CLOSE_WINDOW } , // NGWW_CLOSE
2007-08-14 10:46:38 +00:00
{ WWT_CAPTION , RESIZE_RIGHT , BGC , 11 , 449 , 0 , 13 , STR_NETWORK_MULTIPLAYER , STR_NULL } ,
{ WWT_PANEL , RESIZE_RB , BGC , 0 , 449 , 14 , 263 , 0x0 , STR_NULL } ,
2004-12-04 17:54:56 +00:00
2007-11-24 21:41:59 +00:00
{ WWT_TEXT , RESIZE_NONE , BGC , 9 , 85 , 23 , 35 , STR_NETWORK_CONNECTION , STR_NULL } ,
2008-01-17 20:00:13 +00:00
{ WWT_DROPDOWNIN , RESIZE_NONE , BGC , 90 , 181 , 22 , 33 , STR_NETWORK_LAN_INTERNET_COMBO , STR_NETWORK_CONNECTION_TIP } , // NGWW_CONN_BTN
2004-12-22 18:42:56 +00:00
2007-11-24 21:41:59 +00:00
{ WWT_PANEL , RESIZE_LR , BGC , 290 , 440 , 22 , 33 , 0x0 , STR_NETWORK_ENTER_NAME_TIP } , // NGWW_PLAYER
2004-08-09 17:04:08 +00:00
2007-11-24 21:41:59 +00:00
/* LEFT SIDE */
{ WWT_PUSHTXTBTN , RESIZE_RIGHT , BTC , 10 , 70 , 42 , 53 , STR_NETWORK_GAME_NAME , STR_NETWORK_GAME_NAME_TIP } , // NGWW_NAME
{ WWT_PUSHTXTBTN , RESIZE_LR , BTC , 71 , 150 , 42 , 53 , STR_NETWORK_CLIENTS_CAPTION , STR_NETWORK_CLIENTS_CAPTION_TIP } , // NGWW_CLIENTS
{ WWT_PUSHTXTBTN , RESIZE_LR , BTC , 151 , 190 , 42 , 53 , STR_EMPTY , STR_NETWORK_INFO_ICONS_TIP } , // NGWW_INFO
2004-08-09 17:04:08 +00:00
2007-11-24 21:41:59 +00:00
{ WWT_MATRIX , RESIZE_RB , BGC , 10 , 190 , 54 , 236 , ( 13 < < 8 ) + 1 , STR_NETWORK_CLICK_GAME_TO_SELECT } , // NGWW_MATRIX
{ WWT_SCROLLBAR , RESIZE_LRB , BGC , 191 , 202 , 42 , 236 , 0x0 , STR_0190_SCROLL_BAR_SCROLLS_LIST } ,
2004-08-09 17:04:08 +00:00
2004-12-04 17:54:56 +00:00
/* RIGHT SIDE */
2007-11-24 21:41:59 +00:00
{ WWT_PANEL , RESIZE_LRB , BGC , 210 , 440 , 42 , 236 , 0x0 , STR_NULL } , // NGWW_DETAILS
2007-07-27 19:57:52 +00:00
2007-11-24 21:41:59 +00:00
{ WWT_PUSHTXTBTN , RESIZE_LRTB , BTC , 215 , 315 , 215 , 226 , STR_NETWORK_JOIN_GAME , STR_NULL } , // NGWW_JOIN
{ WWT_PUSHTXTBTN , RESIZE_LRTB , BTC , 330 , 435 , 215 , 226 , STR_NETWORK_REFRESH , STR_NETWORK_REFRESH_TIP } , // NGWW_REFRESH
2006-12-18 12:26:55 +00:00
2007-11-24 21:41:59 +00:00
{ WWT_PUSHTXTBTN , RESIZE_LRTB , BTC , 330 , 435 , 197 , 208 , STR_NEWGRF_SETTINGS_BUTTON , STR_NULL } , // NGWW_NEWGRF
2004-12-04 17:54:56 +00:00
2007-11-24 21:41:59 +00:00
/* BOTTOM */
{ WWT_PUSHTXTBTN , RESIZE_TB , BTC , 10 , 110 , 246 , 257 , STR_NETWORK_FIND_SERVER , STR_NETWORK_FIND_SERVER_TIP } , // NGWW_FIND
{ WWT_PUSHTXTBTN , RESIZE_TB , BTC , 118 , 218 , 246 , 257 , STR_NETWORK_ADD_SERVER , STR_NETWORK_ADD_SERVER_TIP } , // NGWW_ADD
{ WWT_PUSHTXTBTN , RESIZE_TB , BTC , 226 , 326 , 246 , 257 , STR_NETWORK_START_SERVER , STR_NETWORK_START_SERVER_TIP } , // NGWW_START
{ WWT_PUSHTXTBTN , RESIZE_TB , BTC , 334 , 434 , 246 , 257 , STR_012E_CANCEL , STR_NULL } , // NGWW_CANCEL
2006-01-25 19:03:50 +00:00
2007-08-14 10:46:38 +00:00
{ WWT_RESIZEBOX , RESIZE_LRTB , BGC , 438 , 449 , 252 , 263 , 0x0 , STR_RESIZE_BUTTON } ,
2004-08-09 17:04:08 +00:00
2004-09-07 21:48:09 +00:00
{ WIDGETS_END } ,
2004-08-09 17:04:08 +00:00
} ;
static const WindowDesc _network_game_window_desc = {
2007-07-27 19:57:52 +00:00
WDP_CENTER , WDP_CENTER , 450 , 264 , 550 , 264 ,
2007-02-01 15:49:12 +00:00
WC_NETWORK_WINDOW , WC_NONE ,
2007-07-27 19:57:52 +00:00
WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE ,
2004-08-09 17:04:08 +00:00
_network_game_window_widgets ,
NetworkGameWindowWndProc ,
} ;
2007-03-07 11:47:46 +00:00
void ShowNetworkGameWindow ( )
2004-08-09 17:04:08 +00:00
{
2006-01-29 20:24:18 +00:00
static bool first = true ;
2004-08-09 17:04:08 +00:00
Window * w ;
DeleteWindowById ( WC_NETWORK_WINDOW , 0 ) ;
2004-08-22 10:23:37 +00:00
2004-12-22 18:42:56 +00:00
/* Only show once */
2006-01-29 20:24:18 +00:00
if ( first ) {
2006-01-26 13:01:53 +00:00
char * const * srv ;
2006-01-25 19:03:50 +00:00
2006-01-29 20:24:18 +00:00
first = false ;
2004-12-22 18:42:56 +00:00
// add all servers from the config file to our list
2006-01-26 13:01:53 +00:00
for ( srv = & _network_host_list [ 0 ] ; srv ! = endof ( _network_host_list ) & & * srv ! = NULL ; srv + + ) {
2006-01-25 19:03:50 +00:00
NetworkAddServer ( * srv ) ;
2004-12-22 18:42:56 +00:00
}
2006-01-29 20:24:18 +00:00
_ng_sorting . criteria = 2 ; // sort default by collectivity (green-dots on top)
_ng_sorting . order = 0 ; // sort ascending by default
2004-12-22 18:42:56 +00:00
}
2004-08-09 17:04:08 +00:00
w = AllocateWindowDesc ( & _network_game_window_desc ) ;
2006-01-26 16:19:24 +00:00
if ( w ! = NULL ) {
2006-07-26 03:33:12 +00:00
querystr_d * querystr = & WP ( w , network_ql_d ) . q ;
2006-04-07 09:15:17 +00:00
2008-03-24 06:38:20 +00:00
ttd_strlcpy ( _edit_str_net_buf , _network_player_name , lengthof ( _edit_str_net_buf ) ) ;
2006-10-21 22:50:57 +00:00
querystr - > afilter = CS_ALPHANUMERAL ;
2008-03-24 06:38:20 +00:00
InitializeTextBuffer ( & querystr - > text , _edit_str_net_buf , lengthof ( _edit_str_net_buf ) , 120 ) ;
2004-08-09 17:04:08 +00:00
2006-01-26 16:19:24 +00:00
UpdateNetworkGameWindow ( true ) ;
}
2004-12-04 17:54:56 +00:00
}
enum {
NSSWND_START = 64 ,
NSSWND_ROWSIZE = 12
} ;
2007-11-24 18:09:02 +00:00
/** Enum for NetworkStartServerWindow, referring to _network_start_server_window_widgets */
enum NetworkStartServerWidgets {
NSSW_CLOSE = 0 , ///< Close 'X' button
NSSW_GAMENAME = 4 , ///< Background for editbox to set game name
NSSW_SETPWD = 5 , ///< 'Set password' button
NSSW_SELMAP = 7 , ///< 'Select map' list
2008-01-17 20:00:13 +00:00
NSSW_CONNTYPE_BTN = 10 , ///< 'Connection type' droplist button
NSSW_CLIENTS_BTND = 12 , ///< 'Max clients' downarrow
NSSW_CLIENTS_TXT = 13 , ///< 'Max clients' text
NSSW_CLIENTS_BTNU = 14 , ///< 'Max clients' uparrow
NSSW_COMPANIES_BTND = 16 , ///< 'Max companies' downarrow
NSSW_COMPANIES_TXT = 17 , ///< 'Max companies' text
NSSW_COMPANIES_BTNU = 18 , ///< 'Max companies' uparrow
NSSW_SPECTATORS_BTND = 20 , ///< 'Max spectators' downarrow
NSSW_SPECTATORS_TXT = 21 , ///< 'Max spectators' text
NSSW_SPECTATORS_BTNU = 22 , ///< 'Max spectators' uparrow
NSSW_LANGUAGE_BTN = 24 , ///< 'Language spoken' droplist button
NSSW_START = 25 , ///< 'Start' button
NSSW_LOAD = 26 , ///< 'Load' button
NSSW_CANCEL = 27 , ///< 'Cancel' button
2007-11-24 18:09:02 +00:00
} ;
2007-11-24 21:49:49 +00:00
/**
* Handler of actions done in the NetworkStartServer window
*
* @ param w pointer to the Window structure
* @ param e pointer to window event
* @ note Uses network_ql_d ( network_d , querystr_d and list_d ) WP macro
* @ see struct _network_start_server_window_widgets
* @ see enum NetworkStartServerWidgets
*/
2004-08-09 17:04:08 +00:00
static void NetworkStartServerWindowWndProc ( Window * w , WindowEvent * e )
{
2006-01-26 17:10:11 +00:00
network_d * nd = & WP ( w , network_ql_d ) . n ;
2006-01-26 16:19:24 +00:00
2005-04-06 18:44:34 +00:00
switch ( e - > event ) {
2007-11-24 18:09:02 +00:00
case WE_CREATE : // focus input box
nd - > field = NSSW_GAMENAME ;
2005-06-04 07:35:12 +00:00
_network_game_info . use_password = ( _network_server_password [ 0 ] ! = ' \0 ' ) ;
2005-04-06 18:44:34 +00:00
break ;
2004-08-09 17:04:08 +00:00
case WE_PAINT : {
2004-12-04 17:54:56 +00:00
int y = NSSWND_START , pos ;
const FiosItem * item ;
2004-09-10 19:02:27 +00:00
2007-11-24 18:09:02 +00:00
/* draw basic widgets */
2007-08-14 10:46:38 +00:00
SetDParam ( 1 , _connection_types_dropdown [ _network_advertise ] ) ;
SetDParam ( 2 , _network_game_info . clients_max ) ;
SetDParam ( 3 , _network_game_info . companies_max ) ;
SetDParam ( 4 , _network_game_info . spectators_max ) ;
SetDParam ( 5 , STR_NETWORK_LANG_ANY + _network_game_info . server_lang ) ;
2004-08-09 17:04:08 +00:00
DrawWindowWidgets ( w ) ;
2007-11-24 18:09:02 +00:00
/* editbox to set game name */
DrawEditBox ( w , & WP ( w , network_ql_d ) . q , NSSW_GAMENAME ) ;
2004-12-04 17:54:56 +00:00
2007-11-24 18:09:02 +00:00
/* if password is set, draw red '*' next to 'Set password' button */
2007-11-04 00:08:57 +00:00
if ( _network_game_info . use_password ) DoDrawString ( " * " , 408 , 23 , TC_RED ) ;
2005-04-06 18:44:34 +00:00
2007-11-24 18:09:02 +00:00
/* draw list of maps */
GfxFillRect ( 11 , 63 , 258 , 215 , 0xD7 ) ; // black background of maps list
2004-12-04 17:54:56 +00:00
pos = w - > vscroll . pos ;
while ( pos < _fios_num + 1 ) {
item = _fios_list + pos - 1 ;
2006-01-26 16:19:24 +00:00
if ( item = = nd - > map | | ( pos = = 0 & & nd - > map = = NULL ) )
2006-01-25 18:11:06 +00:00
GfxFillRect ( 11 , y - 1 , 258 , y + 10 , 155 ) ; // show highlighted item with a different colour
2004-12-04 17:54:56 +00:00
2006-06-27 21:25:53 +00:00
if ( pos = = 0 ) {
2007-11-04 00:08:57 +00:00
DrawString ( 14 , y , STR_4010_GENERATE_RANDOM_NEW_GAME , TC_DARK_GREEN ) ;
2006-06-27 21:25:53 +00:00
} else {
DoDrawString ( item - > title , 14 , y , _fios_colors [ item - > type ] ) ;
}
2004-12-04 17:54:56 +00:00
pos + + ;
y + = NSSWND_ROWSIZE ;
if ( y > = w - > vscroll . cap * NSSWND_ROWSIZE + NSSWND_START ) break ;
}
2007-04-18 22:41:53 +00:00
} break ;
2004-08-09 17:04:08 +00:00
case WE_CLICK :
2008-03-15 19:50:06 +00:00
if ( e - > we . click . widget ! = NSSW_CONNTYPE_BTN & & e - > we . click . widget ! = NSSW_LANGUAGE_BTN ) HideDropDownMenu ( w ) ;
2006-09-23 02:39:24 +00:00
nd - > field = e - > we . click . widget ;
switch ( e - > we . click . widget ) {
2007-11-24 18:09:02 +00:00
case NSSW_CLOSE : // Close 'X'
case NSSW_CANCEL : // Cancel button
2004-08-09 17:04:08 +00:00
ShowNetworkGameWindow ( ) ;
break ;
2005-11-14 19:48:04 +00:00
2007-11-24 18:09:02 +00:00
case NSSW_SETPWD : // Set password button
nd - > widget_id = NSSW_SETPWD ;
2006-12-30 01:17:53 +00:00
ShowQueryString ( BindCString ( _network_server_password ) , STR_NETWORK_SET_PASSWORD , 20 , 250 , w , CS_ALPHANUMERAL ) ;
2005-11-14 19:48:04 +00:00
break ;
2007-11-24 18:09:02 +00:00
case NSSW_SELMAP : { // Select map
2006-09-23 02:39:24 +00:00
int y = ( e - > we . click . pt . y - NSSWND_START ) / NSSWND_ROWSIZE ;
2005-11-14 19:48:04 +00:00
y + = w - > vscroll . pos ;
if ( y > = w - > vscroll . count ) return ;
2005-07-17 16:01:26 +00:00
2006-01-26 16:19:24 +00:00
nd - > map = ( y = = 0 ) ? NULL : _fios_list + y - 1 ;
2004-12-04 17:54:56 +00:00
SetWindowDirty ( w ) ;
} break ;
2008-01-17 20:00:13 +00:00
case NSSW_CONNTYPE_BTN : // Connection type
2007-11-24 18:09:02 +00:00
ShowDropDownMenu ( w , _connection_types_dropdown , _network_advertise , NSSW_CONNTYPE_BTN , 0 , 0 ) ; // do it for widget NSSW_CONNTYPE_BTN
2004-12-15 21:54:07 +00:00
break ;
2007-11-24 18:09:02 +00:00
case NSSW_CLIENTS_BTND : case NSSW_CLIENTS_BTNU : // Click on up/down button for number of clients
case NSSW_COMPANIES_BTND : case NSSW_COMPANIES_BTNU : // Click on up/down button for number of companies
case NSSW_SPECTATORS_BTND : case NSSW_SPECTATORS_BTNU : // Click on up/down button for number of spectators
2007-08-14 10:46:38 +00:00
/* Don't allow too fast scrolling */
if ( ( w - > flags4 & WF_TIMEOUT_MASK ) < = 2 < < WF_TIMEOUT_SHL ) {
2007-12-08 03:10:50 +00:00
w - > HandleButtonClick ( e - > we . click . widget ) ;
2007-08-14 10:46:38 +00:00
SetWindowDirty ( w ) ;
switch ( e - > we . click . widget ) {
default : NOT_REACHED ( ) ;
2007-11-24 18:09:02 +00:00
case NSSW_CLIENTS_BTND : case NSSW_CLIENTS_BTNU :
_network_game_info . clients_max = Clamp ( _network_game_info . clients_max + e - > we . click . widget - NSSW_CLIENTS_TXT , 2 , MAX_CLIENTS ) ;
break ;
case NSSW_COMPANIES_BTND : case NSSW_COMPANIES_BTNU :
_network_game_info . companies_max = Clamp ( _network_game_info . companies_max + e - > we . click . widget - NSSW_COMPANIES_TXT , 1 , MAX_PLAYERS ) ;
break ;
case NSSW_SPECTATORS_BTND : case NSSW_SPECTATORS_BTNU :
_network_game_info . spectators_max = Clamp ( _network_game_info . spectators_max + e - > we . click . widget - NSSW_SPECTATORS_TXT , 0 , MAX_CLIENTS ) ;
break ;
2007-08-14 10:46:38 +00:00
}
}
_left_button_clicked = false ;
break ;
2007-11-24 18:09:02 +00:00
case NSSW_CLIENTS_TXT : // Click on number of players
nd - > widget_id = NSSW_CLIENTS_TXT ;
2007-08-14 10:46:38 +00:00
SetDParam ( 0 , _network_game_info . clients_max ) ;
2007-11-24 18:09:02 +00:00
ShowQueryString ( STR_CONFIG_PATCHES_INT32 , STR_NETWORK_NUMBER_OF_CLIENTS , 3 , 50 , w , CS_NUMERAL ) ;
2006-01-25 18:11:06 +00:00
break ;
2007-11-24 18:09:02 +00:00
case NSSW_COMPANIES_TXT : // Click on number of companies
nd - > widget_id = NSSW_COMPANIES_TXT ;
2007-08-14 10:46:38 +00:00
SetDParam ( 0 , _network_game_info . companies_max ) ;
2007-11-24 18:09:02 +00:00
ShowQueryString ( STR_CONFIG_PATCHES_INT32 , STR_NETWORK_NUMBER_OF_COMPANIES , 3 , 50 , w , CS_NUMERAL ) ;
2006-01-25 18:11:06 +00:00
break ;
2007-11-24 18:09:02 +00:00
case NSSW_SPECTATORS_TXT : // Click on number of spectators
nd - > widget_id = NSSW_SPECTATORS_TXT ;
2007-08-14 10:46:38 +00:00
SetDParam ( 0 , _network_game_info . spectators_max ) ;
ShowQueryString ( STR_CONFIG_PATCHES_INT32 , STR_NETWORK_NUMBER_OF_SPECTATORS , 3 , 50 , w , CS_NUMERAL ) ;
2006-01-25 18:11:06 +00:00
break ;
2008-01-17 20:00:13 +00:00
case NSSW_LANGUAGE_BTN : { // Language
2007-06-04 20:06:54 +00:00
uint sel = 0 ;
2007-06-04 19:49:00 +00:00
for ( uint i = 0 ; i < lengthof ( _language_dropdown ) - 1 ; i + + ) {
if ( _language_dropdown [ i ] = = STR_NETWORK_LANG_ANY + _network_game_info . server_lang ) {
sel = i ;
break ;
}
}
2007-11-24 18:09:02 +00:00
ShowDropDownMenu ( w , _language_dropdown , sel , NSSW_LANGUAGE_BTN , 0 , 0 ) ;
2006-01-25 18:11:06 +00:00
break ;
2007-06-04 19:49:00 +00:00
}
2007-11-24 18:09:02 +00:00
case NSSW_START : // Start game
2004-12-04 17:54:56 +00:00
_is_network_server = true ;
2006-01-26 16:19:24 +00:00
if ( nd - > map = = NULL ) { // start random new game
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 10:00:30 +00:00
ShowGenerateLandscape ( ) ;
2004-12-04 17:54:56 +00:00
} else { // load a scenario
2006-01-26 16:19:24 +00:00
char * name = FiosBrowseTo ( nd - > map ) ;
2005-07-17 16:01:26 +00:00
if ( name ! = NULL ) {
2006-01-26 16:19:24 +00:00
SetFiosType ( nd - > map - > type ) ;
2007-12-28 04:20:56 +00:00
_file_to_saveload . filetype = FT_SCENARIO ;
2005-07-17 16:01:26 +00:00
ttd_strlcpy ( _file_to_saveload . name , name , sizeof ( _file_to_saveload . name ) ) ;
2006-01-26 16:19:24 +00:00
ttd_strlcpy ( _file_to_saveload . title , nd - > map - > title , sizeof ( _file_to_saveload . title ) ) ;
2005-07-17 16:01:26 +00:00
2004-12-04 17:54:56 +00:00
DeleteWindow ( w ) ;
(svn r5946) -Add: merged the TGP branch to mainline. TGP adds:
- New optional landscape generator (TerraGenesis Perlin)
- Load heightmaps (either BMP or PNG)
- Progress dialog while generating worlds (no longer a 'hanging' screen)
- New dialogs for NewGame, Create Scenario and Play Heightmap
- Easier to configure your landscape
- More things to configure (tree-placer, ..)
- Speedup of world generation
- New console command 'restart': restart the map EXACTLY as it was when you
first started it (needs a game made after or with this commit)
- New console command 'getseed': get the seed of your map and share it with
others (of course only works with generated maps)
- Many new, world generation related, things
- Many internal cleanups and rewrites
Many tnx to those people who helped making this:
Belugas, DaleStan, glx, KUDr, RichK67, Rubidium, and TrueLight (alfabetic)
Many tnx to those who helped testing:
Arnau, Bjarni, and tokai (alfabetic)
And to all other people who helped testing and sending comments / bugs
Stats: 673 lines changed, 3534 new lines, 79 new strings
2006-08-19 10:00:30 +00:00
SwitchMode ( SM_START_SCENARIO ) ;
2004-12-04 17:54:56 +00:00
}
}
2004-08-09 17:04:08 +00:00
break ;
2007-11-24 18:09:02 +00:00
case NSSW_LOAD : // Load game
2004-12-04 17:54:56 +00:00
_is_network_server = true ;
2007-11-24 18:09:02 +00:00
/* XXX - WC_NETWORK_WINDOW (this window) should stay, but if it stays, it gets
2004-12-04 17:54:56 +00:00
* copied all the elements of ' load game ' and upon closing that , it segfaults */
2007-11-24 18:09:02 +00:00
DeleteWindow ( w ) ;
2004-09-06 22:46:02 +00:00
ShowSaveLoadDialog ( SLD_LOAD_GAME ) ;
2004-08-09 17:04:08 +00:00
break ;
}
2004-09-06 22:46:02 +00:00
break ;
2007-11-24 18:09:02 +00:00
case WE_DROPDOWN_SELECT : // we have selected a dropdown item in the list
2006-09-23 02:39:24 +00:00
switch ( e - > we . dropdown . button ) {
2007-11-24 18:09:02 +00:00
case NSSW_CONNTYPE_BTN :
_network_advertise = ( e - > we . dropdown . index ! = 0 ) ;
break ;
case NSSW_LANGUAGE_BTN :
2007-06-04 19:49:00 +00:00
_network_game_info . server_lang = _language_dropdown [ e - > we . dropdown . index ] - STR_NETWORK_LANG_ANY ;
2007-06-01 23:06:01 +00:00
break ;
2007-11-24 18:09:02 +00:00
default :
NOT_REACHED ( ) ;
2004-12-04 17:54:56 +00:00
}
2004-09-06 22:46:02 +00:00
SetWindowDirty ( w ) ;
break ;
case WE_MOUSELOOP :
2007-11-24 18:09:02 +00:00
if ( nd - > field = = NSSW_GAMENAME ) HandleEditBox ( w , & WP ( w , network_ql_d ) . q , NSSW_GAMENAME ) ;
2004-08-09 17:04:08 +00:00
break ;
case WE_KEYPRESS :
2007-11-24 18:09:02 +00:00
if ( nd - > field = = NSSW_GAMENAME ) {
if ( HandleEditBoxKey ( w , & WP ( w , network_ql_d ) . q , NSSW_GAMENAME , e ) = = 1 ) break ; // enter pressed
2006-01-26 16:19:24 +00:00
2006-01-26 17:10:11 +00:00
ttd_strlcpy ( _network_server_name , WP ( w , network_ql_d ) . q . text . buf , sizeof ( _network_server_name ) ) ;
2006-01-26 16:19:24 +00:00
}
2004-08-09 17:04:08 +00:00
break ;
2004-09-10 19:02:27 +00:00
2007-08-14 10:46:38 +00:00
case WE_ON_EDIT_TEXT :
if ( e - > we . edittext . str = = NULL ) break ;
2007-11-24 18:09:02 +00:00
if ( nd - > widget_id = = NSSW_SETPWD ) {
2007-08-14 10:46:38 +00:00
ttd_strlcpy ( _network_server_password , e - > we . edittext . str , lengthof ( _network_server_password ) ) ;
_network_game_info . use_password = ( _network_server_password [ 0 ] ! = ' \0 ' ) ;
} else {
int32 value = atoi ( e - > we . edittext . str ) ;
2007-12-07 18:05:49 +00:00
w - > InvalidateWidget ( nd - > widget_id ) ;
2007-08-14 10:46:38 +00:00
switch ( nd - > widget_id ) {
default : NOT_REACHED ( ) ;
2007-11-24 18:09:02 +00:00
case NSSW_CLIENTS_TXT : _network_game_info . clients_max = Clamp ( value , 2 , MAX_CLIENTS ) ; break ;
case NSSW_COMPANIES_TXT : _network_game_info . companies_max = Clamp ( value , 1 , MAX_PLAYERS ) ; break ;
case NSSW_SPECTATORS_TXT : _network_game_info . spectators_max = Clamp ( value , 0 , MAX_CLIENTS ) ; break ;
2007-08-14 10:46:38 +00:00
}
}
2005-04-06 18:44:34 +00:00
SetWindowDirty ( w ) ;
2007-08-14 10:46:38 +00:00
break ;
2004-08-09 17:04:08 +00:00
}
}
static const Widget _network_start_server_window_widgets [ ] = {
2007-11-24 18:09:02 +00:00
/* Window decoration and background panel */
{ WWT_CLOSEBOX , RESIZE_NONE , BGC , 0 , 10 , 0 , 13 , STR_00C5 , STR_018B_CLOSE_WINDOW } , // NSSW_CLOSE
{ WWT_CAPTION , RESIZE_NONE , BGC , 11 , 419 , 0 , 13 , STR_NETWORK_START_GAME_WINDOW , STR_NULL } ,
2007-11-24 21:49:49 +00:00
{ WWT_PANEL , RESIZE_NONE , BGC , 0 , 419 , 14 , 243 , 0x0 , STR_NULL } ,
2007-11-24 18:09:02 +00:00
/* Set game name and password widgets */
{ WWT_TEXT , RESIZE_NONE , BGC , 10 , 90 , 22 , 34 , STR_NETWORK_NEW_GAME_NAME , STR_NULL } ,
2007-11-24 21:49:49 +00:00
{ WWT_PANEL , RESIZE_NONE , BGC , 100 , 272 , 22 , 33 , 0x0 , STR_NETWORK_NEW_GAME_NAME_TIP } , // NSSW_GAMENAME
2007-11-24 18:09:02 +00:00
{ WWT_PUSHTXTBTN , RESIZE_NONE , BTC , 285 , 405 , 22 , 33 , STR_NETWORK_SET_PASSWORD , STR_NETWORK_PASSWORD_TIP } , // NSSW_SETPWD
2007-08-14 10:46:38 +00:00
2007-11-24 18:09:02 +00:00
/* List of playable scenarios */
{ WWT_TEXT , RESIZE_NONE , BGC , 10 , 110 , 43 , 55 , STR_NETWORK_SELECT_MAP , STR_NULL } ,
{ WWT_INSET , RESIZE_NONE , BGC , 10 , 271 , 62 , 216 , STR_NULL , STR_NETWORK_SELECT_MAP_TIP } , // NSSW_SELMAP
2007-11-24 21:49:49 +00:00
{ WWT_SCROLLBAR , RESIZE_NONE , BGC , 259 , 270 , 63 , 215 , 0x0 , STR_0190_SCROLL_BAR_SCROLLS_LIST } ,
2007-08-14 10:46:38 +00:00
/* Combo/selection boxes to control Connection Type / Max Clients / Max Companies / Max Observers / Language */
2007-11-24 18:09:02 +00:00
{ WWT_TEXT , RESIZE_NONE , BGC , 280 , 419 , 63 , 75 , STR_NETWORK_CONNECTION , STR_NULL } ,
2008-01-17 20:00:13 +00:00
{ WWT_DROPDOWNIN , RESIZE_NONE , BGC , 280 , 410 , 77 , 88 , STR_NETWORK_LAN_INTERNET_COMBO , STR_NETWORK_CONNECTION_TIP } , // NSSW_CONNTYPE_BTN
2007-11-24 18:09:02 +00:00
{ WWT_TEXT , RESIZE_NONE , BGC , 280 , 419 , 95 , 107 , STR_NETWORK_NUMBER_OF_CLIENTS , STR_NULL } ,
{ WWT_IMGBTN , RESIZE_NONE , BGC , 280 , 291 , 109 , 120 , SPR_ARROW_DOWN , STR_NETWORK_NUMBER_OF_CLIENTS_TIP } , // NSSW_CLIENTS_BTND
{ WWT_PUSHTXTBTN , RESIZE_NONE , BGC , 292 , 397 , 109 , 120 , STR_NETWORK_CLIENTS_SELECT , STR_NETWORK_NUMBER_OF_CLIENTS_TIP } , // NSSW_CLIENTS_TXT
{ WWT_IMGBTN , RESIZE_NONE , BGC , 398 , 410 , 109 , 120 , SPR_ARROW_UP , STR_NETWORK_NUMBER_OF_CLIENTS_TIP } , // NSSW_CLIENTS_BTNU
{ WWT_TEXT , RESIZE_NONE , BGC , 280 , 419 , 127 , 139 , STR_NETWORK_NUMBER_OF_COMPANIES , STR_NULL } ,
{ WWT_IMGBTN , RESIZE_NONE , BGC , 280 , 291 , 141 , 152 , SPR_ARROW_DOWN , STR_NETWORK_NUMBER_OF_COMPANIES_TIP } , // NSSW_COMPANIES_BTND
{ WWT_PUSHTXTBTN , RESIZE_NONE , BGC , 292 , 397 , 141 , 152 , STR_NETWORK_COMPANIES_SELECT , STR_NETWORK_NUMBER_OF_COMPANIES_TIP } , // NSSW_COMPANIES_TXT
{ WWT_IMGBTN , RESIZE_NONE , BGC , 398 , 410 , 141 , 152 , SPR_ARROW_UP , STR_NETWORK_NUMBER_OF_COMPANIES_TIP } , // NSSW_COMPANIES_BTNU
{ WWT_TEXT , RESIZE_NONE , BGC , 280 , 419 , 159 , 171 , STR_NETWORK_NUMBER_OF_SPECTATORS , STR_NULL } ,
{ WWT_IMGBTN , RESIZE_NONE , BGC , 280 , 291 , 173 , 184 , SPR_ARROW_DOWN , STR_NETWORK_NUMBER_OF_SPECTATORS_TIP } , // NSSW_SPECTATORS_BTND
{ WWT_PUSHTXTBTN , RESIZE_NONE , BGC , 292 , 397 , 173 , 184 , STR_NETWORK_SPECTATORS_SELECT , STR_NETWORK_NUMBER_OF_SPECTATORS_TIP } , // NSSW_SPECTATORS_TXT
{ WWT_IMGBTN , RESIZE_NONE , BGC , 398 , 410 , 173 , 184 , SPR_ARROW_UP , STR_NETWORK_NUMBER_OF_SPECTATORS_TIP } , // NSSW_SPECTATORS_BTNU
{ WWT_TEXT , RESIZE_NONE , BGC , 280 , 419 , 191 , 203 , STR_NETWORK_LANGUAGE_SPOKEN , STR_NULL } ,
2008-01-17 20:00:13 +00:00
{ WWT_DROPDOWNIN , RESIZE_NONE , BGC , 280 , 410 , 205 , 216 , STR_NETWORK_LANGUAGE_COMBO , STR_NETWORK_LANGUAGE_TIP } , // NSSW_LANGUAGE_BTN
2007-11-24 18:09:02 +00:00
/* Buttons Start / Load / Cancel */
{ WWT_PUSHTXTBTN , RESIZE_NONE , BTC , 40 , 140 , 224 , 235 , STR_NETWORK_START_GAME , STR_NETWORK_START_GAME_TIP } , // NSSW_START
{ WWT_PUSHTXTBTN , RESIZE_NONE , BTC , 150 , 250 , 224 , 235 , STR_NETWORK_LOAD_GAME , STR_NETWORK_LOAD_GAME_TIP } , // NSSW_LOAD
{ WWT_PUSHTXTBTN , RESIZE_NONE , BTC , 260 , 360 , 224 , 235 , STR_012E_CANCEL , STR_NULL } , // NSSW_CANCEL
2004-09-07 21:48:09 +00:00
{ WIDGETS_END } ,
2004-08-09 17:04:08 +00:00
} ;
static const WindowDesc _network_start_server_window_desc = {
2007-07-27 12:49:04 +00:00
WDP_CENTER , WDP_CENTER , 420 , 244 , 420 , 244 ,
2007-02-01 15:49:12 +00:00
WC_NETWORK_WINDOW , WC_NONE ,
2005-07-15 15:09:52 +00:00
WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS ,
2004-08-09 17:04:08 +00:00
_network_start_server_window_widgets ,
NetworkStartServerWindowWndProc ,
} ;
2007-03-07 11:47:46 +00:00
static void ShowNetworkStartServerWindow ( )
2004-08-09 17:04:08 +00:00
{
Window * w ;
DeleteWindowById ( WC_NETWORK_WINDOW , 0 ) ;
2004-09-10 19:02:27 +00:00
2004-08-09 17:04:08 +00:00
w = AllocateWindowDesc ( & _network_start_server_window_desc ) ;
2008-03-24 06:38:20 +00:00
ttd_strlcpy ( _edit_str_net_buf , _network_server_name , lengthof ( _edit_str_net_buf ) ) ;
2004-12-04 17:54:56 +00:00
_saveload_mode = SLD_NEW_GAME ;
BuildFileList ( ) ;
2006-01-31 20:05:44 +00:00
w - > vscroll . cap = 12 ;
2007-04-18 22:10:36 +00:00
w - > vscroll . count = _fios_num + 1 ;
2004-09-10 19:02:27 +00:00
2006-10-21 22:50:57 +00:00
WP ( w , network_ql_d ) . q . afilter = CS_ALPHANUMERAL ;
2008-03-24 06:38:20 +00:00
InitializeTextBuffer ( & WP ( w , network_ql_d ) . q . text , _edit_str_net_buf , lengthof ( _edit_str_net_buf ) , 160 ) ;
2004-08-09 17:04:08 +00:00
}
2007-01-10 18:56:51 +00:00
static PlayerID NetworkLobbyFindCompanyIndex ( byte pos )
2004-12-20 16:02:01 +00:00
{
2007-01-10 18:56:51 +00:00
PlayerID i ;
2005-11-14 19:48:04 +00:00
2004-12-20 16:02:01 +00:00
/* Scroll through all _network_player_info and get the 'pos' item
that is not empty */
2007-01-10 18:56:51 +00:00
for ( i = PLAYER_FIRST ; i < MAX_PLAYERS ; i + + ) {
2004-12-20 16:02:01 +00:00
if ( _network_player_info [ i ] . company_name [ 0 ] ! = ' \0 ' ) {
2005-11-14 19:48:04 +00:00
if ( pos - - = = 0 ) return i ;
2004-12-20 16:02:01 +00:00
}
}
2007-01-10 18:56:51 +00:00
return PLAYER_FIRST ;
2004-12-20 16:02:01 +00:00
}
2007-11-25 11:36:45 +00:00
/** Enum for NetworkLobbyWindow, referring to _network_lobby_window_widgets */
enum NetworkLobbyWindowWidgets {
NLWW_CLOSE = 0 , ///< Close 'X' button
NLWW_MATRIX = 5 , ///< List of companies
NLWW_DETAILS = 7 , ///< Company details
NLWW_JOIN = 8 , ///< 'Join company' button
NLWW_NEW = 9 , ///< 'New company' button
NLWW_SPECTATE = 10 , ///< 'Spectate game' button
NLWW_REFRESH = 11 , ///< 'Refresh server' button
NLWW_CANCEL = 12 , ///< 'Cancel' button
} ;
/**
* Handler of actions done in the NetworkLobby window
*
* @ param w pointer to the Window structure
* @ param e pointer to window event
* @ note uses network_d WP macro
* @ see struct _network_lobby_window_widgets
* @ see enum NetworkLobbyWindowWidgets
*/
2004-08-09 17:04:08 +00:00
static void NetworkLobbyWindowWndProc ( Window * w , WindowEvent * e )
{
2006-01-26 16:19:24 +00:00
network_d * nd = & WP ( w , network_d ) ;
2005-11-14 19:48:04 +00:00
switch ( e - > event ) {
2006-01-25 18:11:06 +00:00
case WE_CREATE :
2007-01-10 18:56:51 +00:00
nd - > company = INVALID_PLAYER ;
2006-01-25 18:11:06 +00:00
break ;
2004-08-09 17:04:08 +00:00
case WE_PAINT : {
2006-01-26 16:19:24 +00:00
const NetworkGameInfo * gi = & nd - > server - > info ;
2004-12-04 17:54:56 +00:00
int y = NET_PRC__OFFSET_TOP_WIDGET_COMPANY , pos ;
2007-11-25 11:36:45 +00:00
/* Join button is disabled when no company is selected */
2007-12-02 14:29:48 +00:00
w - > SetWidgetDisabledState ( NLWW_JOIN , nd - > company = = INVALID_PLAYER ) ;
2007-11-25 11:36:45 +00:00
/* Cannot start new company if there are too many */
2007-12-02 14:29:48 +00:00
w - > SetWidgetDisabledState ( NLWW_NEW , gi - > companies_on > = gi - > companies_max ) ;
2007-11-25 11:36:45 +00:00
/* Cannot spectate if there are too many spectators */
2007-12-02 14:29:48 +00:00
w - > SetWidgetDisabledState ( NLWW_SPECTATE , gi - > spectators_on > = gi - > spectators_max ) ;
2004-08-09 17:04:08 +00:00
2007-11-25 11:36:45 +00:00
/* Draw window widgets */
2006-01-26 12:56:05 +00:00
SetDParamStr ( 0 , gi - > server_name ) ;
2007-11-25 11:36:45 +00:00
DrawWindowWidgets ( w ) ;
2004-08-09 17:04:08 +00:00
2006-01-26 16:19:24 +00:00
/* Draw company list */
2004-12-04 17:54:56 +00:00
pos = w - > vscroll . pos ;
2006-01-25 18:11:06 +00:00
while ( pos < gi - > companies_on ) {
2006-01-26 16:19:24 +00:00
byte company = NetworkLobbyFindCompanyIndex ( pos ) ;
2005-01-14 21:47:35 +00:00
bool income = false ;
2006-01-26 16:19:24 +00:00
if ( nd - > company = = company )
GfxFillRect ( 11 , y - 1 , 154 , y + 10 , 10 ) ; // show highlighted item with a different colour
2004-09-10 19:02:27 +00:00
2007-11-04 00:08:57 +00:00
DoDrawStringTruncated ( _network_player_info [ company ] . company_name , 13 , y , TC_BLACK , 135 - 13 ) ;
2007-01-14 19:59:25 +00:00
if ( _network_player_info [ company ] . use_password ! = 0 ) DrawSprite ( SPR_LOCK , PAL_NONE , 135 , y ) ;
2005-01-14 21:47:35 +00:00
/* If the company's income was positive puts a green dot else a red dot */
2006-01-26 16:19:24 +00:00
if ( _network_player_info [ company ] . income > = 0 ) income = true ;
2007-01-14 19:59:25 +00:00
DrawSprite ( SPR_BLOT , income ? PALETTE_TO_GREEN : PALETTE_TO_RED , 145 , y ) ;
2004-08-09 17:04:08 +00:00
2004-12-04 17:54:56 +00:00
pos + + ;
2006-01-26 16:19:24 +00:00
y + = NET_PRC__SIZE_OF_ROW ;
2005-11-14 19:48:04 +00:00
if ( pos > = w - > vscroll . cap ) break ;
2004-12-04 17:54:56 +00:00
}
2006-01-26 16:19:24 +00:00
/* Draw info about selected company when it is selected in the left window */
GfxFillRect ( 174 , 39 , 403 , 75 , 157 ) ;
2007-11-04 00:08:57 +00:00
DrawStringCentered ( 290 , 50 , STR_NETWORK_COMPANY_INFO , TC_FROMSTRING ) ;
2007-11-25 11:36:45 +00:00
if ( nd - > company ! = INVALID_PLAYER ) {
2005-01-15 19:17:45 +00:00
const uint x = 183 ;
2007-11-25 11:36:45 +00:00
const uint trunc_width = w - > widget [ NLWW_DETAILS ] . right - x ;
2006-01-26 16:19:24 +00:00
y = 80 ;
SetDParam ( 0 , nd - > server - > info . clients_on ) ;
SetDParam ( 1 , nd - > server - > info . clients_max ) ;
SetDParam ( 2 , nd - > server - > info . companies_on ) ;
SetDParam ( 3 , nd - > server - > info . companies_max ) ;
2007-11-04 00:08:57 +00:00
DrawString ( x , y , STR_NETWORK_CLIENTS , TC_GOLD ) ;
2006-01-26 16:19:24 +00:00
y + = 10 ;
2004-12-04 17:54:56 +00:00
2006-01-26 16:19:24 +00:00
SetDParamStr ( 0 , _network_player_info [ nd - > company ] . company_name ) ;
2007-11-04 00:08:57 +00:00
DrawStringTruncated ( x , y , STR_NETWORK_COMPANY_NAME , TC_GOLD , trunc_width ) ;
2004-12-04 17:54:56 +00:00
y + = 10 ;
2006-08-20 19:05:28 +00:00
SetDParam ( 0 , _network_player_info [ nd - > company ] . inaugurated_year ) ;
2007-11-04 00:08:57 +00:00
DrawString ( x , y , STR_NETWORK_INAUGURATION_YEAR , TC_GOLD ) ; // inauguration year
2004-12-04 17:54:56 +00:00
y + = 10 ;
2007-06-21 17:25:17 +00:00
SetDParam ( 0 , _network_player_info [ nd - > company ] . company_value ) ;
2007-11-04 00:08:57 +00:00
DrawString ( x , y , STR_NETWORK_VALUE , TC_GOLD ) ; // company value
2004-12-04 17:54:56 +00:00
y + = 10 ;
2007-06-21 17:25:17 +00:00
SetDParam ( 0 , _network_player_info [ nd - > company ] . money ) ;
2007-11-04 00:08:57 +00:00
DrawString ( x , y , STR_NETWORK_CURRENT_BALANCE , TC_GOLD ) ; // current balance
2004-12-04 17:54:56 +00:00
y + = 10 ;
2007-06-21 17:25:17 +00:00
SetDParam ( 0 , _network_player_info [ nd - > company ] . income ) ;
2007-11-04 00:08:57 +00:00
DrawString ( x , y , STR_NETWORK_LAST_YEARS_INCOME , TC_GOLD ) ; // last year's income
2004-12-04 17:54:56 +00:00
y + = 10 ;
2006-01-26 16:19:24 +00:00
SetDParam ( 0 , _network_player_info [ nd - > company ] . performance ) ;
2007-11-04 00:08:57 +00:00
DrawString ( x , y , STR_NETWORK_PERFORMANCE , TC_GOLD ) ; // performance
2004-12-04 17:54:56 +00:00
y + = 10 ;
2006-01-26 16:19:24 +00:00
SetDParam ( 0 , _network_player_info [ nd - > company ] . num_vehicle [ 0 ] ) ;
SetDParam ( 1 , _network_player_info [ nd - > company ] . num_vehicle [ 1 ] ) ;
SetDParam ( 2 , _network_player_info [ nd - > company ] . num_vehicle [ 2 ] ) ;
SetDParam ( 3 , _network_player_info [ nd - > company ] . num_vehicle [ 3 ] ) ;
SetDParam ( 4 , _network_player_info [ nd - > company ] . num_vehicle [ 4 ] ) ;
2007-11-04 00:08:57 +00:00
DrawString ( x , y , STR_NETWORK_VEHICLES , TC_GOLD ) ; // vehicles
2004-12-04 17:54:56 +00:00
y + = 10 ;
2006-01-26 16:19:24 +00:00
SetDParam ( 0 , _network_player_info [ nd - > company ] . num_station [ 0 ] ) ;
SetDParam ( 1 , _network_player_info [ nd - > company ] . num_station [ 1 ] ) ;
SetDParam ( 2 , _network_player_info [ nd - > company ] . num_station [ 2 ] ) ;
SetDParam ( 3 , _network_player_info [ nd - > company ] . num_station [ 3 ] ) ;
SetDParam ( 4 , _network_player_info [ nd - > company ] . num_station [ 4 ] ) ;
2007-11-04 00:08:57 +00:00
DrawString ( x , y , STR_NETWORK_STATIONS , TC_GOLD ) ; // stations
2004-12-04 17:54:56 +00:00
y + = 10 ;
2006-01-26 16:19:24 +00:00
SetDParamStr ( 0 , _network_player_info [ nd - > company ] . players ) ;
2007-11-04 00:08:57 +00:00
DrawStringTruncated ( x , y , STR_NETWORK_PLAYERS , TC_GOLD , trunc_width ) ; // players
2004-12-04 17:54:56 +00:00
}
2007-04-18 22:41:53 +00:00
} break ;
2004-08-09 17:04:08 +00:00
case WE_CLICK :
2006-09-23 02:39:24 +00:00
switch ( e - > we . click . widget ) {
2007-11-25 11:36:45 +00:00
case NLWW_CLOSE : // Close 'X'
case NLWW_CANCEL : // Cancel button
2004-08-09 17:04:08 +00:00
ShowNetworkGameWindow ( ) ;
break ;
2007-11-25 11:36:45 +00:00
case NLWW_MATRIX : { // Company list
2006-09-23 02:39:24 +00:00
uint32 id_v = ( e - > we . click . pt . y - NET_PRC__OFFSET_TOP_WIDGET_COMPANY ) / NET_PRC__SIZE_OF_ROW ;
2004-08-09 17:04:08 +00:00
2007-11-25 11:36:45 +00:00
if ( id_v > = w - > vscroll . cap ) break ;
2004-12-20 16:02:01 +00:00
2006-01-26 16:19:24 +00:00
id_v + = w - > vscroll . pos ;
2007-01-10 18:56:51 +00:00
nd - > company = ( id_v > = nd - > server - > info . companies_on ) ? INVALID_PLAYER : NetworkLobbyFindCompanyIndex ( id_v ) ;
2004-12-04 17:54:56 +00:00
SetWindowDirty ( w ) ;
2007-04-18 22:41:53 +00:00
} break ;
2007-11-25 11:36:45 +00:00
case NLWW_JOIN : // Join company
/* Button can be clicked only when it is enabled */
_network_playas = nd - > company ;
NetworkClientConnectGame ( _network_last_host , _network_last_port ) ;
2004-08-09 17:04:08 +00:00
break ;
2007-11-25 11:36:45 +00:00
case NLWW_NEW : // New company
2006-10-15 23:48:34 +00:00
_network_playas = PLAYER_NEW_COMPANY ;
2004-12-04 17:54:56 +00:00
NetworkClientConnectGame ( _network_last_host , _network_last_port ) ;
2004-08-09 17:04:08 +00:00
break ;
2007-11-25 11:36:45 +00:00
case NLWW_SPECTATE : // Spectate game
2006-10-14 15:49:43 +00:00
_network_playas = PLAYER_SPECTATOR ;
2004-12-04 17:54:56 +00:00
NetworkClientConnectGame ( _network_last_host , _network_last_port ) ;
2004-08-09 17:04:08 +00:00
break ;
2007-11-25 11:36:45 +00:00
case NLWW_REFRESH : // Refresh
2007-02-02 21:04:50 +00:00
NetworkTCPQueryServer ( _network_last_host , _network_last_port ) ; // company info
NetworkUDPQueryServer ( _network_last_host , _network_last_port ) ; // general data
2004-12-04 17:54:56 +00:00
break ;
2007-04-18 22:41:53 +00:00
} break ;
2006-01-26 12:56:05 +00:00
case WE_MESSAGE :
SetWindowDirty ( w ) ;
break ;
2004-08-09 17:04:08 +00:00
}
}
static const Widget _network_lobby_window_widgets [ ] = {
2007-11-25 11:36:45 +00:00
{ WWT_CLOSEBOX , RESIZE_NONE , BGC , 0 , 10 , 0 , 13 , STR_00C5 , STR_018B_CLOSE_WINDOW } , // NLWW_CLOSE
{ WWT_CAPTION , RESIZE_NONE , BGC , 11 , 419 , 0 , 13 , STR_NETWORK_GAME_LOBBY , STR_NULL } ,
{ WWT_PANEL , RESIZE_NONE , BGC , 0 , 419 , 14 , 234 , 0x0 , STR_NULL } ,
{ WWT_TEXT , RESIZE_NONE , BGC , 10 , 419 , 22 , 34 , STR_NETWORK_PREPARE_TO_JOIN , STR_NULL } ,
/* company list */
{ WWT_PANEL , RESIZE_NONE , BTC , 10 , 155 , 38 , 49 , 0x0 , STR_NULL } ,
{ WWT_MATRIX , RESIZE_NONE , BGC , 10 , 155 , 50 , 190 , ( 10 < < 8 ) + 1 , STR_NETWORK_COMPANY_LIST_TIP } , // NLWW_MATRIX
{ WWT_SCROLLBAR , RESIZE_NONE , BGC , 156 , 167 , 38 , 190 , 0x0 , STR_0190_SCROLL_BAR_SCROLLS_LIST } ,
/* company/player info */
{ WWT_PANEL , RESIZE_NONE , BGC , 173 , 404 , 38 , 190 , 0x0 , STR_NULL } , // NLWW_DETAILS
/* buttons */
{ WWT_PUSHTXTBTN , RESIZE_NONE , BTC , 10 , 151 , 200 , 211 , STR_NETWORK_JOIN_COMPANY , STR_NETWORK_JOIN_COMPANY_TIP } , // NLWW_JOIN
{ WWT_PUSHTXTBTN , RESIZE_NONE , BTC , 10 , 151 , 215 , 226 , STR_NETWORK_NEW_COMPANY , STR_NETWORK_NEW_COMPANY_TIP } , // NLWW_NEW
{ WWT_PUSHTXTBTN , RESIZE_NONE , BTC , 158 , 268 , 200 , 211 , STR_NETWORK_SPECTATE_GAME , STR_NETWORK_SPECTATE_GAME_TIP } , // NLWW_SPECTATE
{ WWT_PUSHTXTBTN , RESIZE_NONE , BTC , 158 , 268 , 215 , 226 , STR_NETWORK_REFRESH , STR_NETWORK_REFRESH_TIP } , // NLWW_REFRESH
{ WWT_PUSHTXTBTN , RESIZE_NONE , BTC , 278 , 388 , 200 , 211 , STR_012E_CANCEL , STR_NULL } , // NLWW_CANCEL
2004-08-09 17:04:08 +00:00
2004-09-07 21:48:09 +00:00
{ WIDGETS_END } ,
2004-08-09 17:04:08 +00:00
} ;
static const WindowDesc _network_lobby_window_desc = {
2007-07-27 12:49:04 +00:00
WDP_CENTER , WDP_CENTER , 420 , 235 , 420 , 235 ,
2007-02-01 15:49:12 +00:00
WC_NETWORK_WINDOW , WC_NONE ,
2004-08-09 17:04:08 +00:00
WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS ,
_network_lobby_window_widgets ,
NetworkLobbyWindowWndProc ,
} ;
2006-01-26 17:10:11 +00:00
/* Show the networklobbywindow with the selected server
* @ param ngl Selected game pointer which is passed to the new window */
2006-01-26 16:19:24 +00:00
static void ShowNetworkLobbyWindow ( NetworkGameList * ngl )
2004-08-09 17:04:08 +00:00
{
Window * w ;
DeleteWindowById ( WC_NETWORK_WINDOW , 0 ) ;
2004-09-10 19:02:27 +00:00
2007-02-02 21:04:50 +00:00
NetworkTCPQueryServer ( _network_last_host , _network_last_port ) ; // company info
NetworkUDPQueryServer ( _network_last_host , _network_last_port ) ; // general data
2004-12-04 17:54:56 +00:00
2004-08-09 17:04:08 +00:00
w = AllocateWindowDesc ( & _network_lobby_window_desc ) ;
2006-01-26 16:19:24 +00:00
if ( w ! = NULL ) {
2006-01-26 17:10:11 +00:00
WP ( w , network_ql_d ) . n . server = ngl ;
2008-03-24 06:38:20 +00:00
strcpy ( _edit_str_net_buf , " " ) ;
2006-01-26 16:19:24 +00:00
w - > vscroll . cap = 10 ;
}
2004-12-04 17:54:56 +00:00
}
2004-08-09 17:04:08 +00:00
2004-12-04 17:54:56 +00:00
// The window below gives information about the connected clients
// and also makes able to give money to them, kick them (if server)
// and stuff like that.
2006-04-29 14:31:16 +00:00
extern void DrawPlayerIcon ( PlayerID pid , int x , int y ) ;
2004-12-04 17:54:56 +00:00
// Every action must be of this form
typedef void ClientList_Action_Proc ( byte client_no ) ;
// Max 10 actions per client
# define MAX_CLIENTLIST_ACTION 10
// Some standard bullshit.. defines variables ;)
static void ClientListWndProc ( Window * w , WindowEvent * e ) ;
static void ClientListPopupWndProc ( Window * w , WindowEvent * e ) ;
static byte _selected_clientlist_item = 255 ;
static byte _selected_clientlist_y = 0 ;
static char _clientlist_action [ MAX_CLIENTLIST_ACTION ] [ 50 ] ;
static ClientList_Action_Proc * _clientlist_proc [ MAX_CLIENTLIST_ACTION ] ;
enum {
CLNWND_OFFSET = 16 ,
CLNWND_ROWSIZE = 10
} ;
2005-01-03 19:45:18 +00:00
static const Widget _client_list_widgets [ ] = {
2005-12-07 15:48:52 +00:00
{ WWT_CLOSEBOX , RESIZE_NONE , 14 , 0 , 10 , 0 , 13 , STR_00C5 , STR_018B_CLOSE_WINDOW } ,
2007-06-23 14:13:05 +00:00
{ WWT_CAPTION , RESIZE_NONE , 14 , 11 , 237 , 0 , 13 , STR_NETWORK_CLIENT_LIST , STR_018C_WINDOW_TITLE_DRAG_THIS } ,
{ WWT_STICKYBOX , RESIZE_NONE , 14 , 238 , 249 , 0 , 13 , STR_NULL , STR_STICKY_BUTTON } ,
2004-12-04 17:54:56 +00:00
2006-10-24 14:15:17 +00:00
{ WWT_PANEL , RESIZE_NONE , 14 , 0 , 249 , 14 , 14 + CLNWND_ROWSIZE + 1 , 0x0 , STR_NULL } ,
2004-12-04 17:54:56 +00:00
{ WIDGETS_END } ,
} ;
2005-01-03 19:45:18 +00:00
static const Widget _client_list_popup_widgets [ ] = {
2006-08-22 14:38:37 +00:00
{ WWT_PANEL , RESIZE_NONE , 14 , 0 , 99 , 0 , 0 , 0 , STR_NULL } ,
2004-12-04 17:54:56 +00:00
{ WIDGETS_END } ,
} ;
static WindowDesc _client_list_desc = {
2007-07-27 12:49:04 +00:00
WDP_AUTO , WDP_AUTO , 250 , 1 , 250 , 1 ,
2007-02-01 15:49:12 +00:00
WC_CLIENT_LIST , WC_NONE ,
2007-06-23 14:13:05 +00:00
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON ,
2004-12-04 17:54:56 +00:00
_client_list_widgets ,
ClientListWndProc
} ;
// Finds the Xth client-info that is active
2006-07-26 03:33:12 +00:00
static const NetworkClientInfo * NetworkFindClientInfo ( byte client_no )
2004-12-04 17:54:56 +00:00
{
2006-07-26 03:33:12 +00:00
const NetworkClientInfo * ci ;
2005-11-13 13:43:55 +00:00
2006-10-18 13:17:46 +00:00
FOR_ALL_ACTIVE_CLIENT_INFOS ( ci ) {
2004-12-04 17:54:56 +00:00
if ( client_no = = 0 ) return ci ;
client_no - - ;
}
return NULL ;
2004-08-09 17:04:08 +00:00
}
2004-12-04 17:54:56 +00:00
// Here we start to define the options out of the menu
static void ClientList_Kick ( byte client_no )
{
if ( client_no < MAX_PLAYERS )
2006-10-17 23:34:12 +00:00
SEND_COMMAND ( PACKET_SERVER_ERROR ) ( DEREF_CLIENT ( client_no ) , NETWORK_ERROR_KICKED ) ;
2004-12-04 17:54:56 +00:00
}
2005-01-02 12:03:43 +00:00
static void ClientList_Ban ( byte client_no )
2004-12-04 17:54:56 +00:00
{
2005-01-02 12:03:43 +00:00
uint i ;
uint32 ip = NetworkFindClientInfo ( client_no ) - > client_ip ;
for ( i = 0 ; i < lengthof ( _network_ban_list ) ; i + + ) {
2006-01-29 18:04:52 +00:00
if ( _network_ban_list [ i ] = = NULL ) {
2005-01-02 12:03:43 +00:00
_network_ban_list [ i ] = strdup ( inet_ntoa ( * ( struct in_addr * ) & ip ) ) ;
break ;
}
}
if ( client_no < MAX_PLAYERS )
2006-10-17 23:34:12 +00:00
SEND_COMMAND ( PACKET_SERVER_ERROR ) ( DEREF_CLIENT ( client_no ) , NETWORK_ERROR_KICKED ) ;
2005-01-02 12:03:43 +00:00
}
2004-12-04 17:54:56 +00:00
static void ClientList_GiveMoney ( byte client_no )
{
if ( NetworkFindClientInfo ( client_no ) ! = NULL )
2006-10-17 22:16:46 +00:00
ShowNetworkGiveMoneyWindow ( NetworkFindClientInfo ( client_no ) - > client_playas ) ;
2004-12-04 17:54:56 +00:00
}
static void ClientList_SpeakToClient ( byte client_no )
{
if ( NetworkFindClientInfo ( client_no ) ! = NULL )
ShowNetworkChatQueryWindow ( DESTTYPE_CLIENT , NetworkFindClientInfo ( client_no ) - > client_index ) ;
}
2006-10-21 22:29:14 +00:00
static void ClientList_SpeakToCompany ( byte client_no )
2004-12-04 17:54:56 +00:00
{
if ( NetworkFindClientInfo ( client_no ) ! = NULL )
2006-10-21 22:29:14 +00:00
ShowNetworkChatQueryWindow ( DESTTYPE_TEAM , NetworkFindClientInfo ( client_no ) - > client_playas ) ;
2004-12-04 17:54:56 +00:00
}
static void ClientList_SpeakToAll ( byte client_no )
{
ShowNetworkChatQueryWindow ( DESTTYPE_BROADCAST , 0 ) ;
}
static void ClientList_None ( byte client_no )
{
// No action ;)
}
// Help, a action is clicked! What do we do?
2007-07-25 00:16:30 +00:00
static void HandleClientListPopupClick ( byte index , byte clientno )
{
2004-12-04 17:54:56 +00:00
// A click on the Popup of the ClientList.. handle the command
if ( index < MAX_CLIENTLIST_ACTION & & _clientlist_proc [ index ] ! = NULL ) {
_clientlist_proc [ index ] ( clientno ) ;
}
}
// Finds the amount of clients and set the height correct
static bool CheckClientListHeight ( Window * w )
{
int num = 0 ;
2006-10-18 13:17:46 +00:00
const NetworkClientInfo * ci ;
2004-12-04 17:54:56 +00:00
// Should be replaced with a loop through all clients
2006-10-18 13:17:46 +00:00
FOR_ALL_ACTIVE_CLIENT_INFOS ( ci ) {
2004-12-04 17:54:56 +00:00
num + + ;
}
num * = CLNWND_ROWSIZE ;
// If height is changed
2005-01-03 19:45:18 +00:00
if ( w - > height ! = CLNWND_OFFSET + num + 1 ) {
2004-12-04 17:54:56 +00:00
// XXX - magic unfortunately; (num + 2) has to be one bigger than heigh (num + 1)
2005-01-03 19:45:18 +00:00
SetWindowDirty ( w ) ;
2007-06-23 14:13:05 +00:00
w - > widget [ 3 ] . bottom = w - > widget [ 3 ] . top + num + 2 ;
2005-01-03 19:45:18 +00:00
w - > height = CLNWND_OFFSET + num + 1 ;
SetWindowDirty ( w ) ;
2004-12-04 17:54:56 +00:00
return false ;
}
return true ;
}
// Finds the amount of actions in the popup and set the height correct
2007-07-25 00:16:30 +00:00
static uint ClientListPopupHeight ( )
{
2004-12-04 17:54:56 +00:00
int i , num = 0 ;
// Find the amount of actions
for ( i = 0 ; i < MAX_CLIENTLIST_ACTION ; i + + ) {
if ( _clientlist_action [ i ] [ 0 ] = = ' \0 ' ) continue ;
if ( _clientlist_proc [ i ] = = NULL ) continue ;
num + + ;
}
num * = CLNWND_ROWSIZE ;
2005-01-03 19:45:18 +00:00
return num + 1 ;
2004-12-04 17:54:56 +00:00
}
// Show the popup (action list)
static Window * PopupClientList ( Window * w , int client_no , int x , int y )
{
2005-01-03 19:45:18 +00:00
int i , h ;
2006-07-26 03:33:12 +00:00
const NetworkClientInfo * ci ;
2004-12-04 17:54:56 +00:00
DeleteWindowById ( WC_TOOLBAR_MENU , 0 ) ;
// Clean the current actions
for ( i = 0 ; i < MAX_CLIENTLIST_ACTION ; i + + ) {
_clientlist_action [ i ] [ 0 ] = ' \0 ' ;
_clientlist_proc [ i ] = NULL ;
}
// Fill the actions this client has
// Watch is, max 50 chars long!
ci = NetworkFindClientInfo ( client_no ) ;
if ( ci = = NULL ) return NULL ;
i = 0 ;
if ( _network_own_client_index ! = ci - > client_index ) {
2006-10-21 23:31:34 +00:00
GetString ( _clientlist_action [ i ] , STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT , lastof ( _clientlist_action [ i ] ) ) ;
2004-12-04 17:54:56 +00:00
_clientlist_proc [ i + + ] = & ClientList_SpeakToClient ;
}
2006-10-24 22:26:20 +00:00
if ( IsValidPlayer ( ci - > client_playas ) | | ci - > client_playas = = PLAYER_SPECTATOR ) {
2006-10-21 23:31:34 +00:00
GetString ( _clientlist_action [ i ] , STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY , lastof ( _clientlist_action [ i ] ) ) ;
2006-10-21 22:29:14 +00:00
_clientlist_proc [ i + + ] = & ClientList_SpeakToCompany ;
2004-12-04 17:54:56 +00:00
}
2006-10-21 23:31:34 +00:00
GetString ( _clientlist_action [ i ] , STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL , lastof ( _clientlist_action [ i ] ) ) ;
2004-12-04 17:54:56 +00:00
_clientlist_proc [ i + + ] = & ClientList_SpeakToAll ;
if ( _network_own_client_index ! = ci - > client_index ) {
2007-09-30 17:38:42 +00:00
/* We are no spectator and the player we want to give money to is no spectator and money gifts are allowed */
if ( IsValidPlayer ( _network_playas ) & & IsValidPlayer ( ci - > client_playas ) & & _patches . give_money ) {
2006-10-21 23:31:34 +00:00
GetString ( _clientlist_action [ i ] , STR_NETWORK_CLIENTLIST_GIVE_MONEY , lastof ( _clientlist_action [ i ] ) ) ;
2006-10-17 22:16:46 +00:00
_clientlist_proc [ i + + ] = & ClientList_GiveMoney ;
2004-12-04 17:54:56 +00:00
}
}
2006-10-17 23:34:12 +00:00
// A server can kick clients (but not himself)
2004-12-04 17:54:56 +00:00
if ( _network_server & & _network_own_client_index ! = ci - > client_index ) {
2006-10-21 23:31:34 +00:00
GetString ( _clientlist_action [ i ] , STR_NETWORK_CLIENTLIST_KICK , lastof ( _clientlist_action [ i ] ) ) ;
2004-12-04 17:54:56 +00:00
_clientlist_proc [ i + + ] = & ClientList_Kick ;
2006-10-21 23:31:34 +00:00
sprintf ( _clientlist_action [ i ] , " Ban " ) ; // XXX GetString?
2005-01-02 12:03:43 +00:00
_clientlist_proc [ i + + ] = & ClientList_Ban ;
2004-12-04 17:54:56 +00:00
}
if ( i = = 0 ) {
2006-10-21 23:31:34 +00:00
GetString ( _clientlist_action [ i ] , STR_NETWORK_CLIENTLIST_NONE , lastof ( _clientlist_action [ i ] ) ) ;
2004-12-04 17:54:56 +00:00
_clientlist_proc [ i + + ] = & ClientList_None ;
}
2005-01-03 19:45:18 +00:00
/* Calculate the height */
2007-07-25 00:16:30 +00:00
h = ClientListPopupHeight ( ) ;
2004-12-04 17:54:56 +00:00
// Allocate the popup
2006-03-17 23:47:03 +00:00
w = AllocateWindow ( x , y , 150 , h + 1 , ClientListPopupWndProc , WC_TOOLBAR_MENU , _client_list_popup_widgets ) ;
2005-01-03 19:45:18 +00:00
w - > widget [ 0 ] . bottom = w - > widget [ 0 ] . top + h ;
2006-03-17 23:47:03 +00:00
w - > widget [ 0 ] . right = w - > widget [ 0 ] . left + 150 ;
2005-01-03 19:45:18 +00:00
2004-12-04 17:54:56 +00:00
w - > flags4 & = ~ WF_WHITE_BORDER_MASK ;
2007-12-16 10:54:08 +00:00
WP ( w , menu_d ) . item_count = 0 ;
2004-12-04 17:54:56 +00:00
// Save our client
2007-12-16 10:54:08 +00:00
WP ( w , menu_d ) . main_button = client_no ;
WP ( w , menu_d ) . sel_index = 0 ;
2004-12-04 17:54:56 +00:00
// We are a popup
_popup_menu_active = true ;
return w ;
}
2006-01-26 16:19:24 +00:00
/** Main handle for the client popup list
* uses menu_d WP macro */
2004-12-04 17:54:56 +00:00
static void ClientListPopupWndProc ( Window * w , WindowEvent * e )
{
2005-11-14 19:48:04 +00:00
switch ( e - > event ) {
2004-12-04 17:54:56 +00:00
case WE_PAINT : {
int i , y , sel ;
2007-11-04 00:08:57 +00:00
TextColour colour ;
2004-12-04 17:54:56 +00:00
DrawWindowWidgets ( w ) ;
// Draw the actions
2007-12-16 10:54:08 +00:00
sel = WP ( w , menu_d ) . sel_index ;
2004-12-04 17:54:56 +00:00
y = 1 ;
for ( i = 0 ; i < MAX_CLIENTLIST_ACTION ; i + + , y + = CLNWND_ROWSIZE ) {
if ( _clientlist_action [ i ] [ 0 ] = = ' \0 ' ) continue ;
if ( _clientlist_proc [ i ] = = NULL ) continue ;
if ( sel - - = = 0 ) { // Selected item, highlight it
2006-03-17 23:47:03 +00:00
GfxFillRect ( 1 , y , 150 - 2 , y + CLNWND_ROWSIZE - 1 , 0 ) ;
2007-11-04 00:08:57 +00:00
colour = TC_WHITE ;
2006-06-27 21:25:53 +00:00
} else {
2007-11-04 00:08:57 +00:00
colour = TC_BLACK ;
2006-06-27 21:25:53 +00:00
}
2004-12-04 17:54:56 +00:00
DoDrawString ( _clientlist_action [ i ] , 4 , y , colour ) ;
}
2007-04-18 22:41:53 +00:00
} break ;
2004-12-04 17:54:56 +00:00
case WE_POPUPMENU_SELECT : {
// We selected an action
2006-09-23 02:39:24 +00:00
int index = ( e - > we . popupmenu . pt . y - w - > top ) / CLNWND_ROWSIZE ;
2004-12-04 17:54:56 +00:00
2006-09-23 02:39:24 +00:00
if ( index > = 0 & & e - > we . popupmenu . pt . y > = w - > top )
2007-12-16 10:54:08 +00:00
HandleClientListPopupClick ( index , WP ( w , menu_d ) . main_button ) ;
2004-12-04 17:54:56 +00:00
DeleteWindowById ( WC_TOOLBAR_MENU , 0 ) ;
2007-04-18 22:41:53 +00:00
} break ;
2004-12-04 17:54:56 +00:00
case WE_POPUPMENU_OVER : {
// Our mouse hoovers over an action? Select it!
2006-09-23 02:39:24 +00:00
int index = ( e - > we . popupmenu . pt . y - w - > top ) / CLNWND_ROWSIZE ;
2004-12-04 17:54:56 +00:00
2007-12-16 10:54:08 +00:00
if ( index = = - 1 | | index = = WP ( w , menu_d ) . sel_index ) return ;
2004-12-04 17:54:56 +00:00
2007-12-16 10:54:08 +00:00
WP ( w , menu_d ) . sel_index = index ;
2004-12-04 17:54:56 +00:00
SetWindowDirty ( w ) ;
} break ;
}
}
// Main handle for clientlist
static void ClientListWndProc ( Window * w , WindowEvent * e )
{
2005-11-14 19:48:04 +00:00
switch ( e - > event ) {
2004-12-04 17:54:56 +00:00
case WE_PAINT : {
NetworkClientInfo * ci ;
int y , i = 0 ;
2007-11-04 00:08:57 +00:00
TextColour colour ;
2004-12-04 17:54:56 +00:00
// Check if we need to reset the height
if ( ! CheckClientListHeight ( w ) ) break ;
DrawWindowWidgets ( w ) ;
y = CLNWND_OFFSET ;
2006-10-18 13:17:46 +00:00
FOR_ALL_ACTIVE_CLIENT_INFOS ( ci ) {
2004-12-04 17:54:56 +00:00
if ( _selected_clientlist_item = = i + + ) { // Selected item, highlight it
GfxFillRect ( 1 , y , 248 , y + CLNWND_ROWSIZE - 1 , 0 ) ;
2007-11-04 00:08:57 +00:00
colour = TC_WHITE ;
2006-06-27 21:25:53 +00:00
} else {
2007-11-04 00:08:57 +00:00
colour = TC_BLACK ;
2006-06-27 21:25:53 +00:00
}
2004-12-04 17:54:56 +00:00
if ( ci - > client_index = = NETWORK_SERVER_INDEX ) {
2004-12-19 15:14:55 +00:00
DrawString ( 4 , y , STR_NETWORK_SERVER , colour ) ;
2005-11-14 19:48:04 +00:00
} else {
2004-12-19 15:14:55 +00:00
DrawString ( 4 , y , STR_NETWORK_CLIENT , colour ) ;
2005-11-14 19:48:04 +00:00
}
2004-12-04 17:54:56 +00:00
// Filter out spectators
2006-10-17 22:16:46 +00:00
if ( IsValidPlayer ( ci - > client_playas ) ) DrawPlayerIcon ( ci - > client_playas , 64 , y + 1 ) ;
2004-12-04 17:54:56 +00:00
2006-03-17 23:47:03 +00:00
DoDrawString ( ci - > client_name , 81 , y , colour ) ;
2004-12-04 17:54:56 +00:00
y + = CLNWND_ROWSIZE ;
}
2007-04-18 22:41:53 +00:00
} break ;
2004-12-04 17:54:56 +00:00
case WE_CLICK :
// Show the popup with option
if ( _selected_clientlist_item ! = 255 ) {
2006-09-23 02:39:24 +00:00
PopupClientList ( w , _selected_clientlist_item , e - > we . click . pt . x + w - > left , e - > we . click . pt . y + w - > top ) ;
2004-12-04 17:54:56 +00:00
}
break ;
case WE_MOUSEOVER :
// -1 means we left the current window
2006-09-23 02:39:24 +00:00
if ( e - > we . mouseover . pt . y = = - 1 ) {
2004-12-04 17:54:56 +00:00
_selected_clientlist_y = 0 ;
_selected_clientlist_item = 255 ;
SetWindowDirty ( w ) ;
break ;
}
// It did not change.. no update!
2006-09-23 02:39:24 +00:00
if ( e - > we . mouseover . pt . y = = _selected_clientlist_y ) break ;
2004-12-04 17:54:56 +00:00
// Find the new selected item (if any)
2006-09-23 02:39:24 +00:00
_selected_clientlist_y = e - > we . mouseover . pt . y ;
if ( e - > we . mouseover . pt . y > CLNWND_OFFSET ) {
_selected_clientlist_item = ( e - > we . mouseover . pt . y - CLNWND_OFFSET ) / CLNWND_ROWSIZE ;
2006-06-27 21:25:53 +00:00
} else {
2004-12-04 17:54:56 +00:00
_selected_clientlist_item = 255 ;
2006-06-27 21:25:53 +00:00
}
2004-12-04 17:54:56 +00:00
// Repaint
SetWindowDirty ( w ) ;
break ;
case WE_DESTROY : case WE_CREATE :
// When created or destroyed, data is reset
_selected_clientlist_item = 255 ;
_selected_clientlist_y = 0 ;
break ;
}
}
2007-03-07 11:47:46 +00:00
void ShowClientList ( )
2004-12-04 17:54:56 +00:00
{
2006-08-31 14:54:25 +00:00
AllocateWindowDescFront ( & _client_list_desc , 0 ) ;
2004-12-04 17:54:56 +00:00
}
2006-09-01 13:35:43 +00:00
static NetworkPasswordType pw_type ;
void ShowNetworkNeedPassword ( NetworkPasswordType npt )
{
StringID caption ;
pw_type = npt ;
switch ( npt ) {
default : NOT_REACHED ( ) ;
2006-10-08 11:54:47 +00:00
case NETWORK_GAME_PASSWORD : caption = STR_NETWORK_NEED_GAME_PASSWORD_CAPTION ; break ;
case NETWORK_COMPANY_PASSWORD : caption = STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION ; break ;
2006-09-01 13:35:43 +00:00
}
2006-12-30 01:17:53 +00:00
ShowQueryString ( STR_EMPTY , caption , 20 , 180 , FindWindowById ( WC_NETWORK_STATUS_WINDOW , 0 ) , CS_ALPHANUMERAL ) ;
2006-09-01 13:35:43 +00:00
}
2004-12-04 17:54:56 +00:00
static void NetworkJoinStatusWindowWndProc ( Window * w , WindowEvent * e )
{
2005-11-14 19:48:04 +00:00
switch ( e - > event ) {
2004-12-04 17:54:56 +00:00
case WE_PAINT : {
uint8 progress ; // used for progress bar
DrawWindowWidgets ( w ) ;
2007-11-04 00:08:57 +00:00
DrawStringCentered ( 125 , 35 , STR_NETWORK_CONNECTING_1 + _network_join_status , TC_GREY ) ;
2004-12-04 17:54:56 +00:00
switch ( _network_join_status ) {
case NETWORK_JOIN_STATUS_CONNECTING : case NETWORK_JOIN_STATUS_AUTHORIZING :
case NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO :
progress = 10 ; // first two stages 10%
break ;
case NETWORK_JOIN_STATUS_WAITING :
SetDParam ( 0 , _network_join_waiting ) ;
2007-11-04 00:08:57 +00:00
DrawStringCentered ( 125 , 46 , STR_NETWORK_CONNECTING_WAITING , TC_GREY ) ;
2004-12-04 17:54:56 +00:00
progress = 15 ; // third stage is 15%
break ;
case NETWORK_JOIN_STATUS_DOWNLOADING :
SetDParam ( 0 , _network_join_kbytes ) ;
SetDParam ( 1 , _network_join_kbytes_total ) ;
2007-11-04 00:08:57 +00:00
DrawStringCentered ( 125 , 46 , STR_NETWORK_CONNECTING_DOWNLOADING , TC_GREY ) ;
2004-12-04 17:54:56 +00:00
/* Fallthrough */
default : /* Waiting is 15%, so the resting receivement of map is maximum 70% */
progress = 15 + _network_join_kbytes * ( 100 - 15 ) / _network_join_kbytes_total ;
}
/* Draw nice progress bar :) */
2007-01-10 18:56:51 +00:00
DrawFrameRect ( 20 , 18 , ( int ) ( ( w - > width - 20 ) * progress / 100 ) , 28 , 10 , FR_NONE ) ;
2007-04-18 22:41:53 +00:00
} break ;
2004-12-04 17:54:56 +00:00
case WE_CLICK :
2006-09-23 02:39:24 +00:00
switch ( e - > we . click . widget ) {
2006-12-30 01:52:09 +00:00
case 2 : /* Disconnect button */
2005-11-14 19:48:04 +00:00
NetworkDisconnect ( ) ;
2006-12-30 01:17:53 +00:00
DeleteWindow ( w ) ;
2005-11-14 19:48:04 +00:00
SwitchMode ( SM_MENU ) ;
ShowNetworkGameWindow ( ) ;
break ;
2004-12-04 17:54:56 +00:00
}
break ;
2006-12-30 01:17:53 +00:00
/* If the server asks for a password, we need to fill it in */
2006-09-01 13:35:43 +00:00
case WE_ON_EDIT_TEXT_CANCEL :
NetworkDisconnect ( ) ;
ShowNetworkGameWindow ( ) ;
break ;
case WE_ON_EDIT_TEXT :
2006-09-23 02:39:24 +00:00
SEND_COMMAND ( PACKET_CLIENT_PASSWORD ) ( pw_type , e - > we . edittext . str ) ;
2006-09-01 13:35:43 +00:00
break ;
2004-12-04 17:54:56 +00:00
}
}
static const Widget _network_join_status_window_widget [ ] = {
2006-12-30 01:52:09 +00:00
{ WWT_CAPTION , RESIZE_NONE , 14 , 0 , 249 , 0 , 13 , STR_NETWORK_CONNECTING , STR_018C_WINDOW_TITLE_DRAG_THIS } ,
2006-10-24 14:15:17 +00:00
{ WWT_PANEL , RESIZE_NONE , 14 , 0 , 249 , 14 , 84 , 0x0 , STR_NULL } ,
2005-01-03 19:45:18 +00:00
{ WWT_PUSHTXTBTN , RESIZE_NONE , BTC , 75 , 175 , 69 , 80 , STR_NETWORK_DISCONNECT , STR_NULL } ,
2004-12-04 17:54:56 +00:00
{ WIDGETS_END } ,
} ;
static const WindowDesc _network_join_status_window_desc = {
2007-07-27 12:49:04 +00:00
WDP_CENTER , WDP_CENTER , 250 , 85 , 250 , 85 ,
2007-02-01 15:49:12 +00:00
WC_NETWORK_STATUS_WINDOW , WC_NONE ,
2006-12-30 01:52:09 +00:00
WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_MODAL ,
2004-12-04 17:54:56 +00:00
_network_join_status_window_widget ,
NetworkJoinStatusWindowWndProc ,
} ;
2007-03-07 11:47:46 +00:00
void ShowJoinStatusWindow ( )
2004-12-04 17:54:56 +00:00
{
2006-12-30 01:52:09 +00:00
Window * w ;
2004-12-04 17:54:56 +00:00
DeleteWindowById ( WC_NETWORK_STATUS_WINDOW , 0 ) ;
2006-12-30 01:52:09 +00:00
w = AllocateWindowDesc ( & _network_join_status_window_desc ) ;
/* Parent the status window to the lobby */
if ( w ! = NULL ) w - > parent = FindWindowById ( WC_NETWORK_WINDOW , 0 ) ;
2004-12-15 21:13:52 +00:00
}
2004-12-04 17:54:56 +00:00
2007-04-26 07:41:24 +00:00
static void SendChat ( const char * buf , DestType type , int dest )
2006-06-11 16:00:56 +00:00
{
2007-07-25 00:16:30 +00:00
if ( StrEmpty ( buf ) ) return ;
2006-06-11 16:00:56 +00:00
if ( ! _network_server ) {
2007-01-10 18:56:51 +00:00
SEND_COMMAND ( PACKET_CLIENT_CHAT ) ( ( NetworkAction ) ( NETWORK_ACTION_CHAT + type ) , type , dest , buf ) ;
2006-06-11 16:00:56 +00:00
} else {
2007-01-10 18:56:51 +00:00
NetworkServer_HandleChat ( ( NetworkAction ) ( NETWORK_ACTION_CHAT + type ) , type , dest , buf , NETWORK_SERVER_INDEX ) ;
2006-06-11 16:00:56 +00:00
}
}
2006-08-20 10:51:27 +00:00
/**
* Find the next item of the list of things that can be auto - completed .
2006-08-20 12:03:39 +00:00
* @ param item The current indexed item to return . This function can , and most
* likely will , alter item , to skip empty items in the arrays .
* @ return Returns the char that matched to the index .
2006-08-20 10:51:27 +00:00
*/
static const char * ChatTabCompletionNextItem ( uint * item )
{
static char chat_tab_temp_buffer [ 64 ] ;
/* First, try clients */
if ( * item < MAX_CLIENT_INFO ) {
/* Skip inactive clients */
while ( _network_client_info [ * item ] . client_index = = NETWORK_EMPTY_INDEX & & * item < MAX_CLIENT_INFO ) ( * item ) + + ;
if ( * item < MAX_CLIENT_INFO ) return _network_client_info [ * item ] . client_name ;
}
/* Then, try townnames */
2006-12-05 13:58:20 +00:00
/* Not that the following assumes all town indices are adjacent, ie no
* towns have been deleted . */
if ( * item < = ( uint ) MAX_CLIENT_INFO + GetMaxTownIndex ( ) ) {
2006-08-20 12:03:39 +00:00
const Town * t ;
2006-08-20 10:51:27 +00:00
FOR_ALL_TOWNS_FROM ( t , * item - MAX_CLIENT_INFO ) {
/* Get the town-name via the string-system */
2007-06-18 23:00:55 +00:00
SetDParam ( 0 , t - > index ) ;
GetString ( chat_tab_temp_buffer , STR_TOWN , lastof ( chat_tab_temp_buffer ) ) ;
2006-08-20 10:51:27 +00:00
return & chat_tab_temp_buffer [ 0 ] ;
}
}
return NULL ;
}
/**
* Find what text to complete . It scans for a space from the left and marks
* the word right from that as to complete . It also writes a \ 0 at the
* position of the space ( if any ) . If nothing found , buf is returned .
*/
static char * ChatTabCompletionFindText ( char * buf )
{
2006-10-17 23:34:12 +00:00
char * p = strrchr ( buf , ' ' ) ;
2006-08-20 12:03:39 +00:00
if ( p = = NULL ) return buf ;
2006-08-20 10:51:27 +00:00
2006-08-20 12:03:39 +00:00
* p = ' \0 ' ;
return p + 1 ;
2006-08-20 10:51:27 +00:00
}
/**
* See if we can auto - complete the current text of the user .
*/
static void ChatTabCompletion ( Window * w )
{
2008-03-24 06:38:20 +00:00
static char _chat_tab_completion_buf [ lengthof ( _edit_str_net_buf ) ] ;
2007-04-26 07:41:24 +00:00
Textbuf * tb = & WP ( w , chatquerystr_d ) . text ;
2006-08-20 10:51:27 +00:00
uint len , tb_len ;
uint item ;
char * tb_buf , * pre_buf ;
const char * cur_name ;
bool second_scan = false ;
item = 0 ;
/* Copy the buffer so we can modify it without damaging the real data */
pre_buf = ( _chat_tab_completion_active ) ? strdup ( _chat_tab_completion_buf ) : strdup ( tb - > buf ) ;
tb_buf = ChatTabCompletionFindText ( pre_buf ) ;
tb_len = strlen ( tb_buf ) ;
while ( ( cur_name = ChatTabCompletionNextItem ( & item ) ) ! = NULL ) {
item + + ;
if ( _chat_tab_completion_active ) {
/* We are pressing TAB again on the same name, is there an other name
* that starts with this ? */
if ( ! second_scan ) {
uint offset ;
uint length ;
/* If we are completing at the begin of the line, skip the ': ' we added */
if ( tb_buf = = pre_buf ) {
offset = 0 ;
length = tb - > length - 2 ;
} else {
/* Else, find the place we are completing at */
offset = strlen ( pre_buf ) + 1 ;
length = tb - > length - offset ;
}
/* Compare if we have a match */
if ( strlen ( cur_name ) = = length & & strncmp ( cur_name , tb - > buf + offset , length ) = = 0 ) second_scan = true ;
continue ;
}
/* Now any match we make on _chat_tab_completion_buf after this, is perfect */
}
len = strlen ( cur_name ) ;
if ( tb_len < len & & strncasecmp ( cur_name , tb_buf , tb_len ) = = 0 ) {
/* Save the data it was before completion */
if ( ! second_scan ) snprintf ( _chat_tab_completion_buf , lengthof ( _chat_tab_completion_buf ) , " %s " , tb - > buf ) ;
_chat_tab_completion_active = true ;
/* Change to the found name. Add ': ' if we are at the start of the line (pretty) */
if ( pre_buf = = tb_buf ) {
2008-03-24 06:38:20 +00:00
snprintf ( tb - > buf , lengthof ( _edit_str_net_buf ) , " %s: " , cur_name ) ;
2006-08-20 10:51:27 +00:00
} else {
2008-03-24 06:38:20 +00:00
snprintf ( tb - > buf , lengthof ( _edit_str_net_buf ) , " %s %s " , pre_buf , cur_name ) ;
2006-08-20 10:51:27 +00:00
}
/* Update the textbuffer */
2007-04-26 07:41:24 +00:00
UpdateTextBufferSize ( & WP ( w , chatquerystr_d ) . text ) ;
2006-08-20 10:51:27 +00:00
SetWindowDirty ( w ) ;
free ( pre_buf ) ;
return ;
}
}
if ( second_scan ) {
/* We walked all posibilities, and the user presses tab again.. revert to original text */
strcpy ( tb - > buf , _chat_tab_completion_buf ) ;
_chat_tab_completion_active = false ;
/* Update the textbuffer */
2007-04-26 07:41:24 +00:00
UpdateTextBufferSize ( & WP ( w , chatquerystr_d ) . text ) ;
2006-08-20 10:51:27 +00:00
SetWindowDirty ( w ) ;
}
free ( pre_buf ) ;
}
2006-06-11 16:00:56 +00:00
2007-04-26 07:41:24 +00:00
/*
* uses chatquerystr_d WP macro
2008-03-24 06:32:53 +00:00
* uses chatquerystr_d - > dtype to store type of chat message ( Private / Team / All )
2007-04-26 07:41:24 +00:00
*/
2004-12-14 16:53:38 +00:00
static void ChatWindowWndProc ( Window * w , WindowEvent * e )
{
2005-04-05 21:03:30 +00:00
switch ( e - > event ) {
case WE_CREATE :
2007-12-13 23:26:00 +00:00
SendWindowMessage ( WC_NEWS_WINDOW , 0 , WE_CREATE , w - > height , 0 ) ;
SetBit ( _no_scroll , SCROLL_CHAT ) ; // do not scroll the game with the arrow-keys
2005-04-05 21:03:30 +00:00
break ;
2004-12-14 16:53:38 +00:00
2006-10-18 21:07:36 +00:00
case WE_PAINT : {
2007-12-13 23:26:00 +00:00
static const StringID chat_captions [ ] = {
STR_NETWORK_CHAT_ALL_CAPTION ,
STR_NETWORK_CHAT_COMPANY_CAPTION ,
STR_NETWORK_CHAT_CLIENT_CAPTION
} ;
2004-12-14 16:53:38 +00:00
DrawWindowWidgets ( w ) ;
2006-10-18 21:07:36 +00:00
2008-03-24 06:38:20 +00:00
assert ( ( uint ) WP ( w , chatquerystr_d ) . dtype < lengthof ( chat_captions ) ) ;
2008-03-24 06:32:53 +00:00
DrawStringRightAligned ( w - > widget [ 2 ] . left - 2 , w - > widget [ 2 ] . top + 1 , chat_captions [ WP ( w , chatquerystr_d ) . dtype ] , TC_BLACK ) ;
2007-04-26 07:41:24 +00:00
DrawEditBox ( w , & WP ( w , chatquerystr_d ) , 2 ) ;
2006-10-18 21:07:36 +00:00
} break ;
2004-12-14 16:53:38 +00:00
case WE_CLICK :
2006-09-23 02:39:24 +00:00
switch ( e - > we . click . widget ) {
2008-03-24 06:32:53 +00:00
case 3 : /* Send */
SendChat ( WP ( w , chatquerystr_d ) . text . buf , WP ( w , chatquerystr_d ) . dtype , WP ( w , chatquerystr_d ) . dest ) ;
/* FALLTHROUGH */
2006-10-18 21:07:36 +00:00
case 0 : /* Cancel */ DeleteWindow ( w ) ; break ;
2004-12-14 16:53:38 +00:00
}
break ;
2006-06-11 16:00:56 +00:00
case WE_MOUSELOOP :
2007-04-26 07:41:24 +00:00
HandleEditBox ( w , & WP ( w , chatquerystr_d ) , 2 ) ;
2006-06-11 16:00:56 +00:00
break ;
2004-12-14 16:53:38 +00:00
2006-06-11 16:00:56 +00:00
case WE_KEYPRESS :
2006-09-23 02:39:24 +00:00
if ( e - > we . keypress . keycode = = WKC_TAB ) {
2006-08-20 10:51:27 +00:00
ChatTabCompletion ( w ) ;
} else {
_chat_tab_completion_active = false ;
2007-04-26 07:41:24 +00:00
switch ( HandleEditBoxKey ( w , & WP ( w , chatquerystr_d ) , 2 , e ) ) {
2008-03-24 06:32:53 +00:00
case 1 : /* Return */
SendChat ( WP ( w , chatquerystr_d ) . text . buf , WP ( w , chatquerystr_d ) . dtype , WP ( w , chatquerystr_d ) . dest ) ;
/* FALLTHROUGH */
2006-08-20 10:51:27 +00:00
case 2 : /* Escape */ DeleteWindow ( w ) ; break ;
}
2004-12-14 16:53:38 +00:00
}
2006-06-11 16:00:56 +00:00
break ;
2004-12-14 16:53:38 +00:00
case WE_DESTROY :
2005-04-05 21:03:30 +00:00
SendWindowMessage ( WC_NEWS_WINDOW , 0 , WE_DESTROY , 0 , 0 ) ;
2007-11-19 21:32:20 +00:00
ClrBit ( _no_scroll , SCROLL_CHAT ) ;
2004-12-14 16:53:38 +00:00
break ;
}
}
static const Widget _chat_window_widgets [ ] = {
2007-07-29 19:19:30 +00:00
{ WWT_CLOSEBOX , RESIZE_NONE , 14 , 0 , 10 , 0 , 13 , STR_00C5 , STR_018B_CLOSE_WINDOW } ,
{ WWT_PANEL , RESIZE_RIGHT , 14 , 11 , 319 , 0 , 13 , 0x0 , STR_NULL } , // background
{ WWT_PANEL , RESIZE_RIGHT , 14 , 75 , 257 , 1 , 12 , 0x0 , STR_NULL } , // text box
{ WWT_PUSHTXTBTN , RESIZE_LR , 14 , 258 , 319 , 1 , 12 , STR_NETWORK_SEND , STR_NULL } , // send button
2004-12-14 16:53:38 +00:00
{ WIDGETS_END } ,
} ;
static const WindowDesc _chat_window_desc = {
2007-07-29 19:19:30 +00:00
WDP_CENTER , - 26 , 320 , 14 , 640 , 14 , // x, y, width, height
2007-02-01 15:49:12 +00:00
WC_SEND_NETWORK_MSG , WC_NONE ,
2007-12-06 15:58:39 +00:00
WDF_STD_TOOLTIPS | WDF_DEF_WIDGET ,
2004-12-14 16:53:38 +00:00
_chat_window_widgets ,
ChatWindowWndProc
} ;
2007-04-26 07:41:24 +00:00
void ShowNetworkChatQueryWindow ( DestType type , int dest )
2004-12-14 16:53:38 +00:00
{
Window * w ;
DeleteWindowById ( WC_SEND_NETWORK_MSG , 0 ) ;
2008-03-24 06:38:20 +00:00
_edit_str_net_buf [ 0 ] = ' \0 ' ;
2006-08-20 10:51:27 +00:00
_chat_tab_completion_active = false ;
2004-12-14 16:53:38 +00:00
w = AllocateWindowDesc ( & _chat_window_desc ) ;
2007-12-02 14:29:48 +00:00
w - > LowerWidget ( 2 ) ;
2008-03-24 06:32:53 +00:00
WP ( w , chatquerystr_d ) . dtype = type ;
2007-04-26 07:41:24 +00:00
WP ( w , chatquerystr_d ) . dest = dest ;
WP ( w , chatquerystr_d ) . afilter = CS_ALPHANUMERAL ;
2008-03-24 06:38:20 +00:00
InitializeTextBuffer ( & WP ( w , chatquerystr_d ) . text , _edit_str_net_buf , lengthof ( _edit_str_net_buf ) , 0 ) ;
2004-12-14 16:53:38 +00:00
}
2007-12-02 14:48:26 +00:00
/** Enum for NetworkGameWindow, referring to _network_game_window_widgets */
enum NetworkCompanyPasswordWindowWidgets {
NCPWW_CLOSE , ///< Close 'X' button
NCPWW_CAPTION , ///< Caption of the whole window
NCPWW_BACKGROUND , ///< The background of the interface
NCPWW_LABEL , ///< Label in front of the password field
NCPWW_PASSWORD , ///< Input field for the password
NCPWW_SAVE_AS_DEFAULT_PASSWORD , ///< Toggle 'button' for saving the current password as default password
NCPWW_CANCEL , ///< Close the window without changing anything
NCPWW_OK , ///< Safe the password etc.
} ;
static void NetworkCompanyPasswordWindowWndProc ( Window * w , WindowEvent * e )
{
switch ( e - > event ) {
case WE_PAINT :
DrawWindowWidgets ( w ) ;
DrawEditBox ( w , & WP ( w , chatquerystr_d ) , 4 ) ;
break ;
case WE_CLICK :
switch ( e - > we . click . widget ) {
case NCPWW_OK : {
if ( w - > IsWidgetLowered ( NCPWW_SAVE_AS_DEFAULT_PASSWORD ) ) {
2008-03-24 06:38:20 +00:00
snprintf ( _network_default_company_pass , lengthof ( _network_default_company_pass ) , " %s " , _edit_str_net_buf ) ;
2007-12-02 14:48:26 +00:00
}
/* empty password is a '*' because of console argument */
2008-03-24 06:38:20 +00:00
if ( StrEmpty ( _edit_str_net_buf ) ) snprintf ( _edit_str_net_buf , lengthof ( _edit_str_net_buf ) , " * " ) ;
char * password = _edit_str_net_buf ;
2007-12-02 14:48:26 +00:00
NetworkChangeCompanyPassword ( 1 , & password ) ;
}
/* FALL THROUGH */
case NCPWW_CANCEL :
DeleteWindow ( w ) ;
break ;
case NCPWW_SAVE_AS_DEFAULT_PASSWORD :
w - > ToggleWidgetLoweredState ( NCPWW_SAVE_AS_DEFAULT_PASSWORD ) ;
SetWindowDirty ( w ) ;
break ;
}
break ;
case WE_MOUSELOOP :
HandleEditBox ( w , & WP ( w , chatquerystr_d ) , 4 ) ;
break ;
case WE_KEYPRESS :
switch ( HandleEditBoxKey ( w , & WP ( w , chatquerystr_d ) , 4 , e ) ) {
case 1 : // Return
2007-12-16 19:28:07 +00:00
e - > event = WE_CLICK ;
e - > we . click . widget = NCPWW_OK ;
NetworkCompanyPasswordWindowWndProc ( w , e ) ;
break ;
2007-12-02 14:48:26 +00:00
case 2 : // Escape
DeleteWindow ( w ) ;
break ;
}
break ;
}
}
static const Widget _ncp_window_widgets [ ] = {
{ WWT_CLOSEBOX , RESIZE_NONE , 14 , 0 , 10 , 0 , 13 , STR_00C5 , STR_018B_CLOSE_WINDOW } ,
{ WWT_CAPTION , RESIZE_NONE , 14 , 11 , 299 , 0 , 13 , STR_COMPANY_PASSWORD_CAPTION , STR_018C_WINDOW_TITLE_DRAG_THIS } ,
{ WWT_PANEL , RESIZE_NONE , 14 , 0 , 299 , 14 , 50 , 0x0 , STR_NULL } ,
{ WWT_TEXT , RESIZE_NONE , 14 , 5 , 100 , 19 , 30 , STR_COMPANY_PASSWORD , STR_NULL } ,
{ WWT_PANEL , RESIZE_NONE , 14 , 101 , 294 , 19 , 30 , 0x0 , STR_NULL } ,
{ WWT_TEXTBTN , RESIZE_NONE , 14 , 101 , 294 , 35 , 46 , STR_MAKE_DEFAULT_COMPANY_PASSWORD , STR_MAKE_DEFAULT_COMPANY_PASSWORD_TIP } ,
{ WWT_PUSHTXTBTN , RESIZE_NONE , 14 , 0 , 149 , 51 , 62 , STR_012E_CANCEL , STR_COMPANY_PASSWORD_CANCEL } ,
{ WWT_PUSHTXTBTN , RESIZE_NONE , 14 , 150 , 299 , 51 , 62 , STR_012F_OK , STR_COMPANY_PASSWORD_OK } ,
{ WIDGETS_END } ,
} ;
static const WindowDesc _ncp_window_desc = {
WDP_AUTO , WDP_AUTO , 300 , 63 , 300 , 63 ,
WC_COMPANY_PASSWORD_WINDOW , WC_NONE ,
2007-12-06 15:58:39 +00:00
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON ,
2007-12-02 14:48:26 +00:00
_ncp_window_widgets ,
NetworkCompanyPasswordWindowWndProc
} ;
void ShowNetworkCompanyPasswordWindow ( )
{
DeleteWindowById ( WC_COMPANY_PASSWORD_WINDOW , 0 ) ;
2008-03-24 06:38:20 +00:00
_edit_str_net_buf [ 0 ] = ' \0 ' ;
2007-12-02 14:48:26 +00:00
Window * w = AllocateWindowDesc ( & _ncp_window_desc ) ;
WP ( w , chatquerystr_d ) . afilter = CS_ALPHANUMERAL ;
2008-03-24 06:38:20 +00:00
InitializeTextBuffer ( & WP ( w , chatquerystr_d ) . text , _edit_str_net_buf , min ( lengthof ( _network_default_company_pass ) , lengthof ( _edit_str_net_buf ) ) , 0 ) ;
2007-12-02 14:48:26 +00:00
}
2004-12-04 17:54:56 +00:00
# endif /* ENABLE_NETWORK */