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.28 by elmex, Mon Apr 16 11:50:45 2007 UTC vs.
Revision 1.38 by root, Sun Jul 1 05:00:20 2007 UTC

1/* 1/*
2 * CrossFire, A Multiplayer game for X-windows 2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 * 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team 4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * Crossfire TRT is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * 20 *
22 * The authors can be reached via e-mail at <crossfire@schmorp.de> 21 * The authors can be reached via e-mail to <crossfire@schmorp.de>
23 */ 22 */
24 23
25#include <global.h> 24#include <global.h>
26#include <sproto.h> 25#include <sproto.h>
27 26
47 if (owner = pet->owner) 46 if (owner = pet->owner)
48 { 47 {
49 /* If the owner has turned on the pet, make the pet 48 /* If the owner has turned on the pet, make the pet
50 * unfriendly. 49 * unfriendly.
51 */ 50 */
52 if ((check_enemy (owner, rv)) == pet) 51 if (check_enemy (owner, rv) == pet)
53 { 52 {
54 CLEAR_FLAG (pet, FLAG_FRIENDLY);
55 remove_friendly_object (pet); 53 remove_friendly_object (pet);
56 pet->attack_movement &= ~PETMOVE; 54 pet->attack_movement &= ~PETMOVE;
57 return owner; 55 return owner;
58 } 56 }
59 } 57 }
60 else 58 else
61 { 59 {
62 /* else the owner is no longer around, so the 60 /* else the owner is no longer around, so the
63 * pet no longer needs to be friendly. 61 * pet no longer needs to be friendly.
64 */ 62 */
65 CLEAR_FLAG (pet, FLAG_FRIENDLY);
66 remove_friendly_object (pet); 63 remove_friendly_object (pet);
67 pet->attack_movement &= ~PETMOVE; 64 pet->attack_movement &= ~PETMOVE;
68 return 0; 65 return 0;
69 } 66 }
67
70 /* If they are not on the same map, the pet won't be agressive */ 68 /* If they are not on the same map, the pet won't be agressive */
71 //if (!on_same_map (pet, owner)) 69 //if (!on_same_map (pet, owner))
72 // return 0; 70 // return 0;
73 71
74 /* See if the pet has an existing enemy. If so, don't start a new one */ 72 /* See if the pet has an existing enemy. If so, don't start a new one */
107 105
108 /* Since the pet has no existing enemy, look for anything nasty 106 /* Since the pet has no existing enemy, look for anything nasty
109 * around the owner that it should go and attack. (if the owner is 107 * around the owner that it should go and attack. (if the owner is
110 * still on a map) 108 * still on a map)
111 */ 109 */
110 // owners sometimes are not on a map but in the inventory of somehting else
112 if (!owner->flag [FLAG_REMOVED]) 111 if (!owner->flag [FLAG_REMOVED] && owner->map)
113 { 112 {
114 tmp3 = 0; 113 tmp3 = 0;
115 114
116 for (i = 0; i < SIZEOFFREE; i++) 115 for (i = 0; i < SIZEOFFREE; i++)
117 { 116 {
249void 248void
250terminate_all_pets (object *owner) 249terminate_all_pets (object *owner)
251{ 250{
252 objectlink *obl, *next; 251 objectlink *obl, *next;
253 252
254 for (obl = first_friendly_object; obl != NULL; obl = next) 253 for (obl = first_friendly_object; obl; obl = next)
255 { 254 {
256 object *ob = obl->ob; 255 object *ob = obl->ob;
257
258 next = obl->next; 256 next = obl->next;
257
259 if (ob->owner == owner) 258 if (ob->owner == owner)
260 {
261 if (!QUERY_FLAG (ob, FLAG_REMOVED))
262 ob->remove ();
263 remove_friendly_object (ob);
264 ob->destroy (); 259 ob->destroy ();
265 }
266 } 260 }
267} 261}
268 262
269/* 263/*
270 * Unfortunately, sometimes, the owner of a pet is in the 264 * Unfortunately, sometimes, the owner of a pet is in the
298int 292int
299follow_owner (object *ob, object *owner) 293follow_owner (object *ob, object *owner)
300{ 294{
301 if (owner->flag [FLAG_REMOVED]) 295 if (owner->flag [FLAG_REMOVED])
302 return 0; // do nothing if the owner is removed 296 return 0; // do nothing if the owner is removed
303 else if (owner->map->in_memory != MAP_IN_MEMORY) 297 else if (!owner->map || owner->map->in_memory != MAP_IN_MEMORY)
304 LOG (llevError, "Owner of the pet not on a map in memory!?\n"); 298 LOG (llevError, "owner '%s' of the pet '%s' not on a map in memory!?\n", &owner->name, &ob->name);
305 else 299 else
306 { 300 {
307 int dir = find_free_spot (ob, owner->map, owner->x, owner->y, 1, SIZEOFFREE); 301 int dir = find_free_spot (ob, owner->map, owner->x, owner->y, 1, SIZEOFFREE);
308 302
309 if (dir >= 0) 303 if (dir >= 0)
330 maptile *m; 324 maptile *m;
331 325
332 /* Check to see if player pulled out */ 326 /* Check to see if player pulled out */
333 if ((owner = ob->owner) == NULL) 327 if ((owner = ob->owner) == NULL)
334 { 328 {
335 ob->remove (); /* Will be freed when returning */
336 remove_friendly_object (ob);
337 ob->destroy (); 329 ob->destroy ();
338 LOG (llevMonster, "Pet: no owner, leaving.\n"); 330 LOG (llevMonster, "Pet: no owner, leaving.\n");
339 return; 331 return;
340 } 332 }
341 333
444 * is_golem is to note that this is a golem spell. 436 * is_golem is to note that this is a golem spell.
445 */ 437 */
446object * 438object *
447fix_summon_pet (archetype *at, object *op, int dir, int is_golem) 439fix_summon_pet (archetype *at, object *op, int dir, int is_golem)
448{ 440{
449 archetype *atmp;
450 object *tmp = NULL, *prev = NULL, *head = NULL; 441 object *tmp = NULL, *prev = NULL, *head = NULL;
451 442
452 for (atmp = at; atmp; atmp = atmp->more) 443 for (archetype *atmp = at; atmp; atmp = (archetype *)atmp->more)
453 { 444 {
454 tmp = arch_to_object (atmp); 445 tmp = arch_to_object (atmp);
455 446
456 if (atmp == at) 447 if (atmp == at)
457 { 448 {
458 if (!is_golem) 449 if (!is_golem)
459 SET_FLAG (tmp, FLAG_MONSTER); 450 SET_FLAG (tmp, FLAG_MONSTER);
460 451
461 tmp->set_owner (op); 452 tmp->set_owner (op);
453
462 if (op->type == PLAYER) 454 if (op->type == PLAYER)
463 { 455 {
464 tmp->stats.exp = 0; 456 tmp->stats.exp = 0;
465 add_friendly_object (tmp); 457 add_friendly_object (tmp);
466 if (is_golem) 458 if (is_golem)
494 } 486 }
495 487
496 if (!head) 488 if (!head)
497 head = tmp; 489 head = tmp;
498 490
499 tmp->x = op->x + freearr_x[dir] + tmp->arch->clone.x; 491 tmp->x = op->x + freearr_x[dir] + tmp->arch->x;
500 tmp->y = op->y + freearr_y[dir] + tmp->arch->clone.y; 492 tmp->y = op->y + freearr_y[dir] + tmp->arch->y;
501 tmp->map = op->map; 493 tmp->map = op->map;
502 494
503 if (tmp->invisible) 495 if (tmp->invisible)
504 tmp->invisible = 0; 496 tmp->invisible = 0;
505 497
537 object *tmp; 529 object *tmp;
538 530
539 if (QUERY_FLAG (op, FLAG_MONSTER)) 531 if (QUERY_FLAG (op, FLAG_MONSTER))
540 return; /* Has already been moved */ 532 return; /* Has already been moved */
541 533
542 if (op->owner == NULL) 534 if (!op->owner)
543 { 535 {
544 LOG (llevDebug, "Golem without owner destructed.\n"); 536 LOG (llevDebug, "Golem without owner destructed.\n");
545 op->remove (); 537 op->remove ();
546 op->destroy (); 538 op->destroy ();
547 return; 539 return;
555 if (--op->stats.hp < 0) 547 if (--op->stats.hp < 0)
556 { 548 {
557 if (op->msg) 549 if (op->msg)
558 new_draw_info (NDI_UNIQUE, 0, op->owner, op->msg); 550 new_draw_info (NDI_UNIQUE, 0, op->owner, op->msg);
559 551
560 op->owner->contr->ranges[range_golem] = 0;
561 remove_friendly_object (op);
562 op->remove ();
563 op->destroy (); 552 op->destroy ();
564 return; 553 return;
565 } 554 }
566 555
567 /* Do golem attacks/movement for single & multisq golems. 556 /* Do golem attacks/movement for single & multisq golems.
599 * but since we are not trying to dereferance that pointer, 588 * but since we are not trying to dereferance that pointer,
600 * that isn't a problem. 589 * that isn't a problem.
601 */ 590 */
602 if (victim && victim != op && victim->head != op) 591 if (victim && victim != op && victim->head != op)
603 { 592 {
604
605 /* for golems with race fields, we don't attack 593 /* for golems with race fields, we don't attack
606 * aligned races 594 * aligned races
607 */ 595 */
608 596
609 if (victim->race && op->race && strstr (op->race, victim->race)) 597 if (victim->race && op->race && strstr (op->race, victim->race))
653 char buf[MAX_BUF]; 641 char buf[MAX_BUF];
654 642
655 /* Because there can be different golem spells, player may want to 643 /* Because there can be different golem spells, player may want to
656 * 'lose' their old golem. 644 * 'lose' their old golem.
657 */ 645 */
658 if (op->type == PLAYER && op->contr->ranges[range_golem]) 646 if (op->type == PLAYER && op->contr->golem)
659 { 647 {
660 new_draw_info (NDI_UNIQUE, 0, op, "You dismiss your existing golem."); 648 new_draw_info (NDI_UNIQUE, 0, op, "You dismiss your existing golem.");
661 op->contr->ranges[range_golem]->remove (); 649 op->contr->golem->remove ();
662 op->contr->ranges[range_golem]->destroy (); 650 op->contr->golem->destroy ();
663 op->contr->ranges[range_golem] = 0; 651 op->contr->golem = 0;
664 } 652 }
665 653
666 if (spob->other_arch) 654 if (spob->other_arch)
667 at = spob->other_arch; 655 at = spob->other_arch;
668 else if (spob->race) 656 else if (spob->race)
688 LOG (llevError, "Spell %s lacks other_arch\n", &spob->name); 676 LOG (llevError, "Spell %s lacks other_arch\n", &spob->name);
689 return 0; 677 return 0;
690 } 678 }
691 679
692 if (!dir) 680 if (!dir)
693 dir = find_free_spot (&at->clone, op->map, op->x, op->y, 1, SIZEOFFREE1 + 1); 681 dir = find_free_spot (at, op->map, op->x, op->y, 1, SIZEOFFREE1 + 1);
694 682
695 if (dir < 0 || ob_blocked (&at->clone, op->map, op->x + freearr_x[dir], op->y + freearr_y[dir])) 683 if (dir < 0 || ob_blocked (at, op->map, op->x + freearr_x[dir], op->y + freearr_y[dir]))
696 { 684 {
697 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); 685 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way.");
698 return 0; 686 return 0;
699 } 687 }
700 688
708 696
709 if (op->type == PLAYER) 697 if (op->type == PLAYER)
710 { 698 {
711 tmp->type = GOLEM; 699 tmp->type = GOLEM;
712 tmp->set_owner (op); 700 tmp->set_owner (op);
701 op->contr->golem = tmp;
702 /* give the player control of the golem */
713 set_spell_skill (op, caster, spob, tmp); 703 set_spell_skill (op, caster, spob, tmp);
714 op->contr->ranges[range_golem] = tmp;
715 /* give the player control of the golem */
716 op->contr->shoottype = range_golem;
717 } 704 }
718 else 705 else
719 { 706 {
720 if (QUERY_FLAG (op, FLAG_FRIENDLY)) 707 if (QUERY_FLAG (op, FLAG_FRIENDLY))
721 { 708 {
910 if (level < tr->magic) 897 if (level < tr->magic)
911 break; 898 break;
912 899
913 lasttr = tr; 900 lasttr = tr;
914 901
915 if (tr->item->name == sparam) 902 if (tr->item->archname == sparam)
916 break; 903 break;
917 } 904 }
918 905
919 if (!lasttr) 906 if (!lasttr)
920 { 907 {
995 return 0; 982 return 0;
996 } 983 }
997 984
998 for (i = 1; i <= nrof; i++) 985 for (i = 1; i <= nrof; i++)
999 { 986 {
1000 archetype *atmp;
1001 object *prev = NULL, *head = NULL, *tmp; 987 object *prev = NULL, *head = NULL, *tmp;
1002 988
1003 if (dir) 989 if (dir)
1004 { 990 {
1005 ndir = dir; 991 ndir = dir;
1006 dir = absdir (dir + 1); 992 dir = absdir (dir + 1);
1007 } 993 }
1008 else 994 else
1009 ndir = find_free_spot (&summon_arch->clone, op->map, op->x, op->y, 1, SIZEOFFREE); 995 ndir = find_free_spot (summon_arch, op->map, op->x, op->y, 1, SIZEOFFREE);
1010 996
1011 if (ndir > 0) 997 if (ndir > 0)
1012 { 998 {
1013 x = freearr_x[ndir]; 999 x = freearr_x[ndir];
1014 y = freearr_y[ndir]; 1000 y = freearr_y[ndir];
1015 } 1001 }
1016 1002
1017 if (ndir < 0 || ob_blocked (&summon_arch->clone, op->map, op->x + x, op->y + y)) 1003 if (ndir < 0 || ob_blocked (summon_arch, op->map, op->x + x, op->y + y))
1018 { 1004 {
1019 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); 1005 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way.");
1020 if (nrof > 1) 1006 if (nrof > 1)
1021 new_draw_info (NDI_UNIQUE, 0, op, "No more pets for this casting."); 1007 new_draw_info (NDI_UNIQUE, 0, op, "No more pets for this casting.");
1022 1008
1023 return nrof > 1; 1009 return nrof > 1;
1024 } 1010 }
1025 1011
1026 for (atmp = summon_arch; atmp != NULL; atmp = atmp->more) 1012 for (archetype *atmp = summon_arch; atmp != NULL; atmp = (archetype *)atmp->more)
1027 { 1013 {
1028 tmp = arch_to_object (atmp); 1014 tmp = arch_to_object (atmp);
1029 if (atmp == summon_arch) 1015 if (atmp == summon_arch)
1030 { 1016 {
1031 if (QUERY_FLAG (tmp, FLAG_MONSTER)) 1017 if (QUERY_FLAG (tmp, FLAG_MONSTER))
1064 tmp->head = head; 1050 tmp->head = head;
1065 prev->more = tmp; 1051 prev->more = tmp;
1066 } 1052 }
1067 1053
1068 prev = tmp; 1054 prev = tmp;
1069 tmp->x = op->x + x + tmp->arch->clone.x; 1055 tmp->x = op->x + x + tmp->arch->x;
1070 tmp->y = op->y + y + tmp->arch->clone.y; 1056 tmp->y = op->y + y + tmp->arch->y;
1071 tmp->map = op->map; 1057 tmp->map = op->map;
1072 } 1058 }
1073 1059
1074 head->direction = freedir[ndir]; 1060 head->direction = freedir[ndir];
1075 head->stats.exp = 0; 1061 head->stats.exp = 0;
1116 return 0; 1102 return 0;
1117 1103
1118 /* get the owners of itself and the target, this is to deal with pets of 1104 /* get the owners of itself and the target, this is to deal with pets of
1119 pets */ 1105 pets */
1120 rowner = get_real_owner (owner); 1106 rowner = get_real_owner (owner);
1121 if (target->type != PLAYER) 1107 towner = target->type == PLAYER ? 0 : get_real_owner (target);
1122 {
1123 towner = get_real_owner (target);
1124 }
1125 else
1126 {
1127 towner = 0;
1128 }
1129 1108
1130 /* if the pet has now owner, exit with error */ 1109 /* if the pet has now owner, exit with error */
1131 if (rowner == NULL) 1110 if (!rowner)
1132 { 1111 {
1133 LOG (llevError, "Pet has no owner.\n"); 1112 LOG (llevError, "Pet has no owner.\n");
1134 return 0; 1113 return 0;
1135 } 1114 }
1136 1115

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines