1 /*
2 * Crossfire -- cooperative multi-player graphical RPG and adventure game
3 *
4 * Copyright (c) 1999-2013 Mark Wedel and the Crossfire Development Team
5 * Copyright (c) 1992 Frank Tore Johansen
6 *
7 * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8 * welcome to redistribute it under certain conditions. For details, see the
9 * 'LICENSE' and 'COPYING' files.
10 *
11 * The authors can be reached via e-mail to crossfire-devel@real-time.com
12 */
13
14 /**
15 * @file
16 * This file covers the pickup menu items. We only implement the new pickup
17 * code - it seems to me that it should be able to cover everything the old
18 * pickup mode does.
19 */
20
21 #include "client.h"
22
23 #include <gtk/gtk.h>
24
25 #include "main.h"
26 #include "image.h"
27 #include "gtk2proto.h"
28
29 typedef struct {
30 GtkWidget *menuitem;
31 guint32 pickup_mode;
32 } PickupMapping;
33
34 #define MAX_PICKUPS 50
35
36 PickupMapping pickup_mapping[MAX_PICKUPS];
37 static int num_pickups=0;
38
39 /*
40 * Definitions for detailed pickup descriptions. The objective is to define
41 * intelligent groups of items that the user can pick up or leave as he likes.
42 */
43
44 /* High bit as flag for new pickup options */
45 #define PU_NOTHING 0x00000000
46
47 #define PU_DEBUG 0x10000000
48 #define PU_INHIBIT 0x20000000
49 #define PU_STOP 0x40000000
50 #define PU_NEWMODE 0x80000000
51
52 #define PU_RATIO 0x0000000F
53
54 #define PU_FOOD 0x00000010
55 #define PU_DRINK 0x00000020
56 #define PU_VALUABLES 0x00000040
57 #define PU_BOW 0x00000080
58
59 #define PU_ARROW 0x00000100
60 #define PU_HELMET 0x00000200
61 #define PU_SHIELD 0x00000400
62 #define PU_ARMOUR 0x00000800
63
64 #define PU_BOOTS 0x00001000
65 #define PU_GLOVES 0x00002000
66 #define PU_CLOAK 0x00004000
67 #define PU_KEY 0x00008000
68
69 #define PU_MISSILEWEAPON 0x00010000
70 #define PU_ALLWEAPON 0x00020000
71 #define PU_MAGICAL 0x00040000
72 #define PU_POTION 0x00080000
73
74 #define PU_SPELLBOOK 0x00100000
75 #define PU_SKILLSCROLL 0x00200000
76 #define PU_READABLES 0x00400000
77 #define PU_MAGIC_DEVICE 0x00800000
78
79 #define PU_NOT_CURSED 0x01000000
80 #define PU_JEWELS 0x02000000
81 #define PU_FLESH 0x04000000
82 #define PU_CONTAINERS 0x08000000
83
84 static unsigned int pmode=0, no_recurse=0;
85
86 /**
87 * Handles the pickup operations. Unfortunately, it isn't easy (possible?)
88 * in layout to attach values to the menu items.
89 *
90 * @param on is TRUE if the button is activated, 0 if it is off.
91 * @param val is the PU_ bitmasks to set/clear.
92 */
new_menu_pickup(int on,int val)93 static void new_menu_pickup(int on, int val)
94 {
95 char modestr[128];
96
97 if (no_recurse) {
98 return;
99 }
100
101 if (on) {
102 pmode |= val | PU_NEWMODE;
103 } else {
104 pmode &= ~val;
105 }
106
107 draw_ext_info(NDI_BLACK, MSG_TYPE_CLIENT, MSG_TYPE_CLIENT_NOTICE,
108 "To set this pickup mode to a key, use:");
109
110 snprintf(modestr, sizeof(modestr), "bind pickup %u",pmode);
111 draw_ext_info(NDI_BLACK, MSG_TYPE_CLIENT, MSG_TYPE_CLIENT_NOTICE, modestr);
112 snprintf(modestr, sizeof(modestr), "pickup %u",pmode);
113 send_command(modestr, -1, 0);
114 }
115
116 void
on_menu_dont_pickup_activate(GtkMenuItem * menuitem,gpointer user_data)117 on_menu_dont_pickup_activate (GtkMenuItem *menuitem,
118 gpointer user_data)
119 {
120 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_INHIBIT);
121 }
122
123 void
on_menu_stop_before_pickup_activate(GtkMenuItem * menuitem,gpointer user_data)124 on_menu_stop_before_pickup_activate (GtkMenuItem *menuitem,
125 gpointer user_data)
126 {
127 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_STOP);
128 }
129
130 /***************************************************************************
131 * armor pickup options
132 **************************************************************************/
133
134 void
on_menu_body_armor_activate(GtkMenuItem * menuitem,gpointer user_data)135 on_menu_body_armor_activate (GtkMenuItem *menuitem,
136 gpointer user_data)
137 {
138 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_ARMOUR);
139 }
140
141 void
on_menu_boots_activate(GtkMenuItem * menuitem,gpointer user_data)142 on_menu_boots_activate (GtkMenuItem *menuitem,
143 gpointer user_data)
144 {
145 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_BOOTS);
146 }
147
148 void
on_menu_cloaks_activate(GtkMenuItem * menuitem,gpointer user_data)149 on_menu_cloaks_activate (GtkMenuItem *menuitem,
150 gpointer user_data)
151 {
152 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_CLOAK);
153 }
154
155 void
on_menu_gloves_activate(GtkMenuItem * menuitem,gpointer user_data)156 on_menu_gloves_activate (GtkMenuItem *menuitem,
157 gpointer user_data)
158 {
159 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_GLOVES);
160 }
161
162 void
on_menu_helmets_activate(GtkMenuItem * menuitem,gpointer user_data)163 on_menu_helmets_activate (GtkMenuItem *menuitem,
164 gpointer user_data)
165 {
166 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_HELMET);
167 }
168
169 void
on_menu_shields_activate(GtkMenuItem * menuitem,gpointer user_data)170 on_menu_shields_activate (GtkMenuItem *menuitem,
171 gpointer user_data)
172 {
173 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_SHIELD);
174 }
175
176 /***************************************************************************
177 * Books submenu
178 ****************************************************************************/
179
180 void
on_menu_skillscrolls_activate(GtkMenuItem * menuitem,gpointer user_data)181 on_menu_skillscrolls_activate (GtkMenuItem *menuitem,
182 gpointer user_data)
183 {
184 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_SKILLSCROLL);
185 }
186
187
188 void
on_menu_normal_book_scrolls_activate(GtkMenuItem * menuitem,gpointer user_data)189 on_menu_normal_book_scrolls_activate (GtkMenuItem *menuitem,
190 gpointer user_data)
191 {
192 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_READABLES);
193 }
194
195
196 void
on_menu_spellbooks_activate(GtkMenuItem * menuitem,gpointer user_data)197 on_menu_spellbooks_activate (GtkMenuItem *menuitem,
198 gpointer user_data)
199 {
200 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_SPELLBOOK);
201 }
202
203 /***************************************************************************/
204
205 void
on_menu_drinks_activate(GtkMenuItem * menuitem,gpointer user_data)206 on_menu_drinks_activate (GtkMenuItem *menuitem,
207 gpointer user_data)
208 {
209 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_DRINK);
210 }
211
212 void
on_menu_food_activate(GtkMenuItem * menuitem,gpointer user_data)213 on_menu_food_activate (GtkMenuItem *menuitem,
214 gpointer user_data)
215 {
216 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_FOOD);
217 }
218
219 void
on_menu_keys_activate(GtkMenuItem * menuitem,gpointer user_data)220 on_menu_keys_activate (GtkMenuItem *menuitem,
221 gpointer user_data)
222 {
223 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_KEY);
224 }
225
226 void
on_menu_magical_items_activate(GtkMenuItem * menuitem,gpointer user_data)227 on_menu_magical_items_activate (GtkMenuItem *menuitem,
228 gpointer user_data)
229 {
230 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_MAGICAL);
231 }
232
233 void
on_menu_potions_activate(GtkMenuItem * menuitem,gpointer user_data)234 on_menu_potions_activate (GtkMenuItem *menuitem,
235 gpointer user_data)
236 {
237 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_POTION);
238 }
239
240 void
on_menu_valuables_activate(GtkMenuItem * menuitem,gpointer user_data)241 on_menu_valuables_activate (GtkMenuItem *menuitem,
242 gpointer user_data)
243 {
244 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_VALUABLES);
245 }
246
247 void
on_menu_wands_rods_horns_activate(GtkMenuItem * menuitem,gpointer user_data)248 on_menu_wands_rods_horns_activate (GtkMenuItem *menuitem,
249 gpointer user_data)
250 {
251 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_MAGIC_DEVICE);
252 }
253
254 void
on_menu_not_cursed_activate(GtkMenuItem * menuitem,gpointer user_data)255 on_menu_not_cursed_activate (GtkMenuItem *menuitem,
256 gpointer user_data)
257 {
258 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_NOT_CURSED);
259 }
260
261 void
on_menu_jewels_activate(GtkMenuItem * menuitem,gpointer user_data)262 on_menu_jewels_activate (GtkMenuItem *menuitem,
263 gpointer user_data)
264 {
265 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_JEWELS);
266 }
267
268 void
on_menu_containers_activate(GtkMenuItem * menuitem,gpointer user_data)269 on_menu_containers_activate (GtkMenuItem *menuitem,
270 gpointer user_data)
271 {
272 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_CONTAINERS);
273 }
274
275 void
on_menu_flesh_activate(GtkMenuItem * menuitem,gpointer user_data)276 on_menu_flesh_activate (GtkMenuItem *menuitem,
277 gpointer user_data)
278 {
279 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_FLESH);
280 }
281
282 /***************************************************************************
283 * Weapons submenu
284 ***************************************************************************/
285
286 void
on_menu_all_weapons_activate(GtkMenuItem * menuitem,gpointer user_data)287 on_menu_all_weapons_activate (GtkMenuItem *menuitem,
288 gpointer user_data)
289 {
290 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_ALLWEAPON);
291 }
292
293 void
on_menu_missile_weapons_activate(GtkMenuItem * menuitem,gpointer user_data)294 on_menu_missile_weapons_activate (GtkMenuItem *menuitem,
295 gpointer user_data)
296 {
297 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_MISSILEWEAPON);
298 }
299
300 void
on_menu_bows_activate(GtkMenuItem * menuitem,gpointer user_data)301 on_menu_bows_activate (GtkMenuItem *menuitem,
302 gpointer user_data)
303 {
304 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_BOW);
305 }
306
307 void
on_menu_arrows_activate(GtkMenuItem * menuitem,gpointer user_data)308 on_menu_arrows_activate (GtkMenuItem *menuitem,
309 gpointer user_data)
310 {
311 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), PU_ARROW);
312 }
313
314 /***************************************************************************
315 * Weight/value submenu
316 ***************************************************************************/
317
318 void
on_menu_ratio_pickup_off_activate(GtkMenuItem * menuitem,gpointer user_data)319 on_menu_ratio_pickup_off_activate (GtkMenuItem *menuitem,
320 gpointer user_data)
321 {
322 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), 0);
323 }
324
325 void
on_menu_ratio_5_activate(GtkMenuItem * menuitem,gpointer user_data)326 on_menu_ratio_5_activate (GtkMenuItem *menuitem,
327 gpointer user_data)
328 {
329 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), 1);
330 }
331
332 void
on_menu_ratio_10_activate(GtkMenuItem * menuitem,gpointer user_data)333 on_menu_ratio_10_activate (GtkMenuItem *menuitem,
334 gpointer user_data)
335 {
336 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), 2);
337 }
338
339 void
on_menu_ratio_15_activate(GtkMenuItem * menuitem,gpointer user_data)340 on_menu_ratio_15_activate (GtkMenuItem *menuitem,
341 gpointer user_data)
342 {
343 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), 3);
344 }
345
346 void
on_menu_ratio_20_activate(GtkMenuItem * menuitem,gpointer user_data)347 on_menu_ratio_20_activate (GtkMenuItem *menuitem,
348 gpointer user_data)
349 {
350 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), 4);
351 }
352
353 void
on_menu_ratio_25_activate(GtkMenuItem * menuitem,gpointer user_data)354 on_menu_ratio_25_activate (GtkMenuItem *menuitem,
355 gpointer user_data)
356 {
357 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), 5);
358 }
359
360 void
on_menu_ratio_30_activate(GtkMenuItem * menuitem,gpointer user_data)361 on_menu_ratio_30_activate (GtkMenuItem *menuitem,
362 gpointer user_data)
363 {
364 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), 6);
365 }
366
367 void
on_menu_ratio_35_activate(GtkMenuItem * menuitem,gpointer user_data)368 on_menu_ratio_35_activate (GtkMenuItem *menuitem,
369 gpointer user_data)
370 {
371 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), 7);
372 }
373
374 void
on_menu_ratio_40_activate(GtkMenuItem * menuitem,gpointer user_data)375 on_menu_ratio_40_activate (GtkMenuItem *menuitem,
376 gpointer user_data)
377 {
378 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), 8);
379 }
380
381 void
on_menu_ratio_45_activate(GtkMenuItem * menuitem,gpointer user_data)382 on_menu_ratio_45_activate (GtkMenuItem *menuitem,
383 gpointer user_data)
384 {
385 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), 9);
386 }
387
388 void
on_menu_ratio_50_activate(GtkMenuItem * menuitem,gpointer user_data)389 on_menu_ratio_50_activate (GtkMenuItem *menuitem,
390 gpointer user_data)
391 {
392 new_menu_pickup(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)), 10);
393 }
394
395 /**
396 * Maps the menuitem lists into pickup values. In this way, client_pickup
397 * knows what values to change.
398 *
399 * @param window_root
400 */
pickup_init(GtkWidget * window_root)401 void pickup_init(GtkWidget *window_root)
402 {
403 static int has_init=0;
404
405 /*
406 * There isn't really any harm doing this multiple times, but isn't any
407 * point either.
408 */
409 if (has_init) {
410 return;
411 }
412 has_init=1;
413
414 /*
415 * The order here really doesn't make much difference. I suppose order
416 * could either be in pickup modes (PU_...) or the list of items in the
417 * menu tree. I chose the later, as easier to make sure all the items are
418 * accounted for.
419 *
420 * In practice, with these values now set up, we could use a single
421 * function to hande all the events from the menubar instead of the values
422 * above - that function basically takes the structure that was clicked,
423 * and finds the value in this array that corresponds to it. But that code
424 * currently works fine and isn't really outdated, so isn't a big reason to
425 * change it.
426 */
427
428 pickup_mapping[num_pickups].menuitem =
429 GTK_WIDGET(gtk_builder_get_object(window_xml, "do_not_pickup"));
430 pickup_mapping[num_pickups].pickup_mode = PU_INHIBIT;
431 num_pickups++;
432
433 pickup_mapping[num_pickups].menuitem =
434 GTK_WIDGET(gtk_builder_get_object(window_xml, "stop_before_pickup"));
435 pickup_mapping[num_pickups].pickup_mode = PU_STOP;
436 num_pickups++;
437
438 pickup_mapping[num_pickups].menuitem =
439 GTK_WIDGET(gtk_builder_get_object(window_xml, "body_armor"));
440 pickup_mapping[num_pickups].pickup_mode = PU_ARMOUR;
441 num_pickups++;
442
443 pickup_mapping[num_pickups].menuitem =
444 GTK_WIDGET(gtk_builder_get_object(window_xml, "boots"));
445 pickup_mapping[num_pickups].pickup_mode = PU_BOOTS;
446 num_pickups++;
447
448 pickup_mapping[num_pickups].menuitem =
449 GTK_WIDGET(gtk_builder_get_object(window_xml, "cloaks"));
450 pickup_mapping[num_pickups].pickup_mode = PU_CLOAK;
451 num_pickups++;
452
453 pickup_mapping[num_pickups].menuitem =
454 GTK_WIDGET(gtk_builder_get_object(window_xml, "gloves"));
455 pickup_mapping[num_pickups].pickup_mode = PU_GLOVES;
456 num_pickups++;
457
458 pickup_mapping[num_pickups].menuitem =
459 GTK_WIDGET(gtk_builder_get_object(window_xml, "helmets"));
460 pickup_mapping[num_pickups].pickup_mode = PU_HELMET;
461 num_pickups++;
462
463 pickup_mapping[num_pickups].menuitem =
464 GTK_WIDGET(gtk_builder_get_object(window_xml, "shields"));
465 pickup_mapping[num_pickups].pickup_mode = PU_SHIELD;
466 num_pickups++;
467
468 pickup_mapping[num_pickups].menuitem =
469 GTK_WIDGET(gtk_builder_get_object(window_xml, "skillscrolls"));
470 pickup_mapping[num_pickups].pickup_mode = PU_SKILLSCROLL;
471 num_pickups++;
472
473 pickup_mapping[num_pickups].menuitem =
474 GTK_WIDGET(gtk_builder_get_object(window_xml, "normal_book_scrolls"));
475 pickup_mapping[num_pickups].pickup_mode = PU_READABLES;
476 num_pickups++;
477
478 pickup_mapping[num_pickups].menuitem =
479 GTK_WIDGET(gtk_builder_get_object(window_xml, "spellbooks"));
480 pickup_mapping[num_pickups].pickup_mode = PU_SPELLBOOK;
481 num_pickups++;
482
483 pickup_mapping[num_pickups].menuitem =
484 GTK_WIDGET(gtk_builder_get_object(window_xml, "drinks"));
485 pickup_mapping[num_pickups].pickup_mode = PU_DRINK;
486 num_pickups++;
487
488 pickup_mapping[num_pickups].menuitem =
489 GTK_WIDGET(gtk_builder_get_object(window_xml, "food"));
490 pickup_mapping[num_pickups].pickup_mode = PU_FOOD;
491 num_pickups++;
492
493 pickup_mapping[num_pickups].menuitem =
494 GTK_WIDGET(gtk_builder_get_object(window_xml, "flesh"));
495 pickup_mapping[num_pickups].pickup_mode = PU_FLESH;
496 num_pickups++;
497
498 pickup_mapping[num_pickups].menuitem =
499 GTK_WIDGET(gtk_builder_get_object(window_xml, "keys"));
500 pickup_mapping[num_pickups].pickup_mode = PU_KEY;
501 num_pickups++;
502
503 pickup_mapping[num_pickups].menuitem =
504 GTK_WIDGET(gtk_builder_get_object(window_xml, "magical_items"));
505 pickup_mapping[num_pickups].pickup_mode = PU_MAGICAL;
506 num_pickups++;
507
508 pickup_mapping[num_pickups].menuitem =
509 GTK_WIDGET(gtk_builder_get_object(window_xml, "potions"));
510 pickup_mapping[num_pickups].pickup_mode = PU_POTION;
511 num_pickups++;
512
513 pickup_mapping[num_pickups].menuitem =
514 GTK_WIDGET(gtk_builder_get_object(window_xml, "valuables"));
515 pickup_mapping[num_pickups].pickup_mode = PU_VALUABLES;
516 num_pickups++;
517
518 pickup_mapping[num_pickups].menuitem =
519 GTK_WIDGET(gtk_builder_get_object(window_xml, "wands_rods_horns"));
520 pickup_mapping[num_pickups].pickup_mode = PU_MAGIC_DEVICE;
521 num_pickups++;
522
523 pickup_mapping[num_pickups].menuitem =
524 GTK_WIDGET(gtk_builder_get_object(window_xml, "jewels"));
525 pickup_mapping[num_pickups].pickup_mode = PU_JEWELS;
526 num_pickups++;
527
528 pickup_mapping[num_pickups].menuitem =
529 GTK_WIDGET(gtk_builder_get_object(window_xml, "containers"));
530 pickup_mapping[num_pickups].pickup_mode = PU_CONTAINERS;
531 num_pickups++;
532
533 pickup_mapping[num_pickups].menuitem =
534 GTK_WIDGET(gtk_builder_get_object(window_xml, "all_weapons"));
535 pickup_mapping[num_pickups].pickup_mode = PU_ALLWEAPON;
536 num_pickups++;
537
538 pickup_mapping[num_pickups].menuitem =
539 GTK_WIDGET(gtk_builder_get_object(window_xml, "missile_weapons"));
540 pickup_mapping[num_pickups].pickup_mode = PU_MISSILEWEAPON;
541 num_pickups++;
542
543 pickup_mapping[num_pickups].menuitem =
544 GTK_WIDGET(gtk_builder_get_object(window_xml, "bows"));
545 pickup_mapping[num_pickups].pickup_mode = PU_BOW;
546 num_pickups++;
547
548 pickup_mapping[num_pickups].menuitem =
549 GTK_WIDGET(gtk_builder_get_object(window_xml, "arrows"));
550 pickup_mapping[num_pickups].pickup_mode = PU_ARROW;
551 num_pickups++;
552
553 pickup_mapping[num_pickups].menuitem =
554 GTK_WIDGET(gtk_builder_get_object(window_xml, "ratio_pickup_off"));
555 pickup_mapping[num_pickups].pickup_mode = ~PU_RATIO;
556 num_pickups++;
557
558 pickup_mapping[num_pickups].menuitem =
559 GTK_WIDGET(gtk_builder_get_object(window_xml, "ratio_5"));
560 pickup_mapping[num_pickups].pickup_mode = 1;
561 num_pickups++;
562
563 pickup_mapping[num_pickups].menuitem =
564 GTK_WIDGET(gtk_builder_get_object(window_xml, "ratio_10"));
565 pickup_mapping[num_pickups].pickup_mode = 2;
566 num_pickups++;
567
568 pickup_mapping[num_pickups].menuitem =
569 GTK_WIDGET(gtk_builder_get_object(window_xml, "ratio_15"));
570 pickup_mapping[num_pickups].pickup_mode = 3;
571 num_pickups++;
572
573 pickup_mapping[num_pickups].menuitem =
574 GTK_WIDGET(gtk_builder_get_object(window_xml, "ratio_20"));
575 pickup_mapping[num_pickups].pickup_mode = 4;
576 num_pickups++;
577
578 pickup_mapping[num_pickups].menuitem =
579 GTK_WIDGET(gtk_builder_get_object(window_xml, "ratio_25"));
580 pickup_mapping[num_pickups].pickup_mode = 5;
581 num_pickups++;
582
583 pickup_mapping[num_pickups].menuitem =
584 GTK_WIDGET(gtk_builder_get_object(window_xml, "ratio_30"));
585 pickup_mapping[num_pickups].pickup_mode = 6;
586 num_pickups++;
587
588 pickup_mapping[num_pickups].menuitem =
589 GTK_WIDGET(gtk_builder_get_object(window_xml, "ratio_35"));
590 pickup_mapping[num_pickups].pickup_mode = 7;
591 num_pickups++;
592
593 pickup_mapping[num_pickups].menuitem =
594 GTK_WIDGET(gtk_builder_get_object(window_xml, "ratio_40"));
595 pickup_mapping[num_pickups].pickup_mode = 8;
596 num_pickups++;
597
598 pickup_mapping[num_pickups].menuitem =
599 GTK_WIDGET(gtk_builder_get_object(window_xml, "ratio_45"));
600 pickup_mapping[num_pickups].pickup_mode = 9;
601 num_pickups++;
602
603 pickup_mapping[num_pickups].menuitem =
604 GTK_WIDGET(gtk_builder_get_object(window_xml, "ratio_50"));
605 pickup_mapping[num_pickups].pickup_mode = 10;
606 num_pickups++;
607
608 pickup_mapping[num_pickups].menuitem =
609 GTK_WIDGET(gtk_builder_get_object(window_xml, "not_cursed"));
610 pickup_mapping[num_pickups].pickup_mode = PU_NOT_CURSED;
611 num_pickups++;
612
613 /*
614 * Do some bounds checking. We could actually set this exactly right,
615 * since additional menu entries are not likely to be added often. We exit
616 * because if we overrun that structure, we've screwed up memory and will
617 * likely crash or otherwise have odd behaviour.
618 */
619 if (num_pickups>=MAX_PICKUPS) {
620 LOG(LOG_ERROR, "pickup.c::pickup_init", "num_pickups (%d) >= MAX_PICKUPS (%d)\n",
621 num_pickups, MAX_PICKUPS);
622 exit(1);
623 }
624
625 }
626
627 /**
628 * We get pickup information from server, update our status.
629 */
client_pickup(guint32 pickup)630 void client_pickup(guint32 pickup)
631 {
632 int i;
633
634 /*
635 * no_recurse is used to limit callbacks - otherwise what happens is when
636 * we call set_active below, it emits the appropriate signal, which results
637 * in new_menu_pickup() getting called, which then sends a new pickup
638 * command to the server, which then results in server sending data to
639 * client, etc.
640 */
641 no_recurse=1;
642 pmode=pickup;
643
644 for (i=0; i < num_pickups; i++) {
645 if ((pickup & ~PU_RATIO) & pickup_mapping[i].pickup_mode ||
646 (pickup & PU_RATIO) == pickup_mapping[i].pickup_mode) {
647 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(pickup_mapping[i].menuitem), 1);
648 } else {
649 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(pickup_mapping[i].menuitem), 0);
650 }
651 }
652 no_recurse=0;
653 }
654