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.50 by root, Thu Jan 1 15:43:35 2009 UTC vs.
Revision 1.67 by root, Sat Apr 23 04:56:56 2011 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen 6 * Copyright (©) 1992 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify 8 * Deliantra is free software: you can redistribute it and/or modify it under
9 * it under the terms of the GNU General Public License as published by 9 * the terms of the Affero GNU General Public License as published by the
10 * the Free Software Foundation, either version 3 of the License, or 10 * Free Software Foundation, either version 3 of the License, or (at your
11 * (at your option) any later version. 11 * 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 Affero GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>.
20 * 21 *
21 * The authors can be reached via e-mail to <support@deliantra.net> 22 * The authors can be reached via e-mail to <support@deliantra.net>
22 */ 23 */
23 24
24#include <global.h> 25#include <global.h>
70 // return 0; 71 // return 0;
71 72
72 /* See if the pet has an existing enemy. If so, don't start a new one */ 73 /* See if the pet has an existing enemy. If so, don't start a new one */
73 if (tmp = check_enemy (pet, rv)) 74 if (tmp = check_enemy (pet, rv))
74 { 75 {
75 if (tmp == owner && !QUERY_FLAG (pet, FLAG_CONFUSED) && QUERY_FLAG (pet, FLAG_FRIENDLY)) 76 if (tmp == owner && !pet->flag [FLAG_CONFUSED] && pet->flag [FLAG_FRIENDLY])
76 /* without this check, you can actually get pets with 77 /* without this check, you can actually get pets with
77 * enemy set to owner! 78 * enemy set to owner!
78 */ 79 */
79 pet->enemy = 0; 80 pet->enemy = 0;
80 else 81 else
124 { 125 {
125 for (tmp = GET_MAP_OB (nm, x, y); tmp != 0; tmp = tmp->above) 126 for (tmp = GET_MAP_OB (nm, x, y); tmp != 0; tmp = tmp->above)
126 { 127 {
127 object *tmp2 = tmp->head == 0 ? tmp : tmp->head; 128 object *tmp2 = tmp->head == 0 ? tmp : tmp->head;
128 129
129 if (QUERY_FLAG (tmp2, FLAG_ALIVE) && ((!QUERY_FLAG (tmp2, FLAG_FRIENDLY) && 130 if (tmp2->flag [FLAG_ALIVE] && ((!tmp2->flag [FLAG_FRIENDLY] &&
130 (tmp2->type != PLAYER)) || 131 (tmp2->type != PLAYER)) ||
131 should_arena_attack (pet, owner, tmp2)) 132 should_arena_attack (pet, owner, tmp2))
132 && !QUERY_FLAG (tmp2, FLAG_UNAGGRESSIVE) && tmp2 != pet && tmp2 != owner && can_detect_enemy (pet, tmp2, rv)) 133 && !tmp2->flag [FLAG_UNAGGRESSIVE] && tmp2 != pet && tmp2 != owner && can_detect_enemy (pet, tmp2, rv))
133 { 134 {
134 135
135 if (!can_see_enemy (pet, tmp2)) 136 if (!can_see_enemy (pet, tmp2))
136 { 137 {
137 if (tmp3 != 0) 138 if (tmp3 != 0)
165 /* No threat to owner, check to see if the pet has an attacker */ 166 /* No threat to owner, check to see if the pet has an attacker */
166 if (attacker) 167 if (attacker)
167 { 168 {
168 /* also need to check to make sure it is not freindly */ 169 /* also need to check to make sure it is not freindly */
169 /* or otherwise non-hostile, and is an appropriate target */ 170 /* or otherwise non-hostile, and is an appropriate target */
170 if (!QUERY_FLAG (attacker, FLAG_FRIENDLY) && on_same_map (pet, attacker)) 171 if (!attacker->flag [FLAG_FRIENDLY] && on_same_map (pet, attacker))
171 { 172 {
172 pet->enemy = attacker; 173 pet->enemy = attacker;
173 174
174 if (check_enemy (pet, rv) != 0) 175 if (check_enemy (pet, rv) != 0)
175 return attacker; 176 return attacker;
197 { 198 {
198 for (tmp = GET_MAP_OB (nm, x, y); tmp != 0; tmp = tmp->above) 199 for (tmp = GET_MAP_OB (nm, x, y); tmp != 0; tmp = tmp->above)
199 { 200 {
200 object *tmp2 = tmp->head == 0 ? tmp : tmp->head; 201 object *tmp2 = tmp->head == 0 ? tmp : tmp->head;
201 202
202 if (QUERY_FLAG (tmp2, FLAG_ALIVE) && ((!QUERY_FLAG (tmp2, FLAG_FRIENDLY) && 203 if (tmp2->flag [FLAG_ALIVE] && ((!tmp2->flag [FLAG_FRIENDLY] &&
203 (tmp2->type != PLAYER)) || 204 (tmp2->type != PLAYER)) ||
204 should_arena_attack (pet, owner, tmp2)) 205 should_arena_attack (pet, owner, tmp2))
205 && !QUERY_FLAG (tmp2, FLAG_UNAGGRESSIVE) && tmp2 != pet && tmp2 != owner && can_detect_enemy (pet, tmp2, rv)) 206 && !tmp2->flag [FLAG_UNAGGRESSIVE] && tmp2 != pet && tmp2 != owner && can_detect_enemy (pet, tmp2, rv))
206 { 207 {
207 208
208 if (!can_see_enemy (pet, tmp2)) 209 if (!can_see_enemy (pet, tmp2))
209 { 210 {
210 if (tmp3 != 0) 211 if (tmp3 != 0)
261} 262}
262 263
263/* 264/*
264 * Unfortunately, sometimes, the owner of a pet is in the 265 * Unfortunately, sometimes, the owner of a pet is in the
265 * process of entering a new map when this is called. 266 * process of entering a new map when this is called.
266 * Thus the map isn't loaded yet, and we have to remove
267 * the pet...
268 * Interesting enough, we don't use the passed map structure in 267 * Interesting enough, we don't use the passed map structure in
269 * this function. 268 * this function.
270 */ 269 */
271void 270void
272remove_all_pets (maptile *map) 271move_all_pets ()
273{ 272{
274 objectlink *obl, *next; 273 objectlink *obl, *next;
275 object *owner; 274 object *owner;
276 275
277 for (obl = first_friendly_object; obl; obl = next) 276 for (obl = first_friendly_object; obl; obl = next)
278 { 277 {
279 next = obl->next; 278 next = obl->next;
280 279
281 if (obl->ob->type != PLAYER 280 if (obl->ob->type != PLAYER
282 && QUERY_FLAG (obl->ob, FLAG_FRIENDLY) 281 && obl->ob->flag [FLAG_FRIENDLY]
283 && (owner = obl->ob->owner) != 0 282 && (owner = obl->ob->owner)
284 && !on_same_map (owner, obl->ob)) 283 && !on_same_map (owner, obl->ob))
285 { 284 {
286 /* follow owner checks map status for us */ 285 /* follow owner checks map status for us */
287 follow_owner (obl->ob, owner); 286 follow_owner (obl->ob, owner);
288 } 287 }
326 325
327 /* Check to see if player pulled out */ 326 /* Check to see if player pulled out */
328 if ((owner = ob->owner) == NULL) 327 if ((owner = ob->owner) == NULL)
329 { 328 {
330 ob->drop_and_destroy (); 329 ob->drop_and_destroy ();
331 LOG (llevMonster, "Pet: no owner, leaving.\n"); 330 LOG (llevTrace, "Pet: no owner, leaving.\n");
332 return; 331 return;
333 } 332 }
334 333
335 /* move monster into the owners map if not in the same map 334 /* move monster into the owners map if not in the same map
336 * except when the owner is removed. 335 * except when the owner is removed.
338 if (!on_same_map (ob, owner) && !owner->flag [FLAG_REMOVED]) 337 if (!on_same_map (ob, owner) && !owner->flag [FLAG_REMOVED])
339 { 338 {
340 follow_owner (ob, owner); 339 follow_owner (ob, owner);
341 return; 340 return;
342 } 341 }
342
343 /* Calculate Direction */ 343 /* Calculate Direction */
344 if (owner->type == PLAYER && owner->contr->petmode == pet_sad) 344 if (owner->type == PLAYER && owner->contr->petmode == pet_sad)
345 { 345 {
346 /* in S&D mode, if we have no enemy, run randomly about. */ 346 /* in S&D mode, if we have no enemy, run randomly about. */
347 for (i = 0; i < 15; i++) 347 for (i = 0; i < 15; i++)
363 struct rv_vector rv; 363 struct rv_vector rv;
364 364
365 get_rangevector (ob, ob->owner, &rv, 0); 365 get_rangevector (ob, ob->owner, &rv, 0);
366 dir = rv.direction; 366 dir = rv.direction;
367 } 367 }
368
368 ob->direction = dir; 369 ob->direction = dir;
369 370
370 /* move_ob returns 0 if the object couldn't move. If that is the 371 /* move_ob returns 0 if the object couldn't move. If that is the
371 * case, lets do some other work. 372 * case, lets do some other work.
372 */ 373 */
373 if (!(move_ob (ob, dir, ob))) 374 if (!(ob->move (dir)))
374 { 375 {
375 object *part; 376 object *part;
376 377
377 /* the failed move_ob above may destroy the pet, so check here */ 378 /* the failed move_ob above may destroy the pet, so check here */
378 if (ob->destroyed ()) 379 if (ob->destroyed ())
389 for (ob2 = GET_MAP_OB (m, dx, dy); ob2 != NULL; ob2 = ob2->above) 390 for (ob2 = GET_MAP_OB (m, dx, dy); ob2 != NULL; ob2 = ob2->above)
390 { 391 {
391 object *new_ob; 392 object *new_ob;
392 393
393 new_ob = ob2->head ? ob2->head : ob2; 394 new_ob = ob2->head ? ob2->head : ob2;
395
394 if (new_ob == ob) 396 if (new_ob == ob)
395 break; 397 break;
398
396 if (new_ob == ob->owner) 399 if (new_ob == ob->owner)
397 return; 400 return;
401
398 if (new_ob->owner == ob->owner) 402 if (new_ob->owner == ob->owner)
399 break; 403 break;
400 404
401 /* Hmm. Did we try to move into an enemy monster? If so, 405 /* Hmm. Did we try to move into an enemy monster? If so,
402 * make it our enemy. 406 * make it our enemy.
403 */ 407 */
404 if (QUERY_FLAG (new_ob, FLAG_ALIVE) && !QUERY_FLAG (ob, FLAG_UNAGGRESSIVE) 408 if (new_ob->flag [FLAG_ALIVE] && !ob->flag [FLAG_UNAGGRESSIVE]
405 && !QUERY_FLAG (new_ob, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (new_ob, FLAG_FRIENDLY)) 409 && !new_ob->flag [FLAG_UNAGGRESSIVE] && !new_ob->flag [FLAG_FRIENDLY])
406 { 410 {
407 411
408 ob->enemy = new_ob; 412 ob->enemy = new_ob;
409 if (new_ob->enemy == NULL) 413 if (new_ob->enemy == NULL)
410 new_ob->enemy = ob; 414 new_ob->enemy = ob;
417 } 421 }
418 } 422 }
419 } 423 }
420 /* Try a different course */ 424 /* Try a different course */
421 dir = absdir (dir + 4 - (rndm (5)) - (rndm (5))); 425 dir = absdir (dir + 4 - (rndm (5)) - (rndm (5)));
422 (void) move_ob (ob, dir, ob); 426 ob->move (dir);
423 } 427 }
424 return;
425} 428}
426 429
427/**************************************************************************** 430/****************************************************************************
428 * 431 *
429 * GOLEM SPELL CODE 432 * GOLEM SPELL CODE
434 * proper for map insertion. 437 * proper for map insertion.
435 * at is the archetype, op is the caster of the spell, dir is the 438 * at is the archetype, op is the caster of the spell, dir is the
436 * direction the monster should be placed in. 439 * direction the monster should be placed in.
437 * is_golem is to note that this is a golem spell. 440 * is_golem is to note that this is a golem spell.
438 */ 441 */
439object * 442static object *
440fix_summon_pet (archetype *at, object *op, int dir, int is_golem) 443fix_summon_pet (archetype *at, object *op, int dir, int is_golem)
441{ 444{
442 object *tmp = NULL, *prev = NULL, *head = NULL; 445 object *tmp = NULL, *prev = NULL, *head = NULL;
443 446
444 for (archetype *atmp = at; atmp; atmp = (archetype *)atmp->more) 447 for (archetype *atmp = at; atmp; atmp = (archetype *)atmp->more)
445 { 448 {
446 tmp = arch_to_object (atmp); 449 tmp = atmp->instance ();
447 450
448 if (atmp == at) 451 if (atmp == at)
449 { 452 {
450 if (!is_golem) 453 if (!is_golem)
451 SET_FLAG (tmp, FLAG_MONSTER); 454 tmp->set_flag (FLAG_MONSTER);
452 455
453 tmp->set_owner (op); 456 tmp->set_owner (op);
454 457
455 if (op->type == PLAYER) 458 if (op->type == PLAYER)
456 { 459 {
457 tmp->stats.exp = 0; 460 tmp->stats.exp = 0;
458 add_friendly_object (tmp); 461 add_friendly_object (tmp);
459 if (is_golem) 462 if (is_golem)
460 CLEAR_FLAG (tmp, FLAG_MONSTER); 463 tmp->clr_flag (FLAG_MONSTER);
461 } 464 }
462 else 465 else
463 { 466 {
464 if (QUERY_FLAG (op, FLAG_FRIENDLY)) 467 if (op->flag [FLAG_FRIENDLY])
465 { 468 {
466 object *owner = op->owner; 469 object *owner = op->owner;
467 470
468 if (owner) 471 if (owner)
469 { /* For now, we transfer ownership */ 472 { /* For now, we transfer ownership */
509 head->last_eat = 0; 512 head->last_eat = 0;
510 head->last_grace = 0; 513 head->last_grace = 0;
511 head->last_sp = 0; 514 head->last_sp = 0;
512 head->other_arch = NULL; 515 head->other_arch = NULL;
513 head->stats.exp = 0; 516 head->stats.exp = 0;
514 CLEAR_FLAG (head, FLAG_CHANGING); 517 head->clr_flag (FLAG_CHANGING);
515 CLEAR_FLAG (head, FLAG_STAND_STILL); 518 head->clr_flag (FLAG_STAND_STILL);
516 CLEAR_FLAG (head, FLAG_GENERATOR); 519 head->clr_flag (FLAG_GENERATOR);
517 CLEAR_FLAG (head, FLAG_SPLITTING); 520 head->clr_flag (FLAG_SPLITTING);
518 if (head->attacktype & AT_GHOSTHIT) 521 if (head->attacktype & AT_GHOSTHIT)
519 head->attacktype = (AT_PHYSICAL | AT_DRAIN); 522 head->attacktype = (AT_PHYSICAL | AT_DRAIN);
520 523
521 return head; 524 return head;
522} 525}
527move_golem (object *op) 530move_golem (object *op)
528{ 531{
529 int made_attack = 0; 532 int made_attack = 0;
530 object *tmp; 533 object *tmp;
531 534
532 if (QUERY_FLAG (op, FLAG_MONSTER)) 535 if (op->flag [FLAG_MONSTER])
533 return; /* Has already been moved */ 536 return; /* Has already been moved */
534 537
535 if (!op->owner) 538 if (!op->owner)
536 { 539 {
537 LOG (llevDebug, "Golem without owner destructed.\n"); 540 LOG (llevDebug, "Golem without owner destructed.\n");
553 return; 556 return;
554 } 557 }
555 558
556 /* Do golem attacks/movement for single & multisq golems. 559 /* Do golem attacks/movement for single & multisq golems.
557 * Assuming here that op is the 'head' object. Pass only op to 560 * Assuming here that op is the 'head' object. Pass only op to
558 * move_ob (makes recursive calls to other parts) 561 * ->move (makes recursive calls to other parts)
559 * move_ob returns 0 if the creature was not able to move. 562 * move_ob returns 0 if the creature was not able to move.
560 */ 563 */
561 if (move_ob (op, op->direction, op)) 564 if (op->move (op->direction, op))
562 return; 565 return;
563 566
564 if (op->destroyed ()) 567 if (op->destroyed ())
565 return; 568 return;
566 569
576 579
577 if (mflags & P_OUT_OF_MAP) 580 if (mflags & P_OUT_OF_MAP)
578 continue; 581 continue;
579 582
580 for (victim = GET_MAP_OB (m, x, y); victim; victim = victim->above) 583 for (victim = GET_MAP_OB (m, x, y); victim; victim = victim->above)
581 if (QUERY_FLAG (victim, FLAG_ALIVE)) 584 if (victim->flag [FLAG_ALIVE])
582 break; 585 break;
583 586
584 /* We used to call will_hit_self to make sure we don't 587 /* We used to call will_hit_self to make sure we don't
585 * hit ourselves, but that didn't work, and I don't really 588 * hit ourselves, but that didn't work, and I don't really
586 * know if that was more efficient anyways than this. 589 * know if that was more efficient anyways than this.
636int 639int
637summon_golem (object *op, object *caster, int dir, object *spob) 640summon_golem (object *op, object *caster, int dir, object *spob)
638{ 641{
639 object *tmp, *god = NULL; 642 object *tmp, *god = NULL;
640 archetype *at; 643 archetype *at;
641 char buf[MAX_BUF];
642 644
643 /* Because there can be different golem spells, player may want to 645 /* Because there can be different golem spells, player may want to
644 * 'lose' their old golem. 646 * 'lose' their old golem.
645 */ 647 */
646 if (op->type == PLAYER && op->contr->golem) 648 if (op->type == PLAYER && op->contr->golem)
699 op->contr->golem = tmp; 701 op->contr->golem = tmp;
700 /* give the player control of the golem */ 702 /* give the player control of the golem */
701 set_spell_skill (op, caster, spob, tmp); 703 set_spell_skill (op, caster, spob, tmp);
702 } 704 }
703 705
704 /* make the speed positive. */
705 tmp->speed = fabs (tmp->speed);
706
707 /* This sets the level dependencies on dam and hp for monsters */ 706 /* This sets the level dependencies on dam and hp for monsters */
708 /* players can't cope with too strong summonings. */ 707 /* players can't cope with too strong summonings. */
709 /* but monsters can. reserve these for players. */ 708 /* but monsters can. reserve these for players. */
710 if (op->type == PLAYER) 709 if (op->type == PLAYER)
711 { 710 {
712 tmp->stats.hp += spob->duration + SP_level_duration_adjust (caster, spob); 711 tmp->stats.hp += spob->duration + SP_level_duration_adjust (caster, spob);
714 if (!spob->stats.dam) 713 if (!spob->stats.dam)
715 tmp->stats.dam += SP_level_dam_adjust (caster, spob); 714 tmp->stats.dam += SP_level_dam_adjust (caster, spob);
716 else 715 else
717 tmp->stats.dam = spob->stats.dam + SP_level_dam_adjust (caster, spob); 716 tmp->stats.dam = spob->stats.dam + SP_level_dam_adjust (caster, spob);
718 717
719 tmp->speed += .02 * SP_level_range_adjust (caster, spob); 718 tmp->set_speed (min (1.f, tmp->speed + .02f * SP_level_range_adjust (caster, spob)));
720 tmp->speed = min (tmp->speed, 1.0);
721 719
722 if (spob->attacktype) 720 if (spob->attacktype)
723 tmp->attacktype = spob->attacktype; 721 tmp->attacktype = spob->attacktype;
724 } 722 }
725 723
736 tmp->direction = dir; 734 tmp->direction = dir;
737 735
738 /* Holy spell - some additional tailoring */ 736 /* Holy spell - some additional tailoring */
739 if (god) 737 if (god)
740 { 738 {
741 object *tmp2;
742
743 sprintf (buf, "%s of %s", &spob->name, &god->name); 739 char *buf = format ("%s of %s", &spob->name, &god->name);
744 buf[0] = toupper (buf[0]); 740 buf[0] = toupper (buf[0]);
745 741
746 for (tmp2 = tmp; tmp2; tmp2 = tmp2->more) 742 for (object *tmp2 = tmp; tmp2; tmp2 = tmp2->more)
747 tmp2->name = buf; 743 tmp2->name = buf;
748 744
749 tmp->attacktype |= god->attacktype; 745 tmp->attacktype |= god->attacktype;
750 memcpy (tmp->resist, god->resist, sizeof (tmp->resist)); 746 memcpy (tmp->resist, god->resist, sizeof (tmp->resist));
751 tmp->race = god->race; 747 tmp->race = god->race;
771/* Returns a monster (chosen at random) that this particular player (and his 767/* Returns a monster (chosen at random) that this particular player (and his
772 * god) find acceptable. This checks level, races allowed by god, etc 768 * god) find acceptable. This checks level, races allowed by god, etc
773 * to determine what is acceptable. 769 * to determine what is acceptable.
774 * This returns NULL if no match was found. 770 * This returns NULL if no match was found.
775 */ 771 */
776object * 772static object *
777choose_cult_monster (object *pl, object *god, int summon_level) 773choose_cult_monster (object *pl, object *god, int summon_level)
778{ 774{
779 char buf[MAX_BUF]; 775 char buf[MAX_BUF];
780 const char *race; 776 const char *race;
781 int racenr, mon_nr, i; 777 int racenr, mon_nr, i;
821 /* search for an apprplritate monster on this race list */ 817 /* search for an apprplritate monster on this race list */
822 mon_nr = 0; 818 mon_nr = 0;
823 for (tobl = list->member; tobl; tobl = tobl->next) 819 for (tobl = list->member; tobl; tobl = tobl->next)
824 { 820 {
825 otmp = tobl->ob; 821 otmp = tobl->ob;
826 if (!otmp || !QUERY_FLAG (otmp, FLAG_MONSTER)) 822 if (!otmp || !otmp->flag [FLAG_MONSTER])
827 continue; 823 continue;
828 if (otmp->level <= summon_level) 824 if (otmp->level <= summon_level)
829 mon_nr++; 825 mon_nr++;
830 } 826 }
831 827
839 835
840 mon_nr = rndm (mon_nr - 1); 836 mon_nr = rndm (mon_nr - 1);
841 for (tobl = list->member; tobl; tobl = tobl->next) 837 for (tobl = list->member; tobl; tobl = tobl->next)
842 { 838 {
843 otmp = tobl->ob; 839 otmp = tobl->ob;
844 if (!otmp || !QUERY_FLAG (otmp, FLAG_MONSTER)) 840 if (!otmp || !otmp->flag [FLAG_MONSTER])
845 continue; 841 continue;
846 842
847 if (otmp->level <= summon_level && !mon_nr--) 843 if (otmp->level <= summon_level && !mon_nr--)
848 return otmp; 844 return otmp;
849 } 845 }
854} 850}
855 851
856int 852int
857summon_object (object *op, object *caster, object *spell_ob, int dir, const char *stringarg) 853summon_object (object *op, object *caster, object *spell_ob, int dir, const char *stringarg)
858{ 854{
859 sint16 x, y, nrof = 1, i; 855 int nrof = 1;
860 archetype *summon_arch; 856 archetype *summon_arch;
861 int ndir; 857 int ndir;
862 858
863 if (spell_ob->other_arch) 859 if (spell_ob->other_arch)
864 summon_arch = spell_ob->other_arch; 860 summon_arch = spell_ob->other_arch;
895 } 891 }
896 892
897 summon_arch = lasttr->item; 893 summon_arch = lasttr->item;
898 nrof = lasttr->nrof; 894 nrof = lasttr->nrof;
899 } 895 }
900 else if (spell_ob->race && !strcmp (spell_ob->race, "GODCULTMON")) 896 else if (spell_ob->race == shstr_GODCULTMON)
901 { 897 {
902 object *god = find_god (determine_god (op)), *mon, *owner; 898 object *god = find_god (determine_god (op)), *mon, *owner;
903 int summon_level, tries; 899 int summon_level, tries;
904 900
905 if (!god && ((owner = op->owner) != NULL)) 901 if (!god && ((owner = op->owner) != NULL))
964 { 960 {
965 new_draw_info (NDI_UNIQUE, 0, op, "There is no monsters available for summoning."); 961 new_draw_info (NDI_UNIQUE, 0, op, "There is no monsters available for summoning.");
966 return 0; 962 return 0;
967 } 963 }
968 964
969 for (i = 1; i <= nrof; i++) 965 for (int i = 1; i <= nrof; i++)
970 { 966 {
971 object *prev = NULL, *head = NULL, *tmp; 967 object *prev = NULL, *head = NULL, *tmp;
972 968
973 if (dir) 969 if (dir)
974 { 970 {
976 dir = absdir (dir + 1); 972 dir = absdir (dir + 1);
977 } 973 }
978 else 974 else
979 ndir = find_free_spot (summon_arch, op->map, op->x, op->y, 1, SIZEOFFREE); 975 ndir = find_free_spot (summon_arch, op->map, op->x, op->y, 1, SIZEOFFREE);
980 976
981 if (ndir > 0)
982 {
983 x = freearr_x[ndir]; 977 sint16 x = freearr_x [ndir];
984 y = freearr_y[ndir]; 978 sint16 y = freearr_y [ndir];
985 }
986 979
987 if (ndir < 0 || summon_arch->blocked (op->map, op->x + x, op->y + y)) 980 if (ndir < 0 || summon_arch->blocked (op->map, op->x + x, op->y + y))
988 { 981 {
989 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); 982 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way.");
990 if (nrof > 1) 983 if (nrof > 1)
991 new_draw_info (NDI_UNIQUE, 0, op, "No more pets for this casting."); 984 new_draw_info (NDI_UNIQUE, 0, op, "No more pets for this casting.");
992 985
993 return nrof > 1; 986 return nrof > 1;
994 } 987 }
995 988
996 for (archetype *atmp = summon_arch; atmp != NULL; atmp = (archetype *)atmp->more) 989 for (archetype *atmp = summon_arch; atmp; atmp = (archetype *)atmp->more)
997 { 990 {
998 tmp = arch_to_object (atmp); 991 tmp = atmp->instance ();
999 if (atmp == summon_arch) 992 if (atmp == summon_arch)
1000 { 993 {
1001 if (QUERY_FLAG (tmp, FLAG_MONSTER)) 994 if (tmp->flag [FLAG_MONSTER])
1002 { 995 {
1003 tmp->set_owner (op); 996 tmp->set_owner (op);
1004 set_spell_skill (op, caster, spell_ob, tmp); 997 set_spell_skill (op, caster, spell_ob, tmp);
1005 tmp->enemy = op->enemy; 998 tmp->enemy = op->enemy;
1006 tmp->type = 0; 999 tmp->type = 0;
1007 CLEAR_FLAG (tmp, FLAG_SLEEP); 1000 tmp->clr_flag (FLAG_SLEEP);
1008 1001
1009 if (op->type == PLAYER || QUERY_FLAG (op, FLAG_FRIENDLY)) 1002 if (op->type == PLAYER || op->flag [FLAG_FRIENDLY])
1010 { 1003 {
1011 /* If this is not set, we make it friendly */ 1004 /* If this is not set, we make it friendly */
1012 if (!QUERY_FLAG (spell_ob, FLAG_MONSTER)) 1005 if (!spell_ob->flag [FLAG_MONSTER])
1013 { 1006 {
1014 add_friendly_object (tmp); 1007 add_friendly_object (tmp);
1015 tmp->stats.exp = 0; 1008 tmp->stats.exp = 0;
1016 1009
1017 if (spell_ob->attack_movement) 1010 if (spell_ob->attack_movement)
1021 tmp->set_owner (op->owner); 1014 tmp->set_owner (op->owner);
1022 } 1015 }
1023 } 1016 }
1024 } 1017 }
1025 1018
1026 if (tmp->speed > MIN_ACTIVE_SPEED) 1019 if (tmp->has_active_speed ())
1027 tmp->speed_left = -1; 1020 tmp->speed_left = -1;
1028 } 1021 }
1029 1022
1030 if (head == NULL) 1023 if (head == NULL)
1031 head = tmp; 1024 head = tmp;
1048 if (head && head->randomitems) 1041 if (head && head->randomitems)
1049 { 1042 {
1050 create_treasure (head->randomitems, head, GT_APPLY | GT_STARTEQUIP, 6, 0); 1043 create_treasure (head->randomitems, head, GT_APPLY | GT_STARTEQUIP, 6, 0);
1051 1044
1052 for (object *tmp = head->inv; tmp; tmp = tmp->below) 1045 for (object *tmp = head->inv; tmp; tmp = tmp->below)
1053 SET_FLAG (tmp, FLAG_DESTROY_ON_DEATH); 1046 tmp->set_flag (FLAG_DESTROY_ON_DEATH);
1054 } 1047 }
1055 } /* for i < nrof */ 1048 } /* for i < nrof */
1056 1049
1057 return 1; 1050 return 1;
1058} 1051}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines