1 | |
|
|
2 | /* |
|
|
3 | * static char *rcsid_c_wiz_c = |
|
|
4 | * "$Id: c_wiz.C,v 1.8 2006/09/10 13:20:27 root Exp $"; |
|
|
5 | */ |
|
|
6 | |
|
|
7 | /* |
1 | /* |
8 | CrossFire, A Multiplayer game for X-windows |
2 | CrossFire, A Multiplayer game for X-windows |
9 | |
3 | |
10 | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
4 | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
11 | Copyright (C) 1992 Frank Tore Johansen |
5 | Copyright (C) 1992 Frank Tore Johansen |
… | |
… | |
22 | |
16 | |
23 | You should have received a copy of the GNU General Public License |
17 | You should have received a copy of the GNU General Public License |
24 | along with this program; if not, write to the Free Software |
18 | along with this program; if not, write to the Free Software |
25 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
26 | |
20 | |
27 | The authors can be reached via e-mail at crossfire-devel@real-time.com |
21 | The authors can be reached via e-mail at <crossfire@schmorp.de> |
28 | */ |
22 | */ |
29 | |
23 | |
30 | #include <global.h> |
24 | #include <global.h> |
31 | #ifndef __CEXTRACT__ |
25 | #ifndef __CEXTRACT__ |
32 | # include <sproto.h> |
26 | # include <sproto.h> |
… | |
… | |
96 | new_draw_info (NDI_UNIQUE, 0, op, "at different map places."); |
90 | new_draw_info (NDI_UNIQUE, 0, op, "at different map places."); |
97 | new_draw_info (NDI_UNIQUE, 0, op, "use at your own risks."); |
91 | new_draw_info (NDI_UNIQUE, 0, op, "use at your own risks."); |
98 | new_draw_info (NDI_UNIQUE, 0, op, "Very long loop used so server may have to be reset."); |
92 | new_draw_info (NDI_UNIQUE, 0, op, "Very long loop used so server may have to be reset."); |
99 | new_draw_info (NDI_UNIQUE, 0, op, "type loadtest TRUE to run"); |
93 | new_draw_info (NDI_UNIQUE, 0, op, "type loadtest TRUE to run"); |
100 | new_draw_info_format (NDI_UNIQUE, 0, op, "{%s}", params); |
94 | new_draw_info_format (NDI_UNIQUE, 0, op, "{%s}", params); |
|
|
95 | |
101 | if (!params) |
96 | if (!params) |
102 | return 0; |
97 | return 0; |
|
|
98 | |
103 | if (strncmp (params, "TRUE", 4)) |
99 | if (strncmp (params, "TRUE", 4)) |
104 | return 0; |
100 | return 0; |
105 | |
101 | |
106 | new_draw_info_format (NDI_UNIQUE, 0, op, "gogogo"); |
102 | new_draw_info_format (NDI_UNIQUE, 0, op, "gogogo"); |
|
|
103 | |
107 | for (x = 0; x < settings.worldmaptilesx; x++) |
104 | for (x = 0; x < settings.worldmaptilesx; x++) |
108 | { |
105 | { |
109 | for (y = 0; y < settings.worldmaptilesy; y++) |
106 | for (y = 0; y < settings.worldmaptilesy; y++) |
110 | { |
107 | { |
111 | sprintf (buf, "/world/world_%d_%d", x + settings.worldmapstartx, y + settings.worldmapstarty); |
108 | sprintf (buf, "/world/world_%d_%d", x + settings.worldmapstartx, y + settings.worldmapstarty); |
… | |
… | |
164 | static object * |
161 | static object * |
165 | find_object_both (char *params) |
162 | find_object_both (char *params) |
166 | { |
163 | { |
167 | if (!params) |
164 | if (!params) |
168 | return NULL; |
165 | return NULL; |
|
|
166 | |
169 | if (params[0] == '#') |
167 | if (params[0] == '#') |
170 | return find_object (atol (params + 1)); |
168 | return find_object (atol (params + 1)); |
171 | else |
169 | else |
172 | return find_object_name (params); |
170 | return find_object_name (params); |
173 | } |
171 | } |
… | |
… | |
318 | if (op != NULL && !QUERY_FLAG (op, FLAG_WIZ)) |
316 | if (op != NULL && !QUERY_FLAG (op, FLAG_WIZ)) |
319 | { |
317 | { |
320 | new_draw_info (NDI_UNIQUE, 0, op, "Sorry, you can't shutdown the server."); |
318 | new_draw_info (NDI_UNIQUE, 0, op, "Sorry, you can't shutdown the server."); |
321 | return 1; |
319 | return 1; |
322 | } |
320 | } |
323 | |
|
|
324 | for (pl = first_player; pl != NULL; pl = pl->next) |
|
|
325 | save_player (pl->ob, 0); |
|
|
326 | |
|
|
327 | for (pl = first_player; pl != NULL; pl = pl->next) |
|
|
328 | if (!QUERY_FLAG (pl->ob, FLAG_REMOVED)) |
|
|
329 | leave_map (pl->ob); |
|
|
330 | |
321 | |
331 | cleanup (); |
322 | cleanup (); |
332 | /* not reached */ |
323 | /* not reached */ |
333 | return 1; |
324 | return 1; |
334 | } |
325 | } |
… | |
… | |
572 | if (params == NULL) |
563 | if (params == NULL) |
573 | { |
564 | { |
574 | new_draw_info (NDI_UNIQUE, 0, op, "Usage: create [nr] [magic] <archetype> [ of <artifact>]" " [variable_to_patch setting]"); |
565 | new_draw_info (NDI_UNIQUE, 0, op, "Usage: create [nr] [magic] <archetype> [ of <artifact>]" " [variable_to_patch setting]"); |
575 | return 1; |
566 | return 1; |
576 | } |
567 | } |
|
|
568 | |
577 | bp = params; |
569 | bp = params; |
578 | |
570 | |
579 | /* We need to know where the line ends */ |
571 | /* We need to know where the line ends */ |
580 | endline = bp + strlen (bp); |
572 | endline = bp + strlen (bp); |
581 | |
573 | |
… | |
… | |
588 | } |
580 | } |
589 | bp++; |
581 | bp++; |
590 | set_nrof = 1; |
582 | set_nrof = 1; |
591 | LOG (llevDebug, "%s creates: (%d) %s\n", &op->name, nrof, bp); |
583 | LOG (llevDebug, "%s creates: (%d) %s\n", &op->name, nrof, bp); |
592 | } |
584 | } |
|
|
585 | |
593 | if (sscanf (bp, "%d ", &magic)) |
586 | if (sscanf (bp, "%d ", &magic)) |
594 | { |
587 | { |
595 | if ((bp = strchr (bp, ' ')) == NULL) |
588 | if ((bp = strchr (bp, ' ')) == NULL) |
596 | { |
589 | { |
597 | new_draw_info (NDI_UNIQUE, 0, op, "Usage: create [nr] [magic] <archetype> [ of <artifact>]" " [variable_to_patch setting]"); |
590 | new_draw_info (NDI_UNIQUE, 0, op, "Usage: create [nr] [magic] <archetype> [ of <artifact>]" " [variable_to_patch setting]"); |
598 | return 1; |
591 | return 1; |
599 | } |
592 | } |
|
|
593 | |
600 | bp++; |
594 | bp++; |
601 | set_magic = 1; |
595 | set_magic = 1; |
602 | LOG (llevDebug, "%s creates: (%d) (%d) %s\n", &op->name, nrof, magic, bp); |
596 | LOG (llevDebug, "%s creates: (%d) (%d) %s\n", &op->name, nrof, magic, bp); |
603 | } |
597 | } |
|
|
598 | |
604 | if ((cp = strstr (bp, " of ")) != NULL) |
599 | if ((cp = strstr (bp, " of ")) != NULL) |
605 | { |
600 | { |
606 | *cp = '\0'; |
601 | *cp = '\0'; |
607 | cp += 4; |
602 | cp += 4; |
608 | } |
603 | } |
|
|
604 | |
609 | for (bp2 = bp; *bp2; bp2++) |
605 | for (bp2 = bp; *bp2; bp2++) |
610 | { |
606 | { |
611 | if (*bp2 == ' ') |
607 | if (*bp2 == ' ') |
612 | { |
608 | { |
613 | *bp2 = '\0'; |
609 | *bp2 = '\0'; |
614 | bp2++; |
610 | bp2++; |
615 | break; |
611 | break; |
616 | } |
612 | } |
617 | } |
613 | } |
618 | |
614 | |
619 | if ((at = find_archetype (bp)) == NULL) |
615 | if ((at = archetype::find (bp)) == NULL) |
620 | { |
616 | { |
621 | new_draw_info (NDI_UNIQUE, 0, op, "No such archetype."); |
617 | new_draw_info (NDI_UNIQUE, 0, op, "No such archetype."); |
622 | return 1; |
618 | return 1; |
623 | } |
619 | } |
624 | |
620 | |
… | |
… | |
630 | * Try to find a spell object for this. Note that |
626 | * Try to find a spell object for this. Note that |
631 | * we also set up spell_name which is only |
627 | * we also set up spell_name which is only |
632 | * the first word. |
628 | * the first word. |
633 | */ |
629 | */ |
634 | |
630 | |
635 | at_spell = find_archetype (cp); |
631 | at_spell = archetype::find (cp); |
636 | if (!at_spell || at_spell->clone.type != SPELL) |
632 | if (!at_spell || at_spell->clone.type != SPELL) |
637 | at_spell = find_archetype_by_object_name (cp); |
633 | at_spell = find_archetype_by_object_name (cp); |
638 | if (!at_spell || at_spell->clone.type != SPELL) |
634 | if (!at_spell || at_spell->clone.type != SPELL) |
639 | { |
635 | { |
640 | strcpy (spell_name, cp); |
636 | strcpy (spell_name, cp); |
641 | fsp = strchr (spell_name, ' '); |
637 | fsp = strchr (spell_name, ' '); |
642 | if (fsp) |
638 | if (fsp) |
643 | { |
639 | { |
644 | *fsp = 0; |
640 | *fsp = 0; |
645 | fsp++; |
641 | fsp++; |
646 | at_spell = find_archetype (spell_name); |
642 | at_spell = archetype::find (spell_name); |
647 | |
643 | |
648 | /* Got a spell, update the first string pointer */ |
644 | /* Got a spell, update the first string pointer */ |
649 | if (at_spell && at_spell->clone.type == SPELL) |
645 | if (at_spell && at_spell->clone.type == SPELL) |
650 | bp2 = cp + strlen (spell_name) + 1; |
646 | bp2 = cp + strlen (spell_name) + 1; |
651 | else |
647 | else |
… | |
… | |
657 | * in this case means its an artifact. |
653 | * in this case means its an artifact. |
658 | */ |
654 | */ |
659 | if (!at_spell) |
655 | if (!at_spell) |
660 | { |
656 | { |
661 | if (find_artifactlist (at->clone.type) == NULL) |
657 | if (find_artifactlist (at->clone.type) == NULL) |
662 | { |
|
|
663 | new_draw_info_format (NDI_UNIQUE, 0, op, "No artifact list for type %d\n", at->clone.type); |
658 | new_draw_info_format (NDI_UNIQUE, 0, op, "No artifact list for type %d\n", at->clone.type); |
664 | } |
|
|
665 | else |
659 | else |
666 | { |
660 | { |
667 | art = find_artifactlist (at->clone.type)->items; |
661 | art = find_artifactlist (at->clone.type)->items; |
668 | |
662 | |
669 | do |
663 | do |
… | |
… | |
671 | if (!strcmp (art->item->name, cp)) |
665 | if (!strcmp (art->item->name, cp)) |
672 | break; |
666 | break; |
673 | art = art->next; |
667 | art = art->next; |
674 | } |
668 | } |
675 | while (art != NULL); |
669 | while (art != NULL); |
|
|
670 | |
676 | if (!art) |
671 | if (!art) |
677 | { |
|
|
678 | new_draw_info_format (NDI_UNIQUE, 0, op, "No such artifact ([%d] of %s)", at->clone.type, cp); |
672 | new_draw_info_format (NDI_UNIQUE, 0, op, "No such artifact ([%d] of %s)", at->clone.type, cp); |
679 | } |
|
|
680 | } |
673 | } |
|
|
674 | |
681 | LOG (llevDebug, "%s creates: (%d) (%d) (%s) of (%s)\n", &op->name, set_nrof ? nrof : 0, set_magic ? magic : 0, bp, cp); |
675 | LOG (llevDebug, "%s creates: (%d) (%d) (%s) of (%s)\n", &op->name, set_nrof ? nrof : 0, set_magic ? magic : 0, bp, cp); |
682 | } |
676 | } |
683 | } /* if cp */ |
677 | } /* if cp */ |
684 | |
678 | |
685 | if ((at->clone.type == ROD || at->clone.type == WAND || at->clone.type == SCROLL || |
679 | if ((at->clone.type == ROD || at->clone.type == WAND || at->clone.type == SCROLL || |
… | |
… | |
693 | * Rather than have two different blocks with a lot of similar code, |
687 | * Rather than have two different blocks with a lot of similar code, |
694 | * just create one object, do all the processing, and then determine |
688 | * just create one object, do all the processing, and then determine |
695 | * if that one object should be inserted or if we need to make copies. |
689 | * if that one object should be inserted or if we need to make copies. |
696 | */ |
690 | */ |
697 | tmp = arch_to_object (at); |
691 | tmp = arch_to_object (at); |
|
|
692 | |
698 | if (settings.real_wiz == FALSE) |
693 | if (settings.real_wiz == FALSE) |
699 | SET_FLAG (tmp, FLAG_WAS_WIZ); |
694 | SET_FLAG (tmp, FLAG_WAS_WIZ); |
|
|
695 | |
700 | if (set_magic) |
696 | if (set_magic) |
701 | set_abs_magic (tmp, magic); |
697 | set_abs_magic (tmp, magic); |
|
|
698 | |
702 | if (art) |
699 | if (art) |
703 | give_artifact_abilities (tmp, art->item); |
700 | give_artifact_abilities (tmp, art->item); |
|
|
701 | |
704 | if (need_identify (tmp)) |
702 | if (need_identify (tmp)) |
705 | { |
703 | { |
706 | SET_FLAG (tmp, FLAG_IDENTIFIED); |
704 | SET_FLAG (tmp, FLAG_IDENTIFIED); |
707 | CLEAR_FLAG (tmp, FLAG_KNOWN_MAGICAL); |
705 | CLEAR_FLAG (tmp, FLAG_KNOWN_MAGICAL); |
708 | } |
706 | } |
… | |
… | |
717 | while (*bp2 && bp2 <= endline) |
715 | while (*bp2 && bp2 <= endline) |
718 | { |
716 | { |
719 | bp4 = NULL; |
717 | bp4 = NULL; |
720 | gotspace = 0; |
718 | gotspace = 0; |
721 | gotquote = 0; |
719 | gotquote = 0; |
|
|
720 | |
722 | /* find the first quote */ |
721 | /* find the first quote */ |
723 | for (bp3 = bp2; *bp3 && gotspace < 2 && gotquote < 2; bp3++) |
722 | for (bp3 = bp2; *bp3 && gotspace < 2 && gotquote < 2; bp3++) |
724 | { |
723 | { |
725 | |
724 | |
726 | /* Found a quote - now lets find the second one */ |
725 | /* Found a quote - now lets find the second one */ |
… | |
… | |
740 | else |
739 | else |
741 | bp3++; |
740 | bp3++; |
742 | } |
741 | } |
743 | } |
742 | } |
744 | else if (*bp3 == ' ') |
743 | else if (*bp3 == ' ') |
745 | { |
|
|
746 | gotspace++; |
744 | gotspace++; |
747 | } |
|
|
748 | } |
745 | } |
749 | |
746 | |
750 | /* |
747 | /* |
751 | * If we got two spaces, send the second one to null. |
748 | * If we got two spaces, send the second one to null. |
752 | * if we've reached the end of the line, increase gotspace - |
749 | * if we've reached the end of the line, increase gotspace - |
… | |
… | |
770 | * anyways. |
767 | * anyways. |
771 | */ |
768 | */ |
772 | new_draw_info_format (NDI_UNIQUE, 0, op, "Malformed create line: %s", bp2); |
769 | new_draw_info_format (NDI_UNIQUE, 0, op, "Malformed create line: %s", bp2); |
773 | break; |
770 | break; |
774 | } |
771 | } |
|
|
772 | |
775 | /* bp2 should still point to the start of this line, |
773 | /* bp2 should still point to the start of this line, |
776 | * with bp3 pointing to the end |
774 | * with bp3 pointing to the end |
777 | */ |
775 | */ |
778 | if (set_variable (tmp, bp2) == -1) |
776 | if (set_variable (tmp, bp2) == -1) |
779 | new_draw_info_format (NDI_UNIQUE, 0, op, "Unknown variable %s", bp2); |
777 | new_draw_info_format (NDI_UNIQUE, 0, op, "Unknown variable %s", bp2); |
780 | else |
778 | else |
781 | new_draw_info_format (NDI_UNIQUE, 0, op, "(%s#%d)->%s", &tmp->name, tmp->count, bp2); |
779 | new_draw_info_format (NDI_UNIQUE, 0, op, "(%s#%d)->%s", &tmp->name, tmp->count, bp2); |
|
|
780 | |
782 | bp2 = bp3 + 1; |
781 | bp2 = bp3 + 1; |
783 | } |
782 | } |
784 | |
783 | |
785 | if (at->clone.nrof) |
784 | if (at->clone.nrof) |
786 | { |
785 | { |
787 | if (at_spell) |
786 | if (at_spell) |
788 | insert_ob_in_ob (arch_to_object (at_spell), tmp); |
787 | insert_ob_in_ob (arch_to_object (at_spell), tmp); |
789 | |
788 | |
790 | tmp->x = op->x; |
789 | tmp->x = op->x; |
791 | tmp->y = op->y; |
790 | tmp->y = op->y; |
|
|
791 | |
792 | if (set_nrof) |
792 | if (set_nrof) |
793 | tmp->nrof = nrof; |
793 | tmp->nrof = nrof; |
|
|
794 | |
794 | tmp->map = op->map; |
795 | tmp->map = op->map; |
795 | |
796 | |
796 | tmp = insert_ob_in_ob (tmp, op); |
797 | tmp = insert_ob_in_ob (tmp, op); |
797 | esrv_send_item (op, tmp); |
798 | esrv_send_item (op, tmp); |
798 | |
799 | |
… | |
… | |
804 | else |
805 | else |
805 | { |
806 | { |
806 | for (i = 0; i < (set_nrof ? nrof : 1); i++) |
807 | for (i = 0; i < (set_nrof ? nrof : 1); i++) |
807 | { |
808 | { |
808 | archetype *atmp; |
809 | archetype *atmp; |
809 | object *prev = NULL, *head = NULL, *dup; |
810 | object *prev = 0, *head = 0; |
810 | |
811 | |
811 | for (atmp = at; atmp != NULL; atmp = atmp->more) |
812 | for (atmp = at; atmp; atmp = atmp->more) |
812 | { |
813 | { |
813 | dup = arch_to_object (atmp); |
814 | object *dup = arch_to_object (atmp); |
814 | |
815 | |
815 | if (at_spell) |
816 | if (at_spell) |
816 | insert_ob_in_ob (arch_to_object (at_spell), dup); |
817 | insert_ob_in_ob (arch_to_object (at_spell), dup); |
817 | |
818 | |
818 | /* |
819 | /* |
819 | * The head is what contains all the important bits, |
820 | * The head is what contains all the important bits, |
820 | * so just copying it over should be fine. |
821 | * so just copying it over should be fine. |
821 | */ |
822 | */ |
822 | if (head == NULL) |
823 | if (!head) |
823 | { |
824 | { |
824 | head = dup; |
825 | head = dup; |
825 | copy_object (tmp, dup); |
826 | copy_object (tmp, dup); |
826 | } |
827 | } |
|
|
828 | |
827 | if (settings.real_wiz == FALSE) |
829 | if (settings.real_wiz == FALSE) |
828 | SET_FLAG (dup, FLAG_WAS_WIZ); |
830 | SET_FLAG (dup, FLAG_WAS_WIZ); |
|
|
831 | |
829 | dup->x = op->x + dup->arch->clone.x; |
832 | dup->x = op->x + dup->arch->clone.x; |
830 | dup->y = op->y + dup->arch->clone.y; |
833 | dup->y = op->y + dup->arch->clone.y; |
831 | dup->map = op->map; |
834 | dup->map = op->map; |
832 | |
835 | |
833 | if (head != dup) |
836 | if (head != dup) |
834 | { |
837 | { |
835 | dup->head = head; |
838 | dup->head = head; |
836 | prev->more = dup; |
839 | prev->more = dup; |
837 | } |
840 | } |
|
|
841 | |
838 | prev = dup; |
842 | prev = dup; |
839 | } |
843 | } |
840 | |
844 | |
841 | if (QUERY_FLAG (head, FLAG_ALIVE)) |
845 | if (QUERY_FLAG (head, FLAG_ALIVE)) |
842 | { |
846 | { |
… | |
… | |
861 | free_object (tmp); |
865 | free_object (tmp); |
862 | return 1; |
866 | return 1; |
863 | } |
867 | } |
864 | |
868 | |
865 | check = head; |
869 | check = head; |
|
|
870 | |
866 | while (check) |
871 | while (check) |
867 | { |
872 | { |
868 | check->x -= size_x; |
873 | check->x -= size_x; |
869 | check->y -= size_y; |
874 | check->y -= size_y; |
870 | check = check->more; |
875 | check = check->more; |
… | |
… | |
882 | */ |
887 | */ |
883 | dm_stack_push (op->contr, head->count); |
888 | dm_stack_push (op->contr, head->count); |
884 | |
889 | |
885 | if (at->clone.randomitems != NULL && !at_spell) |
890 | if (at->clone.randomitems != NULL && !at_spell) |
886 | create_treasure (at->clone.randomitems, head, GT_APPLY, op->map->difficulty, 0); |
891 | create_treasure (at->clone.randomitems, head, GT_APPLY, op->map->difficulty, 0); |
|
|
892 | |
887 | esrv_send_item (op, head); |
893 | esrv_send_item (op, head); |
888 | } |
894 | } |
889 | |
895 | |
890 | /* free the one we used to copy */ |
896 | /* free the one we used to copy */ |
891 | free_object (tmp); |
897 | free_object (tmp); |