Atrinik Client 2.5
gui/party.c
Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team    *
00005 *                                                                       *
00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game)     *
00007 * and Crossfire (Multiplayer game for X-windows).                       *
00008 *                                                                       *
00009 * This program is free software; you can redistribute it and/or modify  *
00010 * it under the terms of the GNU General Public License as published by  *
00011 * the Free Software Foundation; either version 2 of the License, or     *
00012 * (at your option) any later version.                                   *
00013 *                                                                       *
00014 * This program is distributed in the hope that it will be useful,       *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017 * GNU General Public License for more details.                          *
00018 *                                                                       *
00019 * You should have received a copy of the GNU General Public License     *
00020 * along with this program; if not, write to the Free Software           *
00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             *
00022 *                                                                       *
00023 * The author can be reached at admin@atrinik.org                        *
00024 ************************************************************************/
00025 
00030 #include <global.h>
00031 
00033 #define STAT_BAR_WIDTH 60
00034 
00036 #define PARTY_STAT_BAR() \
00037     snprintf(bars, sizeof(bars), "<x=5><bar=#000000 %d 4><bar=#cb0202 %d 4><y=4><bar=#000000 %d 4><bar=#1818a4 %d 4><y=4><bar=#000000 %d 4><bar=#15bc15 %d 4>", STAT_BAR_WIDTH, (int) (STAT_BAR_WIDTH * (hp / 100.0)), STAT_BAR_WIDTH, (int) (STAT_BAR_WIDTH * (sp / 100.0)), STAT_BAR_WIDTH, (int) (STAT_BAR_WIDTH * (grace / 100.0)));
00038 
00040 static button_struct button_close, button_help, button_parties, button_members, button_form, button_leave, button_password, button_chat;
00041 
00045 static sint8 list_contents = -1;
00046 
00050 static void list_handle_enter(list_struct *list)
00051 {
00052     if (list_contents == CMD_PARTY_LIST && list->text)
00053     {
00054         char buf[MAX_BUF];
00055 
00056         snprintf(buf, sizeof(buf), "/party join %s", list->text[list->row_selected - 1][0]);
00057         send_command(buf);
00058     }
00059 }
00060 
00065 static void list_row_highlight(list_struct *list, SDL_Rect box)
00066 {
00067     if (list_contents == CMD_PARTY_WHO)
00068     {
00069         box.w -= STAT_BAR_WIDTH + list->col_spacings[0];
00070     }
00071 
00072     SDL_FillRect(list->surface, &box, SDL_MapRGB(list->surface->format, 0x00, 0x80, 0x00));
00073 }
00074 
00079 static void list_row_selected(list_struct *list, SDL_Rect box)
00080 {
00081     if (list_contents == CMD_PARTY_WHO)
00082     {
00083         box.w -= STAT_BAR_WIDTH + list->col_spacings[0];
00084     }
00085 
00086     SDL_FillRect(list->surface, &box, SDL_MapRGB(list->surface->format, 0x00, 0x00, 0xef));
00087 }
00088 
00096 void widget_party_background(widgetdata *widget)
00097 {
00098     list_struct *list;
00099 
00100     /* Create the surface. */
00101     if (!widget->widgetSF)
00102     {
00103         widget->widgetSF = SDL_ConvertSurface(Bitmaps[BITMAP_CONTENT]->bitmap, Bitmaps[BITMAP_CONTENT]->bitmap->format, Bitmaps[BITMAP_CONTENT]->bitmap->flags);
00104     }
00105 
00106     list = list_exists(LIST_PARTY);
00107 
00108     /* Create the party list. */
00109     if (!list)
00110     {
00111         list = list_create(LIST_PARTY, 12, 2, 8);
00112         list->handle_enter_func = list_handle_enter;
00113         list->surface = widget->widgetSF;
00114         list->text_flags = TEXT_MARKUP;
00115         list->row_highlight_func = list_row_highlight;
00116         list->row_selected_func = list_row_selected;
00117         list_scrollbar_enable(list);
00118         list_set_column(list, 0, 130, 7, NULL, -1);
00119         list_set_column(list, 1, 60, 7, NULL, -1);
00120         list->header_height = 6;
00121 
00122         /* Create various buttons... */
00123         button_create(&button_close);
00124         button_create(&button_help);
00125         button_create(&button_parties);
00126         button_create(&button_members);
00127         button_create(&button_form);
00128         button_create(&button_leave);
00129         button_create(&button_password);
00130         button_create(&button_chat);
00131         button_close.bitmap = button_help.bitmap = BITMAP_BUTTON_ROUND;
00132         button_close.bitmap_pressed = button_help.bitmap_pressed = BITMAP_BUTTON_ROUND_DOWN;
00133 
00134         button_parties.flags = button_members.flags = TEXT_MARKUP;
00135         widget->redraw = 1;
00136         list_contents = -1;
00137     }
00138 }
00139 
00143 void widget_party_render(widgetdata *widget)
00144 {
00145     list_struct *list;
00146     SDL_Rect box, dst;
00147 
00148     list = list_exists(LIST_PARTY);
00149 
00150     if (widget->redraw)
00151     {
00152         _BLTFX bltfx;
00153 
00154         bltfx.surface = widget->widgetSF;
00155         bltfx.flags = 0;
00156         bltfx.alpha = 0;
00157         sprite_blt(Bitmaps[BITMAP_CONTENT], 0, 0, NULL, &bltfx);
00158 
00159         widget->redraw = 0;
00160 
00161         box.h = 0;
00162         box.w = widget->wd;
00163         string_blt(widget->widgetSF, FONT_SERIF12, "Party", 0, 3, COLOR_HGOLD, TEXT_ALIGN_CENTER, &box);
00164 
00165         if (list)
00166         {
00167             list->focus = 1;
00168             list_set_parent(list, widget->x1, widget->y1);
00169             list_show(list, 10, 23);
00170         }
00171     }
00172 
00173     dst.x = widget->x1;
00174     dst.y = widget->y1;
00175     SDL_BlitSurface(widget->widgetSF, NULL, ScreenSurface, &dst);
00176 
00177     /* Render the various buttons. */
00178     button_close.x = widget->x1 + widget->wd - Bitmaps[BITMAP_BUTTON_ROUND]->bitmap->w - 4;
00179     button_close.y = widget->y1 + 4;
00180     button_render(&button_close, "X");
00181 
00182     button_help.x = widget->x1 + widget->wd - Bitmaps[BITMAP_BUTTON_ROUND]->bitmap->w * 2 - 4;
00183     button_help.y = widget->y1 + 4;
00184     button_render(&button_help, "?");
00185 
00186     button_parties.x = widget->x1 + 244;
00187     button_parties.y = widget->y1 + 38;
00188     button_render(&button_parties, list_contents == CMD_PARTY_LIST ? "<u>Parties</u>" : "Parties");
00189 
00190     button_members.x = button_form.x = widget->x1 + 244;
00191     button_members.y = button_form.y = widget->y1 + 60;
00192 
00193     if (cpl.partyname[0] == '\0')
00194     {
00195         button_render(&button_form, "Form");
00196     }
00197     else
00198     {
00199         button_render(&button_members, list_contents == CMD_PARTY_WHO ? "<u>Members</u>" : "Members");
00200         button_leave.x = button_password.x = button_chat.x = widget->x1 + 244;
00201         button_leave.y = widget->y1 + 82;
00202         button_password.y = widget->y1 + 104;
00203         button_chat.y = widget->y1 + 126;
00204         button_render(&button_leave, "Leave");
00205         button_render(&button_password, "Password");
00206         button_render(&button_chat, "Chat");
00207     }
00208 }
00209 
00214 void widget_party_mevent(widgetdata *widget, SDL_Event *event)
00215 {
00216     list_struct *list = list_exists(LIST_PARTY);
00217 
00218     /* If the list has handled the mouse event, we need to redraw the
00219      * widget. */
00220     if (list && list_handle_mouse(list, event->motion.x - widget->x1, event->motion.y - widget->y1, event))
00221     {
00222         widget->redraw = 1;
00223     }
00224     else if (button_event(&button_close, event))
00225     {
00226         widget->show = 0;
00227         button_close.pressed = 0;
00228     }
00229     else if (button_event(&button_help, event))
00230     {
00231         show_help("party list");
00232     }
00233     else if (button_event(&button_parties, event))
00234     {
00235         send_command("/party list");
00236     }
00237     else if (cpl.partyname[0] != '\0' && button_event(&button_members, event))
00238     {
00239         send_command("/party who");
00240     }
00241     else if (cpl.partyname[0] == '\0' && button_event(&button_form, event))
00242     {
00243         reset_keys();
00244         cpl.input_mode = INPUT_MODE_CONSOLE;
00245         text_input_open(253);
00246         text_input_add_string("/party form ");
00247     }
00248     else if (cpl.partyname[0] != '\0' && button_event(&button_password, event))
00249     {
00250         reset_keys();
00251         cpl.input_mode = INPUT_MODE_CONSOLE;
00252         text_input_open(253);
00253         text_input_add_string("/party password ");
00254     }
00255     else if (cpl.partyname[0] != '\0' && button_event(&button_leave, event))
00256     {
00257         send_command("/party leave");
00258         button_leave.pressed = 0;
00259     }
00260     else if (cpl.partyname[0] != '\0' && button_event(&button_chat, event))
00261     {
00262         reset_keys();
00263         cpl.input_mode = INPUT_MODE_CONSOLE;
00264         text_input_open(253);
00265         text_input_add_string("/gsay ");
00266     }
00267 }
00268 
00273 void PartyCmd(unsigned char *data, int len)
00274 {
00275     uint8 type;
00276     int pos;
00277 
00278     pos = 0;
00279     type = data[pos++];
00280 
00281     /* List of parties, or list of party members. */
00282     if (type == CMD_PARTY_LIST || type == CMD_PARTY_WHO)
00283     {
00284         list_struct *list = list_exists(LIST_PARTY);
00285 
00286         list_clear(list);
00287 
00288         while (pos < len)
00289         {
00290             if (type == CMD_PARTY_LIST)
00291             {
00292                 char party_name[MAX_BUF], party_leader[MAX_BUF];
00293 
00294                 GetString_String(data, &pos, party_name, sizeof(party_name));
00295                 GetString_String(data, &pos, party_leader, sizeof(party_leader));
00296                 list_add(list, list->rows, 0, party_name);
00297                 list_add(list, list->rows - 1, 1, party_leader);
00298             }
00299             else if (type == CMD_PARTY_WHO)
00300             {
00301                 char name[MAX_BUF], bars[MAX_BUF];
00302                 uint8 hp, sp, grace;
00303 
00304                 GetString_String(data, &pos, name, sizeof(name));
00305                 hp = data[pos++];
00306                 sp = data[pos++];
00307                 grace = data[pos++];
00308                 list_add(list, list->rows, 0, name);
00309                 PARTY_STAT_BAR();
00310                 list_add(list, list->rows - 1, 1, bars);
00311             }
00312         }
00313 
00314         /* Sort the list of party members alphabetically. */
00315         if (type == CMD_PARTY_WHO)
00316         {
00317             list_sort(list, LIST_SORT_ALPHA);
00318         }
00319 
00320         /* Update column names, depending on the list contents. */
00321         list_set_column(list, 0, -1, -1, type == CMD_PARTY_LIST ? "Party name" : "Player", -1);
00322         list_set_column(list, 1, -1, -1, type == CMD_PARTY_LIST ? "Leader" : "Stats", -1);
00323 
00324         list_contents = type;
00325         cur_widget[PARTY_ID]->redraw = 1;
00326         cur_widget[PARTY_ID]->show = 1;
00327         SetPriorityWidget(cur_widget[PARTY_ID]);
00328     }
00329     /* Join command; store the party name we're member of, and show the
00330      * list of party members, if the party widget is not hidden. */
00331     else if (type == CMD_PARTY_JOIN)
00332     {
00333         GetString_String(data, &pos, cpl.partyname, sizeof(cpl.partyname));
00334 
00335         if (cur_widget[PARTY_ID]->show)
00336         {
00337             send_command("/party who");
00338         }
00339     }
00340     /* Leave; clear the party name and switch to list of parties (unless
00341      * the party widget is hidden). */
00342     else if (type == CMD_PARTY_LEAVE)
00343     {
00344         cpl.partyname[0] = '\0';
00345 
00346         if (cur_widget[PARTY_ID]->show)
00347         {
00348             send_command("/party list");
00349         }
00350     }
00351     /* Party requires password, bring up the console for the player to
00352      * enter the password. */
00353     else if (type == CMD_PARTY_PASSWORD)
00354     {
00355         GetString_String(data, &pos, cpl.partyjoin, sizeof(cpl.partyjoin));
00356         reset_keys();
00357         cpl.input_mode = INPUT_MODE_CONSOLE;
00358         text_input_open(253);
00359         text_input_add_string("/party joinpassword ");
00360     }
00361     /* Update list of party members. */
00362     else if (type == CMD_PARTY_UPDATE)
00363     {
00364         char name[MAX_BUF], bars[MAX_BUF];
00365         uint8 hp, sp, grace;
00366         list_struct *list;
00367         uint32 row;
00368 
00369         if (list_contents != CMD_PARTY_WHO)
00370         {
00371             return;
00372         }
00373 
00374         GetString_String(data, &pos, name, sizeof(name));
00375         hp = data[pos++];
00376         sp = data[pos++];
00377         grace = data[pos++];
00378         list = list_exists(LIST_PARTY);
00379 
00380         PARTY_STAT_BAR();
00381         cur_widget[PARTY_ID]->redraw = 1;
00382 
00383         for (row = 0; row < list->rows; row++)
00384         {
00385             if (!strcmp(list->text[row][0], name))
00386             {
00387                 free(list->text[row][1]);
00388                 list->text[row][1] = strdup(bars);
00389                 return;
00390             }
00391         }
00392 
00393         list_add(list, list->rows, 0, name);
00394         list_add(list, list->rows - 1, 1, bars);
00395         list_sort(list, LIST_SORT_ALPHA);
00396     }
00397     /* Remove member from the list of party members. */
00398     else if (type == CMD_PARTY_REMOVE_MEMBER)
00399     {
00400         char name[MAX_BUF];
00401         list_struct *list;
00402         uint32 row;
00403 
00404         if (list_contents != CMD_PARTY_WHO)
00405         {
00406             return;
00407         }
00408 
00409         GetString_String(data, &pos, name, sizeof(name));
00410         list = list_exists(LIST_PARTY);
00411         cur_widget[PARTY_ID]->redraw = 1;
00412 
00413         for (row = 0; row < list->rows; row++)
00414         {
00415             if (!strcmp(list->text[row][0], name))
00416             {
00417                 list_remove_row(list, row);
00418                 return;
00419             }
00420         }
00421     }
00422 }