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

Comparing deliantra/server/server/pets.C (file contents):
Revision 1.4 by root, Sun Sep 10 15:59:57 2006 UTC vs.
Revision 1.9 by root, Thu Sep 14 22:34:04 2006 UTC

1
2/*
3 * static char *rcsid_pets_c =
4 * "$Id: pets.C,v 1.4 2006/09/10 15:59:57 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>
165 } 159 }
166 160
167 /* No threat to owner, check to see if the pet has an attacker */ 161 /* No threat to owner, check to see if the pet has an attacker */
168 if (attacker) 162 if (attacker)
169 { 163 {
170 /* need to be sure this is the right one! */
171 if (attacker->count == pet->attacked_by_count)
172 {
173 /* also need to check to make sure it is not freindly */ 164 /* also need to check to make sure it is not freindly */
174 /* or otherwise non-hostile, and is an appropriate target */ 165 /* or otherwise non-hostile, and is an appropriate target */
175 if (!QUERY_FLAG (attacker, FLAG_FRIENDLY) && on_same_map (pet, attacker)) 166 if (!QUERY_FLAG (attacker, FLAG_FRIENDLY) && on_same_map (pet, attacker))
176 { 167 {
177 pet->enemy = attacker; 168 pet->enemy = attacker;
169
178 if (check_enemy (pet, rv) != NULL) 170 if (check_enemy (pet, rv) != NULL)
179 return attacker; 171 return attacker;
180 else 172 else
181 pet->enemy = NULL; 173 pet->enemy = NULL;
182 }
183 } 174 }
184 } 175 }
185 176
186 /* Don't have an attacker or legal enemy, so look for a new one!. 177 /* Don't have an attacker or legal enemy, so look for a new one!.
187 * This looks for one around where the pet is. Thus, you could lead 178 * This looks for one around where the pet is. Thus, you could lead
686 if (!god) 677 if (!god)
687 { 678 {
688 new_draw_info_format (NDI_UNIQUE, 0, op, "You must worship a god to cast %s.", &spob->name); 679 new_draw_info_format (NDI_UNIQUE, 0, op, "You must worship a god to cast %s.", &spob->name);
689 return 0; 680 return 0;
690 } 681 }
682
691 at = determine_holy_arch (god, spob->race); 683 at = determine_holy_arch (god, spob->race);
684
692 if (!at) 685 if (!at)
693 { 686 {
694 new_draw_info_format (NDI_UNIQUE, 0, op, "%s has no %s for you to call.", &god->name, &spob->race); 687 new_draw_info_format (NDI_UNIQUE, 0, op, "%s has no %s for you to call.", &god->name, &spob->race);
695 return 0; 688 return 0;
696 } 689 }
702 } 695 }
703 696
704 if (!dir) 697 if (!dir)
705 dir = find_free_spot (NULL, op->map, op->x, op->y, 1, SIZEOFFREE1 + 1); 698 dir = find_free_spot (NULL, op->map, op->x, op->y, 1, SIZEOFFREE1 + 1);
706 699
707 if ((dir == -1) || ob_blocked (&at->clone, op->map, op->x + freearr_x[dir], op->y + freearr_y[dir])) 700 if (dir == -1 || ob_blocked (&at->clone, op->map, op->x + freearr_x[dir], op->y + freearr_y[dir]))
708 { 701 {
709 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); 702 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way.");
710 return 0; 703 return 0;
711 } 704 }
712 /* basically want to get proper map/coordinates for this object */ 705 /* basically want to get proper map/coordinates for this object */
739 tmp->attack_movement = PETMOVE; 732 tmp->attack_movement = PETMOVE;
740 add_friendly_object (tmp); 733 add_friendly_object (tmp);
741 SET_FLAG (tmp, FLAG_FRIENDLY); 734 SET_FLAG (tmp, FLAG_FRIENDLY);
742 } 735 }
743 } 736 }
737
744 SET_FLAG (tmp, FLAG_MONSTER); 738 SET_FLAG (tmp, FLAG_MONSTER);
745 } 739 }
746 740
747 /* make the speed positive. */ 741 /* make the speed positive. */
748 tmp->speed = FABS (tmp->speed); 742 tmp->speed = FABS (tmp->speed);
751 /* players can't cope with too strong summonings. */ 745 /* players can't cope with too strong summonings. */
752 /* but monsters can. reserve these for players. */ 746 /* but monsters can. reserve these for players. */
753 if (op->type == PLAYER) 747 if (op->type == PLAYER)
754 { 748 {
755 tmp->stats.hp += spob->duration + SP_level_duration_adjust (caster, spob); 749 tmp->stats.hp += spob->duration + SP_level_duration_adjust (caster, spob);
750
756 if (!spob->stats.dam) 751 if (!spob->stats.dam)
757 tmp->stats.dam += SP_level_dam_adjust (caster, spob); 752 tmp->stats.dam += SP_level_dam_adjust (caster, spob);
758 else 753 else
759 tmp->stats.dam = spob->stats.dam + SP_level_dam_adjust (caster, spob); 754 tmp->stats.dam = spob->stats.dam + SP_level_dam_adjust (caster, spob);
755
760 tmp->speed += .02 * SP_level_range_adjust (caster, spob); 756 tmp->speed += .02 * SP_level_range_adjust (caster, spob);
761 tmp->speed = MIN (tmp->speed, 1.0); 757 tmp->speed = MIN (tmp->speed, 1.0);
758
762 if (spob->attacktype) 759 if (spob->attacktype)
763 tmp->attacktype = spob->attacktype; 760 tmp->attacktype = spob->attacktype;
764 } 761 }
762
765 tmp->stats.wc -= SP_level_range_adjust (caster, spob); 763 tmp->stats.wc -= SP_level_range_adjust (caster, spob);
766 764
767 /* limit the speed to 0.3 for non-players, 1 for players. */ 765 /* limit the speed to 0.3 for non-players, 1 for players. */
768 766
769 /* make experience increase in proportion to the strength. 767 /* make experience increase in proportion to the strength.
787 785
788 tmp->attacktype |= god->attacktype; 786 tmp->attacktype |= god->attacktype;
789 memcpy (tmp->resist, god->resist, sizeof (tmp->resist)); 787 memcpy (tmp->resist, god->resist, sizeof (tmp->resist));
790 tmp->race = god->race; 788 tmp->race = god->race;
791 tmp->slaying = god->slaying; 789 tmp->slaying = god->slaying;
790
792 /* safety, we must allow a god's servants some reasonable attack */ 791 /* safety, we must allow a god's servants some reasonable attack */
793 if (!(tmp->attacktype & AT_PHYSICAL)) 792 if (!(tmp->attacktype & AT_PHYSICAL))
794 tmp->attacktype |= AT_PHYSICAL; 793 tmp->attacktype |= AT_PHYSICAL;
795 } 794 }
796 795
887 /* This should not happen */ 886 /* This should not happen */
888 LOG (llevDebug, "choose_cult_monster() mon_nr was set, but did not find a monster\n"); 887 LOG (llevDebug, "choose_cult_monster() mon_nr was set, but did not find a monster\n");
889 return NULL; 888 return NULL;
890} 889}
891 890
892
893
894int 891int
895summon_object (object *op, object *caster, object *spell_ob, int dir, const char *stringarg) 892summon_object (object *op, object *caster, object *spell_ob, int dir, const char *stringarg)
896{ 893{
897 sint16 x, y, nrof = 1, i; 894 sint16 x, y, nrof = 1, i;
898 archetype *summon_arch; 895 archetype *summon_arch;
899 int ndir; 896 int ndir;
900 897
901 if (spell_ob->other_arch) 898 if (spell_ob->other_arch)
902 {
903 summon_arch = spell_ob->other_arch; 899 summon_arch = spell_ob->other_arch;
904 }
905 else if (spell_ob->randomitems) 900 else if (spell_ob->randomitems)
906 { 901 {
907 int level = caster_level (caster, spell_ob); 902 int level = caster_level (caster, spell_ob);
908 treasure *tr, *lasttr = NULL;; 903 treasure *tr, *lasttr = NULL;
909 904
905 shstr_cmp sparam (stringarg);
906
910 /* In old code, this was a very convuluted for statement, 907 /* In old code, this was a very convoluted for statement,
911 * with all the checks in the 'for' portion itself. Much 908 * with all the checks in the 'for' portion itself. Much
912 * more readable to break some of the conditions out. 909 * more readable to break some of the conditions out.
913 */ 910 */
914 for (tr = spell_ob->randomitems->items; tr; tr = tr->next) 911 for (tr = spell_ob->randomitems->items; tr; tr = tr->next)
915 { 912 {
916 if (level < tr->magic) 913 if (level < tr->magic)
917 break; 914 break;
915
918 lasttr = tr; 916 lasttr = tr;
919 if (stringarg && !strcmp (tr->item->name, stringarg)) 917
918 if (tr->item->name == sparam)
920 break; 919 break;
920
921 if (tr->next == NULL || tr->next->item == NULL) 921 if (!tr->next || !tr->next->item)
922 break; 922 break;
923 } 923 }
924
924 if (!lasttr) 925 if (!lasttr)
925 { 926 {
926 LOG (llevError, "Treasurelist %s did not generate a valid entry in summon_object\n", &spell_ob->randomitems->name); 927 LOG (llevError, "Treasurelist %s did not generate a valid entry in summon_object\n", &spell_ob->randomitems->name);
927 new_draw_info (NDI_UNIQUE, 0, op, "The spell fails to summon any monsters."); 928 new_draw_info (NDI_UNIQUE, 0, op, "The spell fails to summon any monsters.");
928 return 0; 929 return 0;
929 } 930 }
931
930 summon_arch = lasttr->item; 932 summon_arch = lasttr->item;
931 nrof = lasttr->nrof; 933 nrof = lasttr->nrof;
932
933 } 934 }
934 else if (spell_ob->race && !strcmp (spell_ob->race, "GODCULTMON")) 935 else if (spell_ob->race && !strcmp (spell_ob->race, "GODCULTMON"))
935 { 936 {
936 object *god = find_god (determine_god (op)), *mon, *owner; 937 object *god = find_god (determine_god (op)), *mon, *owner;
937 int summon_level, tries; 938 int summon_level, tries;
938 939
939 if (!god && ((owner = get_owner (op)) != NULL)) 940 if (!god && ((owner = get_owner (op)) != NULL))
940 {
941 god = find_god (determine_god (owner)); 941 god = find_god (determine_god (owner));
942 } 942
943 /* If we can't find a god, can't get what monster to summon */ 943 /* If we can't find a god, can't get what monster to summon */
944 if (!god) 944 if (!god)
945 return 0; 945 return 0;
946 946
947 if (!god->race) 947 if (!god->race)
948 { 948 {
949 new_draw_info_format (NDI_UNIQUE, 0, op, "%s has no creatures that you may summon!", &god->name); 949 new_draw_info_format (NDI_UNIQUE, 0, op, "%s has no creatures that you may summon!", &god->name);
950 return 0; 950 return 0;
951 } 951 }
952
952 /* the summon level */ 953 /* the summon level */
953 summon_level = caster_level (caster, spell_ob); 954 summon_level = caster_level (caster, spell_ob);
954 if (summon_level == 0) 955 if (summon_level == 0)
955 summon_level = 1; 956 summon_level = 1;
957
956 tries = 0; 958 tries = 0;
957 do 959 do
958 { 960 {
959 mon = choose_cult_monster (op, god, summon_level); 961 mon = choose_cult_monster (op, god, summon_level);
960 if (!mon) 962 if (!mon)
961 { 963 {
962 new_draw_info_format (NDI_UNIQUE, 0, op, "%s fails to send anything.", &god->name); 964 new_draw_info_format (NDI_UNIQUE, 0, op, "%s fails to send anything.", &god->name);
963 return 0; 965 return 0;
964 } 966 }
967
965 ndir = dir; 968 ndir = dir;
969
966 if (!ndir) 970 if (!ndir)
967 ndir = find_free_spot (mon, op->map, op->x, op->y, 1, SIZEOFFREE); 971 ndir = find_free_spot (mon, op->map, op->x, op->y, 1, SIZEOFFREE);
972
968 if (ndir == -1 || ob_blocked (mon, op->map, op->x + freearr_x[ndir], op->y + freearr_y[ndir])) 973 if (ndir == -1 || ob_blocked (mon, op->map, op->x + freearr_x[ndir], op->y + freearr_y[ndir]))
969 { 974 {
970 ndir = -1; 975 ndir = -1;
971 if (++tries == 5) 976 if (++tries == 5)
972 { 977 {
974 return 0; 979 return 0;
975 } 980 }
976 } 981 }
977 } 982 }
978 while (ndir == -1); 983 while (ndir == -1);
984
979 if (mon->level > (summon_level / 2)) 985 if (mon->level > (summon_level / 2))
980 nrof = random_roll (1, 2, op, PREFER_HIGH); 986 nrof = random_roll (1, 2, op, PREFER_HIGH);
981 else 987 else
982 nrof = die_roll (2, 2, op, PREFER_HIGH); 988 nrof = die_roll (2, 2, op, PREFER_HIGH);
989
983 summon_arch = mon->arch; 990 summon_arch = mon->arch;
984 } 991 }
985 else 992 else
986 {
987 summon_arch = NULL; 993 summon_arch = 0;
988 }
989 994
990 if (spell_ob->stats.dam) 995 if (spell_ob->stats.dam)
991 nrof += spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob); 996 nrof += spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob);
992 997
993 if (!summon_arch) 998 if (!summon_arch)
1034 set_owner (tmp, op); 1039 set_owner (tmp, op);
1035 set_spell_skill (op, caster, spell_ob, tmp); 1040 set_spell_skill (op, caster, spell_ob, tmp);
1036 tmp->enemy = op->enemy; 1041 tmp->enemy = op->enemy;
1037 tmp->type = 0; 1042 tmp->type = 0;
1038 CLEAR_FLAG (tmp, FLAG_SLEEP); 1043 CLEAR_FLAG (tmp, FLAG_SLEEP);
1044
1039 if (op->type == PLAYER || QUERY_FLAG (op, FLAG_FRIENDLY)) 1045 if (op->type == PLAYER || QUERY_FLAG (op, FLAG_FRIENDLY))
1040 { 1046 {
1041 /* If this is not set, we make it friendly */ 1047 /* If this is not set, we make it friendly */
1042 if (!QUERY_FLAG (spell_ob, FLAG_MONSTER)) 1048 if (!QUERY_FLAG (spell_ob, FLAG_MONSTER))
1043 { 1049 {
1044 SET_FLAG (tmp, FLAG_FRIENDLY); 1050 SET_FLAG (tmp, FLAG_FRIENDLY);
1045 add_friendly_object (tmp); 1051 add_friendly_object (tmp);
1046 tmp->stats.exp = 0; 1052 tmp->stats.exp = 0;
1053
1047 if (spell_ob->attack_movement) 1054 if (spell_ob->attack_movement)
1048 tmp->attack_movement = spell_ob->attack_movement; 1055 tmp->attack_movement = spell_ob->attack_movement;
1056
1049 if (get_owner (op)) 1057 if (get_owner (op))
1050 set_owner (tmp, get_owner (op)); 1058 set_owner (tmp, get_owner (op));
1051 } 1059 }
1052 } 1060 }
1053 } 1061 }
1062
1054 if (tmp->speed > MIN_ACTIVE_SPEED) 1063 if (tmp->speed > MIN_ACTIVE_SPEED)
1055 tmp->speed_left = -1; 1064 tmp->speed_left = -1;
1056 } 1065 }
1066
1057 if (head == NULL) 1067 if (head == NULL)
1058 head = tmp; 1068 head = tmp;
1059 else 1069 else
1060 { 1070 {
1061 tmp->head = head; 1071 tmp->head = head;
1062 prev->more = tmp; 1072 prev->more = tmp;
1063 } 1073 }
1074
1064 prev = tmp; 1075 prev = tmp;
1065 tmp->x = op->x + x + tmp->arch->clone.x; 1076 tmp->x = op->x + x + tmp->arch->clone.x;
1066 tmp->y = op->y + y + tmp->arch->clone.y; 1077 tmp->y = op->y + y + tmp->arch->clone.y;
1067 tmp->map = op->map; 1078 tmp->map = op->map;
1068 } 1079 }
1080
1069 head->direction = freedir[ndir]; 1081 head->direction = freedir[ndir];
1070 head->stats.exp = 0; 1082 head->stats.exp = 0;
1071 head = insert_ob_in_map (head, head->map, op, 0); 1083 head = insert_ob_in_map (head, head->map, op, 0);
1084
1072 if (head && head->randomitems) 1085 if (head && head->randomitems)
1073 { 1086 {
1074 object *tmp; 1087 object *tmp;
1075 1088
1076 create_treasure (head->randomitems, head, GT_APPLY | GT_STARTEQUIP, 6, 0); 1089 create_treasure (head->randomitems, head, GT_APPLY | GT_STARTEQUIP, 6, 0);
1077 for (tmp = head->inv; tmp; tmp = tmp->below) 1090 for (tmp = head->inv; tmp; tmp = tmp->below)
1078 if (!tmp->nrof) 1091 if (!tmp->nrof)
1079 SET_FLAG (tmp, FLAG_NO_DROP); 1092 SET_FLAG (tmp, FLAG_NO_DROP);
1080 } 1093 }
1081 } /* for i < nrof */ 1094 } /* for i < nrof */
1095
1082 return 1; 1096 return 1;
1083} 1097}
1084 1098
1085/* recursively look through the owner property of objects until the real owner 1099/* recursively look through the owner property of objects until the real owner
1086is found */ 1100is found */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines