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