ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/spell_effect.C
(Generate patch)

Comparing deliantra/server/server/spell_effect.C (file contents):
Revision 1.52 by root, Thu May 17 14:14:55 2007 UTC vs.
Revision 1.53 by root, Tue May 22 10:50:01 2007 UTC

609 new_draw_info (NDI_UNIQUE, 0, op, buf); 609 new_draw_info (NDI_UNIQUE, 0, op, buf);
610 break; 610 break;
611 } 611 }
612 } 612 }
613 } 613 }
614
615 return 1;
616}
617
618/* int cast_create_town_portal (object *op, object *caster, int dir)
619 *
620 * This function cast the spell of town portal for op
621 *
622 * The spell operates in two passes. During the first one a place
623 * is marked as a destination for the portal. During the second one,
624 * 2 portals are created, one in the position the player cast it and
625 * one in the destination place. The portal are synchronized and 2 forces
626 * are inserted in the player to destruct the portal next time player
627 * creates a new portal pair.
628 * This spell has a side effect that it allows people to meet each other
629 * in a permanent, private, appartements by making a town portal from it
630 * to the town or another public place. So, check if the map is unique and if
631 * so return an error
632 *
633 * Code by Tchize (david.delbecq@usa.net)
634 */
635int
636cast_create_town_portal (object *op, object *caster, object *spell, int dir)
637{
638 object *dummy, *force, *old_force;
639 archetype *perm_portal;
640 char portal_name[1024], portal_message[1024];
641 maptile *exitmap;
642 int op_level;
643
644 /* The first thing to do is to check if we have a marked destination
645 * dummy is used to make a check inventory for the force
646 */
647 dummy = arch_to_object (spell->other_arch);
648 if (dummy == NULL)
649 {
650 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
651 LOG (llevError, "object::create failed (force in cast_create_town_portal for %s!\n", &op->name);
652 return 0;
653 }
654
655 force = check_inv_recursive (op, dummy);
656
657 if (force == NULL)
658 {
659 /* Here we know there is no destination marked up.
660 * We have 2 things to do:
661 * 1. Mark the destination in the player inventory.
662 * 2. Let the player know it worked.
663 */
664 dummy->name = op->map->path;
665 EXIT_X (dummy) = op->x;
666 EXIT_Y (dummy) = op->y;
667 insert_ob_in_ob (dummy, op);
668 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "You fix this place in your mind. You feel you are able to come here from anywhere.");
669 return 1;
670 }
671
672 dummy->destroy ();
673
674 /* Here we know where the town portal should go to
675 * We should kill any existing portal associated with the player.
676 * Than we should create the 2 portals.
677 * For each of them, we need:
678 * - To create the portal with the name of the player+destination map
679 * - set the owner of the town portal
680 * - To mark the position of the portal in the player's inventory
681 * for easier destruction.
682 *
683 * The mark works has follow:
684 * slaying: Existing town portal
685 * hp, sp : x & y of the associated portal
686 * name : name of the portal
687 * race : map the portal is in
688 */
689
690 /* First step: killing existing town portals */
691 dummy = get_archetype (spell->race);
692 if (dummy == NULL)
693 {
694 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
695 LOG (llevError, "object::create failed (force) in cast_create_town_portal for %s!\n", &op->name);
696 return 0;
697 }
698
699 perm_portal = archetype::find (spell->slaying);
700
701 /* To kill a town portal, we go trough the player's inventory,
702 * for each marked portal in player's inventory,
703 * -We try load the associated map (if impossible, consider the portal destructed)
704 * -We find any portal in the specified location.
705 * If it has the good name, we destruct it.
706 * -We destruct the force indicating that portal.
707 */
708 while ((old_force = check_inv_recursive (op, dummy)))
709 {
710 exitmap = maptile::find_sync (old_force->race, op->map);
711
712 if (exitmap)
713 {
714 exitmap->load_sync ();
715
716 int exitx = EXIT_X (old_force);
717 int exity = EXIT_Y (old_force);
718
719 for (object *tmp = present_arch (perm_portal, exitmap, exitx, exity); tmp; tmp = tmp->above)
720 {
721 if (tmp->name == old_force->name)
722 {
723 tmp->destroy ();
724 break;
725 }
726 }
727 }
728
729 old_force->destroy ();
730 }
731
732 dummy->destroy ();
733
734 /* Creating the portals.
735 * The very first thing to do is to ensure
736 * access to the destination map.
737 * If we can't, don't fizzle. Simply warn player.
738 * This ensure player pays his mana for the spell
739 * because HE is responsible of forgotting.
740 * 'force' is the destination of the town portal, which we got
741 * from the players inventory above.
742 */
743
744 /* Ensure exit map is loaded */
745 exitmap = maptile::find_sync (force->name);
746
747 /* If we were unable to load (ex. random map deleted), warn player */
748 if (!exitmap)
749 {
750 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "Something strange happens. You can't remember where to go!?");
751 force->destroy ();
752 return 1;
753 }
754
755 exitmap->load_sync ();
756
757 op_level = caster_level (caster, spell);
758 if (op_level < 15)
759 snprintf (portal_message, 1024,
760 "The air moves around you and a huge smell of ammonia surounds you as you pass through %s's tiny portal. Pouah!\n",
761 &op->name);
762 else if (op_level < 30)
763 snprintf (portal_message, 1024,
764 "%s's portal smells of ozone. You do a lot of movements and finally pass through the small hole in the air\n", &op->name);
765 else if (op_level < 60)
766 snprintf (portal_message, 1024, "A shining door opens in the air in front of you, showing you the path to another place.\n");
767 else
768 snprintf (portal_message, 1024, "As you walk through %s's portal, flowers come out from the ground around you. You feel awed.\n",
769 &op->name);
770
771 /* Create a portal in front of player
772 * dummy contain the portal and
773 * force contain the track to kill it later
774 */
775 snprintf (portal_name, 1024, "%s's portal to %s", &op->name, &force->name);
776 dummy = get_archetype (spell->slaying); /*The portal */
777 if (dummy == NULL)
778 {
779 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
780 LOG (llevError, "object::create failed (perm_magic_portal) in cast_create_town_portal for %s!\n", &op->name);
781 return 0;
782 }
783
784 EXIT_PATH (dummy) = force->name;
785 EXIT_X (dummy) = EXIT_X (force);
786 EXIT_Y (dummy) = EXIT_Y (force);
787 dummy->name = dummy->name_pl = portal_name;
788 dummy->msg = portal_message;
789 dummy->race = op->name; /*Save the owner of the portal */
790 cast_create_obj (op, caster, dummy, 0);
791
792 /* Now we need to to create a town portal marker inside the player
793 * object, so on future castings, we can know that he has an active
794 * town portal.
795 */
796 object *tmp = get_archetype (spell->race);
797
798 if (!tmp)
799 {
800 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
801 LOG (llevError, "object::create failed (force) in cast_create_town_portal for %s!\n", &op->name);
802 return 0;
803 }
804
805 tmp->race = op->map->path;
806 tmp->name = portal_name;
807 EXIT_X (tmp) = dummy->x;
808 EXIT_Y (tmp) = dummy->y;
809 op->insert (tmp);
810
811 /* Create a portal in the destination map
812 * dummy contain the portal and
813 * force the track to kill it later
814 * the 'force' variable still contains the 'reminder' of
815 * where this portal goes to.
816 */
817 snprintf (portal_name, 1024, "%s's portal to %s", &op->name, &op->map->path);
818 dummy = get_archetype (spell->slaying); /*The portal */
819 if (dummy == NULL)
820 {
821 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
822 LOG (llevError, "object::create failed (perm_magic_portal) in cast_create_town_portal for %s!\n", &op->name);
823 return 0;
824 }
825
826 EXIT_PATH (dummy) = op->map->path;
827 EXIT_X (dummy) = op->x;
828 EXIT_Y (dummy) = op->y;
829 dummy->name = dummy->name_pl = portal_name;
830 dummy->msg = portal_message;
831 dummy->race = op->name; /*Save the owner of the portal */
832 exitmap->insert (dummy, EXIT_X (force), EXIT_Y (force), op);
833
834 /* Now we create another town portal marker that
835 * points back to the one we just made
836 */
837 tmp = get_archetype (spell->race);
838 if (tmp == NULL)
839 {
840 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
841 LOG (llevError, "object::create failed (force) in cast_create_town_portal for %s!\n", &op->name);
842 return 0;
843 }
844
845 tmp->race = force->name;
846 tmp->name = portal_name;
847 EXIT_X (tmp) = dummy->x;
848 EXIT_Y (tmp) = dummy->y;
849 insert_ob_in_ob (tmp, op);
850
851 /* Describe the player what happened
852 */
853 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "You see air moving and showing you the way home.");
854 force->destroy ();
855 614
856 return 1; 615 return 1;
857} 616}
858 617
859/* This creates magic walls. Really, it can create most any object, 618/* This creates magic walls. Really, it can create most any object,

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines