|
Atrinik Client 2.5
|
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 00032 char *skill_level_name[] = 00033 { 00034 "", 00035 "Ag", 00036 "Pe", 00037 "Me", 00038 "Ph", 00039 "Ma", 00040 "Wi" 00041 }; 00042 00044 uint64 inventory_filter = INVENTORY_FILTER_ALL; 00045 00050 static int inventory_matches_filter(object *op) 00051 { 00052 /* No filtering of objects in the below inventory. */ 00053 if (op->env == cpl.below) 00054 { 00055 return 1; 00056 } 00057 00058 /* Always show open container. */ 00059 if (cpl.container && cpl.container->tag == op->tag) 00060 { 00061 return 1; 00062 } 00063 00064 if (inventory_filter == INVENTORY_FILTER_ALL) 00065 { 00066 return 1; 00067 } 00068 00069 if (inventory_filter & INVENTORY_FILTER_APPLIED && op->flags & F_APPLIED) 00070 { 00071 return 1; 00072 } 00073 00074 if (inventory_filter & INVENTORY_FILTER_CONTAINER && op->itype == TYPE_CONTAINER) 00075 { 00076 return 1; 00077 } 00078 00079 if (inventory_filter & INVENTORY_FILTER_MAGICAL && op->flags & F_MAGIC) 00080 { 00081 return 1; 00082 } 00083 00084 if (inventory_filter & INVENTORY_FILTER_CURSED && op->flags & (F_CURSED | F_DAMNED)) 00085 { 00086 return 1; 00087 } 00088 00089 if (inventory_filter & INVENTORY_FILTER_UNIDENTIFIED && op->item_qua == 255) 00090 { 00091 return 1; 00092 } 00093 00094 if (inventory_filter & INVENTORY_FILTER_UNAPPLIED && !(op->flags & F_APPLIED)) 00095 { 00096 return 1; 00097 } 00098 00099 if (inventory_filter & INVENTORY_FILTER_LOCKED && op->flags & F_LOCKED) 00100 { 00101 return 1; 00102 } 00103 00104 return 0; 00105 } 00106 00110 void inventory_filter_set(uint64 filter) 00111 { 00112 inventory_filter = filter; 00113 cpl.win_inv_slot = 0; 00114 cpl.win_inv_start = 0; 00115 cpl.win_inv_tag = get_inventory_data(cpl.ob, &cpl.win_inv_ctag, &cpl.win_inv_slot, &cpl.win_inv_start, &cpl.win_inv_count, INVITEMXLEN, INVITEMYLEN); 00116 draw_info(COLOR_GREEN, "Inventory filter changed."); 00117 } 00118 00122 void inventory_filter_toggle(uint64 filter) 00123 { 00124 if (inventory_filter & filter) 00125 { 00126 inventory_filter &= ~filter; 00127 } 00128 else 00129 { 00130 inventory_filter |= filter; 00131 } 00132 00133 cpl.win_inv_slot = 0; 00134 cpl.win_inv_start = 0; 00135 cpl.win_inv_tag = get_inventory_data(cpl.ob, &cpl.win_inv_ctag, &cpl.win_inv_slot, &cpl.win_inv_start, &cpl.win_inv_count, INVITEMXLEN, INVITEMYLEN); 00136 draw_info(COLOR_GREEN, "Inventory filter changed."); 00137 } 00138 00139 /* This function returns number of items and adjusts the inventory window data */ 00140 int get_inventory_data(object *op, int *ctag, int *slot, int *start, int *count, int wxlen, int wylen) 00141 { 00142 object *tmp, *tmpc; 00143 int i = 0, ret = -1; 00144 00145 cpl.window_weight = 0.0f; 00146 *ctag = -1; 00147 *count = 0; 00148 00149 if (!op) 00150 { 00151 *slot = *start = 0; 00152 return -1; 00153 } 00154 00155 if (!op->inv) 00156 { 00157 *slot = *start = 0; 00158 return -1; 00159 } 00160 00161 if (*slot < 0) 00162 *slot = 0; 00163 00164 /* Pre count items, and adjust slot cursor */ 00165 for (tmp = op->inv; tmp; tmp = tmp->next) 00166 { 00167 if (inventory_matches_filter(tmp)) 00168 { 00169 (*count)++; 00170 cpl.window_weight += tmp->weight * (float)tmp->nrof; 00171 } 00172 00173 if (tmp->tag == cpl.container_tag) 00174 cpl.container = tmp; 00175 00176 if (cpl.container && cpl.container->tag == tmp->tag) 00177 { 00178 tmpc = cpl.sack->inv; 00179 00180 for (; tmpc; tmpc = tmpc->next) 00181 (*count)++; 00182 } 00183 } 00184 00185 if (!*count) 00186 *slot = 0; 00187 else if (*slot >= *count) 00188 *slot = *count - 1; 00189 00190 /* Now find tag */ 00191 for (tmp = op->inv; tmp; tmp = tmp->next) 00192 { 00193 if (inventory_matches_filter(tmp)) 00194 { 00195 if (*slot == i) 00196 ret = tmp->tag; 00197 00198 i++; 00199 } 00200 00201 if (cpl.container && cpl.container->tag == tmp->tag) 00202 { 00203 tmpc = cpl.sack->inv; 00204 00205 for (; tmpc; tmpc = tmpc->next) 00206 { 00207 if (*slot == i) 00208 { 00209 *ctag = cpl.container->tag; 00210 ret = tmpc->tag; 00211 } 00212 00213 i++; 00214 } 00215 } 00216 } 00217 00218 /* And adjust the slot/start position of the window */ 00219 if (*slot < *start) 00220 *start = *slot - (*slot % wxlen); 00221 else if (*slot > *start + (wxlen * wylen) - 1) 00222 *start = ((int)(*slot / wxlen)) * wxlen - (wxlen * (wylen - 1)); 00223 00224 return ret; 00225 } 00226 00227 static void show_inventory_item_stats(object *tmp, widgetdata *widget) 00228 { 00229 char buf[MAX_BUF]; 00230 00231 if (tmp->nrof > 1) 00232 { 00233 snprintf(buf, sizeof(buf), "%d %s", tmp->nrof, tmp->s_name); 00234 } 00235 else 00236 { 00237 snprintf(buf, sizeof(buf), "%s", tmp->s_name); 00238 } 00239 00240 string_truncate_overflow(FONT_ARIAL10, buf, widget->wd - 26 - 4); 00241 string_blt(ScreenSurface, FONT_ARIAL10, buf, widget->x1 + 26, widget->y1 + 2, COLOR_HGOLD, 0, NULL); 00242 00243 snprintf(buf, sizeof(buf), "%4.3f kg", tmp->weight * (double) tmp->nrof); 00244 string_blt(ScreenSurface, FONT_ARIAL10, buf, widget->x1 + widget->wd - 4 - string_get_width(FONT_ARIAL10, buf, 0), widget->y1 + 15, COLOR_HGOLD, 0, NULL); 00245 00246 /* This comes from server when not identified */ 00247 if (tmp->item_qua == 255) 00248 { 00249 string_blt(ScreenSurface, FONT_ARIAL10, "not identified", widget->x1 + 26, widget->y1 + 15, COLOR_RED, 0, NULL); 00250 } 00251 else 00252 { 00253 string_blt(ScreenSurface, FONT_ARIAL10, "con: ", widget->x1 + 26, widget->y1 + 15, COLOR_HGOLD, 0, NULL); 00254 00255 snprintf(buf, sizeof(buf), "%d/%d", tmp->item_qua, tmp->item_con); 00256 string_blt(ScreenSurface, FONT_ARIAL10, buf, widget->x1 + 53, widget->y1 + 15, COLOR_HGOLD, 0, NULL); 00257 00258 if (tmp->item_level) 00259 { 00260 snprintf(buf, sizeof(buf), "allowed: lvl %d %s", tmp->item_level, skill_level_name[tmp->item_skill]); 00261 00262 if ((!tmp->item_skill && tmp->item_level <= cpl.stats.level) || (tmp->item_skill && tmp->item_level <= cpl.stats.skill_level[tmp->item_skill - 1])) 00263 { 00264 string_blt(ScreenSurface, FONT_ARIAL10, buf, widget->x1 + 101, widget->y1 + 15, COLOR_HGOLD, 0, NULL); 00265 } 00266 else 00267 { 00268 string_blt(ScreenSurface, FONT_ARIAL10, buf, widget->x1 + 101, widget->y1 + 15, COLOR_RED, 0, NULL); 00269 } 00270 } 00271 else 00272 { 00273 string_blt(ScreenSurface, FONT_ARIAL10, "allowed: all", widget->x1 + 101, widget->y1 + 15, COLOR_HGOLD, 0, NULL); 00274 } 00275 } 00276 } 00277 00278 void widget_inventory_event(widgetdata *widget, int x, int y, SDL_Event event) 00279 { 00280 int mx = 0, my = 0; 00281 mx = x - widget->x1; 00282 my = y - widget->y1; 00283 00284 switch (event.type) 00285 { 00286 case SDL_MOUSEBUTTONUP: 00287 if (draggingInvItem(DRAG_GET_STATUS) > DRAG_IWIN_BELOW) 00288 { 00289 /* KEYFUNC_APPLY and KEYFUNC_DROP works only if cpl.inventory_win = IWIN_INV. The tag must 00290 * be placed in cpl.win_inv_tag. So we do this and after DnD we restore the old values. */ 00291 int old_inv_win = cpl.inventory_win; 00292 int old_inv_tag = cpl.win_inv_tag; 00293 cpl.inventory_win = IWIN_INV; 00294 00295 if (draggingInvItem(DRAG_GET_STATUS) == DRAG_PDOLL) 00296 { 00297 cpl.win_inv_tag = cpl.win_pdoll_tag; 00298 /* We don't have to check for the coordinates, if we are here we are in the widget */ 00299 00300 /* Drop to inventory */ 00301 keybind_process_command("?APPLY"); 00302 } 00303 00304 cpl.inventory_win = old_inv_win; 00305 cpl.win_inv_tag = old_inv_tag; 00306 } 00307 else if (draggingInvItem(DRAG_GET_STATUS) == DRAG_IWIN_BELOW) 00308 { 00309 keybind_process_command("?GET"); 00310 } 00311 00312 draggingInvItem(DRAG_NONE); 00313 break; 00314 00315 case SDL_MOUSEBUTTONDOWN: 00316 /* Inventory (open / close) */ 00317 if (mx >= 4 && mx <= 22 && my >= 4 && my <= 26) 00318 { 00319 if (cpl.inventory_win == IWIN_INV) 00320 cpl.inventory_win = IWIN_BELOW; 00321 else 00322 cpl.inventory_win = IWIN_INV; 00323 00324 break; 00325 } 00326 00327 /* scrollbar */ 00328 if (mx > 258 && mx < 268) 00329 { 00330 if (my <= 39 && my >= 30 && cpl.win_inv_slot >= INVITEMXLEN) 00331 cpl.win_inv_slot -= INVITEMXLEN; 00332 else if (my >= 116 && my <= 125) 00333 { 00334 cpl.win_inv_slot += INVITEMXLEN; 00335 00336 if (cpl.win_inv_slot > cpl.win_inv_count) 00337 cpl.win_inv_slot = cpl.win_inv_count; 00338 } 00339 } 00340 else if (mx > 3) 00341 { 00342 /* Stuff */ 00343 00344 /* Mousewheel */ 00345 if (event.button.button == 4 && cpl.win_inv_slot >= INVITEMXLEN) 00346 cpl.win_inv_slot -= INVITEMXLEN; 00347 /* Mousewheel */ 00348 else if (event.button.button == 5) 00349 { 00350 cpl.win_inv_slot += INVITEMXLEN; 00351 00352 if (cpl.win_inv_slot > cpl.win_inv_count) 00353 cpl.win_inv_slot = cpl.win_inv_count; 00354 } 00355 else if ((event.button.button == SDL_BUTTON_LEFT || event.button.button == SDL_BUTTON_RIGHT || event.button.button == SDL_BUTTON_MIDDLE) && my > 29 && my < 125) 00356 { 00357 cpl.win_inv_slot = (my - 30) / 32 * INVITEMXLEN + (mx - 3) / 32 + cpl.win_inv_start; 00358 cpl.win_inv_tag = get_inventory_data(cpl.ob, &cpl.win_inv_ctag, &cpl.win_inv_slot, &cpl.win_inv_start, &cpl.win_inv_count, INVITEMXLEN, INVITEMYLEN); 00359 00360 if (event.button.button == SDL_BUTTON_RIGHT || event.button.button == SDL_BUTTON_MIDDLE) 00361 keybind_process_command("?MARK"); 00362 else 00363 { 00364 if (cpl.inventory_win == IWIN_INV) 00365 draggingInvItem(DRAG_IWIN_INV); 00366 } 00367 } 00368 } 00369 00370 break; 00371 00372 case SDL_MOUSEMOTION: 00373 /* Scrollbar sliders */ 00374 if (event.button.button == SDL_BUTTON_LEFT && !draggingInvItem(DRAG_GET_STATUS)) 00375 { 00376 /* IWIN_INV Slider */ 00377 if (cpl.inventory_win == IWIN_INV && my + 38 && my + 116 && mx + 227 && mx + 236) 00378 { 00379 if (old_mouse_y - y > 0) 00380 cpl.win_inv_slot -= INVITEMXLEN; 00381 else if (old_mouse_y - y < 0) 00382 cpl.win_inv_slot += INVITEMXLEN; 00383 00384 if (cpl.win_inv_slot > cpl.win_inv_count) 00385 cpl.win_inv_slot = cpl.win_inv_count; 00386 00387 break; 00388 } 00389 } 00390 } 00391 } 00392 00393 void widget_show_inventory_window(widgetdata *widget) 00394 { 00395 int i, invxlen, invylen; 00396 object *op, *tmp, *tmpx = NULL; 00397 object *tmpc; 00398 char buf[256]; 00399 widgetdata *tmp_widget; 00400 00401 if (cpl.inventory_win != IWIN_INV) 00402 { 00403 if (!setting_get_int(OPT_CAT_GENERAL, OPT_PLAYERDOLL)) 00404 { 00405 /* do this for all player doll widgets, even though there shouldn't be more than one */ 00406 for (tmp_widget = cur_widget[PDOLL_ID]; tmp_widget; tmp_widget = tmp_widget->type_next) 00407 { 00408 tmp_widget->show = 0; 00409 } 00410 } 00411 00412 if (widget->ht != 32) 00413 { 00414 resize_widget(widget, RESIZE_BOTTOM, 32); 00415 } 00416 00417 sprite_blt(Bitmaps[BITMAP_INV_BG], widget->x1, widget->y1, NULL, NULL); 00418 00419 string_blt(ScreenSurface, FONT_ARIAL10, "Carrying", widget->x1 + 162, widget->y1 + 4, COLOR_HGOLD, 0, NULL); 00420 00421 snprintf(buf, sizeof(buf), "%4.3f kg", cpl.real_weight); 00422 string_blt(ScreenSurface, FONT_ARIAL10, buf, widget->x1 + 207, widget->y1 + 4, COLOR_WHITE, 0, NULL); 00423 00424 string_blt(ScreenSurface, FONT_ARIAL10, "Limit", widget->x1 + 162, widget->y1 + 15, COLOR_HGOLD, 0, NULL); 00425 00426 snprintf(buf, sizeof(buf), "%4.3f kg", (float) cpl.weight_limit / 1000.0); 00427 string_blt(ScreenSurface, FONT_ARIAL10, buf, widget->x1 + 207, widget->y1 + 15, COLOR_WHITE, 0, NULL); 00428 00429 string_blt(ScreenSurface, FONT_ARIAL10, "(SHIFT for inventory)", widget->x1 + 35, widget->y1 + 9, COLOR_WHITE, TEXT_OUTLINE, NULL); 00430 return; 00431 } 00432 00433 if (!setting_get_int(OPT_CAT_GENERAL, OPT_PLAYERDOLL)) 00434 { 00435 /* do this for all player doll widgets, even though there shouldn't be more than one */ 00436 for (tmp_widget = cur_widget[PDOLL_ID]; tmp_widget; tmp_widget = tmp_widget->type_next) 00437 { 00438 tmp_widget->show = 1; 00439 } 00440 } 00441 00442 if (widget->ht != 129) 00443 { 00444 resize_widget(widget, RESIZE_BOTTOM, 129); 00445 } 00446 00447 invxlen = INVITEMXLEN; 00448 invylen = INVITEMYLEN; 00449 00450 sprite_blt(Bitmaps[BITMAP_INVENTORY], widget->x1, widget->y1, NULL, NULL); 00451 00452 blt_window_slider(Bitmaps[BITMAP_INV_SCROLL], ((cpl.win_inv_count - 1) / invxlen) + 1, invylen, cpl.win_inv_start / invxlen, -1, widget->x1 + 261, widget->y1 + 42); 00453 00454 if (!cpl.ob) 00455 { 00456 return; 00457 } 00458 00459 op = cpl.ob; 00460 00461 for (tmpc = NULL, i = 0, tmp = op->inv; tmp && i < cpl.win_inv_start; tmp = tmp->next) 00462 { 00463 if (inventory_matches_filter(tmp)) 00464 { 00465 i++; 00466 } 00467 00468 if (cpl.container && cpl.container->tag == tmp->tag) 00469 { 00470 tmpx = tmp; 00471 tmpc = cpl.sack->inv; 00472 00473 for (; tmpc && i < cpl.win_inv_start; tmpc = tmpc->next,i++); 00474 00475 if (tmpc) 00476 { 00477 break; 00478 } 00479 } 00480 } 00481 00482 i = 0; 00483 00484 if (tmpc) 00485 { 00486 tmp = tmpx; 00487 goto jump_in_container1; 00488 } 00489 00490 for (; tmp && i < invxlen * invylen; tmp = tmp->next) 00491 { 00492 if (inventory_matches_filter(tmp)) 00493 { 00494 if (tmp->tag == cpl.mark_count) 00495 { 00496 sprite_blt(Bitmaps[BITMAP_INVSLOT_MARKED], widget->x1 + (i % invxlen) * 32 + 3, widget->y1 + (i / invxlen) * 32 + 31, NULL, NULL); 00497 } 00498 00499 blt_inv_item(tmp, widget->x1 + (i % invxlen) * 32 + 4, widget->y1 + (i / invxlen) * 32 + 32); 00500 00501 if (cpl.inventory_win != IWIN_BELOW && i + cpl.win_inv_start == cpl.win_inv_slot) 00502 { 00503 sprite_blt(Bitmaps[BITMAP_INVSLOT], widget->x1 + (i % invxlen) * 32 + 3, widget->y1 + (i / invxlen) * 32 + 31, NULL, NULL); 00504 show_inventory_item_stats(tmp, widget); 00505 } 00506 00507 i++; 00508 } 00509 00510 /* We have an open container - 'insert' the items inside in the panel */ 00511 if (cpl.container && cpl.container->tag == tmp->tag) 00512 { 00513 sprite_blt(Bitmaps[BITMAP_CMARK_START], widget->x1 + ((i - 1) % invxlen) * 32 + 4, widget->y1 + ((i - 1) / invxlen) * 32 + 32, NULL, NULL); 00514 tmpc = cpl.sack->inv; 00515 00516 jump_in_container1: 00517 for (; tmpc && i < invxlen * invylen; tmpc = tmpc->next) 00518 { 00519 if (tmpc->tag == cpl.mark_count) 00520 { 00521 sprite_blt(Bitmaps[BITMAP_INVSLOT_MARKED], widget->x1 + (i % invxlen) * 32 + 3, widget->y1 + (i / invxlen) * 32 + 31, NULL, NULL); 00522 } 00523 00524 blt_inv_item(tmpc, widget->x1 + (i % invxlen) * 32 + 4, widget->y1 + (i / invxlen) * 32 + 32); 00525 00526 if (cpl.inventory_win != IWIN_BELOW && i + cpl.win_inv_start == cpl.win_inv_slot) 00527 { 00528 sprite_blt(Bitmaps[BITMAP_INVSLOT], widget->x1 + (i % invxlen) * 32 + 3, widget->y1 + (i / invxlen) * 32 + 31, NULL, NULL); 00529 00530 show_inventory_item_stats(tmpc, widget); 00531 } 00532 00533 sprite_blt(Bitmaps[BITMAP_CMARK_MIDDLE], widget->x1 + (i % invxlen) * 32 + 4, widget->y1 + (i / invxlen) * 32 + 32, NULL, NULL); 00534 i++; 00535 } 00536 00537 if (!tmpc) 00538 { 00539 sprite_blt(Bitmaps[BITMAP_CMARK_END], widget->x1 + ((i - 1) % invxlen) * 32 + 4, widget->y1 + ((i - 1) / invxlen) * 32 + 32, NULL, NULL); 00540 } 00541 } 00542 } 00543 } 00544 00545 void widget_below_window_event(widgetdata *widget, int x, int y, int MEvent) 00546 { 00547 /* ground ( IWIN_BELOW ) */ 00548 if (y >= widget->y1 + 19 && y <= widget->y1 + widget->ht - 4 && x > widget->x1 + 4 && x < widget->x1 + widget->wd - 12) 00549 { 00550 if (cpl.inventory_win == IWIN_INV) 00551 { 00552 cpl.inventory_win = IWIN_BELOW; 00553 } 00554 00555 cpl.win_below_slot = (x - widget->x1 - 5) / 32; 00556 00557 cpl.win_below_tag = get_inventory_data(cpl.below, &cpl.win_below_ctag, &cpl.win_below_slot, &cpl.win_below_start, &cpl.win_below_count, INVITEMBELOWXLEN, INVITEMBELOWYLEN); 00558 00559 if ((SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT))) 00560 { 00561 if (cpl.below->inv) 00562 { 00563 draggingInvItem(DRAG_IWIN_BELOW); 00564 } 00565 } 00566 else 00567 { 00568 keybind_process_command("?APPLY"); 00569 } 00570 } 00571 else if (y >= widget->y1 + 20 && y <= widget->y1 + 29 && x > widget->x1 + 262 && x < widget->x1 + 269 && MEvent == MOUSE_DOWN) 00572 { 00573 if (cpl.inventory_win == IWIN_INV) 00574 { 00575 cpl.inventory_win = IWIN_BELOW; 00576 } 00577 00578 cpl.win_below_slot = cpl.win_below_slot - INVITEMBELOWXLEN; 00579 00580 if (cpl.win_below_slot < 0) 00581 { 00582 cpl.win_below_slot = 0; 00583 } 00584 00585 cpl.win_below_tag = get_inventory_data(cpl.below, &cpl.win_below_ctag, &cpl.win_below_slot, &cpl.win_below_start, &cpl.win_below_count, INVITEMBELOWXLEN, INVITEMBELOWYLEN); 00586 } 00587 else if (y >= widget->y1 + 42 && y <= widget->y1 + 51 && x > widget->x1 + 262 && x < widget->x1 + 269 && MEvent == MOUSE_DOWN) 00588 { 00589 if (cpl.inventory_win == IWIN_INV) 00590 { 00591 cpl.inventory_win = IWIN_BELOW; 00592 } 00593 00594 cpl.win_below_slot = cpl.win_below_slot + INVITEMBELOWXLEN; 00595 00596 if (cpl.win_below_slot > cpl.win_below_count -1) 00597 { 00598 cpl.win_below_slot = cpl.win_below_count -1; 00599 } 00600 00601 cpl.win_below_tag = get_inventory_data(cpl.below, &cpl.win_below_ctag, &cpl.win_below_slot, &cpl.win_below_start, &cpl.win_below_count, INVITEMBELOWXLEN, INVITEMBELOWYLEN); 00602 } 00603 } 00604 00605 void widget_show_below_window(widgetdata *widget) 00606 { 00607 int i, slot,at; 00608 object *tmp, *tmpc, *tmpx = NULL; 00609 char buf[256]; 00610 00611 sprite_blt(Bitmaps[BITMAP_BELOW], widget->x1, widget->y1, NULL, NULL); 00612 00613 blt_window_slider(Bitmaps[BITMAP_BELOW_SCROLL], ((cpl.win_below_count - 1) / INVITEMBELOWXLEN) + 1, INVITEMBELOWYLEN, cpl.win_below_start / INVITEMBELOWXLEN, -1, widget->x1 + 263, widget->y1 + 30); 00614 00615 if (!cpl.below) 00616 { 00617 return; 00618 } 00619 00620 for (i = 0, tmpc = NULL, tmp = cpl.below->inv; tmp && i < cpl.win_below_start; tmp = tmp->next) 00621 { 00622 i++; 00623 tmpx = tmp; 00624 00625 if (cpl.container && cpl.container->tag == tmp->tag) 00626 { 00627 tmpc = cpl.sack->inv; 00628 00629 for (; tmpc && i < cpl.win_below_start; tmpc = tmpc->next, i++); 00630 00631 if (tmpc) 00632 { 00633 break; 00634 } 00635 } 00636 } 00637 00638 i = 0; 00639 00640 if (tmpc) 00641 { 00642 tmp = tmpx; 00643 goto jump_in_container2; 00644 } 00645 00646 for (; tmp && i < INVITEMBELOWXLEN * INVITEMBELOWYLEN; tmp = tmp->next) 00647 { 00648 at = tmp->flags & F_APPLIED; 00649 00650 if (tmp->tag != cpl.container_tag) 00651 tmp->flags &= ~F_APPLIED; 00652 00653 blt_inv_item(tmp, widget->x1 + (i % INVITEMBELOWXLEN) * 32 + 5, widget->y1 + (i / INVITEMBELOWXLEN) * 32 + 19); 00654 00655 if (at) 00656 { 00657 tmp->flags |= F_APPLIED; 00658 } 00659 00660 if (i + cpl.win_below_start == cpl.win_below_slot) 00661 { 00662 if (cpl.inventory_win == IWIN_BELOW) 00663 slot = BITMAP_INVSLOT; 00664 else 00665 slot = BITMAP_INVSLOT_U; 00666 00667 sprite_blt(Bitmaps[slot], widget->x1 + (i % INVITEMBELOWXLEN) * 32 + 5, widget->y1 + (i / INVITEMBELOWXLEN) * 32 + 19, NULL, NULL); 00668 00669 if (tmp->nrof > 1) 00670 snprintf(buf, sizeof(buf), "%d %s", tmp->nrof, tmp->s_name); 00671 else 00672 snprintf(buf, sizeof(buf), "%s", tmp->s_name); 00673 00674 string_truncate_overflow(FONT_ARIAL10, buf, 250); 00675 string_blt(ScreenSurface, FONT_ARIAL10, buf, widget->x1 + 6, widget->y1 + 4, COLOR_HGOLD, 0, NULL); 00676 } 00677 00678 i++; 00679 00680 /* We have an open container - 'insert' the items inside in the panel */ 00681 if (cpl.container && cpl.container->tag == tmp->tag) 00682 { 00683 sprite_blt(Bitmaps[BITMAP_CMARK_START], widget->x1 + ((i - 1) % INVITEMBELOWXLEN) * 32 + 5, widget->y1 + ((i - 1) / INVITEMBELOWXLEN) * 32 + 19, NULL, NULL); 00684 tmpc = cpl.sack->inv; 00685 00686 jump_in_container2: 00687 for (; tmpc && i < INVITEMBELOWXLEN * INVITEMBELOWYLEN; tmpc = tmpc->next) 00688 { 00689 blt_inv_item(tmpc, widget->x1 + (i % INVITEMBELOWXLEN) * 32 + 5, widget->y1 + (i / INVITEMBELOWXLEN) * 32 + 19); 00690 00691 if (i + cpl.win_below_start == cpl.win_below_slot) 00692 { 00693 if (cpl.inventory_win == IWIN_BELOW) 00694 slot = BITMAP_INVSLOT; 00695 else 00696 slot = BITMAP_INVSLOT_U; 00697 00698 sprite_blt(Bitmaps[slot], widget->x1 + (i % INVITEMBELOWXLEN) * 32 + 5, widget->y1 + (i / INVITEMBELOWXLEN) * 32 + 19, NULL, NULL); 00699 00700 if (tmpc->nrof > 1) 00701 snprintf(buf, sizeof(buf), "%d %s", tmpc->nrof, tmpc->s_name); 00702 else 00703 snprintf(buf, sizeof(buf), "%s", tmpc->s_name); 00704 00705 string_truncate_overflow(FONT_ARIAL10, buf, 250); 00706 string_blt(ScreenSurface, FONT_ARIAL10, buf, widget->x1 + 6, widget->y1 + 3, COLOR_HGOLD, 0, NULL); 00707 } 00708 00709 sprite_blt(Bitmaps[BITMAP_CMARK_MIDDLE], widget->x1 + (i % INVITEMBELOWXLEN) * 32 + 5, widget->y1 + (i / INVITEMBELOWXLEN) * 32 + 19, NULL, NULL); 00710 i++; 00711 } 00712 00713 if (!tmpc) 00714 sprite_blt(Bitmaps[BITMAP_CMARK_END], widget->x1 + ((i - 1) % INVITEMBELOWXLEN) * 32 + 5, widget->y1 + ((i - 1) / INVITEMBELOWXLEN) * 32 + 19, NULL, NULL); 00715 } 00716 } 00717 } 00718 00719 #define ICONDEFLEN 32 00720 int blt_inv_item_centered(object *tmp, int x, int y) 00721 { 00722 int temp, xstart, xlen, ystart, ylen; 00723 sint16 anim1; 00724 SDL_Rect box; 00725 _BLTFX bltfx; 00726 bltfx.flags = 0; 00727 bltfx.dark_level = 0; 00728 bltfx.surface = NULL; 00729 bltfx.alpha = 128; 00730 00731 if (!FaceList[tmp->face].sprite) 00732 return 0; 00733 00734 anim1 = tmp->face; 00735 00736 /* This is part of animation... Because ISO items have different offsets and sizes, 00737 * we must use ONE sprite base offset to center an animation over an animation. 00738 * we use the first frame of an animation for it.*/ 00739 if (tmp->animation_id > 0) 00740 { 00741 check_animation_status(tmp->animation_id); 00742 00743 /* First bitmap of this animation */ 00744 if (animations[tmp->animation_id].num_animations && animations[tmp->animation_id].facings <= 1) 00745 anim1 = animations[tmp->animation_id].faces[0]; 00746 } 00747 00748 /* Fallback: first animation bitmap not loaded */ 00749 if (!FaceList[anim1].sprite) 00750 anim1 = tmp->face; 00751 00752 xstart = FaceList[anim1].sprite->border_left; 00753 xlen = FaceList[anim1].sprite->bitmap->w - xstart-FaceList[anim1].sprite->border_right; 00754 ystart = FaceList[anim1].sprite->border_up; 00755 ylen = FaceList[anim1].sprite->bitmap->h - ystart-FaceList[anim1].sprite->border_down; 00756 00757 if (xlen > 32) 00758 { 00759 box.w = 32; 00760 temp = (xlen - 32) / 2; 00761 box.x = xstart + temp; 00762 xstart = 0; 00763 } 00764 else 00765 { 00766 box.w = xlen; 00767 box.x = xstart; 00768 xstart = (32 - xlen) / 2; 00769 } 00770 00771 if (ylen > 32) 00772 { 00773 box.h = 32; 00774 temp = (ylen - 32) / 2; 00775 box.y = ystart + temp; 00776 ystart = 0; 00777 } 00778 else 00779 { 00780 box.h = ylen; 00781 box.y = ystart; 00782 ystart = (32 - ylen) / 2; 00783 } 00784 00785 /* Now we have a perfect centered sprite. 00786 * But: If this is the start pos of our 00787 * first animation and not of our sprite, 00788 * we must shift it a bit to insert our 00789 * face exactly. */ 00790 if (anim1 != tmp->face) 00791 { 00792 temp = xstart-box.x; 00793 00794 box.x = 0; 00795 box.w = FaceList[tmp->face].sprite->bitmap->w; 00796 xstart = temp; 00797 00798 temp = ystart - box.y + (FaceList[anim1].sprite->bitmap->h - FaceList[tmp->face].sprite->bitmap->h); 00799 box.y = 0; 00800 box.h = FaceList[tmp->face].sprite->bitmap->h; 00801 ystart = temp; 00802 00803 if (xstart < 0) 00804 { 00805 box.x = -xstart; 00806 box.w = FaceList[tmp->face].sprite->bitmap->w + xstart; 00807 00808 if (box.w > 32) 00809 box.w = 32; 00810 00811 xstart = 0; 00812 } 00813 else 00814 { 00815 if (box.w + xstart > 32) 00816 box.w -= ((box.w + xstart) - 32); 00817 } 00818 00819 if (ystart < 0) 00820 { 00821 box.y = -ystart; 00822 box.h = FaceList[tmp->face].sprite->bitmap->h + ystart; 00823 00824 if (box.h > 32) 00825 box.h = 32; 00826 00827 ystart = 0; 00828 } 00829 else 00830 { 00831 if (box.h + ystart > 32) 00832 box.h -= ((box.h + ystart) - 32); 00833 } 00834 } 00835 00836 if (tmp->flags & F_INVISIBLE) 00837 bltfx.flags = BLTFX_FLAG_SRCALPHA | BLTFX_FLAG_GREY; 00838 00839 if (tmp->flags & F_ETHEREAL) 00840 bltfx.flags = BLTFX_FLAG_SRCALPHA; 00841 00842 sprite_blt(FaceList[tmp->face].sprite, x + xstart, y + ystart, &box, &bltfx); 00843 00844 return 1; 00845 } 00846 00856 void blt_inv_item(object *tmp, int x, int y) 00857 { 00858 int fire_ready; 00859 00860 blt_inv_item_centered(tmp, x, y); 00861 00862 if (tmp->nrof > 1) 00863 { 00864 char buf[64]; 00865 00866 if (tmp->nrof > 9999) 00867 { 00868 snprintf(buf, sizeof(buf), "many"); 00869 } 00870 else 00871 { 00872 snprintf(buf, sizeof(buf), "%d", tmp->nrof); 00873 } 00874 00875 string_blt(ScreenSurface, FONT_ARIAL10, buf, x + ICONDEFLEN / 2 - string_get_width(FONT_ARIAL10, buf, 0) / 2, y + 18, COLOR_WHITE, TEXT_OUTLINE, NULL); 00876 } 00877 00878 /* Determine whether there is a readied object for firing or not. */ 00879 fire_ready = (fire_mode_tab[FIRE_MODE_THROW].item == tmp->tag || fire_mode_tab[FIRE_MODE_BOW].amun == tmp->tag) && tmp->env == cpl.ob; 00880 00881 if (tmp->flags & F_APPLIED) 00882 { 00883 sprite_blt(Bitmaps[BITMAP_APPLY], x, y, NULL, NULL); 00884 00885 if (fire_ready) 00886 { 00887 sprite_blt(Bitmaps[BITMAP_FIRE_READY], x, y + 8, NULL, NULL); 00888 } 00889 } 00890 else if (tmp->flags & F_UNPAID) 00891 { 00892 sprite_blt(Bitmaps[BITMAP_UNPAID], x, y, NULL, NULL); 00893 } 00894 else if (fire_ready) 00895 { 00896 sprite_blt(Bitmaps[BITMAP_FIRE_READY], x, y, NULL, NULL); 00897 } 00898 00899 if (tmp->flags & F_LOCKED) 00900 { 00901 sprite_blt(Bitmaps[BITMAP_LOCK], x, y + ICONDEFLEN - Bitmaps[BITMAP_LOCK]->bitmap->w - 2, NULL, NULL); 00902 } 00903 00904 if (tmp->flags & F_MAGIC) 00905 { 00906 sprite_blt(Bitmaps[BITMAP_MAGIC], x + ICONDEFLEN - Bitmaps[BITMAP_MAGIC]->bitmap->w - 2, y + ICONDEFLEN - Bitmaps[BITMAP_MAGIC]->bitmap->h - 2, NULL, NULL); 00907 } 00908 00909 if (tmp->flags & F_DAMNED) 00910 { 00911 sprite_blt(Bitmaps[BITMAP_DAMNED], x + ICONDEFLEN - Bitmaps[BITMAP_DAMNED]->bitmap->w - 2, y, NULL, NULL); 00912 } 00913 else if (tmp->flags & F_CURSED) 00914 { 00915 sprite_blt(Bitmaps[BITMAP_CURSED], x + ICONDEFLEN - Bitmaps[BITMAP_CURSED]->bitmap->w - 2, y, NULL, NULL); 00916 } 00917 00918 if (tmp->flags & F_TRAPPED) 00919 { 00920 sprite_blt(Bitmaps[BITMAP_TRAPPED], x + ICONDEFLEN / 2 - Bitmaps[BITMAP_TRAPPED]->bitmap->w / 2, y + ICONDEFLEN / 2 - Bitmaps[BITMAP_TRAPPED]->bitmap->h / 2, NULL, NULL); 00921 } 00922 }
1.7.4