1 #include <stdlib.h>
2 #include "trade.h"
3 #include "asc.h"
4 #include "cursors.h"
5 #include "elwindows.h"
6 #include "gamewin.h"
7 #include "hud.h"
8 #include "init.h"
9 #include "interface.h"
10 #include "items.h"
11 #include "item_info.h"
12 #include "manufacture.h"
13 #include "multiplayer.h"
14 #include "spells.h"
15 #include "storage.h"
16 #include "string.h"
17 #include "textures.h"
18 #include "trade_log.h"
19 #include "translate.h"
20 #ifdef OPENGL_TRACE
21 #include "gl_init.h"
22 #endif
23 #include "sound.h"
24 
25 #define ITEM_INVENTORY 1
26 #define ITEM_ROWS 4
27 #define ITEM_COLS 4
28 #define MAX_ITEMS (ITEM_COLS * ITEM_ROWS)
29 #define ITEM_INFO_ROWS 4
30 #define ITEM_BANK 2
31 
32 int trade_you_accepted=0;
33 int trade_other_accepted=0;
34 
35 static trade_item your_trade_list[MAX_ITEMS];
36 static trade_item others_trade_list[MAX_ITEMS];
37 static char other_player_trade_name[20];
38 static unsigned char items_string[350]={0};
39 static size_t last_items_string_id = 0;
40 static int no_view_my_items=0;
41 static int trade_border = 0;
42 static int trade_gridsize = 0;
43 static int trade_grid_start_y = 0;
44 static int button_x_left = 0;
45 static int button_x_right = 0;
46 static int button_y_top = 0;
47 static int button_y_bot = 0;
48 static const char *tool_tip_str = NULL;
49 static int mouse_over_your_trade_pos = -1;
50 static int mouse_over_others_trade_pos = -1;
51 static int show_abort_help=0;
52 static int storage_available=0;
53 
display_trade_handler(window_info * win)54 static int display_trade_handler(window_info *win)
55 {
56 	int x_off = 0;
57 	int i;
58 	char str[20];
59 
60 	//Draw the names in the accept boxes
61 
62 	if(trade_you_accepted==1){
63 		glColor3f(1.0f,1.0f,0.0f);
64 	} else if(trade_you_accepted==2){
65 		glColor3f(0.0f,1.0f,0.0f);
66 	} else {
67 		glColor3f(1.0f,0.0f,0.0f);
68 	}
69 
70 	x_off = trade_border + ITEM_COLS / 2 * trade_gridsize;
71 	draw_string_small_zoomed_centered(x_off, button_y_bot - win->default_font_len_y * 0.9, (unsigned char*)accept_str, 1, win->current_scale);
72 
73 	if(trade_other_accepted<=0){    // RED
74 		glColor3f(1.0f,0.0f,0.0f);
75 	} else if(trade_other_accepted==1){ // YELLOW
76 		glColor3f(1.0f,1.0f,0.0f);
77 	} else {    // all others default to GREEN
78 		glColor3f(0.0f,1.0f,0.0f);
79 	}
80 
81 	x_off = trade_border + (ITEM_COLS + 1) * trade_gridsize + ITEM_COLS / 2 * trade_gridsize;
82 	draw_string_small_zoomed_centered(x_off, button_y_bot - win->default_font_len_y * 0.9, (unsigned char*)accept_str, 1, win->current_scale);
83 
84 	glColor3fv(gui_color);
85 
86 	//Draw the trade session names
87 	x_off = trade_border + ITEM_COLS / 2 * trade_gridsize;
88 	draw_string_small_zoomed_centered(x_off, trade_grid_start_y - win->small_font_len_y, (unsigned char*)you_str, 1, win->current_scale);
89 	x_off = trade_border + (ITEM_COLS + 1) * trade_gridsize + ITEM_COLS / 2 * trade_gridsize;
90 	draw_string_small_zoomed_centered(x_off, trade_grid_start_y - win->small_font_len_y, (unsigned char*)other_player_trade_name, 1, win->current_scale);
91 
92 	glColor3f(1.0f,1.0f,1.0f);
93 
94 	//Now let's draw the goods on trade...
95 
96 	for(i=MAX_ITEMS-1; i>=0; --i){
97 		if(your_trade_list[i].quantity){
98 			GLfloat u_start, v_start, u_end, v_end;
99 			int x_start, x_end, y_start, y_end;
100 			int cur_item;
101 			GLuint this_texture;
102 			int y_text;
103 			float zoom;
104 			ver_alignment valign;
105 
106 			cur_item=your_trade_list[i].image_id%25;
107 			get_item_uv(cur_item, &u_start, &v_start, &u_end, &v_end);
108 			this_texture=get_items_texture(your_trade_list[i].image_id/25);
109 			if (this_texture != -1)
110 			{
111 				bind_texture(this_texture);
112 			}
113 
114 			x_start = trade_border + (i % ITEM_COLS) * trade_gridsize;
115 			x_end = x_start + trade_gridsize - 1;
116 			y_start= trade_grid_start_y + (i / ITEM_ROWS) * trade_gridsize;
117 			y_end = y_start + trade_gridsize - 1;
118 
119 			glBegin(GL_QUADS);
120 			draw_2d_thing(u_start,v_start,u_end,v_end,x_start,y_start,x_end,y_end);
121 			glEnd();
122 
123 			safe_snprintf(str, sizeof(str), "%i",your_trade_list[i].quantity);
124 			zoom = (mouse_over_your_trade_pos == i && enlarge_text())
125 				? win->current_scale : win->current_scale_small;
126 			if (i & 1)
127 			{
128 				y_text = y_start;
129 				valign = TOP_LINE;
130 			}
131 			else
132 			{
133 				y_text = y_end;
134 				valign = BOTTOM_LINE;
135 			}
136 			draw_text(x_start, y_text, (const unsigned char*)str, strlen(str), win->font_category,
137 				TDO_SHADOW, 1, TDO_FOREGROUND, 1.0, 1.0, 1.0, TDO_BACKGROUND, 0.0, 0.0, 0.0,
138 				TDO_ZOOM, zoom, TDO_VERTICAL_ALIGNMENT, valign, TDO_END);
139 			//by doing the images in reverse, you can't cover up the digits>4
140 			//also, by offsetting each one, numbers don't overwrite each other:
141 			//before: 123456 in one box and 56 in the other could allow
142 			//        1234                  56  which looks legitimate
143 			//now:    123456
144 			//            56 - the odd/even numbers are staggered
145 			//                 stopping potential scams
146 		}
147 	}
148 	mouse_over_your_trade_pos = -1;
149 
150 	for(i=MAX_ITEMS-1; i>=0; --i){
151 		if(others_trade_list[i].quantity){
152 			GLfloat u_start, v_start, u_end, v_end;
153 			int x_start, x_end, y_start, y_end;
154 			int cur_item;
155 			GLuint this_texture;
156 			int y_text;
157 			float zoom;
158 			ver_alignment valign;
159 
160 			cur_item=others_trade_list[i].image_id%25;
161 			get_item_uv(cur_item, &u_start, &v_start, &u_end, &v_end);
162 
163 			this_texture=get_items_texture(others_trade_list[i].image_id/25);
164 
165 			if (this_texture != -1)
166 			{
167 				bind_texture(this_texture);
168 			}
169 
170 			x_start = trade_border + (ITEM_COLS + 1) * trade_gridsize + (i % ITEM_COLS) * trade_gridsize;
171 			x_end = x_start + trade_gridsize - 1;
172 			y_start= trade_grid_start_y + (i / ITEM_ROWS) * trade_gridsize;
173 			y_end = y_start + trade_gridsize - 1;
174 
175 			glBegin(GL_QUADS);
176 			draw_2d_thing(u_start,v_start,u_end,v_end,x_start,y_start,x_end,y_end);
177 			glEnd();
178 
179 			safe_snprintf(str, sizeof(str), "%i",others_trade_list[i].quantity);
180 			zoom = (mouse_over_others_trade_pos == i && enlarge_text())
181 				? win->current_scale : win->current_scale_small;
182 			if (i & 1)
183 			{
184 				y_text = y_start;
185 				valign = TOP_LINE;
186 			}
187 			else
188 			{
189 				y_text = y_end;
190 				valign = BOTTOM_LINE;
191 			}
192 			draw_text(x_start, y_text, (const unsigned char*)str, strlen(str), win->font_category,
193 				TDO_SHADOW, 1, TDO_FOREGROUND, 1.0, 1.0, 1.0, TDO_BACKGROUND, 0.0, 0.0, 0.0,
194 				TDO_ZOOM, zoom, TDO_VERTICAL_ALIGNMENT, valign, TDO_END);
195 
196 			if(storage_available && others_trade_list[i].type==ITEM_BANK){
197 				str[0]='S';
198 				str[1]=0;
199 				if (i & 1)
200 				{
201 					y_text = y_end;
202 					valign = BOTTOM_LINE;
203 				}
204 				else
205 				{
206 					y_text = y_start;
207 					valign = TOP_LINE;
208 				}
209 				draw_text(x_end - win->small_font_max_len_x/2, y_text, (const unsigned char*)str, strlen(str), win->font_category,
210 					TDO_SHADOW, 1, TDO_FOREGROUND, 1.0, 1.0, 1.0, TDO_BACKGROUND, 0.0, 0.0, 0.0,
211 					TDO_ZOOM, win->current_scale_small, TDO_VERTICAL_ALIGNMENT, valign, TDO_ALIGNMENT, RIGHT, TDO_END);
212 			}
213 		}
214 	}
215 	mouse_over_others_trade_pos = -1;
216 
217 	glDisable(GL_TEXTURE_2D);
218 
219 	glColor3fv(gui_color);
220 	// grids for goods on trade
221 	rendergrid (ITEM_COLS, ITEM_ROWS, trade_border, trade_grid_start_y, trade_gridsize, trade_gridsize);
222 	rendergrid (ITEM_COLS, ITEM_ROWS, trade_border + (ITEM_COLS + 1) * trade_gridsize, trade_grid_start_y, trade_gridsize, trade_gridsize);
223 
224 	// Accept buttons
225 	glBegin (GL_LINE_LOOP);
226 		glVertex3i(button_x_left, button_y_top, 0);
227 		glVertex3i(button_x_right ,button_y_top, 0);
228 		glVertex3i(button_x_right, button_y_bot, 0);
229 		glVertex3i(button_x_left, button_y_bot, 0);
230 	glEnd ();
231 
232 	x_off = (ITEM_COLS + 1) * trade_gridsize;
233 	glBegin (GL_LINE_LOOP);
234 		glVertex3i(x_off + button_x_left, button_y_top, 0);
235 		glVertex3i(x_off + button_x_right ,button_y_top, 0);
236 		glVertex3i(x_off + button_x_right, button_y_bot, 0);
237 		glVertex3i(x_off + button_x_left, button_y_bot, 0);
238 	glEnd ();
239 
240 	//Draw the help text
241 	if(show_help_text && show_abort_help)
242 	{
243 		show_help_colored_scaled_centered((const unsigned char*)abort_str,
244 			win->len_x - win->box_size / 2, win->box_size + win->box_size/5,
245 			1.0f, 1.0f, 1.0f, win->current_scale);
246 	}
247 
248 	glEnable(GL_TEXTURE_2D);
249 
250 	//now, draw the inventory text, if any.
251 	if (last_items_string_id != inventory_item_string_id)
252 	{
253 		put_small_text_in_box_zoomed((unsigned char*)inventory_item_string,
254 			strlen(inventory_item_string), win->len_x - trade_border, items_string,
255 			win->current_scale);
256 		last_items_string_id = inventory_item_string_id;
257 	}
258 	draw_string_small_zoomed(trade_border/2, button_y_bot + trade_border, items_string,
259 		ITEM_INFO_ROWS, win->current_scale);
260 
261 	if (tool_tip_str != NULL)
262 	{
263 		show_help(tool_tip_str, 0, win->len_y+10, win->current_scale);
264 		tool_tip_str = NULL;
265 	}
266 
267 #ifdef OPENGL_TRACE
268 CHECK_GL_ERRORS();
269 #endif //OPENGL_TRACE
270 
271 	return 1;
272 }
273 
274 
click_trade_handler(window_info * win,int mx,int my,Uint32 flags)275 static int click_trade_handler(window_info *win, int mx, int my, Uint32 flags)
276 {
277 	Uint8 str[256];
278 	int left_click = flags & ELW_LEFT_MOUSE;
279 	int right_click = flags & ELW_RIGHT_MOUSE;
280 	int trade_quantity_storage_offset = 3; /* Offset of trade quantity in packet. Can be 3 or 4 */
281 
282 	if ( !(left_click || right_click) ) return 0;
283 
284 	if(right_click) {
285 		if ((item_dragged == -1) && (storage_item_dragged == -1) && is_gamewin_look_action()) {
286 			clear_gamewin_look_action();
287 			return 1;
288 		}
289 		if ((item_dragged != -1) || (storage_item_dragged != -1)) {
290 			item_dragged = storage_item_dragged = -1;
291 			return 1;
292 		}
293 	}
294 
295 	if(left_click && item_dragged!=-1){
296 		str[0]=PUT_OBJECT_ON_TRADE;
297 		str[1]=ITEM_INVENTORY;
298 		str[2]=item_list[item_dragged].pos;
299 		*((Uint32 *)(str+3))= SDL_SwapLE32(item_quantity);
300 		my_tcp_send(my_socket,str,7);
301 		do_drop_item_sound();
302 		return 1;
303 	} else if(storage_available && left_click && storage_item_dragged!=-1){
304 		str[0]=PUT_OBJECT_ON_TRADE;
305 		str[1]=ITEM_BANK;
306 		if ( storage_items[storage_item_dragged].pos > 255 ) {
307 			*((Uint16 *)(str+2))= SDL_SwapLE16(storage_items[storage_item_dragged].pos);
308 			trade_quantity_storage_offset++; /* Offset is 1 byte ahead now */
309 		} else {
310 			str[2]=storage_items[storage_item_dragged].pos;
311 		}
312 		*((Uint32 *)(str+trade_quantity_storage_offset))= SDL_SwapLE32(item_quantity);
313 		my_tcp_send(my_socket,str, 4 + trade_quantity_storage_offset );
314 		do_drop_item_sound();
315 		return 1;
316 	} else if(mx > trade_border && mx < trade_border + ITEM_COLS * trade_gridsize &&
317 				my > trade_grid_start_y && my < trade_grid_start_y + ITEM_ROWS * trade_gridsize){
318 		int pos=get_mouse_pos_in_grid (mx, my, ITEM_COLS, ITEM_ROWS, trade_border, trade_grid_start_y, trade_gridsize, trade_gridsize);
319 
320 		if (pos >= 0 && your_trade_list[pos].quantity)
321 		{
322 			if(right_click || is_gamewin_look_action()) {
323 				str[0]=LOOK_AT_TRADE_ITEM;
324 				str[1]=pos;
325 				str[2]=0;//your trade
326 				my_tcp_send(my_socket,str,3);
327 			} else {
328 				str[0]=REMOVE_OBJECT_FROM_TRADE;
329 				str[1]=pos;
330 				*((Uint32 *)(str+2))=SDL_SwapLE32(item_quantity);
331 				my_tcp_send(my_socket,str,6);
332 				do_drag_item_sound();
333 			}
334 		}
335 
336 		return 1;
337 	} else if(mx > trade_border + (ITEM_COLS + 1) * trade_gridsize && mx < trade_border + (ITEM_COLS * 2 + 1) * trade_gridsize &&
338 				trade_grid_start_y && my < trade_grid_start_y + ITEM_ROWS * trade_gridsize){
339 		int pos=get_mouse_pos_in_grid(mx, my, ITEM_COLS, ITEM_ROWS, trade_border + (ITEM_COLS + 1) * trade_gridsize, trade_grid_start_y,
340 			trade_gridsize, trade_gridsize);
341 
342 		if (pos >= 0 && others_trade_list[pos].quantity)
343 		{
344 			if(right_click || is_gamewin_look_action()){
345 				str[0]=LOOK_AT_TRADE_ITEM;
346 				str[1]=pos;
347 				str[2]=1;//their trade
348 				my_tcp_send(my_socket,str,3);
349 			} else if (left_click && storage_available){
350 				if(others_trade_list[pos].type==ITEM_BANK)
351 					others_trade_list[pos].type=ITEM_INVENTORY;
352 				else
353 					others_trade_list[pos].type=ITEM_BANK;
354 			}
355 		}
356 
357 		return 1;
358 	} else if(mx > button_x_left && mx < button_x_right && my > button_y_top && my < button_y_bot) {
359 		//check to see if we hit the Accept box
360 		if(trade_you_accepted==2 || right_click){
361 			str[0]= REJECT_TRADE;
362 			my_tcp_send(my_socket, str, 1);
363 			do_click_sound();
364 		} else {
365 			str[0]= ACCEPT_TRADE;
366 			if(trade_you_accepted==1){
367 				int i;
368 				for(i=0;i<MAX_ITEMS;i++){
369 					str[i+1]=(others_trade_list[i].quantity>0)*others_trade_list[i].type;
370 				}
371 				trade_accepted(other_player_trade_name, your_trade_list, others_trade_list, MAX_ITEMS);
372 			}
373 			my_tcp_send(my_socket, str, MAX_ITEMS + 1);
374 			do_click_sound();
375 		}
376 
377 		return 1;
378 	}
379 
380 	else if (my > button_y_bot + trade_border) {
381 		static Uint32 last_click = 0;
382 		if (safe_button_click(&last_click)) {
383 			set_shown_string(0,"");
384 			return 1;
385 		}
386 	}
387 
388 	return 1;
389 }
390 
mouseover_trade_handler(window_info * win,int mx,int my)391 static int mouseover_trade_handler(window_info *win, int mx, int my)
392 {
393 	int check_for_eye = 0;
394 	int pos = -1;
395 	trade_item *over_item = NULL;
396 
397 	if(mx > win->len_x - win->box_size && my < win->box_size)
398 		show_abort_help = 1;
399 	else
400 		show_abort_help = 0;
401 
402 	if (show_help_text && *inventory_item_string && (my > button_y_bot + trade_border))
403 	{
404 		tool_tip_str = (disable_double_click)?click_clear_str :double_click_clear_str;
405 		return 0;
406 	}
407 
408 	pos = get_mouse_pos_in_grid (mx, my, ITEM_COLS, ITEM_ROWS, trade_border, trade_grid_start_y, trade_gridsize, trade_gridsize);
409 	if (pos >= 0 && your_trade_list[pos].quantity)
410 	{
411 		over_item = &your_trade_list[pos];
412 		mouse_over_your_trade_pos = pos;
413 		check_for_eye = 1;
414 	}
415 	else {
416 		pos = get_mouse_pos_in_grid(mx, my, ITEM_COLS, ITEM_ROWS, trade_border + (ITEM_COLS + 1) * trade_gridsize, trade_grid_start_y,
417 			trade_gridsize, trade_gridsize);
418 		if (pos >= 0 && others_trade_list[pos].quantity)
419 		{
420 			over_item = &others_trade_list[pos];
421 			mouse_over_others_trade_pos = pos;
422 			check_for_eye = 1;
423 		}
424 	}
425 
426 	if (show_item_desc_text && (over_item != NULL) && item_info_available() && (get_item_count(over_item->id, over_item->image_id) == 1))
427 		tool_tip_str = get_item_description(over_item->id, over_item->image_id);
428 
429 	/* if we're over an occupied slot and the eye cursor function is active, show the eye cursor */
430 	if (check_for_eye && is_gamewin_look_action())
431 	{
432 		elwin_mouse = CURSOR_EYE;
433 		return 1;
434 	}
435 
436 	return 0;
437 }
438 
get_trade_partner_name(const Uint8 * player_name,int len)439 void get_trade_partner_name (const Uint8 *player_name, int len)
440 {
441 	int i;
442 
443 	storage_available = player_name[0];
444 
445 	for (i = 0; i+1 < len; i++)
446 		other_player_trade_name[i] = player_name[i+1];
447 	other_player_trade_name[i] = '\0';
448 }
449 
450 
get_your_trade_objects(const Uint8 * data)451 void get_your_trade_objects (const Uint8 *data)
452 {
453 	int i;
454 
455 	//clear the items first
456 	for(i = 0; i < MAX_ITEMS; i++)
457 		your_trade_list[i].quantity = 0;
458 	for(i = 0; i < MAX_ITEMS; i++)
459 		others_trade_list[i].quantity = 0;
460 
461 	no_view_my_items=1;
462 	get_your_items(data);
463 
464 	//reset the accepted flags too
465 	trade_you_accepted=0;
466 	trade_other_accepted=0;
467 
468 	//we have to close the manufacture window, otherwise bad things can happen.
469 	hide_window_MW(MW_MANU);
470 	hide_window_MW(MW_SPELLS);
471 	//Open the inventory window
472 	display_items_menu();
473 	view_window(MW_TRADE);
474 }
475 
put_item_on_trade(const Uint8 * data)476 void put_item_on_trade (const Uint8 *data)
477 {
478 	int pos;
479 
480 	pos=data[7];
481 	if (pos >= MAX_ITEMS)
482 		return;
483 	if(!data[8])
484 	{
485 		your_trade_list[pos].image_id=SDL_SwapLE16(*((Uint16 *)(data)));
486 		your_trade_list[pos].quantity+=SDL_SwapLE32(*((Uint32 *)(data+2)));
487 		your_trade_list[pos].type=data[6];
488 		if (item_uid_enabled)
489 			your_trade_list[pos].id=SDL_SwapLE16(*((Uint16 *)(data+9)));
490 		else
491 			your_trade_list[pos].id=unset_item_uid;
492 	}
493 	else
494 	{
495 		others_trade_list[pos].image_id=SDL_SwapLE16(*((Uint16 *)(data)));
496 		others_trade_list[pos].quantity+=SDL_SwapLE32(*((Uint32 *)(data+2)));
497 		others_trade_list[pos].type=data[6];
498 		if (item_uid_enabled)
499 			others_trade_list[pos].id=SDL_SwapLE16(*((Uint16 *)(data+9)));
500 		else
501 			others_trade_list[pos].id=unset_item_uid;
502 	}
503 }
504 
remove_item_from_trade(const Uint8 * data)505 void remove_item_from_trade (const Uint8 *data)
506 {
507 	int pos;
508 	int quantity;
509 
510 	pos=data[4];
511 	if (pos >= MAX_ITEMS)
512 		return;
513 	quantity=SDL_SwapLE32(*((Uint32 *)(data)));
514 
515 	if(!data[5])
516 	{
517 		your_trade_list[pos].quantity-=quantity;
518 	}
519 	else
520 	{
521 		others_trade_list[pos].quantity-=quantity;
522 	}
523 }
524 
ui_scale_trade_handler(window_info * win)525 static int ui_scale_trade_handler(window_info *win)
526 {
527 	int len_x = 0;
528 	int len_y = 0;
529 
530 	last_items_string_id = 0;
531 	trade_border = (int)(0.5 + win->current_scale * 10);
532 	trade_gridsize = (int)(0.5 + win->current_scale * 33);
533 	trade_grid_start_y = trade_border + win->box_size;
534 
535 	button_x_left = trade_border + trade_gridsize;
536 	button_x_right = button_x_left + (ITEM_COLS - 2) * trade_gridsize;
537 	button_y_top = trade_grid_start_y + trade_gridsize * ITEM_ROWS + trade_border;
538 	button_y_bot = button_y_top + win->default_font_len_y;
539 
540 	len_x = (ITEM_COLS * 2 + 1) * trade_gridsize + 2 * trade_border;
541 	len_y = button_y_bot + win->small_font_len_y * ITEM_INFO_ROWS + trade_border * 1.5;
542 
543 	resize_window(win->window_id, len_x, len_y);
544 
545 	return 1;
546 }
547 
close_trade_handler(window_info * win)548 static int close_trade_handler(window_info *win)
549 {
550 	// User click the close button, abort the trade
551 	unsigned char msg = EXIT_TRADE;
552 	my_tcp_send(my_socket, &msg, 1);
553 	return 1;
554 }
555 
display_trade_menu()556 void display_trade_menu()
557 {
558 	int trade_win = get_id_MW(MW_TRADE);
559 
560 	if(trade_win < 0){
561 		trade_win = create_window(win_trade, (not_on_top_now(MW_TRADE) ?game_root_win : -1), 0,
562 			get_pos_x_MW(MW_TRADE), get_pos_y_MW(MW_TRADE), 0, 0, ELW_USE_UISCALE|ELW_WIN_DEFAULT);
563 		set_id_MW(MW_TRADE, trade_win);
564 
565 		set_window_custom_scale(trade_win, MW_TRADE);
566 		set_window_handler(trade_win, ELW_HANDLER_DISPLAY, &display_trade_handler );
567 		set_window_handler(trade_win, ELW_HANDLER_CLICK, &click_trade_handler );
568 		set_window_handler(trade_win, ELW_HANDLER_MOUSEOVER, &mouseover_trade_handler );
569 		set_window_handler(trade_win, ELW_HANDLER_CLOSE, &close_trade_handler );
570 		set_window_handler(trade_win, ELW_HANDLER_UI_SCALE, &ui_scale_trade_handler );
571 
572 		if (trade_win >= 0 && trade_win < windows_list.num_windows)
573 			ui_scale_trade_handler(&windows_list.window[trade_win]);
574 		check_proportional_move(MW_TRADE);
575 
576 	} else {
577 		show_window(trade_win);
578 		select_window(trade_win);
579 	}
580 }
581