1 #include "c-angband.h"
2 #include "net-client.h"
3 #include "../common/md5.h"
4
5 char* item_prompt(cptr prompt, int item, int amt);
6
7 /* Handle custom commands */
8 #define advance_prompt() prompt = prompt + strlen(prompt) + 1
cmd_custom(byte i)9 void cmd_custom(byte i)
10 {
11 custom_command_type *cc_ptr;
12 char dir;
13 int item, item2;
14 s32b value;
15 cptr prompt;
16 char entry[60];
17 bool need_second, need_target;
18 byte second_item_tester = 0;
19
20 /* Byte is always 0, check if its > max */
21 if (i > custom_commands) return;
22 cc_ptr = &custom_command[i];
23 dir = item = item2 = value = 0;
24 prompt = cc_ptr->prompt;
25 entry[0] = '\0';
26
27 need_second = (cc_ptr->flag & COMMAND_NEED_SECOND ? TRUE : FALSE);
28 need_target = (cc_ptr->flag & COMMAND_NEED_TARGET ? TRUE : FALSE);
29
30 /* Pre-tests */
31 if (cc_ptr->flag & COMMAND_TEST_ALIVE)
32 {
33 if (p_ptr->ghost)
34 {
35 if (!STRZERO(prompt)) c_msg_print(prompt);
36 return;
37 }
38 advance_prompt();
39 }
40 if (cc_ptr->flag & COMMAND_TEST_DEAD)
41 {
42 if (!p_ptr->ghost)
43 {
44 if (!STRZERO(prompt)) c_msg_print(prompt);
45 return;
46 }
47 advance_prompt();
48 }
49 if (cc_ptr->flag & COMMAND_TEST_SPELL)
50 {
51 if (c_info[pclass].spell_book != cc_ptr->tval)
52 {
53 if (!STRZERO(prompt)) c_msg_print(prompt);
54 return;
55 }
56 advance_prompt();
57 }
58 /* if (cc_ptr->flag & COMMAND_SPECIAL_FILE)
59 {
60 special_line_type = cc_ptr->tval;
61 strcpy(special_line_header, prompt);
62 peruse_file();
63 return;
64 }
65 else */ if (cc_ptr->flag & COMMAND_INTERACTIVE)
66 {
67 int line_type = cc_ptr->tval;
68 bool use_anykey = (cc_ptr->flag & COMMAND_INTERACTIVE_ANYKEY) ? TRUE : FALSE;
69 strcpy(special_line_header, prompt);
70 cmd_interactive(line_type, use_anykey);
71 return;
72 }
73 /* Search for an item (automatic) */
74 if (cc_ptr->flag & COMMAND_ITEM_QUICK)
75 {
76 if (!c_check_item(&item, cc_ptr->tval))
77 {
78 if (!STRZERO(prompt)) c_msg_print(prompt);
79 return;
80 }
81 advance_prompt();
82 }
83 /* Ask for a store item (interactive) ? */
84 else if (cc_ptr->flag & COMMAND_ITEM_STORE)
85 {
86 if (!get_store_stock(&item, prompt)) return;
87 advance_prompt();
88
89 /* Get an amount */
90 if ((cc_ptr->flag & COMMAND_ITEM_AMMOUNT))
91 {
92 value = 1;
93 /* - from stock */
94 if (store.stock[item].number > 1)
95 {
96 /* Hack -- note cost of "fixed" items */
97 if (store_num != 7)
98 c_msg_print(format("That costs %ld gold per item.", (long)store_prices[item]));
99
100 if (STRZERO(prompt)) prompt = "How many? ";
101 shopping_buying = TRUE;
102 value = c_get_quantity(prompt, store.stock[item].number);
103 shopping_buying = FALSE;
104 }
105 if (!value) return;
106 advance_prompt();
107 }
108
109 /* Dirty Hack -- save multiplied price as "entry" */
110 sprintf(entry, "%" PRId32, (u32b)(store_prices[item]*value));
111 }
112 /* Ask for an item (interactive) ? */
113 else if (cc_ptr->flag & COMMAND_NEED_ITEM)
114 {
115 item_tester_tval = cc_ptr->tval;
116 spellcasting = (cc_ptr->flag & COMMAND_SPELL_BOOK) ? TRUE : FALSE;
117 if (!c_get_item(&item, prompt,
118 (cc_ptr->flag & COMMAND_ITEM_EQUIP ? TRUE : FALSE),
119 (cc_ptr->flag & COMMAND_ITEM_INVEN ? TRUE : FALSE),
120 (cc_ptr->flag & COMMAND_ITEM_FLOOR ? TRUE : FALSE)))
121 return;
122 second_item_tester = c_secondary_tester(item);
123 advance_prompt();
124
125 /* Get an amount */
126 if ((cc_ptr->flag & COMMAND_ITEM_AMMOUNT))
127 {
128 value = 1;
129 /* - from inventory */
130 if (item >= 0 && inventory[item].number > 1)
131 {
132 if (STRZERO(prompt)) prompt = "How many? ";
133 value = c_get_quantity(prompt, inventory[item].number);
134 }
135 /* - from floor */
136 if (item < 0 && floor_item.number > 1)
137 {
138 if (STRZERO(prompt)) prompt = "How many? ";
139 value = c_get_quantity(prompt, floor_item.number);
140 }
141 if (!value) return;
142 advance_prompt();
143 }
144
145 /* Dirty Hack -- Reset! */
146 if (cc_ptr->flag & COMMAND_ITEM_RESET)
147 {
148 need_second = need_target = FALSE;
149 dir = item2 = 0;
150 if (item >= 0)
151 {
152 need_target = (inventory[item].ident & ITEM_ASK_AIM ? TRUE : FALSE);
153 need_second = (inventory[item].ident & ITEM_ASK_ITEM ? TRUE : FALSE);
154 }
155 else
156 {
157 need_target = (floor_item.ident & ITEM_ASK_AIM ? TRUE : FALSE);
158 need_second = (floor_item.ident & ITEM_ASK_ITEM ? TRUE : FALSE);
159 }
160 }
161 }
162 /* Spell? */
163 if (cc_ptr->flag & COMMAND_NEED_SPELL)
164 {
165 int index, spell, indoff = 0;
166 cptr p = prompt;
167 advance_prompt();
168 if (cc_ptr->flag & COMMAND_SPELL_BOOK)
169 {
170 if (!get_spell(&spell, p, prompt, &item, FALSE, FALSE)) return;
171 index = item * SPELLS_PER_BOOK + spell;
172 }
173 else
174 {
175 int book = cc_ptr->tval;
176 if (!get_spell(&spell, p, prompt, &book, FALSE, TRUE)) return;
177 index = book * SPELLS_PER_BOOK + spell;
178 indoff = cc_ptr->tval * SPELLS_PER_BOOK;
179 }
180 advance_prompt();
181 if (cc_ptr->flag & COMMAND_SPELL_INDEX)
182 {
183 value = index - indoff;
184 }
185 else
186 {
187 value = spell;
188 }
189
190 /* Dirty Hack -- Reset! */
191 if (cc_ptr->flag & COMMAND_SPELL_RESET)
192 {
193 need_second = need_target = FALSE;
194 dir = item2 = 0;
195 if (spell >= SPELL_PROJECTED) need_target = TRUE;
196 else
197 {
198 need_target = (spell_flag[index] & PY_SPELL_AIM ? TRUE : FALSE);
199 need_second = (spell_flag[index] & PY_SPELL_ITEM ? TRUE : FALSE);
200 if (need_second) second_item_tester = spell_test[index];
201 }
202 }
203 }
204 /* Second item? */
205 if (need_second) /* cc_ptr->flag & COMMAND_NEED_SECOND) */
206 {
207 if (STRZERO(prompt)) prompt = "Which item? ";
208 item_tester_tval = second_item_tester;
209 if (!c_get_item(&item2, prompt,
210 (cc_ptr->flag & COMMAND_SECOND_EQUIP ? TRUE : FALSE),
211 (cc_ptr->flag & COMMAND_SECOND_INVEN ? TRUE : FALSE),
212 (cc_ptr->flag & COMMAND_SECOND_FLOOR ? TRUE : FALSE)))
213 return;
214 advance_prompt();
215 }
216 /* Target? */
217 if (need_target) /* cc_ptr->flag & COMMAND_NEED_TARGET) */
218 {
219 if (!c_get_dir(&dir, prompt,
220 (cc_ptr->flag & COMMAND_TARGET_ALLOW ? TRUE : FALSE),
221 (cc_ptr->flag & COMMAND_TARGET_FRIEND ? TRUE : FALSE)))
222 return;
223 advance_prompt();
224 }
225 /* Auto-modify prompt? */
226 if (cc_ptr->flag & COMMAND_PROMPT_ITEM)
227 {
228 prompt = item_prompt(prompt, item, value);
229 }
230 /* Need values? */
231 if (cc_ptr->flag & COMMAND_NEED_VALUE)
232 {
233 if (STRZERO(prompt)) prompt = "Quantity: ";
234 value = c_get_quantity(prompt, 999000000);
235 if (!value) return;
236 advance_prompt();
237 }
238 if (cc_ptr->flag & COMMAND_NEED_CHAR)
239 {
240 if (STRZERO(prompt)) prompt = "Command: ";
241 if (!get_com(prompt, &entry[0]))
242 return;
243 entry[1] = '\0';
244 advance_prompt();
245 }
246 else if (cc_ptr->flag & COMMAND_NEED_STRING)
247 {
248 if (STRZERO(prompt)) prompt = "Entry: ";
249 if (!get_string(prompt, entry, sizeof(entry) - 1))
250 return;
251 advance_prompt();
252 }
253 if (cc_ptr->flag & COMMAND_NEED_CONFIRM)
254 {
255 if (STRZERO(prompt)) prompt = "Really perform said action ? ";
256 if (!get_check(prompt))
257 return;
258 advance_prompt();
259 }
260 /* Post-effects */
261 if (cc_ptr->flag & COMMAND_SECOND_VALUE)
262 {
263 if (!value) value = (s32b)item2;
264 else value = -value;
265 }
266 if (cc_ptr->flag & COMMAND_SECOND_DIR)
267 {
268 if (!dir) dir = item2;
269 else dir = -dir;
270 }
271 if (cc_ptr->flag & COMMAND_SECOND_CHAR)
272 {
273 entry[0] = item2;
274 entry[1] = '\0';
275 }
276
277
278 send_custom_command(i, item, dir, value, entry);
279 }
280 /* Handle all commands */
process_command()281 void process_command()
282 {
283 byte i;
284 for (i = 0; i < custom_commands; i++)
285 {
286 if (custom_command[i].flag & COMMAND_STORE) continue;
287 if (custom_command[i].m_catch == command_cmd)
288 {
289 cmd_custom(i);
290 return;
291 }
292 }
293
294 #ifndef MOBILE_UI
295 /* Hack -- pick command from a menu */
296 if (command_cmd == '\r')
297 {
298 command_cmd = do_cmd_menu();
299 if (command_cmd != '\r')
300 {
301 process_command();
302 return;
303 }
304 }
305 #endif
306
307 /* Parse the command */
308 switch (command_cmd)
309 {
310 /* Ignore */
311 case ' ':
312 {
313 msg_flush();
314 }
315 case ESCAPE:
316 {
317 if (first_escape)
318 send_clear();
319 first_escape = FALSE;
320 break;
321 }
322
323 /* Ignore return */
324 case '\r':
325 {
326 break;
327 }
328
329 /*** Movement Commands ***/
330 /* Move */
331 case ';':
332 {
333 cmd_walk();
334 break;
335 }
336
337 /*** Running, Staying, Resting ***/
338 case '.':
339 {
340 cmd_run();
341 break;
342 }
343
344 case ',':
345 case 'g':
346 {
347 cmd_stay();
348 break;
349 }
350 /* Recenter map */
351 case 'L':
352 {
353 cmd_locate();
354 break;
355 }
356 /* Rest */
357 case 'R':
358 {
359 cmd_rest();
360 break;
361 }
362 /*** Inventory commands ***/
363 case 'i':
364 {
365 cmd_inven();
366 break;
367 }
368
369 case 'e':
370 {
371 cmd_equip();
372 break;
373 }
374
375 case '$':
376 {
377 cmd_drop_gold();
378 break;
379 }
380 case 'k':
381 {
382 cmd_destroy();
383 break;
384 }
385 /*** Spell casting ***/
386 case 'b':
387 {
388 cmd_browse();
389 break;
390 }
391 #if 0
392 case 'G':
393 {
394 cmd_study();
395 break;
396 }
397
398 case 'm':
399 {
400 cmd_cast();
401 break;
402 }
403
404 case 'p':
405 {
406 cmd_pray();
407 break;
408 }
409 #endif
410 case 'U':
411 {
412 cmd_ghost();
413 break;
414 }
415
416 case KTRL('U'):
417 {
418 cmd_use_item();
419 break;
420 }
421
422 /*** Looking/Targetting ***/
423 case '*':
424 {
425 cmd_target();
426 break;
427 }
428
429 case '(':
430 {
431 cmd_target_friendly();
432 break;
433 }
434
435 case 'l':
436 {
437 cmd_look();
438 break;
439 }
440
441 /*** Information ***/
442 case 'C':
443 {
444 cmd_character();
445 break;
446 }
447 /*** Miscellaneous ***/
448 case ':':
449 {
450 cmd_message();
451 break;
452 }
453
454 case 'P':
455 {
456 cmd_party();
457 break;
458 }
459
460 case '\'': /* Handle chat */
461 {
462 cmd_chat();
463 break;
464 }
465
466 case KTRL('D'): /* 'Describe item. This means "brag about it in chat" */
467 {
468 cmd_describe();
469 break;
470 }
471
472 case KTRL('O'): /* Repeat last message */
473 {
474 do_cmd_message_one();
475 break;
476 }
477
478 case KTRL('P'):
479 {
480 do_cmd_messages();
481 break;
482 }
483
484 case KTRL('X'):
485 {
486 quit(NULL);
487 }
488
489 case KTRL('R'):
490 {
491 cmd_redraw();
492 break;
493 }
494
495 case 'Q':
496 {
497 cmd_suicide();
498 break;
499 }
500
501 case '\xff':
502 {
503 cmd_mouseclick();
504 break;
505 }
506
507 case KTRL('E'):
508 {
509 toggle_inven_equip();
510 break;
511 }
512
513 case '=':
514 {
515 do_cmd_options();
516 break;
517 }
518
519 case '\"':
520 {
521 cmd_load_pref();
522 break;
523 }
524
525 #ifndef MOBILE_UI
526 case '%':
527 {
528 interact_macros();
529 break;
530 }
531 #endif
532
533 case '!':
534 {
535 do_cmd_port();
536 break;
537 }
538
539 default:
540 {
541 prt("Hit '?' for help.", 0, 0);
542 break;
543 }
544 }
545 }
546
547
548
549 /* Process server-side requests. We queue the actual requests in net-client.c
550 * and process them here at a later time, so we don't unexpectedly change state
551 * in the middle of a network frame. */
552 /* Note: this probably should be in some other file, but which? */
process_requests()553 void process_requests()
554 {
555 if (pause_requested)
556 {
557 pause_requested = FALSE;
558 section_icky_row = Term->hgt;
559 section_icky_col = Term->wid;
560 //cmd_interactive();
561 prepare_popup(0, TRUE);
562 }
563 if (local_browser_requested)
564 {
565 local_browser_requested = FALSE;
566 peruse_file();
567 }
568 if (simple_popup_requested)
569 {
570 simple_popup_requested = FALSE;
571 prepare_popup(0, TRUE);
572 }
573 if (special_line_requested)
574 {
575 //int type = special_line_requested;
576 special_line_requested = FALSE;
577 //cmd_interactive();
578 prepare_popup(0, FALSE);
579 }
580 if (confirm_requested)
581 {
582 confirm_requested = FALSE;
583 if (get_check(confirm_prompt)) send_confirm(confirm_type, confirm_id);
584 }
585 if (enter_store)
586 {
587 enter_store = FALSE;
588 display_store();
589 }
590 }
591
592
593
cmd_walk(void)594 void cmd_walk(void)
595 {
596 int dir = command_dir;
597
598 if (!dir)
599 {
600 get_dir(&dir);
601 }
602
603 send_walk(dir);
604 }
605
cmd_run(void)606 void cmd_run(void)
607 {
608 int dir = command_dir;
609
610 if (!dir)
611 {
612 get_dir(&dir);
613 }
614
615 Send_run(dir);
616 }
617
cmd_stay(void)618 void cmd_stay(void)
619 {
620 Send_stay();
621 }
622
cmd_locate(void)623 void cmd_locate(void)
624 {
625 int dir;
626 char ch;
627
628 /* Initialize */
629 send_locate(5);
630
631 /* Show panels until done */
632 while (1)
633 {
634 /* Assume no direction */
635 dir = 0;
636
637 /* Get a direction */
638 while (!dir)
639 {
640 /* Hack -- inform Term2 */
641 if (z_ask_dir_aux) z_ask_dir_aux("Locate", FALSE, FALSE);
642
643 /* Get a command (or Cancel) */
644 ch = inkey();
645
646 /* Check for cancel */
647 if (ch == ESCAPE) break;
648
649 /* Extract direction */
650 dir = target_dir(ch);
651
652 /* Error */
653 if (!dir) bell();
654 }
655
656 /* No direction */
657 if (!dir) break;
658
659 /* Send the command */
660 send_locate(dir);
661 }
662
663 /* Done */
664 send_locate(0);
665
666 /* Clear */
667 c_msg_print(NULL);
668 }
669
cmd_rest(void)670 void cmd_rest(void)
671 {
672 send_rest();
673 }
674
cmd_inven(void)675 void cmd_inven(void)
676 {
677 /* show_inven() might not show anything, yet we still pause the screen,
678 * using inkey() below. To avoid all that altogether, let's quit early */
679 if (inventory[0].number == 0) return;
680
681 /* Save the screen */
682 Term_save();
683
684 command_gap = 50;
685
686 /* Show inven and *make screen icky* */
687 show_inven();
688
689 /* Pause */
690 (void)inkey();
691
692 /* Restore the screen */
693 Term_load();
694
695 /* The screen is OK now */
696 section_icky_row = 0;
697 section_icky_col = 0;
698
699 /* Flush any events */
700 Flush_queue();
701 }
702
cmd_equip(void)703 void cmd_equip(void)
704 {
705 /* Save the screen */
706 Term_save();
707
708 command_gap = 50;
709
710 /* Hack -- show empty slots */
711 item_tester_full = TRUE;
712
713 /* Show equip and *make screen icky */
714 show_equip();
715
716 /* Undo the hack above */
717 item_tester_full = FALSE;
718
719 (void)inkey();
720
721 Term_load();
722
723 /* The screen is OK now */
724 section_icky_row = 0;
725 section_icky_col = 0;
726
727 /* Flush any events */
728 Flush_queue();
729 }
730
cmd_drop_gold(void)731 void cmd_drop_gold(void)
732 {
733 s32b amt = 0;
734
735 /* Get how much */
736 if (p_ptr->au)
737 amt = c_get_quantity("How much gold? ", p_ptr->au);
738
739 /* Send it */
740 if (amt)
741 Send_drop_gold(amt);
742 }
743
744 /* Given a 'prompt' prefix, an 'item' id and ammount ('amt'),
745 * return a prompt string describing such item. */
item_prompt(cptr prompt,int item,int amt)746 char* item_prompt(cptr prompt, int item, int amt)
747 {
748 static char out_val[160];
749
750 /* Inventory/Equipment item */
751 if (item >= 0)
752 {
753 /* Whole stack */
754 if (inventory[item].number == amt)
755 sprintf(out_val, "%s%s? ", prompt, inventory_name[item]);
756 /* Part of stack */
757 else
758 sprintf(out_val, "%s%d of your %s? ", prompt, amt, inventory_name[item]);
759 }
760 /* Floor item */
761 else
762 {
763 /* Whole stack */
764 if (floor_item.number == amt)
765 sprintf(out_val, "%s%s? ", prompt, floor_name);
766 /* Part of stack */
767 else
768 sprintf(out_val, "%s%d of %s? ", prompt, amt, floor_name);
769 }
770
771 return out_val;
772 }
773
cmd_destroy(void)774 void cmd_destroy(void)
775 {
776 int item, amt;
777 char out_val[160];
778
779 if (!c_get_item(&item, "Destroy what? ", TRUE, TRUE, TRUE))
780 {
781 return;
782 }
783
784 /* Not on-the-floor item */
785 if (item >= 0)
786 {
787 /* Get an amount */
788 if (inventory[item].number > 1)
789 {
790 amt = c_get_quantity("How many? ", inventory[item].number);
791 }
792 else amt = 1;
793
794 /* Sanity check */
795 if (inventory[item].number == amt)
796 sprintf(out_val, "Really destroy %s? ", inventory_name[item]);
797 else
798 sprintf(out_val, "Really destroy %d of your %s? ", amt, inventory_name[item]);
799 if (!get_check(out_val)) return;
800
801 }
802 else
803 {
804 /* Get an amount */
805 if (floor_item.number > 1)
806 {
807 amt = c_get_quantity("How many? ", floor_item.number);
808 }
809 else amt = 1;
810
811 /* Sanity check */
812 if (floor_item.number == amt)
813 sprintf(out_val, "Really destroy %s? ", floor_name);
814 else
815 sprintf(out_val, "Really destroy %d of %s? ", amt, floor_name);
816 if (!get_check(out_val)) return;
817 }
818
819 /* Send it */
820 Send_destroy(item, amt);
821 }
822
cmd_describe(void)823 void cmd_describe(void)
824 {
825 int item;
826 char buf[80];
827
828 if (!c_get_item(&item, "Describe what? ", TRUE, TRUE, TRUE))
829 {
830 return;
831 }
832
833 buf[0] = '\0';
834
835 /* Copy item name */
836 if (item < 0)
837 strcpy(buf, floor_name);
838 else
839 strcpy(buf, inventory_name[item]);
840
841 if (buf[0] != '\0')
842 send_msg(buf);
843 }
844
cmd_target_interactive(int mode)845 int cmd_target_interactive(int mode)
846 {
847 bool done = FALSE;
848 event_type ke;
849 char ch;
850
851 /* Save screen */
852 Term_save();
853
854 /* Set modes */
855 looking = TRUE;
856 target_recall = FALSE;
857 cursor_icky = TRUE;
858 topline_icky = TRUE;
859
860 /* Tell the server to init targetting */
861 Send_target_interactive(mode, 0);
862
863 while (!done)
864 {
865 ke = inkey_ex();
866 ch = ke.key;
867
868 if (!ch)
869 continue;
870
871 if (ch == '\xff')
872 {
873 send_mouse(MCURSOR_META | mode
874 | (ke.index ? MCURSOR_KTRL : 0),
875 ke.mousex - DUNGEON_OFFSET_X,
876 ke.mousey - DUNGEON_OFFSET_Y);
877 if (ke.index) done = TRUE;
878 continue;
879 }
880
881 Send_target_interactive(mode, ch);
882
883 switch (ch)
884 {
885 case 't':
886 case '5':
887 case '0':
888 case '.':
889 case 'g':
890 case ESCAPE:
891 done = TRUE;
892 break;
893 }
894 }
895
896 /* Fix screen */
897 Term_load();
898
899 /* Unset modes */
900 looking = FALSE;
901 topline_icky = FALSE;
902 section_icky_row = 0;
903 section_icky_col = 0;
904
905 /* Reset cursor stuff */
906 cursor_icky = FALSE;
907 Term_consolidate_cursor(FALSE, 0, 0);
908
909 return done;
910 }
911
cmd_target(void)912 int cmd_target(void)
913 {
914 return cmd_target_interactive(TARGET_KILL);
915 }
916
cmd_target_friendly(void)917 int cmd_target_friendly(void)
918 {
919 return cmd_target_interactive(TARGET_FRND);
920 }
921
cmd_look(void)922 void cmd_look(void)
923 {
924 (void)cmd_target_interactive(TARGET_LOOK);
925 }
926
cmd_changepass(void)927 void cmd_changepass(void)
928 {
929 char pass1[MAX_PASS_LEN];
930 char pass2[MAX_PASS_LEN];
931 int pause = 0;
932 char ch;
933 pass1[0] = '\0';
934 pass2[0] = '\0';
935
936
937 if (get_string_masked("New Password: ", pass1, MAX_PASS_LEN-1))
938 {
939 if (get_string_masked("Confirm It: ", pass2, MAX_PASS_LEN-1))
940 {
941 if (!strcmp(pass1,pass2)) {
942 MD5Password(pass1);
943 send_pass(pass1);
944 prt(" Password changed [press any key]",0,0);
945 } else {
946 prt(" Not matching [paused]",0,0);
947 }
948
949 while (!pause)
950 {
951 ch = inkey();
952 if (ch) pause = 1;
953 }
954 }
955 }
956 }
957
cmd_character(void)958 void cmd_character(void)
959 {
960 char ch = 0;
961 int done = 0;
962
963 u32b old_window;
964 u32b tmp_window;
965
966 old_window = window_flag[0];
967 tmp_window = window_flag[0];
968
969 tmp_window &= ~PW_PLAYER_2;
970 tmp_window &= ~PW_STATUS;
971
972 /* Screen is icky */
973 screen_icky = TRUE;
974
975 /* Save screen */
976 Term_save();
977
978 while (!done)
979 {
980 if (char_screen_mode == 0) window_flag[0] = tmp_window | PW_PLAYER_0;
981 if (char_screen_mode == 1) window_flag[0] = tmp_window | PW_PLAYER_3;
982 if (char_screen_mode == 2) window_flag[0] = tmp_window | PW_PLAYER_1;
983
984 /* Display player info */
985 display_player(char_screen_mode);
986
987 /* Display message */
988 prt("[ESC to quit, h to toggle history, p to change password]", 21, 12);
989
990 /* Wait for key */
991 ch = inkey();
992
993 /* Check for "display history" */
994 if (ch == 'h' || ch == 'H')
995 {
996 /* Toggle */
997 char_screen_mode++;
998 if (char_screen_mode > 2) char_screen_mode = 0;
999 }
1000
1001 /* Check for "change password" */
1002 if (ch == 'p' || ch == 'P')
1003 {
1004 cmd_changepass();
1005 }
1006
1007 /* Check for quit */
1008 if (ch == 'q' || ch == 'Q' || ch == ESCAPE)
1009 {
1010 /* Quit */
1011 done = 1;
1012 }
1013 }
1014
1015 window_flag[0] = old_window;
1016
1017 /* Reload screen */
1018 Term_load();
1019
1020 /* Screen is no longer icky */
1021 screen_icky = FALSE;
1022
1023 redraw_indicators(old_window);
1024
1025 /* Flush any events */
1026 Flush_queue();
1027 }
1028
1029
cmd_interactive(byte line_type,bool use_anykey)1030 void cmd_interactive(byte line_type, bool use_anykey)
1031 {
1032 char ch;
1033 bool done = FALSE;
1034
1035 /* Hack -- if the screen is already icky, ignore this command */
1036 if (screen_icky) return;
1037
1038 /* The screen is icky */
1039 screen_icky = TRUE;
1040 special_line_onscreen = TRUE;
1041 //special_line_type = line_type;
1042
1043 /* Save the screen */
1044 Term_save();
1045
1046 /* Send the request */
1047 send_interactive(line_type);
1048
1049 /* Wait until we get the whole thing */
1050 while (!done)
1051 {
1052 /* Wait for net input, or a key */
1053 ch = inkey();
1054
1055 if (!ch)
1056 continue;
1057
1058 if (use_anykey) ch = ESCAPE;
1059
1060 send_term_key(ch);
1061
1062 /* Check for user abort */
1063 if (ch == ESCAPE && !icky_levels)
1064 break;
1065 }
1066
1067 /* Reload the screen */
1068 Term_load();
1069
1070 /* The screen is OK now */
1071 screen_icky = FALSE;
1072 special_line_onscreen = FALSE;
1073 //special_line_type = 0;
1074
1075 /* Flush any queued events */
1076 Flush_queue();
1077 }
1078
cmd_chat()1079 void cmd_chat()
1080 {
1081 char com;
1082 char buf[80];
1083
1084 if (!get_com("Chat command [n - next, p - previous, c - close, o - open]:", &com)) return;
1085
1086 switch (com)
1087 {
1088 case 'b':
1089 case 'p':
1090 case '4':
1091 cmd_chat_cycle(-1);
1092 break;
1093 case 'f':
1094 case 'n':
1095 case '6':
1096 cmd_chat_cycle(+1);
1097 break;
1098 case 'c':
1099 case 'l':
1100 cmd_chat_close(view_channel);
1101 break;
1102 case 'o':
1103 case 'j':
1104 buf[0] = '\0';
1105 if (!get_string("Channel: ", buf, 59)) break;
1106
1107 /* Request channel join */
1108 if (buf[0] == '#')
1109 {
1110 send_channel(CHAN_JOIN, 0, buf);
1111 }
1112 /* Open tab locally */
1113 else
1114 {
1115 send_channel(CHAN_SELECT, 0, buf);
1116
1117 do_chat_open(MAX_CHANNELS, buf);
1118 }
1119
1120 break;
1121
1122 }
1123 }
cmd_chat_close(int n)1124 void cmd_chat_close(int n)
1125 {
1126
1127 if (n)
1128 {
1129 /* Request channel leave */
1130 if (channels[n].name[0] == '#')
1131 {
1132 send_channel(CHAN_LEAVE, channels[n].id, channels[n].name);
1133 }
1134 /* Close locally */
1135 else
1136 {
1137 if (view_channel == n)
1138 cmd_chat_cycle(-1);
1139
1140 channels[n].name[0] = '\0';
1141 channels[n].id = 0;
1142
1143 if (p_ptr->main_channel == n)
1144 p_ptr->main_channel = 0;
1145 if (STRZERO(channels[view_channel].name))
1146 cmd_chat_cycle(+1);
1147
1148 /* Window update */
1149 p_ptr->window |= PW_MESSAGE_CHAT;
1150 }
1151 }
1152 }
cmd_chat_cycle(int dir)1153 void cmd_chat_cycle(int dir)
1154 {
1155 s16b new_channel = view_channel;
1156 bool done = FALSE;
1157 while (!done)
1158 {
1159 new_channel += dir;
1160
1161 if (new_channel >= MAX_CHANNELS || new_channel < 0) return;
1162 if (STRZERO(channels[new_channel].name)) continue;
1163
1164 break;
1165 }
1166
1167 if (new_channel != view_channel)
1168 {
1169 /* Set new */
1170 view_channel = new_channel;
1171 p_ptr->on_channel[view_channel] = FALSE;
1172
1173 /* Redraw */
1174 p_ptr->window |= (PW_MESSAGE_CHAT);
1175 }
1176 }
1177
cmd_message(void)1178 void cmd_message(void)
1179 {
1180 //[flm] powerhack to prevent next hack:
1181 bool refocus_chat = FALSE;
1182 #ifdef USE_WIN
1183 #ifdef PMSG_TERM
1184 refocus_chat = win32_window_visible(PMSG_TERM) ? TRUE : FALSE;
1185 #endif
1186 #endif
1187 // [hack] hack to just change the window focus in WIN32 client
1188 if (refocus_chat)
1189 {
1190 set_chat_focus();
1191 }
1192 else
1193 {
1194 char buf[60];
1195
1196 buf[0] = '\0';
1197
1198 if (get_string("Message: ", buf, 59))
1199 if (buf[0] != '\0')
1200 send_msg(buf);
1201 };
1202 }
1203
cmd_party(void)1204 void cmd_party(void)
1205 {
1206 char i;
1207 char buf[80];
1208
1209 /* Screen is icky */
1210 screen_icky = TRUE;
1211
1212 /* We are now in party mode */
1213 party_mode = TRUE;
1214
1215 /* Save screen */
1216 Term_save();
1217
1218 /* Process requests until done */
1219 while (1)
1220 {
1221 /* Clear screen */
1222 Term_clear();
1223
1224 /* Initialize buffer */
1225 buf[0] = '\0';
1226
1227 /* Describe */
1228 Term_putstr(0, 2, -1, TERM_WHITE, "Party commands");
1229
1230 /* Selections */
1231 Term_putstr(5, 4, -1, TERM_WHITE, "(1) Create a party");
1232 Term_putstr(5, 5, -1, TERM_WHITE, "(2) Add a player to party");
1233 Term_putstr(5, 6, -1, TERM_WHITE, "(3) Delete a player from party");
1234 Term_putstr(5, 7, -1, TERM_WHITE, "(4) Leave your current party");
1235 Term_putstr(5, 8, -1, TERM_WHITE, "(5) Specify player to attack");
1236 Term_putstr(5, 9, -1, TERM_WHITE, "(6) Make peace");
1237
1238 /* Show current party status */
1239 Term_putstr(0, 13, -1, TERM_WHITE, party_info);
1240
1241 /* Prompt */
1242 Term_putstr(0, 11, -1, TERM_WHITE, "Command: ");
1243 Term_show_ui_cursor();
1244
1245 /* Get a key */
1246 i = inkey();
1247
1248 /* Leave */
1249 if (i == ESCAPE) break;
1250
1251 /* Create party */
1252 else if (i == '1')
1253 {
1254 /* Get party name */
1255 if (get_string("Party name: ", buf, 79))
1256 send_party(PARTY_CREATE, buf);
1257 }
1258
1259 /* Add player */
1260 else if (i == '2')
1261 {
1262 /* Get player name */
1263 if (get_string("Add player: ", buf, 79))
1264 send_party(PARTY_ADD, buf);
1265 }
1266
1267 /* Delete player */
1268 else if (i == '3')
1269 {
1270 /* Get player name */
1271 if (get_string("Delete player: ", buf, 79))
1272 send_party(PARTY_DELETE, buf);
1273 }
1274
1275 /* Leave party */
1276 else if (i == '4')
1277 {
1278 /* Send the command */
1279 send_party(PARTY_REMOVE_ME, "");
1280 }
1281
1282 /* Attack player/party */
1283 else if (i == '5')
1284 {
1285 /* Get player name */
1286 if (get_string("Player/party to attack: ", buf, 79))
1287 send_party(PARTY_HOSTILE, buf);
1288 }
1289
1290 /* Make peace with player/party */
1291 else if (i == '6')
1292 {
1293 /* Get player/party name */
1294 if (get_string("Make peace with: ", buf, 79))
1295 send_party(PARTY_PEACE, buf);
1296 }
1297
1298 /* Oops */
1299 else
1300 {
1301 /* Ring bell */
1302 bell();
1303 }
1304
1305 /* Flush messages */
1306 c_msg_print(NULL);
1307 }
1308
1309 Term_hide_ui_cursor();
1310
1311 /* Reload screen */
1312 Term_load();
1313
1314 /* Screen is no longer icky */
1315 screen_icky = FALSE;
1316
1317 /* No longer in party mode */
1318 party_mode = FALSE;
1319
1320 /* Flush any events */
1321 Flush_queue();
1322 }
1323
1324
cmd_browse(void)1325 void cmd_browse(void)
1326 {
1327 int item;
1328
1329 if (p_ptr->ghost)
1330 {
1331 show_browse(10);
1332 return;
1333 }
1334
1335 if (!c_info[pclass].spell_book)
1336 {
1337 c_msg_print("You cannot read books!");
1338 return;
1339 }
1340
1341 item_tester_tval = c_info[pclass].spell_book;
1342 spellcasting = TRUE;
1343 if (!c_get_item(&item, "Browse which book? ", FALSE, TRUE, FALSE))
1344 {
1345 if (item == -2) c_msg_print("You have no books that you can read.");
1346 return;
1347 }
1348
1349 /* Show it */
1350 show_browse(item);
1351 }
1352 #if 0
1353 void cmd_study(void)
1354 {
1355 int item;
1356
1357 if (!c_info[pclass].spell_book)
1358 {
1359 c_msg_print("You cannot gain spells!");
1360 return;
1361 }
1362
1363 item_tester_tval = c_info[pclass].spell_book;
1364
1365 if (!c_get_item(&item, "Gain from which book? ", FALSE, TRUE, FALSE))
1366 {
1367 if (item == -2) c_msg_print("You have no books that you can read.");
1368 return;
1369 }
1370
1371 /* Pick a spell and do it */
1372 do_study(item);
1373 }
1374
1375 void cmd_cast(void)
1376 {
1377 int item;
1378
1379 if (c_info[pclass].spell_book != TV_MAGIC_BOOK)
1380 {
1381 c_msg_print("You cannot cast spells!");
1382 return;
1383 }
1384
1385 item_tester_tval = TV_MAGIC_BOOK;
1386
1387 if (!c_get_item(&item, "Cast from what book? ", FALSE, TRUE, FALSE))
1388 {
1389 if (item == -2) c_msg_print("You have no books that you can cast from.");
1390 return;
1391 }
1392
1393 /* Pick a spell and do it */
1394 do_cast(item);
1395 }
1396
1397 void cmd_pray(void)
1398 {
1399 int item;
1400
1401 if (c_info[pclass].spell_book != TV_PRAYER_BOOK)
1402 {
1403 c_msg_print("Pray hard enough and your prayers may be answered.");
1404 return;
1405 }
1406
1407 item_tester_tval = TV_PRAYER_BOOK;
1408
1409 if (!c_get_item(&item, "Pray from what book? ", FALSE, TRUE, FALSE))
1410 {
1411 if (item == -2) c_msg_print("You have no books that you can pray from.");
1412 return;
1413 }
1414
1415 /* Pick a spell and do it */
1416 do_pray(item);
1417 }
1418 #endif
cmd_ghost(void)1419 void cmd_ghost(void)
1420 {
1421 if (p_ptr->ghost)
1422 do_ghost();
1423 else
1424 {
1425 c_msg_print("You are not undead.");
1426 }
1427 }
1428
toggle_inven_equip(void)1429 void toggle_inven_equip(void)
1430 {
1431 flip_inven = !flip_inven;
1432 p_ptr->window |= (PW_INVEN | PW_EQUIP);
1433 }
1434
cmd_load_pref(void)1435 void cmd_load_pref(void)
1436 {
1437 char buf[80];
1438
1439 buf[0] = '\0';
1440
1441 if (get_string("Action: ", buf, 79))
1442 process_pref_file_command(buf);
1443 }
1444
cmd_redraw(void)1445 void cmd_redraw(void)
1446 {
1447 /* Request new data */
1448 send_redraw();
1449 /* Clear screen */
1450 Term_clear();
1451 }
1452
cmd_suicide(void)1453 void cmd_suicide(void)
1454 {
1455 int i;
1456
1457 /* Verify */
1458 if (!get_check("Do you really want to commit suicide? ")) return;
1459
1460 /* Check again */
1461 topline_icky = TRUE;
1462 prt("Please verify SUICIDE by typing the '@' sign: ", 0, 0);
1463 flush();
1464 i = inkey();
1465 topline_icky = FALSE;
1466 prt("", 0, 0);
1467 if (i != '@') return;
1468
1469 /* Send it */
1470 send_suicide();
1471 }
1472
cmd_mouseclick()1473 void cmd_mouseclick()
1474 {
1475 event_type ke = command_cmd_ex;
1476 int btn, mod = 0;
1477 btn = ke.index;
1478 if (btn & 16) { btn &= ~16; mod = MCURSOR_KTRL; }
1479 if (btn & 32) { btn &= ~32; mod = MCURSOR_SHFT; }
1480 if (btn & 64) { btn &= ~64; mod = MCURSOR_ALTR; }
1481
1482 /* XXX HORRIBLE HACK XXX */
1483 if (btn) { /* Allow remacro */
1484 char ks[1024], *p;
1485 strnfmt(ks, sizeof(ks), "%c_TERMcave_MB%02x%c",
1486 31, ke.index, 13);
1487 if (macro_find_exact(ks) >= 0) {
1488 for (p = ks; *p; p++) Term_keypress(*p);
1489 return;
1490 }
1491 } /* XXX XXX XXX */
1492
1493 /* XXX HORRIBLE HACK#2 XXX*/
1494 if (btn) { /* Allow rebinding */
1495 byte map_from = btn | mod;
1496 if (mousemap[map_from])
1497 {
1498
1499 btn = mousemap[map_from] & 0x0F;
1500 mod = mousemap[map_from] & 0xF0;
1501 }
1502 } /* XXX XXX XXX */
1503
1504 /* If the mouse is outside the dungeon, do nothing. */
1505 if (ke.mousex - DUNGEON_OFFSET_X < 0
1506 || ke.mousey - DUNGEON_OFFSET_Y < 0)
1507 return;
1508
1509 send_mouse(0
1510 | (btn == 1 ? MCURSOR_LMB : 0)
1511 | (btn == 2 ? MCURSOR_MMB : 0)
1512 | (btn == 3 ? MCURSOR_RMB : 0)
1513 | mod,
1514 ke.mousex - DUNGEON_OFFSET_X,
1515 ke.mousey - DUNGEON_OFFSET_Y);
1516 }
1517