1 #include "asc.h"
2 #include "context_menu.h"
3 #include "cursors.h"
4 #include "elconfig.h"
5 #include "elwindows.h"
6 #include "font.h"
7 #include "gamewin.h"
8 #include "gl_init.h"
9 #include "hud.h"
10 #include "hud_quickbar_window.h"
11 #include "hud_misc_window.h"
12 #include "interface.h"
13 #include "item_info.h"
14 #include "items.h"
15 #include "keys.h"
16 #include "multiplayer.h"
17 #include "sound.h"
18 #include "spells.h"
19 #include "textures.h"
20
21 int quickbar_draggable=1;
22 int quickbar_dir=HORIZONTAL;
23 // with quickbar_relocatable off, the default will be docked to right hud
24 int quickbar_relocatable=0;
25 int num_quickbar_slots = 6;
26 int cm_quickbar_enabled = 0;
27 int independant_quickbar_action_modes = 0;
28
29 static size_t cm_quickbar_id = CM_INIT_VALUE;
30 static int mouseover_quickbar_item_pos = -1;
31 static int item_quickbar_slot_size = -1;
32 static int default_item_quickbar_x = -1;
33 static int default_item_quickbar_y = -1;
34 static int shown_quickbar_slots = -1;
35 static int qb_action_mode=ACTION_USE;
36
37 enum { CMQB_ENABLE=0, CMQB_SEP1, CMQB_RELOC, CMQB_DRAG, CMQB_FLIP, CMQB_SEP2, CMQB_RESET };
38
39
40 /*Change flags*/
change_flags(int win_id,Uint32 flags)41 static void change_flags(int win_id, Uint32 flags)
42 {
43 int order = windows_list.window[win_id].order;
44
45 windows_list.window[win_id].flags = flags;
46 if ( (order > 0 && (flags & ELW_SHOW_LAST)) || (order < 0 && !(flags & ELW_SHOW_LAST)) )
47 windows_list.window[win_id].order = -order;
48 }
49
50
51 /*Return flags*/
get_flags(int win_id)52 static Uint32 get_flags(int win_id)
53 {
54 return windows_list.window[win_id].flags;
55 }
56
57
58 // returns try if the window is not in the default place, false if it is, even if it can be relocated
is_relocated(void)59 static int is_relocated(void)
60 {
61 int quickbar_win = get_id_MW(MW_QUICKBAR);
62 window_info *win = NULL;
63 if (quickbar_win < 0 || quickbar_win > windows_list.num_windows)
64 return 1;
65 win = &windows_list.window[quickbar_win];
66 if ((quickbar_draggable) || (quickbar_dir != VERTICAL) ||
67 (win->cur_x != default_item_quickbar_x) || (win->cur_y != default_item_quickbar_y))
68 return 1;
69 else
70 return 0;
71 }
72
73
74 // return the window y len based on the number of slots
get_quickbar_y_len(void)75 static int get_quickbar_y_len(void)
76 {
77 return shown_quickbar_slots * item_quickbar_slot_size + 1;
78 }
79
80
81 /* get the base y coord of the quick bar if its in
82 it's default place, otherwise return where the top would be */
get_quickbar_y_base(void)83 int get_quickbar_y_base(void)
84 {
85 if (is_relocated())
86 return default_item_quickbar_y;
87 else
88 return default_item_quickbar_y + get_quickbar_y_len();
89 }
90
91
92 /*Enable/disable quickbar title bar and dragability*/
toggle_quickbar_draggable(void)93 static void toggle_quickbar_draggable(void)
94 {
95 int quickbar_win = get_id_MW(MW_QUICKBAR);
96 Uint32 flags = get_flags(quickbar_win);
97 if (!quickbar_draggable)
98 {
99 flags &= ~ELW_SHOW_LAST;
100 flags |= ELW_DRAGGABLE | ELW_TITLE_BAR;
101 change_flags (quickbar_win, flags);
102 quickbar_draggable = 1;
103 }
104 else
105 {
106 flags |= ELW_SHOW_LAST;
107 flags &= ~(ELW_DRAGGABLE | ELW_TITLE_BAR);
108 change_flags (quickbar_win, flags);
109 quickbar_draggable = 0;
110 }
111 }
112
113
114 // common function to resize window depending on orientation
resize_item_quickbar_window(int window_id)115 static void resize_item_quickbar_window(int window_id)
116 {
117 if (quickbar_dir==VERTICAL)
118 resize_window(window_id, item_quickbar_slot_size, get_quickbar_y_len());
119 else
120 resize_window(window_id, get_quickbar_y_len(), item_quickbar_slot_size);
121 }
122
123
124 // return the number of shown slots, increasing to the oprions value if appropriate
update_shown_quickbar_slots(window_info * win)125 static void update_shown_quickbar_slots(window_info *win)
126 {
127 int last_shown_slots = shown_quickbar_slots;
128
129 if (quickbar_relocatable && is_relocated())
130 shown_quickbar_slots = num_quickbar_slots;
131 else
132 {
133 int max_slots = (window_height - get_min_hud_misc_len_y() - default_item_quickbar_y - 1) / item_quickbar_slot_size;
134 if (max_slots > num_quickbar_slots)
135 shown_quickbar_slots = num_quickbar_slots;
136 else if (max_slots < 1)
137 shown_quickbar_slots = 1;
138 else
139 shown_quickbar_slots = max_slots;
140 }
141
142 if (last_shown_slots != shown_quickbar_slots)
143 resize_item_quickbar_window(win->window_id);
144 }
145
146
147 /*Change the quickbar from vertical to horizontal, or vice versa*/
flip_quickbar(int window_id)148 static void flip_quickbar(int window_id)
149 {
150 if (quickbar_dir == VERTICAL)
151 quickbar_dir = HORIZONTAL;
152 else
153 quickbar_dir = VERTICAL;
154 resize_item_quickbar_window(window_id);
155 }
156
157
158 /*Return the quickbar to it's Built-in position*/
reset_quickbar()159 static void reset_quickbar()
160 {
161 int quickbar_win = get_id_MW(MW_QUICKBAR);
162 limit_win_scale_to_default(get_scale_WM(MW_QUICKBAR));
163 quickbar_dir = VERTICAL;
164 quickbar_draggable = 0;
165 if (quickbar_relocatable)
166 {
167 set_var_unsaved("relocate_quickbar", INI_FILE_VAR);
168 quickbar_relocatable = 0;
169 }
170 change_flags(quickbar_win, ELW_USE_UISCALE|ELW_TITLE_NONE|ELW_SHOW|ELW_USE_BACKGROUND|ELW_USE_BORDER|ELW_SHOW_LAST);
171 init_window(quickbar_win, -1, 0, default_item_quickbar_x, default_item_quickbar_y, item_quickbar_slot_size, get_quickbar_y_len());
172 }
173
174
cm_quickbar_pre_show_handler(window_info * win,int widget_id,int mx,int my,window_info * cm_win)175 static void cm_quickbar_pre_show_handler(window_info *win, int widget_id, int mx, int my, window_info *cm_win)
176 {
177 cm_grey_line(cm_quickbar_id, CMQB_DRAG, (quickbar_relocatable) ?0 :1);
178 cm_grey_line(cm_quickbar_id, CMQB_FLIP, (quickbar_relocatable) ?0 :1);
179 }
180
181
context_quickbar_handler(window_info * win,int widget_id,int mx,int my,int option)182 static int context_quickbar_handler(window_info *win, int widget_id, int mx, int my, int option)
183 {
184 switch (option)
185 {
186 case CMQB_RELOC: if (quickbar_relocatable) toggle_quickbar_draggable(); break;
187 case CMQB_DRAG: quickbar_draggable ^= 1; toggle_quickbar_draggable(); break;
188 case CMQB_RESET: reset_quickbar(); break;
189 case CMQB_FLIP: flip_quickbar(win->window_id); break;
190 }
191 return 1;
192 }
193
194
quickbar_item_description_help(window_info * win,int pos,int slot)195 static void quickbar_item_description_help(window_info *win, int pos, int slot)
196 {
197 Uint16 item_id = item_list[pos].id;
198 int image_id = item_list[pos].image_id;
199 if (show_item_desc_text && item_info_available() && (get_item_count(item_id, image_id) == 1))
200 {
201 const char *str = get_item_description(item_id, image_id);
202 if (str != NULL)
203 {
204 int xpos = 0, ypos = 0;
205 const int tooltip_sep = (int)(0.5 + win->current_scale * 5);
206 int len_str = get_string_width_zoom((const unsigned char*)str,
207 win->font_category, win->current_scale_small) + tooltip_sep;
208 /* vertical place right (or left) and aligned with slot */
209 if (quickbar_dir==VERTICAL)
210 {
211 xpos = win->len_x + 5;
212 if ((xpos + len_str + win->cur_x) > window_width)
213 xpos = -len_str;
214 ypos = slot * item_quickbar_slot_size + (item_quickbar_slot_size - win->small_font_len_y) / 2;
215 }
216 /* horizontal place right at bottom (or top) of window */
217 else
218 {
219 xpos = 0;
220 ypos = win->len_y + 5;
221 if ((xpos + len_str + win->cur_x) > window_width)
222 xpos = window_width - win->cur_x - len_str;
223 if ((xpos + win->cur_x) < 0)
224 xpos = -win->cur_x + 5;
225 if ((ypos + win->small_font_len_y + win->cur_y) > window_height)
226 ypos = -(5 + win->small_font_len_y + (quickbar_draggable * win->title_height));
227 }
228 show_help(str, xpos, ypos, win->current_scale);
229 }
230 }
231 }
232
233
mouseover_quickbar_handler(window_info * win,int mx,int my)234 static int mouseover_quickbar_handler(window_info *win, int mx, int my) {
235 int y,i=0;
236 int x_screen,y_screen;
237
238 for(y=0;y<shown_quickbar_slots;y++)
239 {
240 if(quickbar_dir==VERTICAL)
241 {
242 x_screen=0;
243 y_screen=y*item_quickbar_slot_size;
244 }
245 else
246 {
247 x_screen=y*item_quickbar_slot_size;
248 y_screen=0;
249 }
250 if(mx>x_screen && mx<x_screen+item_quickbar_slot_size && my>y_screen && my<y_screen+item_quickbar_slot_size)
251 {
252 for(i=0;i<ITEM_NUM_ITEMS;i++){
253 if(item_list[i].quantity && item_list[i].pos==y)
254 {
255 if(qb_action_mode==ACTION_LOOK) {
256 elwin_mouse=CURSOR_EYE;
257 } else if(qb_action_mode==ACTION_USE) {
258 elwin_mouse=CURSOR_USE;
259 } else if(qb_action_mode==ACTION_USE_WITEM) {
260 elwin_mouse=CURSOR_USE_WITEM;
261 } else {
262 elwin_mouse=CURSOR_PICK;
263 }
264 quickbar_item_description_help(win, i, y);
265 mouseover_quickbar_item_pos = y;
266 return 1;
267 }
268 }
269 }
270 }
271 return 0;
272 }
273
274
click_quickbar_handler(window_info * win,int mx,int my,Uint32 flags)275 static int click_quickbar_handler(window_info *win, int mx, int my, Uint32 flags)
276 {
277 int i,y;
278 int x_screen,y_screen;
279 Uint8 str[100];
280 int trigger=ELW_LEFT_MOUSE|KMOD_CTRL|KMOD_SHIFT;//flags we'll use for the quickbar relocation handling
281 int right_click = flags & ELW_RIGHT_MOUSE;
282 int ctrl_on = flags & KMOD_CTRL;
283 int shift_on = flags & KMOD_SHIFT;
284
285 // only handle mouse button clicks, not scroll wheels moves or clicks
286 if (( (flags & ELW_MOUSE_BUTTON) == 0) || ( (flags & ELW_MID_MOUSE) != 0)) return 0;
287
288 if(right_click) {
289 switch(qb_action_mode) {
290 case ACTION_WALK:
291 if(item_dragged != -1)
292 item_dragged = -1;
293 else
294 qb_action_mode = ACTION_LOOK;
295 break;
296 case ACTION_LOOK:
297 qb_action_mode=ACTION_USE;
298 break;
299 case ACTION_USE:
300 qb_action_mode=ACTION_USE_WITEM;
301 break;
302 case ACTION_USE_WITEM:
303 if(use_item!=-1)
304 use_item=-1;
305 else
306 qb_action_mode=ACTION_WALK;
307 break;
308 default:
309 use_item=-1;
310 qb_action_mode=ACTION_WALK;
311 }
312 if (cm_quickbar_enabled)
313 cm_show_direct(cm_quickbar_id, win->window_id, -1);
314 return 1;
315 }
316
317 if (qb_action_mode == ACTION_USE_WITEM)
318 set_gamewin_usewith_action();
319
320 // no in window check needed, already done
321 //see if we clicked on any item in the main category
322 for(y=0;y<shown_quickbar_slots;y++)
323 {
324 if(quickbar_dir==VERTICAL)
325 {
326 x_screen=0;
327 y_screen=y*item_quickbar_slot_size;
328 }
329 else
330 {
331 x_screen=y*item_quickbar_slot_size;
332 y_screen=0;
333 }
334 if(mx>x_screen && mx<x_screen+item_quickbar_slot_size && my>y_screen && my<y_screen+item_quickbar_slot_size)
335 {
336 //see if there is an empty space to drop this item over.
337 if(item_dragged!=-1)//we have to drop this item
338 {
339 int any_item=0;
340 if(item_dragged == y)
341 {
342 try_auto_equip(item_dragged);
343 return 1;
344 }
345 for(i=0;i<shown_quickbar_slots;i++)
346 {
347 if(item_list[i].quantity && item_list[i].pos==y)
348 {
349 any_item=1;
350 if(item_dragged==i)//drop the item only over itself
351 item_dragged=-1;
352 do_drop_item_sound();
353 return 1;
354 }
355 }
356 if(!any_item)
357 {
358 //send the drop info to the server
359 str[0]=MOVE_INVENTORY_ITEM;
360 str[1]=item_list[item_dragged].pos;
361 str[2]=y;
362 my_tcp_send(my_socket,str,3);
363 item_dragged=-1;
364 do_drag_item_sound();
365 return 1;
366 }
367 }
368 if(quickbar_relocatable>0)
369 {
370 if((flags&trigger)==(ELW_LEFT_MOUSE|KMOD_CTRL))
371 {
372 //toggle draggable
373 toggle_quickbar_draggable();
374 }
375 else if ( (flags & trigger)== (ELW_LEFT_MOUSE | KMOD_SHIFT) && (get_flags (win->window_id) & (ELW_TITLE_BAR | ELW_DRAGGABLE)) == (ELW_TITLE_BAR | ELW_DRAGGABLE) )
376 {
377 //toggle vertical/horisontal
378 flip_quickbar(win->window_id);
379 }
380 else if (((flags&trigger)==trigger))
381 {
382 //reset
383 reset_quickbar();
384 }
385 }
386 //see if there is any item there
387 for(i=0;i<shown_quickbar_slots;i++)
388 {
389 //should we get the info for it?
390 if(item_list[i].quantity && item_list[i].pos==y)
391 {
392
393 if(ctrl_on){
394 str[0]=DROP_ITEM;
395 str[1]=item_list[i].pos;
396 *((Uint32 *)(str+2))=item_list[i].quantity;
397 my_tcp_send(my_socket, str, 6);
398 do_drop_item_sound();
399 return 1;
400 } else if(qb_action_mode==ACTION_LOOK)
401 {
402 click_time=cur_time;
403 str[0]=LOOK_AT_INVENTORY_ITEM;
404 str[1]=item_list[i].pos;
405 my_tcp_send(my_socket,str,2);
406 }
407 else if(qb_action_mode==ACTION_USE)
408 {
409 if(item_list[i].use_with_inventory)
410 {
411 str[0]=USE_INVENTORY_ITEM;
412 str[1]=item_list[i].pos;
413 my_tcp_send(my_socket,str,2);
414 used_item_counter_action_use(i);
415 #ifdef NEW_SOUND
416 item_list[i].action = USE_INVENTORY_ITEM;
417 #endif // NEW_SOUND
418 return 1;
419 }
420 return 1;
421 }
422 else if(qb_action_mode==ACTION_USE_WITEM) {
423 if(use_item!=-1) {
424 str[0]=ITEM_ON_ITEM;
425 str[1]=item_list[use_item].pos;
426 str[2]=item_list[i].pos;
427 my_tcp_send(my_socket,str,3);
428 used_item_counter_action_use(use_item);
429 #ifdef NEW_SOUND
430 item_list[use_item].action = ITEM_ON_ITEM;
431 item_list[i].action = ITEM_ON_ITEM;
432 #endif // NEW_SOUND
433 if (!shift_on)
434 use_item=-1;
435 }
436 else
437 use_item=i;
438 return 1;
439 }
440 else//we might test for other things first, like use or drop
441 {
442 if(item_dragged==-1)//we have to drag this item
443 {
444 item_dragged=i;
445 do_drag_item_sound();
446 }
447 }
448
449 return 1;
450 }
451 }
452 }
453 }
454 return 1;
455 }
456
457
display_quickbar_handler(window_info * win)458 static int display_quickbar_handler(window_info *win)
459 {
460 unsigned char str[80];
461 int y, i;
462 Uint32 _cur_time = SDL_GetTicks(); /* grab a snapshot of current time */
463 int xpos = -1;
464 const int scaled_2 = (int)(0.5 + win->current_scale * 2);
465 const int scaled_27 = (int)(0.5 + win->current_scale * 27);
466
467 update_shown_quickbar_slots(win);
468 check_for_swap_completion();
469
470 glEnable(GL_TEXTURE_2D);
471 glColor3f(1.0f,1.0f,1.0f);
472 //ok, now let's draw the objects...
473 for(i=shown_quickbar_slots-1;i>=0;i--)
474 {
475 if(item_list[i].quantity > 0)
476 {
477 float u_start,v_start,u_end,v_end;
478 int this_texture,cur_item,cur_pos;
479 int x_start,x_end,y_start,y_end, itmp;
480 float zoom;
481
482 // don't display an item that is in the proces of being moved after equipment swap
483 if (item_swap_in_progress(i))
484 continue;
485
486 //get the UV coordinates.
487 cur_item=item_list[i].image_id%25;
488 get_item_uv(cur_item, &u_start, &v_start, &u_end,
489 &v_end);
490
491 //get the x and y
492 cur_pos=item_list[i].pos;
493
494 x_start = scaled_2;
495 x_end = x_start + scaled_27;
496 y_start = item_quickbar_slot_size * (cur_pos % shown_quickbar_slots) + scaled_2;
497 y_end = y_start + scaled_27;
498
499 if(quickbar_dir != VERTICAL)
500 {
501 itmp = x_start; x_start = y_start; y_start = itmp;
502 itmp = x_end; x_end = y_end; y_end = itmp;
503 }
504
505 //get the texture this item belongs to
506 this_texture=get_items_texture(item_list[i].image_id/25);
507
508 bind_texture(this_texture);
509 glBegin(GL_QUADS);
510 draw_2d_thing(u_start,v_start,u_end,v_end,x_start,y_start,x_end,y_end);
511 glEnd();
512
513 if ((_cur_time - item_list_extra[i].slot_busy_start) < 250)
514 gray_out(x_start,y_start,item_quickbar_slot_size);
515
516 if (item_list[i].cooldown_time > _cur_time)
517 {
518 float cooldown = ((float)(item_list[i].cooldown_time - _cur_time)) / ((float)item_list[i].cooldown_rate);
519 float x_center = (x_start + x_end)*0.5f;
520 float y_center = (y_start + y_end)*0.5f;
521
522 if (cooldown < 0.0f)
523 cooldown = 0.0f;
524 else if (cooldown > 1.0f)
525 cooldown = 1.0f;
526
527 glDisable(GL_TEXTURE_2D);
528 glEnable(GL_BLEND);
529
530 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
531 glBegin(GL_TRIANGLE_FAN);
532 glColor4f(0.14f, 0.35f, 0.82f, 0.50f);
533
534 glVertex2f(x_center, y_center);
535
536 if (cooldown >= 0.875f) {
537 float t = tan(2.0f*M_PI*(1.0f - cooldown));
538 glVertex2f(t*x_end + (1.0f - t)*x_center, y_start);
539 glVertex2f(x_end, y_start);
540 glVertex2f(x_end, y_end);
541 glVertex2f(x_start, y_end);
542 glVertex2f(x_start, y_start);
543 } else if (cooldown >= 0.625f) {
544 float t = 0.5f + 0.5f*tan(2.0f*M_PI*(0.75f - cooldown));
545 glVertex2f(x_end, t*y_end + (1.0f - t)*y_start);
546 glVertex2f(x_end, y_end);
547 glVertex2f(x_start, y_end);
548 glVertex2f(x_start, y_start);
549 } else if (cooldown >= 0.375f) {
550 float t = 0.5f + 0.5f*tan(2.0f*M_PI*(0.5f - cooldown));
551 glVertex2f(t*x_start + (1.0f - t)*x_end, y_end);
552 glVertex2f(x_start, y_end);
553 glVertex2f(x_start, y_start);
554 } else if (cooldown >= 0.125f) {
555 float t = 0.5f + 0.5f*tan(2.0f*M_PI*(0.25f - cooldown));
556 glVertex2f(x_start, t*y_start + (1.0f - t)*y_end);
557 glVertex2f(x_start, y_start);
558 } else {
559 float t = tan(2.0f*M_PI*(cooldown));
560 glVertex2f(t*x_start + (1.0f - t)*x_center, y_start);
561 }
562
563 glVertex2f(x_center, y_start);
564 glEnd();
565
566 glDisable(GL_BLEND);
567 glEnable(GL_TEXTURE_2D);
568 }
569
570 safe_snprintf((char*)str, sizeof(str), "%d", item_list[i].quantity);
571 xpos = x_start;
572 zoom = (mouseover_quickbar_item_pos == i && enlarge_text())
573 ? win->current_scale : win->current_scale_small;
574 if (quickbar_dir==VERTICAL)
575 {
576 int lenstr = get_string_width_zoom(str, win->font_category, zoom);
577 xpos = min2i(xpos, window_width - win->cur_x - lenstr);
578 }
579
580 draw_text(xpos, y_end, str, strlen((const char*)str), win->font_category, TDO_SHADOW, 1,
581 TDO_FOREGROUND, 1.0, 1.0, 1.0, TDO_BACKGROUND, 0.0, 0.0, 0.0, TDO_ZOOM, zoom,
582 TDO_VERTICAL_ALIGNMENT, BOTTOM_LINE, TDO_END);
583 }
584 }
585 mouseover_quickbar_item_pos = -1;
586
587 // Render the grid *after* the images. It seems impossible to code
588 // it such that images are rendered exactly within the boxes on all
589 // cards
590 glDisable(GL_TEXTURE_2D);
591 glBegin(GL_LINES);
592 use_window_color(win->window_id, ELW_COLOR_LINE);
593 //draw the grid
594 if(quickbar_dir==VERTICAL)
595 {
596 for(y=1;y<shown_quickbar_slots;y++)
597 {
598 glVertex3i(0, y*item_quickbar_slot_size+1, 0);
599 glVertex3i(item_quickbar_slot_size, y*item_quickbar_slot_size+1, 0);
600 }
601 }
602 else
603 {
604 for(y=1;y<shown_quickbar_slots;y++)
605 {
606 glVertex3i(y*item_quickbar_slot_size+1, 0, 0);
607 glVertex3i(y*item_quickbar_slot_size+1, item_quickbar_slot_size, 0);
608 }
609 }
610 glEnd();
611 glEnable(GL_TEXTURE_2D);
612 #ifdef OPENGL_TRACE
613 CHECK_GL_ERRORS();
614 #endif //OPENGL_TRACE
615
616 return 1;
617 }
618
619
ui_scale_quickbar_handler(window_info * win)620 static int ui_scale_quickbar_handler(window_info *win)
621 {
622 update_shown_quickbar_slots(win);
623 item_quickbar_slot_size = (int)(0.5 + win->current_scale * 30);
624 default_item_quickbar_x = window_width - item_quickbar_slot_size - 1;
625 default_item_quickbar_y = get_hud_logo_size();
626 if (!quickbar_relocatable)
627 reset_quickbar();
628 else
629 {
630 resize_item_quickbar_window(win->window_id);
631 if (win->cur_x > window_width || win->cur_y > window_height)
632 move_window(win->window_id, -1, 0, 100, 100);
633 }
634 update_shown_quickbar_slots(win);
635 return 1;
636 }
637
638
init_quickbar(void)639 void init_quickbar (void)
640 {
641 int quickbar_win = get_id_MW(MW_QUICKBAR);
642 Uint32 flags = ELW_USE_UISCALE | ELW_USE_BACKGROUND | ELW_USE_BORDER;
643
644 if (!quickbar_relocatable)
645 {
646 flags |= ELW_SHOW_LAST;
647 quickbar_draggable = 0;
648 }
649 if (quickbar_draggable)
650 flags |= ELW_TITLE_BAR | ELW_DRAGGABLE;
651
652 if (quickbar_win < 0)
653 {
654 quickbar_win = create_window ("Quickbar", -1, 0, get_pos_x_MW(MW_QUICKBAR), get_pos_y_MW(MW_QUICKBAR), 0, 0, flags);
655 if (quickbar_win < 0 || quickbar_win >= windows_list.num_windows)
656 return;
657 set_id_MW(MW_QUICKBAR, quickbar_win);
658
659 set_window_custom_scale(quickbar_win, MW_QUICKBAR);
660 ui_scale_quickbar_handler(&windows_list.window[quickbar_win]);
661
662 set_window_handler(quickbar_win, ELW_HANDLER_DISPLAY, &display_quickbar_handler);
663 set_window_handler(quickbar_win, ELW_HANDLER_CLICK, &click_quickbar_handler);
664 set_window_handler(quickbar_win, ELW_HANDLER_MOUSEOVER, &mouseover_quickbar_handler );
665 set_window_handler(quickbar_win, ELW_HANDLER_UI_SCALE, &ui_scale_quickbar_handler );
666
667 cm_quickbar_id = cm_create(cm_quickbar_menu_str, context_quickbar_handler);
668 cm_set_pre_show_handler(cm_quickbar_id, cm_quickbar_pre_show_handler);
669 cm_bool_line(cm_quickbar_id, CMQB_RELOC, &quickbar_relocatable, "relocate_quickbar");
670 cm_bool_line(cm_quickbar_id, CMQB_DRAG, &quickbar_draggable, NULL);
671 cm_bool_line(cm_quickbar_id, CMQB_ENABLE, &cm_quickbar_enabled, NULL);
672 }
673 else
674 {
675 change_flags (quickbar_win, flags);
676 ui_scale_quickbar_handler(&windows_list.window[quickbar_win]);
677 show_window (quickbar_win);
678 }
679 }
680
681
682 // try to use or auto equip the item in the slot
quick_use(int use_id,size_t * timer)683 static void quick_use(int use_id, size_t *timer)
684 {
685 Uint8 quick_use_str[3];
686 int i;
687
688 for(i=0; i<ITEM_NUM_ITEMS; i++)
689 {
690 if (item_list[i].pos==use_id)
691 {
692 if (item_list[i].quantity)
693 {
694 // its a usabale item so try to use it
695 if (item_list[i].use_with_inventory)
696 {
697 quick_use_str[0]= USE_INVENTORY_ITEM;
698 quick_use_str[1]= use_id;
699 quick_use_str[2]= i;
700 my_tcp_send(my_socket,quick_use_str,2);
701 used_item_counter_action_use(i);
702 #ifdef NEW_SOUND
703 item_list[i].action = USE_INVENTORY_ITEM;
704 #endif // NEW_SOUND
705 }
706 // this else catches all other item types, but is not used if we have recenly use the slot
707 // if the item type is not equipable, the server will tell us like it normally does
708 else if (!item_swap_in_progress(i) && ((SDL_GetTicks() - *timer) > 500))
709 {
710 *timer = SDL_GetTicks();
711 try_auto_equip(i);
712 }
713 // the slot will shown as busy for sort while
714 else
715 {
716 item_list_extra[i].slot_busy_start = SDL_GetTicks();
717 do_alert1_sound();
718 }
719 }
720 return;
721 }
722 }
723 }
724
725
726 // check if key is one of the item keys and use it if so.
action_item_keys(SDL_Keycode key_code,Uint16 key_mod)727 int action_item_keys(SDL_Keycode key_code, Uint16 key_mod)
728 {
729 size_t i;
730 el_key_def keys[] = {K_ITEM1, K_ITEM2, K_ITEM3, K_ITEM4, K_ITEM5, K_ITEM6,
731 K_ITEM7, K_ITEM8, K_ITEM9, K_ITEM10, K_ITEM11, K_ITEM12 };
732 static size_t timers[sizeof(keys)/sizeof(el_key_def)] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
733 for (i=0; i<sizeof(keys)/sizeof(el_key_def); i++)
734 if(KEY_DEF_CMP(keys[i], key_code, key_mod))
735 {
736 quick_use (i, &timers[i]);
737 return 1;
738 }
739 return 0;
740 }
741
742 // Limit external setting of the action mode: Called due to an action keypress or action icon in the icon window.
set_quickbar_action_mode(int new_mode)743 void set_quickbar_action_mode(int new_mode)
744 {
745 // Only change the action mode if is one used by the window.
746 if (!independant_quickbar_action_modes && ((new_mode == ACTION_WALK) || (new_mode == ACTION_LOOK) || (new_mode == ACTION_USE) || (new_mode == ACTION_USE_WITEM)))
747 qb_action_mode = new_mode;
748 }
749