diff -ruN -Xfreeciv/diff_ignore freeciv/client/clinet.c freeciv_build/client/clinet.c
--- freeciv/client/clinet.c Tue Sep 19 18:06:55 2000
+++ freeciv_build/client/clinet.c Mon Sep 25 18:25:55 2000
@@ -238,6 +238,8 @@
The result must be free'd with delete_server_list() when no
longer used
**************************************************************************/
+#define MAXSERVERS 100
+
struct server_list *create_server_list(char *errbuf, int n_errbuf)
{
struct server_list *server_list;
@@ -251,6 +253,8 @@
char *server;
int port;
char str[512];
+ char *servers[MAXSERVERS];
+ int numservers=0;
if ((proxy_url = getenv("http_proxy"))) {
if (strncmp(proxy_url,"http://",strlen("http://"))) {
@@ -356,33 +360,49 @@
server_list = fc_malloc(sizeof(struct server_list));
server_list_init(server_list);
- while(fgets(str, 512, f) != NULL) {
- if((0 == strncmp(str, "
'); if(p==NULL) continue;
- name=++p;
- p=strstr(p,""); if(p==NULL) continue;
- *p++='\0';
-
- GET_FIELD(port);
- GET_FIELD(version);
- GET_FIELD(status);
- GET_FIELD(players);
- GET_FIELD(metastring);
-
- pserver->name = mystrdup(name);
- pserver->port = mystrdup(port);
- pserver->version = mystrdup(version);
- pserver->status = mystrdup(status);
- pserver->players = mystrdup(players);
- pserver->metastring = mystrdup(metastring);
-
- server_list_insert(server_list, pserver);
- }
+ while(fgets(str, 512, f) != NULL && numservers=0; numservers--) {
+ char *name,*port,*version,*status,*players,*metastring, *lastturn, *joinas;
+ char *p;
+ int minutes;
+ struct server *pserver = (struct server*)fc_malloc(sizeof(struct server));
+
+ strcpy(str, servers[numservers]);
+ free(servers[numservers]);
+
+ p=strstr(str,"'); if(p==NULL) continue;
+ name=++p;
+ p=strstr(p,""); if(p==NULL) continue;
+ *p++='\0';
+
+ GET_FIELD(port);
+ GET_FIELD(version);
+ GET_FIELD(status);
+ GET_FIELD(players);
+ GET_FIELD(metastring);
+ GET_FIELD(lastturn);
+ GET_FIELD(joinas);
+
+ if (!strcmp(joinas,"-"))
+ joinas="";
+
+ minutes=200;
+ if (strchr(lastturn,'m')) minutes=atoi(lastturn);
+ if (strchr(lastturn,'h')) minutes=atoi(lastturn)*60;
+
+ pserver->name = mystrdup(name);
+ pserver->port = mystrdup(port);
+ pserver->version = mystrdup(version);
+ pserver->status = mystrdup(status);
+ pserver->players = mystrdup(players);
+ pserver->metastring = mystrdup(metastring);
+ pserver->lastturn = minutes;
+ pserver->joinas = mystrdup(joinas);
+ server_list_insert(server_list, pserver);
}
fclose(f);
@@ -410,3 +430,13 @@
free(server_list);
}
+/**************************************************************************
+...
+**************************************************************************/
+void server_command(char *str)
+{
+ struct packet_generic_message apacket;
+
+ mystrlcpy(apacket.message, str, MAX_LEN_MSG-MAX_LEN_USERNAME+1);
+ send_packet_generic_message(&aconnection, PACKET_CHAT_MSG, &apacket);
+}
diff -ruN -Xfreeciv/diff_ignore freeciv/client/clinet.h freeciv_build/client/clinet.h
--- freeciv/client/clinet.h Sun Jan 2 13:55:22 2000
+++ freeciv_build/client/clinet.h Mon Sep 25 18:25:55 2000
@@ -34,6 +34,8 @@
char *status;
char *players;
char *metastring;
+ int lastturn;
+ char *joinas;
};
#define SPECLIST_TAG server
@@ -46,5 +48,6 @@
struct server_list *create_server_list(char *errbuf, int n_errbuf);
void delete_server_list(struct server_list *server_list);
+void server_command(char *str);
#endif /* FC__CLINET_H */
diff -ruN -Xfreeciv/diff_ignore freeciv/client/gui-gtk/connectdlg.c freeciv_build/client/gui-gtk/connectdlg.c
--- freeciv/client/gui-gtk/connectdlg.c Sun Jul 23 13:55:06 2000
+++ freeciv_build/client/gui-gtk/connectdlg.c Mon Sep 25 19:57:21 2000
@@ -16,9 +16,14 @@
#include
#include
+#include
#include
+#ifdef HAVE_UNISTD_H
+#include
+#endif
+
#include "fcintl.h"
#include "support.h"
#include "version.h"
@@ -30,12 +35,18 @@
#include "gui_stuff.h"
#include "connectdlg.h"
+#include "helpdlg_g.h"
+
+#define AUTOSTART_SERVER _("localhost (autostarted)")
/* in civclient.c; FIXME hardcoded sizes */
extern char name[];
extern char server_host[];
extern int server_port;
+static int server_game_running;
+static int server_autostart;
+
static GtkWidget *iname, *ihost, *iport;
static GtkWidget *connw, *quitw;
@@ -51,24 +62,239 @@
static int get_meta_list(GtkWidget *list, char *errbuf, int n_errbuf);
+static int group_vals[20]; /* The values of Options radio buttons */
+
+static int option_suggest_name=TRUE, option_hide_inactive=TRUE;
+
+
/**************************************************************************
...
**************************************************************************/
-static void connect_callback(GtkWidget *w, gpointer data)
+static void start_localgame(void)
{
- char errbuf [512];
+ char buf[200];
+ int aifill[] ={2+1, 4+1, 8+1};
+ int xsize[] ={50, 60, 80};
+ int ysize[] ={40, 50, 50};
+ char *difficulty[]={"easy", "normal", "hard"};
+ int gen [] ={1,2};
+
+ sprintf(buf, "/set aifill %d", aifill[group_vals[0]]);
+ server_command(buf);
+ sprintf(buf, "/set xsize %d", xsize[group_vals[1]]);
+ server_command(buf);
+ sprintf(buf, "/set ysize %d", ysize[group_vals[1]]);
+ server_command(buf);
+ sprintf(buf, "/%s", difficulty[group_vals[2]]);
+ server_command(buf);
+ sprintf(buf, "/set generator %d", gen[group_vals[3]]);
+ server_command(buf);
+ server_command("/start");
+}
- mystrlcpy(name, gtk_entry_get_text(GTK_ENTRY(iname)), 512);
- mystrlcpy(server_host, gtk_entry_get_text(GTK_ENTRY(ihost)), 512);
- server_port=atoi(gtk_entry_get_text(GTK_ENTRY(iport)));
-
- if(connect_to_server(name, server_host, server_port,
- errbuf, sizeof(errbuf))!=-1) {
+/**************************************************************************
+...
+**************************************************************************/
+int start_server(int port)
+{
+ char buf[200];
+
+ sprintf(buf,"(civserver -b -p %d &) >/dev/null", port);
+ return system(buf);
+#if 0
+ /* does not work */
+ if ((server_pid=fork())<0) {
+ append_output_window(_("Lost connection to server!"));
+ return 1;
+ } else if (server_pid==0) { /* child */
+ sprintf(buf,"%d",port);
+ freopen("/dev/null", "w", stdout);
+ execlp("civserver", "civserver", "-b", "-p", buf);
+ exit(0);
+ }
+ sleep(2);
+ return 0;
+#endif
+}
+/**************************************************************************
+...
+**************************************************************************/
+static GtkWidget *input_dialog;
+
+static void sel_name_dialog_destroy(GtkWidget *button)
+{
+ GtkWidget *parent;
+
+ parent=gtk_object_get_data(GTK_OBJECT(button->parent->parent->parent),
+ "parent");
+
+ gtk_widget_set_sensitive(parent, TRUE);
+
+ gtk_widget_destroy(button->parent->parent->parent);
+}
+
+
+static gint sel_name_del_callback(GtkWidget *widget, GdkEvent *event,
+ gpointer data)
+{
+ gtk_widget_set_sensitive( (GtkWidget *)data, TRUE );
+ return FALSE;
+}
+
+/****************************************************************
+...
+*****************************************************************/
+static void connection_attempt(char *tempname, int fromlist);
+static char joinas_name[128];
+
+static void select_name_callback(GtkWidget *w, gpointer data)
+{
+ sel_name_dialog_destroy(w);
+
+ if(data)
+ connection_attempt(joinas_name, TRUE);
+}
+
+void sel_name_radio_callback( GtkWidget *w, gpointer data )
+{
+ sz_strlcpy(joinas_name, data);
+}
+
+static void gui_select_name(char *joinas)
+{
+ GtkWidget *shell, *frame, *ok, *cancel, *parent=dialog, *button, *vbox;
+ GSList *namegroup=0;
+ static char namebuf[1024];
+ char *r, *w, *name;
+
+ gtk_widget_set_sensitive(parent, FALSE);
+
+ shell=gtk_dialog_new();
+ gtk_signal_connect(GTK_OBJECT(shell),"delete_event",
+ GTK_SIGNAL_FUNC(sel_name_del_callback), parent);
+
+ gtk_window_set_title(GTK_WINDOW(shell), _("Select player name"));
+
+ gtk_container_border_width(GTK_CONTAINER(GTK_DIALOG(shell)->vbox), 5);
+
+ frame=gtk_frame_new("Select player name");
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(shell)->vbox), frame, TRUE, TRUE, 0);
+
+ vbox = gtk_vbox_new(0,TRUE);
+ r=joinas;
+ w=namebuf;
+ do {
+ if (*r==';')
+ break;
+
+ name=w;
+ for ( ; *r && *r!=',' && *r!=';'; r++)
+ *w++ = *r;
+ *w++=0;
+ for ( ; *r && strchr(" ,",*r); r++) ;
+
+ if (name==namebuf)
+ sz_strlcpy(joinas_name, name);
+
+ button=gtk_radio_button_new_with_label(namegroup, name);
+ namegroup = gtk_radio_button_group( GTK_RADIO_BUTTON( button ) );
+ gtk_signal_connect(GTK_OBJECT(button), "toggled",
+ GTK_SIGNAL_FUNC(sel_name_radio_callback), name);
+ gtk_box_pack_start( GTK_BOX( vbox ), button, TRUE, FALSE, 0 );
+ gtk_widget_show (button);
+ } while(*r);
+ gtk_container_add(GTK_CONTAINER(frame), vbox);
+
+
+ ok=gtk_button_new_with_label(_("Ok"));
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(shell)->action_area),
+ ok, TRUE, TRUE, 0);
+ gtk_signal_connect(GTK_OBJECT(ok), "clicked",
+ GTK_SIGNAL_FUNC(select_name_callback), (gpointer)1);
+
+ cancel=gtk_button_new_with_label(_("Cancel"));
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(shell)->action_area),
+ cancel, TRUE, TRUE, 0);
+ gtk_signal_connect(GTK_OBJECT(cancel), "clicked",
+ GTK_SIGNAL_FUNC(select_name_callback), 0);
+
+ gtk_set_relative_position(parent, shell, 10, 10);
+
+ gtk_object_set_data(GTK_OBJECT(shell), "parent",parent);
+
+ gtk_widget_show_all(GTK_DIALOG(shell)->vbox);
+ gtk_widget_show_all(GTK_DIALOG(shell)->action_area);
+ gtk_widget_show(shell);
+
+ input_dialog=shell;
+}
+
+
+/**************************************************************************
+...
+**************************************************************************/
+static void rules_callback(GtkWidget *w, gpointer data)
+{
+ popup_help_dialog_string(HELP_ESSENTIALS_ITEM);
+}
+
+
+/**************************************************************************
+...
+**************************************************************************/
+static char *joinas_names;
+
+static void connection_attempt(char *tempname, int fromlist)
+{
+ char errbuf [512], ok, attempts=0;
+
+ if (*server_host=='-') /* An error message */
+ return;
+
+ server_autostart= !strcmp(server_host, AUTOSTART_SERVER);
+
+ if (server_autostart) {
+ mystrlcpy(server_host, "localhost", 512);
+ server_port=5555;
+
+ if (start_server(server_port))
+ append_output_window(_("Failed to start server"));
+ }
+
+ if (option_suggest_name && !fromlist && server_game_running
+ && joinas_names && *joinas_names) {
+ gui_select_name(joinas_names);
+ return;
+ }
+
+ do {
+ ok=connect_to_server(tempname, server_host, server_port,
+ errbuf, sizeof(errbuf)) != -1;
+ if (server_autostart && !ok)
+ sleep(1);
+ } while (server_autostart && !ok && ++attempts<=5);
+
+ if (ok) {
gtk_widget_destroy(dialog);
gtk_widget_set_sensitive(toplevel,TRUE);
+
+ if (server_autostart)
+ start_localgame();
}
- else
+ else {
append_output_window(errbuf);
+ if (server_autostart)
+ append_output_window("Make sure the latest civserver is first in path\n");
+ }
+}
+
+static void connect_callback(GtkWidget *w, gpointer data)
+{
+ mystrlcpy(name, gtk_entry_get_text(GTK_ENTRY(iname)), 512);
+ mystrlcpy(server_host, gtk_entry_get_text(GTK_ENTRY(ihost)), 512);
+ server_port=atoi(gtk_entry_get_text(GTK_ENTRY(iport)));
+
+ connection_attempt(name, FALSE);
}
/**************************************************************************
@@ -97,14 +323,25 @@
/**************************************************************************
...
**************************************************************************/
+#define MAXSERVERS 100
+static char *joinas_list[MAXSERVERS];
+
void meta_list_callback(GtkWidget *w, gint row, gint column)
{
- gchar *name, *port;
+ gchar *name, *port, *status;
gtk_clist_get_text(GTK_CLIST(w), row, 0, &name);
gtk_entry_set_text(GTK_ENTRY(ihost), name);
+ mystrlcpy(server_host, name, 512);
+
gtk_clist_get_text(GTK_CLIST(w), row, 1, &port);
gtk_entry_set_text(GTK_ENTRY(iport), port);
+ server_port=atoi(port);
+
+ gtk_clist_get_text(GTK_CLIST(w), row, 3, &status);
+ server_game_running=!strcmp(status,"Running");
+
+ joinas_names = joinas_list[row];
}
/**************************************************************************
@@ -127,36 +364,52 @@
/**************************************************************************
...
**************************************************************************/
-void gui_server_connect(void)
-{
- GtkWidget *label, *table, *book, *scrolled, *list, *vbox, *update;
- static char *titles_[6]= {N_("Server Name"), N_("Port"), N_("Version"),
- N_("Status"), N_("Players"), N_("Comment")};
- static char **titles;
- char buf [256];
- int i;
-
- if (!titles) titles = intl_slist(6, titles_);
+static int button_group_num, button_num;
- gtk_widget_set_sensitive(turn_done_button, FALSE);
- gtk_widget_set_sensitive(toplevel, FALSE);
-
- dialog=gtk_dialog_new();
- gtk_signal_connect(GTK_OBJECT(dialog),"delete_event",
- GTK_SIGNAL_FUNC(connect_deleted_callback), NULL);
-
- gtk_window_set_title(GTK_WINDOW(dialog), _(" Connect to Freeciv Server"));
+static void buttons_callback( GtkWidget *w, gpointer data )
+{
+ group_vals[(int)data/16]= (int)data%16;
+}
- book = gtk_notebook_new ();
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), book, TRUE, TRUE, 0);
+static void
+button_in_table(int groupnum, char *label, int active,
+ GtkWidget *table, int x, int y)
+{
+ static GSList *group;
+ int xx= x>=0?x+1:-x+2, yy=y>=0?y+1:-y+2;
+ GtkWidget *button;
+
+ x=x>=0?x:-x; y=y>=0?y:-y;
+
+ if (button_group_num != groupnum)
+ group=0, button_num=0, button_group_num=groupnum;
+
+ button = gtk_radio_button_new_with_label (group, label);
+ group = gtk_radio_button_group( GTK_RADIO_BUTTON( button ) );
+ gtk_table_attach (GTK_TABLE(table), button, x, xx, y, yy, GTK_FILL,0,0,0);
+ gtk_signal_connect(GTK_OBJECT(button), "toggled",
+ GTK_SIGNAL_FUNC(buttons_callback), (gpointer)(groupnum*16 + button_num++));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), active);
+ gtk_widget_show (button);
+}
+/**************************************************************************
+The "Options" tab of the connect dialog
+**************************************************************************/
+static int create_local_entry(GtkWidget *list);
- label=gtk_label_new(_("Freeciv Server Selection"));
+static GtkWidget *gui_name_selection(void)
+{
+ GtkWidget *vbox, *label, *table, *update, *list, *scrolled;
+ int i;
+ static char **titles;
+ static char *titles_[6]= {N_("Server Name"), N_("Port"), N_("Version"),
+ N_("Status"), N_("Players"), N_("Comment")};
vbox=gtk_vbox_new(FALSE, 2);
- gtk_notebook_append_page (GTK_NOTEBOOK (book), vbox, label);
- table = gtk_table_new (4, 2, FALSE);
+ /*--------------Name: field---------------*/
+ table = gtk_table_new (1, 4, FALSE);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_table_set_col_spacings (GTK_TABLE (table), 5);
gtk_container_border_width (GTK_CONTAINER (table), 5);
@@ -168,25 +421,7 @@
iname=gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(iname), name);
- gtk_table_attach_defaults (GTK_TABLE (table), iname, 1, 2, 0, 1);
-
- label=gtk_label_new(_("Host:"));
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, 0, 0, 0, 0);
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-
- ihost=gtk_entry_new();
- gtk_entry_set_text(GTK_ENTRY(ihost), server_host);
- gtk_table_attach_defaults (GTK_TABLE (table), ihost, 1, 2, 1, 2);
-
- label=gtk_label_new(_("Port:"));
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, 0, 0, 0, 0);
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-
- my_snprintf(buf, sizeof(buf), "%d", server_port);
-
- iport=gtk_entry_new();
- gtk_entry_set_text(GTK_ENTRY(iport), buf);
- gtk_table_attach_defaults (GTK_TABLE (table), iport, 1, 2, 2, 3);
+ gtk_table_attach_defaults (GTK_TABLE (table), iname, 1, 3, 0, 1);
#if IS_BETA_VERSION
{
@@ -202,10 +437,8 @@
}
#endif
- label=gtk_label_new(_("Metaserver"));
-
- vbox=gtk_vbox_new(FALSE, 2);
- gtk_notebook_append_page (GTK_NOTEBOOK (book), vbox, label);
+ /*--------------Server list---------------*/
+ if (!titles) titles = intl_slist(6, titles_);
list=gtk_clist_new_with_titles(6, titles);
gtk_clist_column_titles_passive(GTK_CLIST(list));
@@ -213,28 +446,243 @@
for(i=0; i<6; i++)
gtk_clist_set_column_auto_resize(GTK_CLIST(list), i, TRUE);
+ create_local_entry(list);
+
scrolled=gtk_scrolled_window_new(NULL,NULL);
gtk_container_add(GTK_CONTAINER(scrolled), list);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0);
- update=gtk_button_new_with_label(_("Update"));
+
+ /*--------------Update button---------------*/
+ update=gtk_button_new_with_label(_("Find online games"));
gtk_box_pack_start(GTK_BOX(vbox), update, FALSE, FALSE, 2);
+
+ /*--------------Signals---------------------*/
gtk_signal_connect(GTK_OBJECT(list), "select_row",
GTK_SIGNAL_FUNC(meta_list_callback), NULL);
gtk_signal_connect(GTK_OBJECT(list), "button_press_event",
GTK_SIGNAL_FUNC(meta_click_callback), NULL);
gtk_signal_connect(GTK_OBJECT(update), "clicked",
GTK_SIGNAL_FUNC(meta_update_callback), (gpointer)list);
+ gtk_clist_select_row(GTK_CLIST(list),0,0);
+
+ gtk_signal_connect(GTK_OBJECT(iname), "activate",
+ GTK_SIGNAL_FUNC(connect_callback), NULL);
+
+ return vbox;
+}
+
+
+/**************************************************************************
+The "Options" tab of the connect dialog
+**************************************************************************/
+
+static GtkWidget *gui_options(void)
+{
+ GtkWidget *vbox, *label, *frame, *table;
+
+ vbox=gtk_vbox_new(FALSE, 2);
+ frame=gtk_frame_new("Autostart server options");
+ gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
+
+ /* Create and attach table */
+ table = gtk_table_new (4, 5, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 5);
+ gtk_container_border_width (GTK_CONTAINER (table), 5);
+ gtk_container_add(GTK_CONTAINER(frame), table);
+
+ /*-------------------number of opponents------------------*/
+ button_group_num=-1;
+ label=gtk_label_new(_("AI Opponents:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL,0,0,0);
+ button_in_table(0, "2", FALSE, table, 1, 0);
+ button_in_table(0, "4", TRUE, table, 2, 0);
+ button_in_table(0, "8", FALSE, table, 3, 0);
+
+ /*-------------------mapsize------------------------------*/
+ label=gtk_label_new(_("Map size:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL,0,0,0);
+ button_in_table(1, "50x40", FALSE, table, 1, 1);
+ button_in_table(1, "60x50", TRUE, table, 2, 1);
+ button_in_table(1, "80x50", FALSE, table, 3, 1);
+
+ /*-------------------difficulty---------------------------*/
+ label=gtk_label_new(_("Difficulty:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, GTK_FILL,0,0,0);
+ button_in_table(2, _("easy"), TRUE, table, 1, 2);
+ button_in_table(2, _("normal"), FALSE, table, 2, 2);
+ button_in_table(2, _("hard"), FALSE, table, 3, 2);
+
+ /*-------------------islands------------------------------*/
+ label=gtk_label_new(_("Islands:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4, GTK_FILL,0,0,0);
+ button_in_table(3, _("random"), TRUE, table, 1, 3);
+ button_in_table(3, _("one per player"), FALSE, table, -2, 3);
+
+ return vbox;
+}
+
+
+
+
+/**************************************************************************
+The "Advanced" tab of the connect dialog
+**************************************************************************/
+static GtkWidget *options_toggle1, *options_toggle2;
+static void options_toggle_callback( GtkWidget *w, gpointer data )
+{
+ option_suggest_name= GTK_TOGGLE_BUTTON(options_toggle1)->active;
+ option_hide_inactive=GTK_TOGGLE_BUTTON(options_toggle2)->active;
+}
+
+static GtkWidget *gui_advanced(void)
+{
+ GtkWidget *vbox, *vbox2, *label, *frame, *table;
+ char buf[10];
+
+ vbox=gtk_vbox_new(FALSE, 2);
+
+ /*====================server list options=======================*/
+ frame=gtk_frame_new(_("Server list options"));
+ gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
+
+ table = gtk_table_new (2, 1, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 5);
+ gtk_container_border_width (GTK_CONTAINER (table), 5);
+ gtk_container_add(GTK_CONTAINER(frame), table);
+
+ /*-------------------suggest names------------------------------*/
+ options_toggle1= gtk_check_button_new_with_label(
+ _("Suggest names when joining running game"));
+ gtk_table_attach(GTK_TABLE (table), options_toggle1,0,1,0,1, GTK_FILL,0,0,0);
+ gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(options_toggle1),
+ option_suggest_name);
+ gtk_signal_connect(GTK_OBJECT(options_toggle1), "toggled",
+ GTK_SIGNAL_FUNC(options_toggle_callback), NULL);
+
+ /*-------------------hide servers------------------------------*/
+ options_toggle2= gtk_check_button_new_with_label(
+ _("Hide inactive and full servers"));
+ gtk_table_attach(GTK_TABLE (table), options_toggle2,0,1,1,2, GTK_FILL,0,0,0);
+ gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(options_toggle2),
+ option_hide_inactive);
+ gtk_signal_connect(GTK_OBJECT(options_toggle2), "toggled",
+ GTK_SIGNAL_FUNC(options_toggle_callback), NULL);
+
+
+ /*====================manual server selection=======================*/
+ frame=gtk_frame_new(_("Manual server specification"));
+ gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
+
+ vbox2=gtk_vbox_new(FALSE, 2);
+ gtk_container_add(GTK_CONTAINER(frame), vbox2);
+
+ /*--------------------server name----------------------------*/
+ table = gtk_table_new (2, 2, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 5);
+ gtk_container_border_width (GTK_CONTAINER (table), 5);
+ gtk_box_pack_start(GTK_BOX(vbox2), table, FALSE, TRUE, 0);
+
+
+ /*--------------------server host----------------------------*/
+ label=gtk_label_new(_("Host:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, 0,0,0,0);
+
+ ihost=gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(ihost), server_host);
+ gtk_table_attach_defaults (GTK_TABLE (table), ihost, 1, 2, 0, 1);
+
+ /*--------------------server port----------------------------*/
+ label=gtk_label_new(_("Port:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, 0,0,0,0);
+
+ sprintf(buf, "%d", server_port);
+ iport=gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(iport), buf);
+ gtk_table_attach_defaults (GTK_TABLE (table), iport, 1, 2, 1, 2);
+
+ gtk_signal_connect(GTK_OBJECT(ihost), "activate",
+ GTK_SIGNAL_FUNC(connect_callback), NULL);
+ gtk_signal_connect(GTK_OBJECT(iport), "activate",
+ GTK_SIGNAL_FUNC(connect_callback), NULL);
+
+ return vbox;
+}
+
+
+/**************************************************************************
+...
+**************************************************************************/
+
+void gui_server_connect(void)
+{
+ GtkWidget *label, *book, *vbox, *vbox2, *vbox3, *rulesw;
+ GdkGeometry gdkGeometry;
+
+ mystrlcpy(server_host, "localhost", 512);
+ server_port=5555;
+ server_game_running=0;
+
+ memset(&gdkGeometry,0,sizeof(gdkGeometry));
+ gdkGeometry.min_width=600;
+ gdkGeometry.min_height=300;
+
+ gtk_widget_set_sensitive(turn_done_button, FALSE);
+ gtk_widget_set_sensitive(toplevel, FALSE);
+
+ dialog=gtk_dialog_new();
+ gtk_signal_connect(GTK_OBJECT(dialog),"delete_event",
+ GTK_SIGNAL_FUNC(connect_deleted_callback), NULL);
+
+ gtk_window_set_title(GTK_WINDOW(dialog), _(" Connect to Freeciv Server"));
+
+ gtk_window_set_geometry_hints(GTK_WINDOW(dialog), 0, &gdkGeometry, GDK_HINT_MIN_SIZE);
+
+ book = gtk_notebook_new ();
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), book, TRUE, TRUE, 0);
+
+
+ /*===========================================================================*/
+ vbox3=gui_advanced(); /* initializes ihost/iport */
+ vbox2=gui_options();
+ vbox=gui_name_selection(); /* uses ihost/iport */
+
+ /*===========================================================================*/
+
+ label=gtk_label_new(_("Game selection"));
+ gtk_notebook_append_page (GTK_NOTEBOOK (book), vbox, label);
+
+ label=gtk_label_new(_("Options"));
+ gtk_notebook_append_page (GTK_NOTEBOOK (book), vbox2, label);
+
+ label=gtk_label_new(_("Manual"));
+ gtk_notebook_append_page (GTK_NOTEBOOK (book), vbox3, label);
+
+ /*======================= Action area =======================================*/
connw=gtk_button_new_with_label(_("Connect"));
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), connw,
TRUE, TRUE, 0);
GTK_WIDGET_SET_FLAGS(connw, GTK_CAN_DEFAULT);
gtk_widget_grab_default(connw);
+ rulesw=gtk_button_new_with_label(_("Help"));
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), rulesw,
+ TRUE, TRUE, 0);
+ GTK_WIDGET_SET_FLAGS(rulesw, GTK_CAN_DEFAULT);
+
quitw=gtk_button_new_with_label(_("Quit"));
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), quitw,
TRUE, TRUE, 0);
@@ -242,14 +690,10 @@
gtk_widget_grab_focus (iname);
- gtk_signal_connect(GTK_OBJECT(iname), "activate",
- GTK_SIGNAL_FUNC(connect_callback), NULL);
- gtk_signal_connect(GTK_OBJECT(ihost), "activate",
- GTK_SIGNAL_FUNC(connect_callback), NULL);
- gtk_signal_connect(GTK_OBJECT(iport), "activate",
- GTK_SIGNAL_FUNC(connect_callback), NULL);
gtk_signal_connect(GTK_OBJECT(connw), "clicked",
GTK_SIGNAL_FUNC(connect_callback), NULL);
+ gtk_signal_connect(GTK_OBJECT(rulesw), "clicked",
+ GTK_SIGNAL_FUNC(rules_callback), NULL);
gtk_signal_connect(GTK_OBJECT(quitw), "clicked",
GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
@@ -264,21 +708,58 @@
/**************************************************************************
Get the list of servers from the metaserver
**************************************************************************/
-static int get_meta_list(GtkWidget *list, char *errbuf, int n_errbuf)
+
+static int create_local_entry(GtkWidget *list)
{
+ char *row[6], buf[6][64];
int i;
- char *row[6];
- char buf[6][64];
+
+ for (i=0; i<6; i++)
+ row[i]=buf[i];
+
+ gtk_clist_freeze(GTK_CLIST(list));
+ sz_strlcpy( buf[0], AUTOSTART_SERVER);
+ sz_strlcpy( buf[1], "5555");
+ sz_strlcpy( buf[2], "");
+ sz_strlcpy( buf[3], "");
+ sz_strlcpy( buf[4], "");
+ sz_strlcpy( buf[5], _("Play against the computer"));
+ gtk_clist_append(GTK_CLIST(list), row);
+ gtk_clist_thaw(GTK_CLIST(list));
+
+ return 1; /* 1 entry created */
+}
+
+
+
+static int get_meta_list(GtkWidget *list, char *errbuf, int n_errbuf)
+{
+ int i, pos, bestpos=0, score, bestscore=0;
+ int numservers=0, numshown=0;
+ char *row[6], buf[6][64], *errmsg[6];
struct server_list *server_list = create_server_list(errbuf, n_errbuf);
if(!server_list) return -1;
gtk_clist_freeze(GTK_CLIST(list));
gtk_clist_clear(GTK_CLIST(list));
+ pos=create_local_entry(list);
+
for (i=0; i<6; i++)
- row[i]=buf[i];
+ row[i]=buf[i], errmsg[i]="";
server_list_iterate(*server_list,pserver) {
+ numservers++;
+ if (option_hide_inactive) {
+ if (!strcmp(pserver->status, "Game over"))
+ continue;
+
+ if (!strcmp(pserver->status, "Running") &&
+ (pserver->lastturn>=10 || !*pserver->joinas))
+ continue;
+ }
+ numshown++;
+
sz_strlcpy(buf[0], pserver->name);
sz_strlcpy(buf[1], pserver->port);
sz_strlcpy(buf[2], pserver->version);
@@ -287,10 +768,37 @@
sz_strlcpy(buf[5], pserver->metastring);
gtk_clist_append(GTK_CLIST(list), row);
+
+ if (posjoinas)+1);
+ strcpy(joinas_list[pos],pserver->joinas);
+ }
+
+ /*------------determine which one to highlight--------*/
+ score=0;
+ if(!strcmp(pserver->status,"Pregame"))
+ score=100*atoi(pserver->players);
+ if(!strcmp(pserver->status,"Running") && pserver->lastturn<10 && *pserver->joinas)
+ score=atoi(pserver->players);
+ if (score>bestscore)
+ bestpos=pos, bestscore=score;
+ pos++;
}
server_list_iterate_end;
+ if (numshown==0) {
+ errmsg[0]="--------------";
+ if (numservers==0)
+ errmsg[5]=_("(No servers found, try updating again)");
+ else
+ errmsg[5]=_("(All servers hidden, use advanced options & update)");
+ gtk_clist_append(GTK_CLIST(list), errmsg);
+ }
+
+
+
delete_server_list(server_list);
+ gtk_clist_select_row(GTK_CLIST(list),bestpos,0);
gtk_clist_thaw(GTK_CLIST(list));
return 0;
diff -ruN -Xfreeciv/diff_ignore freeciv/client/include/helpdlg_g.h freeciv_build/client/include/helpdlg_g.h
--- freeciv/client/include/helpdlg_g.h Mon Dec 27 16:09:02 1999
+++ freeciv_build/client/include/helpdlg_g.h Mon Sep 25 18:42:51 2000
@@ -24,6 +24,7 @@
#define HELP_PLAYING_ITEM "Strategy and tactics"
#define HELP_LANGUAGES_ITEM "Languages"
+#define HELP_ESSENTIALS_ITEM "Essentials"
#define HELP_CONNECTING_ITEM "Connecting"
#define HELP_CHATLINE_ITEM "Chatline"
#define HELP_CONTROLS_ITEM "Controls"
diff -ruN -Xfreeciv/diff_ignore freeciv/data/helpdata.txt freeciv_build/data/helpdata.txt
--- freeciv/data/helpdata.txt Mon Aug 14 18:58:09 2000
+++ freeciv_build/data/helpdata.txt Mon Sep 25 18:26:27 2000
@@ -396,6 +396,278 @@
freeciv-dev@xxxxxxxxxxx\
")
+[help_essentials]
+name = _("Essentials")
+text = _("\
+F R E E C I V E S S E N T I A L S\n\
+===================================\n\
+\n\
+ (Check www.freeciv.org/civintro for a nicer looking version)\n\
+\n\
+HOW TO START\n\
+============\n\
+If you want to play against the computer, just hit the start \
+button, maybe after adjusting difficulty and other options on \
+the options tab. For multiplayer games, hit the 'Find games' \
+button and click a game in pregame state, possibly with nonzero \
+players.\
+"), _("\
+THE GOAL\n\
+========\n\
+The goal of Freeciv is to build cities, which in turn can build armies \
+to attack the other players. You get 2 settlers and 1 explorer. Using \
+the numeric keypad, move the settlers to a good location (see below) \
+and build a city by pressing b. You can move diagonally, by the way. \
+Freeciv is turn based; every unit can move once per turn. The turn ends \
+when everyone clicks 'Turn done' or when a timeout is over. \
+"), _("\
+CITIES\n\
+======\n\
+Cities extract resources from the square they're built on plus one \
+nearby square for each inhabitant; you start with 1 inhabitant. The \
+resources are: Food (to grow cities), Production (to build \
+settlers/armies) and Trade (for research and money). Click a city to \
+bring it up for management. Click on a used square on the small map to \
+remove your worker (and turn him into an entertainer, see below), then \
+click on an unused square to place your worker. However the default \
+placement is usually good.\
+"), _("\
+ FOOD\n\
+ All food from the used squares is added to the granary. Every\n\
+ inhabitant uses two food per turn though, and settlers built by\n\
+ this city require one or two also. When the granary reaches 20 \n\
+ food, the city grows to size 2 and can use an additional nearby\n\
+ square. Settlers can irrigate (press i) nearby squares if there\n\
+ is water adjacent, which increases food by one for some square \n\
+ types, see table below. The square under the city gets a free \n\
+ irrigation.\
+"), _("\
+ PRODUCTION\n\
+ The production you get from a square can be used to produce \n\
+ military units or settlers. Producing a settler reduces the city\n\
+ size by 1 and can only be done in cities of size 2 and larger. \n\
+ Some units require one production every turn (upkeep) for as \n\
+ long as they're alive. You can change the unit or building to be\n\
+ produced in the city report, or buy unfinished units. Settlers \n\
+ can mine (press m) some square types, which increases their \n\
+ production; see table below. The square the city is on gets one \n\
+ production if otherwise zero.\
+"), _("\
+ TRADE\n\
+ Trade can be turned into tax, luxury or science. Science lets \n\
+ you research new military unit types. Tax yields money, which \n\
+ you can use to prematurely complete a cities production. Luxury\n\
+ creates happy inhabitants. You can select the distribution of \n\
+ your trade by pressing shift-R. Corruption reduces the amount \n\
+ of trade that a city delivers; the further away from the capital,\n\
+ the more corruption. Settlers can build roads (press r) which add\n\
+ 1 trade to some square types, see table below, and allow for \n\
+ faster movement. The square the city is on gets a free road.\
+"), _("\
+City inhabitants can be happy, content or unhappy (shown by different icons \
+in the city window). If there are more unhappy than happy inhabitants, \
+the city falls into disorder and stops producing anything. The first \
+four inhabitants of a city are content. Additional ones are unhappy and \
+must be made content either with temples in their cities, with wonders \
+(see below), with luxuries or with entertainers. \
+"), _("\
+RESEARCH\n\
+========\n\
+In the Reports menu you find the Science report. There you can decide \
+what to research. You can select an immediate thing to research and a \
+long term goal that the next immediate will be selected from. Most \
+research items require others to be discovered already. After discovery \
+of knowledge, you can build new types of military units, new wonders or \
+use new governments. This window pops up whenever research on one item \
+finishes.\
+"), _("\
+GOVERNMENT\n\
+==========\n\
+The type of government you have affects how many resources your cities \
+can extract from the land. You can change government by researching the \
+new government type and then starting a revolution (in Kingdom menu,\
+will take a few turns). The most important ones:\
+"), _("\
+ DESPOTISM: This is your initial government type. Each square\n\
+ that yields more than 2 of anything (food, production or trade)\n\
+ has that yield reduced by one. Settlers use one food per turn for\n\
+ upkeep, military units are free unless there are more built by a\n\
+ city than the city has inhabitants. Science rate can only be\n\
+ set to 60%. High corruption\
+"), _("\
+ MONARCHY: No more resource reduction. Settlers use one food.\n\
+ The first 3 military units per city are free of upkeep. Maximum\n\
+ science rate is 70%. Corruption is small.\
+"), _("\
+ REPUBLIC: Each square with trade gets another trade unit.\n\
+ Settlers use two food, and one production. All military units\n\
+ use one production. Only one military unit is tolerated abroad\n\
+ (not in city), additional units create one unhappy inhabitant. \n\
+ Corruption is small.\
+"), _("\
+WONDERS\n\
+=======\n\
+Each wonder of the world can only be built by one player and only in \
+one city. Other cities can build and send caravans (after you research\
+Trade) to help in building wonders. The most important wonders are: \n\
+\n\
+ MAGELLAN'S EXPEDITION: Sea units can move 2 squares further per \n\
+ turn. Requires Navigation\n\
+ LEONARDOS WORKSHOP: 1 obsoloete military units gets upgraded.\n\
+ Requires Invention.\n\
+ MICHELANGELOS CHAPEL: 3 unhappy inhabitants become content in\n\
+ every city. Requires Monotheism.\n\
+ J.S.BACH'S CATHEDRAL: Makes 2 inhabitants happy in every city.\n\
+ Requires Theology.\
+"), _("\
+SQUARE TYPES\n\
+============\n\
+These are the food, production and trade yields of all squares under \
+MONARCHY. To identify a square type, click map with middle button.\n\
+\n\
+ F P T F P T F P T Irr Min Roa Defen\n\
+ Ocean 1/0/2 +Fish 3/0/2 +Whale 2/2/3 - - - -\n\
+Grassland 2/0/0 +Resources 2/1/0 +Resources 2/1/0 F - T -\n\
+ Plains 1/1/0 +Buffalo 1/3/0 +Wheat 3/1/0 F - T -\n\
+ Desert 0/1/0 +Oasis 3/1/0 +Oil 0/4/0 F PP T -\n\
+ Tundra 1/0/0 +Game 3/1/0 +Fur 2/0/3 F - - -\n\
+ Forest 1/2/0 +Pheasant 3/2/0 +Silk 1/2/3 - - - +50%\n\
+ Jungle 1/0/0 +Gems 1/0/4 +Fruit 4/0/1 - - - +50%\n\
+ Hills 1/0/0 +Coal 1/2/0 +Wine 1/0/4 F PPP - +100%\n\
+Mountains 0/1/0 +Gold 0/1/6 +Iron 0/4/0 - P - +200%\n\
+ Swamp 1/0/0 +Peat 1/4/0 +Spice 3/0/4 - - - +50%\n\
+ Glacier 0/0/0 +Ivory 1/1/4 +Oil 0/4/0 - - - -\n\
+\n\
+These are the food, production and trade yields of all squares under \
+MONARCHY. Note that the fields in the second and third column \
+are rare. For the initial government type, reduce all numbers above 2 \
+by 1. For Republic, add 1 trade to each square with trade. \
+Irrigation/Mine/Road shows the increases in food, production, and trade \
+when those are improvements are performed by a settler. Defense is the \
+increase in defense power you get when attacked on such a field. Rivers \
+add 1 trade and 50% defense power; they also ease movement along them. \
+Squares with increased defense power are harder to walk fast (horses \
+get slowed down) except for explorers. \
+"), _("\
+MILITARY UNITS\n\
+==============\n\
+Most important military units:\n\
+\n\
+ Name A D M Requires Remarks\n\
+ Explorer - 1 3 Seafaring No slowdown by rought terrain\n\
+ Settlers - 1 1 - Builds cities, improves land\n\
+ Diplomat - - 2 Writing Can subvert cities & bribe units\n\
+ Caravan - 1 1 Trade Carries production to wonders\n\
+ Phalanx 1 2 1 Bronze working OK defense against land units\n\
+ Horsemen 2 1 2 Horseback riding Good invader of emptied cities\n\
+ Trireme 1 1 3 Map making Carries 2, turn must end at coast\n\
+ Caravel 2 1 3 Navigation Carries 3 units\n\
+ Ironclad 4 4 4 Steam engine Strong attacker of coastal cities\n\
+ Destroyer 4 4 6 Electricity Like ironclad but faster\n\
+ Cruiser 6 6 5 Steel Much stronger than destroyers\n\
+\n\
+Military units are characterized by three numbers: attack power, \
+defense power, and movement speed. Those three numbers plus the \
+production cost are what you see when changing production. When unit A \
+attacks unit B by moving onto B's square, A's attack power is \
+matched up against B's defense power. If A has attack power 2 and B has \
+defense power 1, then A has about a two-thirds chance of winning (more \
+info in the Freeciv manual). The survivor often becomes veteran, which \
+increases his attack and defense power by 50%. Being built in a city \
+with Barracks makes a unit veteran, too.\n\
+\n\
+Rivers and some terrain types increase the defense power of the \
+defender, see table below. Units in cities enjoy a 50% defense power \
+increase as well. Damaged units have red bars in the bottom left \
+corner, they move more slowly and have their attack power reduced. They \
+recover slowly (faster in cities or when fortified).\n\
+\n\
+Pressing f will fortify the unit, which increases defense power by 50%. \
+Pressing s will put the unit on sentry; they will wait until healed or \
+until an enemy unit moves to an adjacent field. Pressing g lets you \
+select a destination to go to. If an enemy is there, it will be \
+attacked. Military units can take enemy cities when there are no \
+defenders left. Defended cities have a little flag in their top left \
+corner. If you lose your capital, you get very high corruption and your \
+kingdom may split.\n\
+\n\
+If several military units are on one square, the strongest one defends. \
+If it is defeated, all units die (except in cities). Sea units can \
+attack land units but not vice versa. Some sea units can carry land \
+units, just move onto them at the coast. Loaded units have a + in \
+their bottom right corner.\n\
+\n\
+Diplomats are very powerful. They are easy to defeat but can incite \
+revolts in enemy cities (the city becomes yours), steal technologies or \
+bribe enemy units. Diplomat actions can be performed directly from a \
+ship. Defending diplomats in cities may prevent them.\
+"), _("\
+WINNING STRATEGY\n\
+================\n\
+Most multi-player games are played using '/set generator 2'. This \
+creates one island for every player plus some small empty additional \
+ones. Here's standard strategy to play these.\n\
+\n\
+1. Find good settling spots. A good settling spot must at least\n\
+ yield 4 food (from the two squares used) and as much production\n\
+ as possible. Don't look longer than, say, for 3-4 turns. Whales\n\
+ and pheasants are the best resource to be close to. Grassland and\n\
+ plains are good to settle on, wheat/oasis/buffalo even better.\n\
+2. Once you built the city, set its production to settlers. Bring up\n\
+ the science report and set research to Alphabet and the goal to\n\
+ The Republic.\n\
+3. As soon as any city reaches size two, click it and set all\n\
+ workers on production fields using the little map. As soon as you\n\
+ can afford it, buy the settler.\n\
+4. Keep producing nothing but settlers and have them build nearby\n\
+ cities. There should only be 1-2 empty squares between the\n\
+ cities. Don't build irrigation, mines or roads.\n\
+5. When The Republic is only one step away, set goal to Navigation.\n\
+ When Republic is reached, set research to Map Making and \n\
+ immediately start a revolution (from Kingdom menu). Once you're\n\
+ a republic, build roads on used squares.\n\
+6. VARIANT: If you get discovered by an enemy, build ships as soon\n\
+ as you can, and defending units like warriors and phalanxes if\n\
+ necessary. You may choose to collaborate with neighbors, use\n\
+ Players menu to find out who to talk to.\n\
+7. When Navigation is only one step away, set goal to Steam Engine.\n\
+ When Navigation is reached, build a couple of caravels to explore\n\
+ your neighborhood and settle nearby islands. VARIANT: It's often\n\
+ useful to research Trade before Steam Engine so you can build\n\
+ wonders.\n\
+8. Once most spots on your island are taken, start building roads,\n\
+ preferably on grassland and plains. Use the roads to move faster\n\
+ and gain trade.\n\
+9. As soon as Steam Engine is reached, build lots of ironclads.\n\
+ Increase tax rate to buy them. Accompany them with horsemen on\n\
+ caravels. Find neighbors, kill their city defenses with the\n\
+ ironclads and invade their cities with the horsemen. Place\n\
+ ironclads in conquered cities for initial defense.\n\
+10.After Steam Engine, you may want to research Electricity and\n\
+ Steel to get even better ships, destroyers and cruisers. Once\n\
+ you got Steel, set tax rate to maximum and put everything into\n\
+ war.\n\
+"), _("\
+If you play on the default generator, there are three possibilities:\n\
+\n\
+1. If you have your own island, play like above.\n\
+2. If you have a shared island but your enemies are far away\n\
+ or you can have peace with them (which usually is preferable),\n\
+ you can play mostly like generator 2, just research horseback\n\
+ riding and bronze working right after republic (gives horsemen\n\
+ and phalanx).\n\
+3. If your neighbors are close and you can't have peace or alliance,\n\
+ research horsemen, monarchy and feudalism to defend. Then play\n\
+ like generator 2, only try to attack cities just after you got\n\
+ the new offensive unit (horsemen, knights). Consider building\n\
+ some Barracks.\n\
+ VARIANT: Research horsemen and the republic. Now build diplomats\n\
+ and bribe enemy cities of size 1-2 and attacking units. Also\n\
+ research map making to allow for surprise attacks off the boat.\n\
+ When your opponent is no urgent threat anymore, set your\n\
+ science back to maximum and resarch gunpowder or navigation.\n\
+")
+
[help_connecting]
name = _("Connecting")
text = _("\
diff -ruN -Xfreeciv/diff_ignore freeciv/server/civserver.c freeciv_build/server/civserver.c
--- freeciv/server/civserver.c Fri Sep 1 15:48:59 2000
+++ freeciv_build/server/civserver.c Mon Sep 25 18:25:18 2000
@@ -73,6 +73,9 @@
else if (is_option("--help", argv[inx])) {
showhelp = 1;
break;
+ } else if (is_option("--background", argv[inx])) {
+ srvarg.background = 1;
+ break;
} else if ((option = get_option("--log", argv, &inx, argc)) != NULL)
srvarg.log_filename = option;
else if ((option = get_option("--gamelog", argv, &inx, argc)) != NULL)
@@ -129,6 +132,7 @@
fprintf(stderr, _(" -m, --meta\t\tSend info to metaserver\n"));
fprintf(stderr, _(" -M, --Metaserver ADDR\tSet ADDR as metaserver address\n"));
fprintf(stderr, _(" -s, --server HOST\tList this server as host HOST\n"));
+ fprintf(stderr, _(" -b, --background\tStart noninteractively, enable client cmds\n"));
#ifdef DEBUG
fprintf(stderr, _(" -d, --debug NUM\tSet debug log level (0 to 4,"
" or 4:file1,min,max:...)\n"));
diff -ruN -Xfreeciv/diff_ignore freeciv/server/meta.c freeciv_build/server/meta.c
--- freeciv/server/meta.c Tue Aug 22 16:48:04 2000
+++ freeciv_build/server/meta.c Mon Sep 25 18:25:18 2000
@@ -373,8 +373,8 @@
/* Fixme: how should metaserver handle multi-connects?
* Uses player_addr_hack() for now.
*/
- cat_snprintf(info, sizeof(info), "%2d %-20s %s\n", i, pplayer->name,
- player_addr_hack(pplayer));
+ cat_snprintf(info, sizeof(info), "%2d %-20s %s %s\n", i, pplayer->name,
+ player_addr_hack(pplayer), pplayer->is_alive?"":"(dead)");
}
}
diff -ruN -Xfreeciv/diff_ignore freeciv/server/sernet.c freeciv_build/server/sernet.c
--- freeciv/server/sernet.c Tue Sep 19 18:06:56 2000
+++ freeciv_build/server/sernet.c Mon Sep 25 18:25:18 2000
@@ -331,7 +331,8 @@
MY_FD_ZERO(&writefs);
MY_FD_ZERO(&exceptfs);
#ifndef SOCKET_ZERO_ISNT_STDIN
- FD_SET(0, &readfs);
+ if (!srvarg.background)
+ FD_SET(0, &readfs);
#endif
FD_SET(sock, &readfs);
FD_SET(sock, &exceptfs);
@@ -408,7 +409,7 @@
#else /* !HAVE_LIBREADLINE */
int didget;
char buf[BUF_SIZE+1];
-
+
if((didget=read(0, buf, BUF_SIZE))==-1) {
freelog(LOG_FATAL, "read from stdin failed");
exit(1);
diff -ruN -Xfreeciv/diff_ignore freeciv/server/srv_main.c freeciv_build/server/srv_main.c
--- freeciv/server/srv_main.c Tue Sep 19 18:06:56 2000
+++ freeciv_build/server/srv_main.c Mon Sep 25 18:25:18 2000
@@ -220,6 +220,9 @@
if (srvarg.script_filename)
read_init_script(srvarg.script_filename);
+ if (srvarg.background)
+ handle_stdin_input((struct connection *)NULL, "cmdlevel ctrl");
+
/* load a saved game */
if(srvarg.load_filename) {
@@ -1703,6 +1706,19 @@
toggle_ai_player_direct(NULL, pplayer);
}
check_for_full_turn_done();
+ }
+
+ if (srvarg.background) {
+ int i, humans=0;
+ for(i=0; iconnections))
+ humans++;
+ }
+ if (humans==0) {
+ close_connections_and_socket();
+ exit(0);
+ }
}
}
diff -ruN -Xfreeciv/diff_ignore freeciv/server/srv_main.h freeciv_build/server/srv_main.h
--- freeciv/server/srv_main.h Tue Aug 22 16:48:06 2000
+++ freeciv_build/server/srv_main.h Mon Sep 25 18:25:18 2000
@@ -36,6 +36,7 @@
char *script_filename;
/* server name for metaserver to use for us */
char metaserver_servername[64];
+ int background;
};
void srv_init(void);