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