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