From bdfcd6915e0b432d6f26e9091098a7825b73de9c Mon Sep 17 00:00:00 2001 From: cohrs Date: Tue, 19 Mar 2002 08:27:55 +0000 Subject: [PATCH] Gnome player selection - provide full 3.4-style player selection, based on tty_player_selection - generalize selection dialog so it can be used for all 4 prompts --- win/gnome/gnbind.c | 242 ++++++++++++++++++++++++++++++++++++------- win/gnome/gnplayer.c | 44 ++++---- win/gnome/gnplayer.h | 5 +- 3 files changed, 231 insertions(+), 60 deletions(-) diff --git a/win/gnome/gnbind.c b/win/gnome/gnbind.c index 1ca3577c6..9695746b4 100644 --- a/win/gnome/gnbind.c +++ b/win/gnome/gnbind.c @@ -115,47 +115,219 @@ void gnome_init_nhwindows(int* argc, char** argv) void gnome_player_selection() { - int num_roles, availcount, i, nRole; + int n, i, sel; const char** choices; - int* rolemap; + int* pickmap; - /* select a role */ - for (num_roles = 0; roles[num_roles].name.m; ++num_roles) continue; - choices = (const char **)alloc(sizeof(char *) * (num_roles+1)); - rolemap = (int*)alloc(sizeof(int) * (num_roles + 1)); - for (;;) { - availcount = 0; - for (i = 0; i < num_roles; i++) { - if (ok_role(i, flags.initrace, flags.initgend, flags.initalign)) { - choices[availcount] = roles[i].name.m; - if (flags.initgend >= 0 && flags.female && roles[i].name.f) - choices[availcount] = roles[i].name.f; - rolemap[availcount] = i; - ++availcount; + /* prevent an unnecessary prompt */ + rigid_role_checks(); + + if (!flags.randomall && flags.initrole < 0) { + + /* select a role */ + for (n = 0; roles[n].name.m; n++) continue; + choices = (const char **)alloc(sizeof(char *) * (n+1)); + pickmap = (int*)alloc(sizeof(int) * (n+1)); + for (;;) { + for (n = 0, i = 0; roles[i].name.m; i++) { + if (ok_role(i, flags.initrace, + flags.initgend, flags.initalign)) { + if (flags.initgend >= 0 && flags.female && roles[i].name.f) + choices[n] = roles[i].name.f; + else + choices[n] = roles[i].name.m; + pickmap[n++] = i; + } } + if (n > 0) break; + else if (flags.initalign >= 0) flags.initalign = -1; /* reset */ + else if (flags.initgend >= 0) flags.initgend = -1; + else if (flags.initrace >= 0) flags.initrace = -1; + else panic("no available ROLE+race+gender+alignment combinations"); } - if (availcount > 0) break; - else if (flags.initalign >= 0) flags.initalign = -1; /* reset */ - else if (flags.initgend >= 0) flags.initgend = -1; - else if (flags.initrace >= 0) flags.initrace = -1; - else panic("no available ROLE+race+gender+alignment combinations"); - } - choices[availcount] = (const char *) 0; - nRole = ghack_player_sel_dialog(choices); + choices[n] = (const char *) 0; + if (n > 1) + sel = ghack_player_sel_dialog(choices, + _("Player selection"), _("Choose one of the following roles:")); + else sel = 0; + if (sel >= 0) sel = pickmap[sel]; + else if (sel == ROLE_NONE) { /* Quit */ + clearlocks(); + gnome_exit_nhwindows(0); + } + free(choices); + free(pickmap); + } else if (flags.initrole < 0) sel = ROLE_RANDOM; + else sel = flags.initrole; - if (nRole == -1) { /* Quit */ - clearlocks(); - gnome_exit_nhwindows(0); - } else if (nRole == -2) { /* Random role */ - nRole = rolemap[rn2(availcount)]; - pline("This game you will be %s", an(choices[nRole])); - } else { - nRole = rolemap[nRole]; + if (sel == ROLE_RANDOM) { /* Random role */ + sel = pick_role(flags.initrace, flags.initgend, + flags.initalign, PICK_RANDOM); + if (sel < 0) sel = randrole(); + } + + flags.initrole = sel; + + /* Select a race, if necessary */ + /* force compatibility with role, try for compatibility with + * pre-selected gender/alignment */ + if (flags.initrace < 0 || !validrace(flags.initrole, flags.initrace)) { + if (flags.initrace == ROLE_RANDOM || flags.randomall) { + flags.initrace = pick_race(flags.initrole, flags.initgend, + flags.initalign, PICK_RANDOM); + if (flags.initrace < 0) flags.initrace = randrace(flags.initrole); + } else { + /* Count the number of valid races */ + n = 0; /* number valid */ + for (i = 0; races[i].noun; i++) { + if (ok_race(flags.initrole, i, flags.initgend, flags.initalign)) + n++; + } + if (n == 0) { + for (i = 0; races[i].noun; i++) { + if (validrace(flags.initrole, i)) n++; + } + } + + choices = (const char **)alloc(sizeof(char *) * (n+1)); + pickmap = (int*)alloc(sizeof(int) * (n + 1)); + for (n = 0, i = 0; races[i].noun; i++) { + if (ok_race(flags.initrole, i, flags.initgend, + flags.initalign)) { + choices[n] = races[i].noun; + pickmap[n++] = i; + } + } + choices[n] = (const char *) 0; + /* Permit the user to pick, if there is more than one */ + if (n > 1) + sel = ghack_player_sel_dialog(choices, _("Race selection"), + _("Choose one of the following races:")); + else sel = 0; + if (sel >= 0) sel = pickmap[sel]; + else if (sel == ROLE_NONE) { /* Quit */ + clearlocks(); + gnome_exit_nhwindows(0); + } + flags.initrace = sel; + free(choices); + free(pickmap); + } + if (flags.initrace == ROLE_RANDOM) { /* Random role */ + sel = pick_race(flags.initrole, flags.initgend, + flags.initalign, PICK_RANDOM); + if (sel < 0) sel = randrace(flags.initrole); + flags.initrace = sel; + } + } + + /* Select a gender, if necessary */ + /* force compatibility with role/race, try for compatibility with + * pre-selected alignment */ + if (flags.initgend < 0 || + !validgend(flags.initrole, flags.initrace, flags.initgend)) { + if (flags.initgend == ROLE_RANDOM || flags.randomall) { + flags.initgend = pick_gend(flags.initrole, flags.initrace, + flags.initalign, PICK_RANDOM); + if (flags.initgend < 0) + flags.initgend = randgend(flags.initrole, flags.initrace); + } else { + /* Count the number of valid genders */ + n = 0; /* number valid */ + for (i = 0; i < ROLE_GENDERS; i++) { + if (ok_gend(flags.initrole, flags.initrace, i, flags.initalign)) + n++; + } + if (n == 0) { + for (i = 0; i < ROLE_GENDERS; i++) { + if (validgend(flags.initrole, flags.initrace, i)) n++; + } + } + + choices = (const char **)alloc(sizeof(char *) * (n+1)); + pickmap = (int*)alloc(sizeof(int) * (n + 1)); + for (n = 0, i = 0; i < ROLE_GENDERS; i++) { + if (ok_gend(flags.initrole, flags.initrace, i, + flags.initalign)) { + choices[n] = genders[i].adj; + pickmap[n++] = i; + } + } + choices[n] = (const char *) 0; + /* Permit the user to pick, if there is more than one */ + if (n > 1) + sel = ghack_player_sel_dialog(choices, _("Gender selection"), + _("Choose one of the following genders:")); + else sel = 0; + if (sel >= 0) sel = pickmap[sel]; + else if (sel == ROLE_NONE) { /* Quit */ + clearlocks(); + gnome_exit_nhwindows(0); + } + flags.initgend = sel; + free(choices); + free(pickmap); + } + if (flags.initgend == ROLE_RANDOM) { /* Random gender */ + sel = pick_gend(flags.initrole, flags.initrace, + flags.initalign, PICK_RANDOM); + if (sel < 0) sel = randgend(flags.initrole, flags.initrace); + flags.initgend = sel; + } + } + + /* Select an alignment, if necessary */ + /* force compatibility with role/race/gender */ + if (flags.initalign < 0 || + !validalign(flags.initrole, flags.initrace, flags.initalign)) { + if (flags.initalign == ROLE_RANDOM || flags.randomall) { + flags.initalign = pick_align(flags.initrole, flags.initrace, + flags.initgend, PICK_RANDOM); + if (flags.initalign < 0) + flags.initalign = randalign(flags.initrole, flags.initrace); + } else { + /* Count the number of valid alignments */ + n = 0; /* number valid */ + for (i = 0; i < ROLE_ALIGNS; i++) { + if (ok_align(flags.initrole, flags.initrace, flags.initgend, i)) + n++; + } + if (n == 0) { + for (i = 0; i < ROLE_ALIGNS; i++) + if (validalign(flags.initrole, flags.initrace, i)) n++; + } + + choices = (const char **)alloc(sizeof(char *) * (n+1)); + pickmap = (int*)alloc(sizeof(int) * (n + 1)); + for (n = 0, i = 0; i < ROLE_ALIGNS; i++) { + if (ok_align(flags.initrole, + flags.initrace, flags.initgend, i)) { + choices[n] = aligns[i].adj; + pickmap[n++] = i; + } + } + choices[n] = (const char *) 0; + /* Permit the user to pick, if there is more than one */ + if (n > 1) + sel = ghack_player_sel_dialog(choices, _("Alignment selection"), + _("Choose one of the following alignments:")); + else sel = 0; + if (sel >= 0) sel = pickmap[sel]; + else if (sel == ROLE_NONE) { /* Quit */ + clearlocks(); + gnome_exit_nhwindows(0); + } + flags.initalign = sel; + free(choices); + free(pickmap); + } + if (flags.initalign == ROLE_RANDOM) { + sel = pick_align(flags.initrole, flags.initrace, + flags.initgend, PICK_RANDOM); + if (sel < 0) sel = randalign(flags.initrole, flags.initrace); + flags.initalign = sel; + } } - - flags.initrole = nRole; - free(choices); - free(rolemap); } diff --git a/win/gnome/gnplayer.c b/win/gnome/gnplayer.c index 04fcaa748..f34fa506a 100644 --- a/win/gnome/gnplayer.c +++ b/win/gnome/gnplayer.c @@ -2,10 +2,10 @@ /* Copyright (C) 1998 by Erik Andersen */ /* NetHack may be freely redistributed. See license for details. */ -#include "gnplayer.h" -#include "gnmain.h" #include #include +#include "gnplayer.h" +#include "gnmain.h" #include "hack.h" static gint role_number; @@ -13,15 +13,15 @@ static GtkWidget* clist; static void player_sel_key_hit (GtkWidget *widget, GdkEventKey *event, gpointer data) -{ - const char** roles = data; - int i; - for (i = 0; roles[i] != 0; ++i) { - if (roles[i][0] == toupper(event->keyval)) { - role_number = i; - gtk_clist_select_row( GTK_CLIST (clist), i, 0); - } - } +{ + const char** roles = data; + int i; + for (i = 0; roles[i] != 0; ++i) { + if (roles[i][0] == toupper(event->keyval)) { + role_number = i; + gtk_clist_select_row( GTK_CLIST (clist), i, 0); + } + } } static void @@ -31,23 +31,25 @@ player_sel_row_selected (GtkCList *clist, int row, int col, GdkEvent *event) } int -ghack_player_sel_dialog( const char** roles) +ghack_player_sel_dialog(const char** choices, + const gchar* title, + const gchar* prompt) { int i; static GtkWidget* dialog; static GtkWidget* swin; static GtkWidget* frame1; - dialog = gnome_dialog_new (_("Player selection"), + dialog = gnome_dialog_new(title, GNOME_STOCK_BUTTON_OK, - _("Random role"), + _("Random"), GNOME_STOCK_BUTTON_CANCEL, NULL); gnome_dialog_close_hides (GNOME_DIALOG (dialog), FALSE); gtk_signal_connect (GTK_OBJECT (dialog), "key_press_event", - GTK_SIGNAL_FUNC (player_sel_key_hit), roles ); + GTK_SIGNAL_FUNC (player_sel_key_hit), choices ); - frame1 = gtk_frame_new (_("Choose one of the following roles:")); + frame1 = gtk_frame_new(prompt); gtk_object_set_data (GTK_OBJECT (dialog), "frame1", frame1); gtk_widget_show (frame1); gtk_container_border_width (GTK_CONTAINER (frame1), 3); @@ -67,10 +69,10 @@ ghack_player_sel_dialog( const char** roles) gtk_box_pack_start_defaults (GTK_BOX (GNOME_DIALOG (dialog)->vbox), frame1); /* Add the roles into the list here... */ - for (i=0; roles[i]; i++) { + for (i=0; choices[i]; i++) { gchar accelBuf[BUFSZ]; - const char *text[3]={accelBuf, roles[i],NULL}; - sprintf( accelBuf, "%c ", tolower(roles[i][0])); + const char *text[3]={accelBuf, choices[i],NULL}; + sprintf( accelBuf, "%c ", tolower(choices[i][0])); gtk_clist_insert (GTK_CLIST (clist), i, (char**)text); } @@ -89,11 +91,11 @@ ghack_player_sel_dialog( const char** roles) /* Quit on button 2 or error */ if (i < 0 || i > 1) { - return( -1); + return(ROLE_NONE); } /* Random is button 1*/ if (i == 1 ) { - return( -2); + return(ROLE_RANDOM); } return ( role_number); } diff --git a/win/gnome/gnplayer.h b/win/gnome/gnplayer.h index 994e4e47b..73929dee4 100644 --- a/win/gnome/gnplayer.h +++ b/win/gnome/gnplayer.h @@ -5,9 +5,6 @@ #ifndef GnomeHackPlayerSelDialog_h #define GnomeHackPlayerSelDialog_h - -int ghack_player_sel_dialog(const char **); - +int ghack_player_sel_dialog(const char **, const gchar*, const gchar*); #endif /* GnomeHackPlayerSelDialog_h */ -