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.107 by elmex, Thu Sep 17 16:53:15 2009 UTC vs.
Revision 1.133 by root, Sun May 2 19:51:50 2010 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 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>
57} 58}
58 59
59int 60int
60recharge (object *op, object *caster, object *spell_ob) 61recharge (object *op, object *caster, object *spell_ob)
61{ 62{
62 object *wand, *tmp;
63 int ncharges; 63 int ncharges;
64 64
65 wand = find_marked_object (op); 65 object *wand = op->mark ();
66
66 if (!wand || wand->type != WAND) 67 if (!wand || wand->type != WAND)
67 { 68 {
68 new_draw_info (NDI_UNIQUE, 0, op, "You need to mark the wand you want to recharge."); 69 op->failmsg ("You need to mark the wand you want to recharge.");
69 return 0; 70 return 0;
70 } 71 }
72
71 if (!(random_roll (0, 3, op, PREFER_HIGH))) 73 if (!(random_roll (0, 3, op, PREFER_HIGH)))
72 { 74 {
73 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s vibrates violently, then explodes!", query_name (wand)); 75 op->failmsgf ("The %s vibrates violently, then explodes!", query_name (wand));
74 op->play_sound (sound_find ("ob_explode")); 76 op->play_sound (sound_find ("ob_explode"));
75 wand->destroy (); 77 wand->destroy ();
76 tmp = get_archetype ("fireball"); 78 object *tmp = get_archetype (shstr_fireball);
77 tmp->stats.dam = (spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob)) / 10; 79 tmp->stats.dam = (spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob)) / 10;
78 80
79 if (!tmp->stats.dam) 81 if (!tmp->stats.dam)
80 tmp->stats.dam = 1; 82 tmp->stats.dam = 1;
81 83
92 94
93 if (wand->inv && wand->inv->level) 95 if (wand->inv && wand->inv->level)
94 ncharges /= wand->inv->level; 96 ncharges /= wand->inv->level;
95 else 97 else
96 { 98 {
97 new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s is broken.", query_name (wand)); 99 op->failmsgf ("Your %s is broken.", query_name (wand));
98 return 0; 100 return 0;
99 } 101 }
100 102
101 if (!ncharges) 103 if (!ncharges)
102 ncharges = 1; 104 ncharges = 1;
103 105
104 wand->stats.food += ncharges; 106 wand->stats.food += ncharges;
105 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s glows with power.", query_name (wand)); 107 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s glows with power.", query_name (wand));
106 108
107 if (wand->arch && QUERY_FLAG (wand->arch, FLAG_ANIMATE)) 109 if (wand->arch && wand->arch->flag [FLAG_ANIMATE])
108 { 110 {
109 SET_FLAG (wand, FLAG_ANIMATE); 111 wand->set_flag (FLAG_ANIMATE);
110 wand->set_speed (wand->arch->speed); 112 wand->set_speed (wand->arch->speed);
111 } 113 }
112 114
113 return 1; 115 return 1;
114} 116}
128{ 130{
129 int bonus_plus = 0; 131 int bonus_plus = 0;
130 const char *missile_name = "arrow"; 132 const char *missile_name = "arrow";
131 133
132 for (object *tmp = op->inv; tmp; tmp = tmp->below) 134 for (object *tmp = op->inv; tmp; tmp = tmp->below)
133 if (tmp->type == BOW && QUERY_FLAG (tmp, FLAG_APPLIED)) 135 if (tmp->type == BOW && tmp->flag [FLAG_APPLIED])
134 missile_name = tmp->race; 136 missile_name = tmp->race;
135 137
136 int missile_plus = spell->stats.dam + SP_level_dam_adjust (caster, spell); 138 int missile_plus = spell->stats.dam + SP_level_dam_adjust (caster, spell);
137 139
138 archetype *missile_arch = archetype::find (missile_name); 140 archetype *missile_arch = archetype::find (missile_name);
157 break; 159 break;
158 160
159 if (!al) 161 if (!al)
160 { 162 {
161 missile->destroy (); 163 missile->destroy ();
162 new_draw_info_format (NDI_UNIQUE, 0, op, "No such object %ss of %s", missile_name, spellparam); 164 op->failmsgf ("No such object %ss of %s", missile_name, spellparam);
163 return 0; 165 return 0;
164 } 166 }
165 167
166 if (al->item->slaying) 168 if (al->item->slaying)
167 { 169 {
168 missile->destroy (); 170 missile->destroy ();
169 new_draw_info_format (NDI_UNIQUE, 0, op, "You are not allowed to create %ss of %s", missile_name, spellparam); 171 op->failmsgf ("You are not allowed to create %ss of %s", missile_name, spellparam);
170 return 0; 172 return 0;
171 } 173 }
172 174
173 give_artifact_abilities (missile, al->item); 175 give_artifact_abilities (missile, al->item);
174 /* These special arrows cost something extra. Don't have them also be magical - 176 /* These special arrows cost something extra. Don't have them also be magical -
192 194
193 missile->magic = missile_plus; 195 missile->magic = missile_plus;
194 /* Can't get any money for these objects */ 196 /* Can't get any money for these objects */
195 missile->value = 0; 197 missile->value = 0;
196 198
197 SET_FLAG (missile, FLAG_IDENTIFIED); 199 missile->set_flag (FLAG_IDENTIFIED);
198 200
199 if (!cast_create_obj (op, caster, missile, dir) && op->type == PLAYER && !missile->destroyed ()) 201 if (!cast_create_obj (op, caster, missile, dir) && op->type == PLAYER && !missile->destroyed ())
200 pick_up (op, missile); 202 pick_up (op, missile);
201 203
202 return 1; 204 return 1;
256 /* Pretty unlikely (there are some very low food items), but you never 258 /* Pretty unlikely (there are some very low food items), but you never
257 * know 259 * know
258 */ 260 */
259 if (!at) 261 if (!at)
260 { 262 {
261 new_draw_info (NDI_UNIQUE, 0, op, "You don't have enough experience to create any food."); 263 op->failmsgf ("You don't have enough experience to create any food.");
262 return 0; 264 return 0;
263 } 265 }
264 266
265 food_value /= at->stats.food; 267 food_value /= at->stats.food;
266 new_op = arch_to_object (at); 268 new_op = at->instance ();
267 new_op->nrof = food_value; 269 new_op->nrof = food_value;
268 270
269 new_op->value = 0; 271 new_op->value = 0;
270 if (new_op->nrof < 1) 272 if (new_op->nrof < 1)
271 new_op->nrof = 1; 273 new_op->nrof = 1;
296 mflags = get_map_flags (m, &m, x, y, &x, &y); 298 mflags = get_map_flags (m, &m, x, y, &x, &y);
297 299
298 if (mflags & P_OUT_OF_MAP) 300 if (mflags & P_OUT_OF_MAP)
299 break; 301 break;
300 302
301 if (!QUERY_FLAG (op, FLAG_WIZCAST) && (mflags & P_NO_MAGIC)) 303 if (!op->flag [FLAG_WIZCAST] && (mflags & P_NO_MAGIC))
302 { 304 {
303 new_draw_info (NDI_UNIQUE, 0, op, "Something blocks your magic."); 305 new_draw_info (NDI_UNIQUE, 0, op, "Something blocks your magic.");
304 return 0; 306 return 0;
305 } 307 }
306 308
307 if (mflags & P_IS_ALIVE) 309 if (mflags & P_IS_ALIVE)
308 { 310 {
309 for (tmp = GET_MAP_OB (m, x, y); tmp; tmp = tmp->above) 311 for (tmp = GET_MAP_OB (m, x, y); tmp; tmp = tmp->above)
310 if (QUERY_FLAG (tmp, FLAG_ALIVE) && (tmp->type == PLAYER || QUERY_FLAG (tmp, FLAG_MONSTER))) 312 if (tmp->flag [FLAG_ALIVE] && (tmp->type == PLAYER || tmp->flag [FLAG_MONSTER]))
311 { 313 {
312 new_draw_info (NDI_UNIQUE, 0, op, "You detect something."); 314 new_draw_info (NDI_UNIQUE, 0, op, "You detect something.");
313 if (tmp->head != NULL) 315 if (tmp->head != NULL)
314 tmp = tmp->head; 316 tmp = tmp->head;
315 examine_monster (op, tmp); 317 examine_monster (op, tmp);
338 if (pl->type == PLAYER) 340 if (pl->type == PLAYER)
339 { 341 {
340 /* If race isn't set, then invisible unless it is undead */ 342 /* If race isn't set, then invisible unless it is undead */
341 if (!pl->contr->invis_race) 343 if (!pl->contr->invis_race)
342 { 344 {
343 if (QUERY_FLAG (mon, FLAG_UNDEAD)) 345 if (mon->flag [FLAG_UNDEAD])
344 return 0; 346 return 0;
345 347
346 return 1; 348 return 1;
347 } 349 }
348 350
379int 381int
380cast_invisible (object *op, object *caster, object *spell_ob) 382cast_invisible (object *op, object *caster, object *spell_ob)
381{ 383{
382 if (op->invisible > 1000) 384 if (op->invisible > 1000)
383 { 385 {
384 new_draw_info (NDI_UNIQUE, 0, op, "You can not extend the duration of your invisibility any further"); 386 op->failmsg ("You can not extend the duration of your invisibility any further");
385 return 0; 387 return 0;
386 } 388 }
387 389
388 /* Remove the switch with 90% duplicate code - just handle the differences with 390 /* Remove the switch with 90% duplicate code - just handle the differences with
389 * and if statement or two. 391 * and if statement or two.
395 397
396 if (op->type == PLAYER) 398 if (op->type == PLAYER)
397 { 399 {
398 op->contr->invis_race = spell_ob->race; 400 op->contr->invis_race = spell_ob->race;
399 401
400 if (QUERY_FLAG (spell_ob, FLAG_MAKE_INVIS)) 402 if (spell_ob->flag [FLAG_MAKE_INVIS])
401 op->contr->tmp_invis = 0; 403 op->contr->tmp_invis = 0;
402 else 404 else
403 op->contr->tmp_invis = 1; 405 op->contr->tmp_invis = 1;
404 406
405 op->contr->hidden = 0; 407 op->contr->hidden = 0;
447 // earth to dust tears down everything that can be torn down 449 // earth to dust tears down everything that can be torn down
448 for (object *next, *tmp = m->at (sx, sy).bot; tmp; tmp = next) 450 for (object *next, *tmp = m->at (sx, sy).bot; tmp; tmp = next)
449 { 451 {
450 next = tmp->above; 452 next = tmp->above;
451 453
452 if (QUERY_FLAG (tmp, FLAG_TEAR_DOWN)) 454 if (tmp->flag [FLAG_TEAR_DOWN])
453 hit_player (tmp, 9998, op, AT_PHYSICAL, 0); 455 hit_player (tmp, 9998, op, AT_PHYSICAL, 0);
454 } 456 }
455 } 457 }
456 458
457 return 1; 459 return 1;
459 461
460void 462void
461execute_word_of_recall (object *op) 463execute_word_of_recall (object *op)
462{ 464{
463 if (object *pl = op->in_player ()) 465 if (object *pl = op->in_player ())
464 {
465 if (pl->ms ().flags () & P_NO_CLERIC && !QUERY_FLAG (pl, FLAG_WIZCAST)) 466 if (pl->ms ().flags () & P_NO_CLERIC && !pl->flag [FLAG_WIZCAST])
466 new_draw_info (NDI_UNIQUE, 0, pl, "You feel something fizzle inside you."); 467 new_draw_info (NDI_UNIQUE, 0, pl, "You feel something fizzle inside you.");
467 else 468 else
468 pl->player_goto (op->slaying, op->stats.hp, op->stats.sp); 469 pl->player_goto (op->slaying, op->stats.hp, op->stats.sp);
469 }
470 470
471 op->destroy (); 471 op->destroy ();
472} 472}
473 473
474/* Word of recall causes the player to return 'home'. 474/* Word of recall causes the player to return 'home'.
476 * time delay effect. 476 * time delay effect.
477 */ 477 */
478int 478int
479cast_word_of_recall (object *op, object *caster, object *spell_ob) 479cast_word_of_recall (object *op, object *caster, object *spell_ob)
480{ 480{
481 object *dummy; 481 if (!op->is_player ())
482 int time;
483
484 if (op->type != PLAYER)
485 return 0; 482 return 0;
486 483
487 if (find_obj_by_type_subtype (op, SPELL_EFFECT, SP_WORD_OF_RECALL)) 484 if (find_obj_by_type_subtype (op, SPELL_EFFECT, SP_WORD_OF_RECALL))
488 { 485 {
489 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you."); 486 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you.");
490 return 1; 487 return 1;
491 } 488 }
492 489
493 dummy = get_archetype (FORCE_NAME); 490 object *dummy = get_archetype (FORCE_NAME);
494 491
495 if (!dummy)
496 {
497 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
498 LOG (llevError, "cast_word_of_recall: get_archetype(force) failed!\n");
499 return 0;
500 }
501
502 time = spell_ob->duration - SP_level_duration_adjust (caster, spell_ob); 492 int time = max (1, spell_ob->duration - SP_level_duration_adjust (caster, spell_ob));
503 if (time < 1)
504 time = 1;
505 493
506 /* value of speed really doesn't make much difference, as long as it is 494 /* value of speed really doesn't make much difference, as long as it is
507 * positive. Lower value may be useful so that the problem doesn't 495 * positive. Lower value may be useful so that the problem doesn't
508 * do anything really odd if it say a -1000 or something. 496 * do anything really odd if it say a -1000 or something.
509 */ 497 */
510 dummy->set_speed (0.002); 498 dummy->set_speed (0.002);
511 dummy->speed_left = -dummy->speed * time; 499 dummy->speed_left = -dummy->speed * time;
512 dummy->type = SPELL_EFFECT; 500 dummy->type = SPELL_EFFECT;
513 dummy->subtype = SP_WORD_OF_RECALL; 501 dummy->subtype = SP_WORD_OF_RECALL;
514 502 dummy->slaying = op->contr->savebed_map;
515 /* If we could take advantage of enter_player_savebed() here, it would be 503 dummy->stats.hp = op->contr->bed_x;
516 * nice, but until the map load fails, we can't. 504 dummy->stats.sp = op->contr->bed_y;
517 */
518 EXIT_PATH (dummy) = op->contr->savebed_map;
519 EXIT_X (dummy) = op->contr->bed_x;
520 EXIT_Y (dummy) = op->contr->bed_y;
521 505
522 op->insert (dummy); 506 op->insert (dummy);
523 507
524 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you."); 508 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you.");
525 509
564 548
565int 549int
566perceive_self (object *op) 550perceive_self (object *op)
567{ 551{
568 const char *cp = describe_item (op, op); 552 const char *cp = describe_item (op, op);
569 archetype *at = archetype::find (ARCH_DEPLETION); 553 archetype *at = archetype::find (shstr_depletion);
570 554
571 dynbuf_text &buf = msg_dynbuf; buf.clear (); 555 dynbuf_text &buf = msg_dynbuf; buf.clear ();
572 556
573 if (!op->is_player ()) 557 if (!op->is_player ())
574 return 0; 558 return 0;
593 for (int i = 0; i < NUM_STATS; i++) 577 for (int i = 0; i < NUM_STATS; i++)
594 if (tmp->stats.stat (i) < 0) 578 if (tmp->stats.stat (i) < 0)
595 buf.printf (" - Your %s is depleted by %d.\n", statname[i], -tmp->stats.stat (i)); 579 buf.printf (" - Your %s is depleted by %d.\n", statname[i], -tmp->stats.stat (i));
596 } 580 }
597 581
598 if (is_dragon_pl (op)) 582 if (op->is_dragon ())
599 /* now grab the 'dragon_ability'-force from the player's inventory */ 583 /* now grab the 'dragon_ability'-force from the player's inventory */
600 for (tmp = op->inv; tmp; tmp = tmp->below) 584 for (tmp = op->inv; tmp; tmp = tmp->below)
601 { 585 {
602 if (tmp->type == FORCE && tmp->arch->archname == shstr_dragon_ability_force) 586 if (tmp->type == FORCE && tmp->arch->archname == shstr_dragon_ability_force)
603 { 587 {
644 628
645 if ((spell_ob->move_block || x != op->x || y != op->y) && 629 if ((spell_ob->move_block || x != op->x || y != op->y) &&
646 (get_map_flags (m, &m, x, y, &x, &y) & (P_OUT_OF_MAP | P_IS_ALIVE) || 630 (get_map_flags (m, &m, x, y, &x, &y) & (P_OUT_OF_MAP | P_IS_ALIVE) ||
647 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK (m, x, y)) == spell_ob->move_block))) 631 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK (m, x, y)) == spell_ob->move_block)))
648 { 632 {
649 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way."); 633 op->failmsg ("Something is in the way.");
650 return 0; 634 return 0;
651 } 635 }
652 636
653 if (spell_ob->other_arch) 637 if (spell_ob->other_arch)
654 tmp = arch_to_object (spell_ob->other_arch); 638 tmp = spell_ob->other_arch->instance ();
655 else if (spell_ob->race) 639 else if (spell_ob->race)
656 { 640 {
657 char buf1[MAX_BUF]; 641 char buf1[MAX_BUF];
658 642
659 sprintf (buf1, spell_ob->race, dir); 643 sprintf (buf1, spell_ob->race, dir);
663 LOG (llevError, "summon_wall: Unable to find archetype %s\n", buf1); 647 LOG (llevError, "summon_wall: Unable to find archetype %s\n", buf1);
664 new_draw_info (NDI_UNIQUE, 0, op, "This spell is broken."); 648 new_draw_info (NDI_UNIQUE, 0, op, "This spell is broken.");
665 return 0; 649 return 0;
666 } 650 }
667 651
668 tmp = arch_to_object (at); 652 tmp = at->instance ();
669 } 653 }
670 else 654 else
671 { 655 {
672 LOG (llevError, "magic_wall: spell %s lacks other_arch\n", &spell_ob->name); 656 LOG (llevError, "magic_wall: spell %s lacks other_arch\n", &spell_ob->name);
673 return 0; 657 return 0;
678 tmp->attacktype = spell_ob->attacktype; 662 tmp->attacktype = spell_ob->attacktype;
679 tmp->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob); 663 tmp->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
680 tmp->stats.dam = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob); 664 tmp->stats.dam = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob);
681 tmp->range = 0; 665 tmp->range = 0;
682 } 666 }
683 else if (QUERY_FLAG (tmp, FLAG_ALIVE)) 667 else if (tmp->flag [FLAG_ALIVE])
684 { 668 {
685 tmp->stats.hp = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob); 669 tmp->stats.hp = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
686 tmp->stats.maxhp = tmp->stats.hp; 670 tmp->stats.maxhp = tmp->stats.hp;
687 } 671 }
688 672
689 if (QUERY_FLAG (spell_ob, FLAG_IS_USED_UP) || QUERY_FLAG (tmp, FLAG_IS_USED_UP)) 673 if (spell_ob->flag [FLAG_IS_USED_UP] || tmp->flag [FLAG_IS_USED_UP])
690 { 674 {
691 tmp->stats.food = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob); 675 tmp->stats.food = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
692 SET_FLAG (tmp, FLAG_IS_USED_UP); 676 tmp->set_flag (FLAG_IS_USED_UP);
693 } 677 }
694 678
695 if (QUERY_FLAG (spell_ob, FLAG_TEAR_DOWN)) 679 if (spell_ob->flag [FLAG_TEAR_DOWN])
696 { 680 {
697 tmp->stats.hp = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob); 681 tmp->stats.hp = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob);
698 tmp->stats.maxhp = tmp->stats.hp; 682 tmp->stats.maxhp = tmp->stats.hp;
699 SET_FLAG (tmp, FLAG_TEAR_DOWN); 683 tmp->set_flag (FLAG_TEAR_DOWN);
700 SET_FLAG (tmp, FLAG_ALIVE); 684 tmp->set_flag (FLAG_ALIVE);
701 } 685 }
702 686
703 /* This can't really hurt - if the object doesn't kill anything, 687 /* This can't really hurt - if the object doesn't kill anything,
704 * these fields just won't be used. Do not set the owner for 688 * these fields just won't be used. Do not set the owner for
705 * earthwalls, though, so they survive restarts. 689 * earthwalls, though, so they survive restarts.
717 return 0; 701 return 0;
718 } 702 }
719 703
720 /* If this is a spellcasting wall, need to insert the spell object */ 704 /* If this is a spellcasting wall, need to insert the spell object */
721 if (tmp->other_arch && tmp->other_arch->type == SPELL) 705 if (tmp->other_arch && tmp->other_arch->type == SPELL)
722 insert_ob_in_ob (arch_to_object (tmp->other_arch), tmp); 706 insert_ob_in_ob (tmp->other_arch->instance (), tmp);
723 707
724 /* This code causes the wall to extend some distance in 708 /* This code causes the wall to extend some distance in
725 * each direction, or until an obstruction is encountered. 709 * each direction, or until an obstruction is encountered.
726 * posblocked and negblocked help determine how far the 710 * posblocked and negblocked help determine how far the
727 * created wall can extend, it won't go extend through 711 * created wall can extend, it won't go extend through
747 object *tmp2 = tmp->clone (); 731 object *tmp2 = tmp->clone ();
748 m->insert (tmp2, x, y, op); 732 m->insert (tmp2, x, y, op);
749 733
750 /* If this is a spellcasting wall, need to insert the spell object */ 734 /* If this is a spellcasting wall, need to insert the spell object */
751 if (tmp2->other_arch && tmp2->other_arch->type == SPELL) 735 if (tmp2->other_arch && tmp2->other_arch->type == SPELL)
752 tmp2->insert (arch_to_object (tmp2->other_arch)); 736 tmp2->insert (tmp2->other_arch->instance ());
753 737
754 } 738 }
755 else 739 else
756 posblocked = 1; 740 posblocked = 1;
757 741
764 { 748 {
765 object *tmp2 = tmp->clone (); 749 object *tmp2 = tmp->clone ();
766 m->insert (tmp2, x, y, op); 750 m->insert (tmp2, x, y, op);
767 751
768 if (tmp2->other_arch && tmp2->other_arch->type == SPELL) 752 if (tmp2->other_arch && tmp2->other_arch->type == SPELL)
769 tmp2->insert (arch_to_object (tmp2->other_arch)); 753 tmp2->insert (tmp2->other_arch->instance ());
770 } 754 }
771 else 755 else
772 negblocked = 1; 756 negblocked = 1;
773 } 757 }
774 758
775 if (QUERY_FLAG (tmp, FLAG_BLOCKSVIEW)) 759 if (tmp->flag [FLAG_BLOCKSVIEW])
776 update_all_los (op->map, op->x, op->y); 760 update_all_los (op->map, op->x, op->y);
777 761
778 return 1; 762 return 1;
779} 763}
780 764
789 if (op->type != PLAYER) 773 if (op->type != PLAYER)
790 return 0; 774 return 0;
791 775
792 if (!dir) 776 if (!dir)
793 { 777 {
794 new_draw_info (NDI_UNIQUE, 0, op, "In what direction?"); 778 op->failmsg ("In what direction?");
795 return 0; 779 return 0;
796 } 780 }
797 781
798 /* Given the new outdoor maps, can't let players dimension door for 782 /* Given the new outdoor maps, can't let players dimension door for
799 * ever, so put limits in. 783 * ever, so put limits in.
804 { 788 {
805 int count = atoi (spellparam); 789 int count = atoi (spellparam);
806 790
807 if (count > maxdist) 791 if (count > maxdist)
808 { 792 {
809 new_draw_info (NDI_UNIQUE, 0, op, "You can't dimension door that far!"); 793 op->failmsg ("You can't dimension door that far!");
810 return 0; 794 return 0;
811 } 795 }
812 796
813 for (dist = 0; dist < count; dist++) 797 for (dist = 0; dist < count; dist++)
814 { 798 {
875 break; 859 break;
876 860
877 } 861 }
878 if (!dist) 862 if (!dist)
879 { 863 {
880 new_draw_info (NDI_UNIQUE, 0, op, "Your spell failed!\n"); 864 op->failmsg ("Your spell failed!\n");
881 return 0; 865 return 0;
882 } 866 }
883 } 867 }
884 868
885 /* Actually move the player now */ 869 /* Actually move the player now */
886 if (!(op = op->map->insert (op, op->x + freearr_x[dir] * dist, op->y + freearr_y[dir] * dist, op))) 870 if (!(op = op->map->insert (op, op->x + freearr_x[dir] * dist, op->y + freearr_y[dir] * dist, op)))
887 return 1; 871 return 1;
888 872
889 op->speed_left = -FABS (op->speed) * 5; /* Freeze them for a short while */ 873 op->speed_left = -5. * op->speed; /* Freeze them for a short while */
874
890 return 1; 875 return 1;
891} 876}
892 877
893/* cast_heal: Heals something. 878/* cast_heal: Heals something.
894 * op is the caster. 879 * op is the caster.
949 if (cure_disease (tmp, op, spell)) 934 if (cure_disease (tmp, op, spell))
950 success = 1; 935 success = 1;
951 936
952 if (spell->attacktype & AT_POISON) 937 if (spell->attacktype & AT_POISON)
953 { 938 {
954 at = archetype::find ("poisoning"); 939 at = archetype::find (shstr_poisoning);
955 poison = present_arch_in_ob (at, tmp); 940 poison = present_arch_in_ob (at, tmp);
956 if (poison) 941 if (poison)
957 { 942 {
958 success = 1; 943 success = 1;
959 new_draw_info (NDI_UNIQUE, 0, tmp, "Your body feels cleansed"); 944 new_draw_info (NDI_UNIQUE, 0, tmp, "Your body feels cleansed");
961 } 946 }
962 } 947 }
963 948
964 if (spell->attacktype & AT_CONFUSION) 949 if (spell->attacktype & AT_CONFUSION)
965 { 950 {
966 poison = present_in_ob_by_name (FORCE, "confusion", tmp); 951 poison = present_in_ob_by_name (FORCE, shstr_confusion, tmp);
967 if (poison) 952 if (poison)
968 { 953 {
969 success = 1; 954 success = 1;
970 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer"); 955 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer");
971 poison->duration = 1; 956 poison->duration = 1;
972 } 957 }
973 } 958 }
974 959
975 if (spell->attacktype & AT_BLIND) 960 if (spell->attacktype & AT_BLIND)
976 { 961 {
977 at = archetype::find ("blindness"); 962 at = archetype::find (shstr_blindness);
978 poison = present_arch_in_ob (at, tmp); 963 poison = present_arch_in_ob (at, tmp);
979 if (poison) 964 if (poison)
980 { 965 {
981 success = 1; 966 success = 1;
982 new_draw_info (NDI_UNIQUE, 0, tmp, "Your vision begins to return."); 967 new_draw_info (NDI_UNIQUE, 0, tmp, "Your vision begins to return.");
1000 tmp->stats.grace = tmp->stats.maxgrace; 985 tmp->stats.grace = tmp->stats.maxgrace;
1001 success = 1; 986 success = 1;
1002 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!"); 987 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!");
1003 } 988 }
1004 989
1005 if (spell->stats.food && tmp->stats.food < 999) 990 if (spell->stats.food && tmp->stats.food < MAX_FOOD)
1006 { 991 {
1007 tmp->stats.food += spell->stats.food; 992 tmp->stats.food += spell->stats.food;
1008 993 min_it (tmp->stats.food, MAX_FOOD);
1009 if (tmp->stats.food > 999)
1010 tmp->stats.food = 999;
1011 994
1012 success = 1; 995 success = 1;
1013 /* We could do something a bit better like the messages for healing above */ 996 /* We could do something a bit better like the messages for healing above */
1014 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel your belly fill with food"); 997 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel your belly fill with food");
1015 } 998 }
1062 break; 1045 break;
1063 } 1046 }
1064 else if (spell_ob->race && spell_ob->race == tmp2->name) 1047 else if (spell_ob->race && spell_ob->race == tmp2->name)
1065 { 1048 {
1066 if (!silent) 1049 if (!silent)
1067 new_draw_info_format (NDI_UNIQUE, 0, op, "You can not cast %s while %s is in effect", &spell_ob->name, &tmp2->name_pl); 1050 op->failmsgf ("You can not cast %s while %s is in effect",
1051 &spell_ob->name, &tmp2->name_pl);
1068 1052
1069 return 0; 1053 return 0;
1070 } 1054 }
1071 } 1055 }
1072 } 1056 }
1073 1057
1074 if (!force)
1075 {
1076 force = get_archetype (FORCE_NAME);
1077 force->subtype = FORCE_CHANGE_ABILITY;
1078
1079 if (spell_ob->race)
1080 force->name = spell_ob->race;
1081 else
1082 force->name = spell_ob->name;
1083
1084 force->name_pl = spell_ob->name;
1085 new_draw_info (NDI_UNIQUE, 0, op, "You create an aura of magical force.");
1086
1087 }
1088 else
1089 {
1090 int duration = change_ability_duration (spell_ob, caster); 1058 int duration = change_ability_duration (spell_ob, caster);
1091 1059
1060 if (force)
1061 {
1092 if (duration > force->duration) 1062 if (duration > force->duration)
1093 { 1063 {
1094 force->duration = duration; 1064 force->duration = duration;
1095 new_draw_info (NDI_UNIQUE, 0, op, "You recast the spell while in effect."); 1065 new_draw_info (NDI_UNIQUE, 0, op, "You recast the spell while in effect.");
1096 } 1066 }
1098 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect."); 1068 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect.");
1099 1069
1100 return 1; 1070 return 1;
1101 } 1071 }
1102 1072
1103 force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50; 1073 new_draw_info_format (NDI_UNIQUE, 0, op,
1074 "You create an aura of magical force. H<The effect will last for about %.10g seconds.>",
1075 TICK2TIME (duration));
1076
1077 force = get_archetype (FORCE_NAME);
1078 force->subtype = FORCE_CHANGE_ABILITY;
1079 force->duration = duration;
1080
1081 if (spell_ob->race)
1082 force->name = spell_ob->race;
1083 else
1084 force->name = spell_ob->name;
1085
1086 force->name_pl = spell_ob->name;
1087
1104 force->speed = 1.0; 1088 force->speed = 1.0;
1105 force->speed_left = -1.0; 1089 force->speed_left = -1.0;
1106 SET_FLAG (force, FLAG_APPLIED); 1090 force->set_flag (FLAG_APPLIED);
1107 1091
1108 /* Now start processing the effects. First, protections */ 1092 /* Now start processing the effects. First, protections */
1109 for (i = 0; i < NROFATTACKS; i++) 1093 for (i = 0; i < NROFATTACKS; i++)
1110 {
1111 if (spell_ob->resist[i]) 1094 if (spell_ob->resist[i])
1112 {
1113 force->resist[i] = spell_ob->resist[i] + SP_level_dam_adjust (caster, spell_ob); 1095 force->resist[i] = min (100, spell_ob->resist[i] + SP_level_dam_adjust (caster, spell_ob));
1114 if (force->resist[i] > 100)
1115 force->resist[i] = 100;
1116 }
1117 }
1118 1096
1119 if (spell_ob->stats.hp) 1097 if (spell_ob->stats.hp)
1120 force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust (caster, spell_ob); 1098 force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust (caster, spell_ob);
1121 1099
1122 if (tmp->type == PLAYER) 1100 if (tmp->type == PLAYER)
1141 } 1119 }
1142 } 1120 }
1143 1121
1144 force->move_type = spell_ob->move_type; 1122 force->move_type = spell_ob->move_type;
1145 1123
1146 if (QUERY_FLAG (spell_ob, FLAG_SEE_IN_DARK)) 1124 if (spell_ob->flag [FLAG_SEE_IN_DARK])
1147 SET_FLAG (force, FLAG_SEE_IN_DARK); 1125 force->set_flag (FLAG_SEE_IN_DARK);
1148 1126
1149 if (QUERY_FLAG (spell_ob, FLAG_XRAYS)) 1127 if (spell_ob->flag [FLAG_XRAYS])
1150 SET_FLAG (force, FLAG_XRAYS); 1128 force->set_flag (FLAG_XRAYS);
1151 1129
1152 /* Haste/bonus speed */ 1130 /* Haste/bonus speed */
1153 if (spell_ob->stats.exp) 1131 if (spell_ob->stats.exp)
1154 { 1132 {
1155 if (op->speed > 0.5f) 1133 if (op->speed > 0.5f)
1233 { 1211 {
1234 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect."); 1212 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect.");
1235 } 1213 }
1236 return 0; 1214 return 0;
1237 } 1215 }
1216
1238 force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50; 1217 force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50;
1239 force->speed = 1.0; 1218 force->speed = 1.0;
1240 force->speed_left = -1.0; 1219 force->speed_left = -1.0;
1241 SET_FLAG (force, FLAG_APPLIED); 1220 force->set_flag (FLAG_APPLIED);
1242 1221
1243 if (!god) 1222 if (!god)
1244 { 1223 {
1245 new_draw_info (NDI_UNIQUE, 0, op, "Your blessing seems empty."); 1224 new_draw_info (NDI_UNIQUE, 0, op, "Your blessing seems empty.");
1246 } 1225 }
1247 else 1226 else
1248 { 1227 {
1249 /* Only give out good benefits, and put a max on it */ 1228 /* Only give out good benefits, and put a max on it */
1250 for (i = 0; i < NROFATTACKS; i++) 1229 for (i = 0; i < NROFATTACKS; i++)
1251 {
1252 if (god->resist[i] > 0) 1230 if (god->resist[i] > 0)
1253 {
1254 force->resist[i] = MIN (god->resist[i], spell_ob->resist[ATNR_GODPOWER]); 1231 force->resist[i] = min (god->resist[i], spell_ob->resist[ATNR_GODPOWER]);
1255 } 1232
1256 }
1257 force->path_attuned |= god->path_attuned; 1233 force->path_attuned |= god->path_attuned;
1258 1234
1259 if (spell_ob->attacktype) 1235 if (spell_ob->attacktype)
1260 force->slaying = god->slaying; 1236 force->slaying = god->slaying;
1261 1237
1303 * the nuggets, alchemy the gold from that, etc. 1279 * the nuggets, alchemy the gold from that, etc.
1304 * Otherwise, give 9 silver on the gold for other objects, 1280 * Otherwise, give 9 silver on the gold for other objects,
1305 * so that it would still be more affordable to haul 1281 * so that it would still be more affordable to haul
1306 * the stuff back to town. 1282 * the stuff back to town.
1307 */ 1283 */
1308 if (QUERY_FLAG (obj, FLAG_UNPAID)) 1284 if (obj->flag [FLAG_UNPAID])
1309 value = 0; 1285 value = 0;
1310 else if (obj->type == MONEY || obj->type == GEM) 1286 else if (obj->type == MONEY || obj->type == GEM)
1311 value /= 3; 1287 value /= 3;
1312 else 1288 else
1313 value = value * 9 / 10; 1289 value = value * 9 / 10;
1326 if (op->type != PLAYER) 1302 if (op->type != PLAYER)
1327 return 0; 1303 return 0;
1328 1304
1329 archetype *nugget[3]; 1305 archetype *nugget[3];
1330 1306
1331 nugget[0] = archetype::find ("pyrite3"); 1307 nugget[0] = archetype::find (shstr_pyrite3);
1332 nugget[1] = archetype::find ("pyrite2"); 1308 nugget[1] = archetype::find (shstr_pyrite2);
1333 nugget[2] = archetype::find ("pyrite"); 1309 nugget[2] = archetype::find (shstr_pyrite);
1334 1310
1335 /* Put a maximum weight of items that can be alchemised. Limits the power 1311 /* Put a maximum weight of items that can be alchemised. Limits the power
1336 * some, and also prevents people from alchemising every table/chair/clock 1312 * some, and also prevents people from alchemising every table/chair/clock
1337 * in sight 1313 * in sight
1338 */ 1314 */
1367 1343
1368 for (object *next, *tmp = mp->at (nx, ny).bot; tmp; tmp = next) 1344 for (object *next, *tmp = mp->at (nx, ny).bot; tmp; tmp = next)
1369 { 1345 {
1370 next = tmp->above; 1346 next = tmp->above;
1371 1347
1372 if (tmp->weight > 0 && !QUERY_FLAG (tmp, FLAG_NO_PICK) && 1348 if (tmp->weight > 0 && !tmp->flag [FLAG_NO_PICK] &&
1373 !QUERY_FLAG (tmp, FLAG_ALIVE) && !QUERY_FLAG (tmp, FLAG_IS_CAULDRON)) 1349 !tmp->flag [FLAG_ALIVE] && !tmp->flag [FLAG_IS_CAULDRON])
1374 { 1350 {
1375 if (tmp->inv) 1351 if (tmp->inv)
1376 { 1352 {
1377 object *next1, *tmp1; 1353 object *next1, *tmp1;
1378 1354
1379 for (tmp1 = tmp->inv; tmp1; tmp1 = next1) 1355 for (tmp1 = tmp->inv; tmp1; tmp1 = next1)
1380 { 1356 {
1381 next1 = tmp1->below; 1357 next1 = tmp1->below;
1382 if (tmp1->weight > 0 && !QUERY_FLAG (tmp1, FLAG_NO_PICK) && 1358 if (tmp1->weight > 0 && !tmp1->flag [FLAG_NO_PICK] &&
1383 !QUERY_FLAG (tmp1, FLAG_ALIVE) && !QUERY_FLAG (tmp1, FLAG_IS_CAULDRON)) 1359 !tmp1->flag [FLAG_ALIVE] && !tmp1->flag [FLAG_IS_CAULDRON])
1384 alchemy_object (tmp1, value, weight); 1360 alchemy_object (tmp1, value, weight);
1385 } 1361 }
1386 } 1362 }
1387 1363
1388 alchemy_object (tmp, value, weight); 1364 alchemy_object (tmp, value, weight);
1393 } 1369 }
1394 1370
1395 value -= rndm (value >> 4); 1371 value -= rndm (value >> 4);
1396 value = min (value, value_max); 1372 value = min (value, value_max);
1397 1373
1398 for (int i = 0; i < sizeof (nugget) / sizeof (nugget [0]); ++i) 1374 for (int i = 0; i < array_length (nugget); ++i)
1399 if (int nrof = value / nugget [i]->value) 1375 if (int nrof = value / nugget [i]->value)
1400 { 1376 {
1401 value -= nrof * nugget[i]->value; 1377 value -= nrof * nugget[i]->value;
1402 1378
1403 object *tmp = arch_to_object (nugget[i]); 1379 object *tmp = nugget[i]->instance ();
1404 tmp->nrof = nrof; 1380 tmp->nrof = nrof;
1405 tmp->flag [FLAG_IDENTIFIED] = true; 1381 tmp->flag [FLAG_IDENTIFIED] = true;
1406 op->map->insert (tmp, x, y, op, 0); 1382 op->map->insert (tmp, x, y, op, 0);
1407 } 1383 }
1408 1384
1422remove_curse (object *op, object *caster, object *spell) 1398remove_curse (object *op, object *caster, object *spell)
1423{ 1399{
1424 int success = 0, was_one = 0; 1400 int success = 0, was_one = 0;
1425 1401
1426 for (object *tmp = op->inv; tmp; tmp = tmp->below) 1402 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1427 if (QUERY_FLAG (tmp, FLAG_APPLIED) && 1403 if (tmp->flag [FLAG_APPLIED] &&
1428 ((QUERY_FLAG (tmp, FLAG_CURSED) && QUERY_FLAG (spell, FLAG_CURSED)) || 1404 ((tmp->flag [FLAG_CURSED] && spell->flag [FLAG_CURSED]) ||
1429 (QUERY_FLAG (tmp, FLAG_DAMNED) && QUERY_FLAG (spell, FLAG_DAMNED)))) 1405 (tmp->flag [FLAG_DAMNED] && spell->flag [FLAG_DAMNED])))
1430 { 1406 {
1431 was_one++; 1407 was_one++;
1432 1408
1433 if (tmp->level <= casting_level (caster, spell)) 1409 if (tmp->level <= casting_level (caster, spell))
1434 { 1410 {
1435 success++; 1411 success++;
1436 if (QUERY_FLAG (spell, FLAG_DAMNED)) 1412 if (spell->flag [FLAG_DAMNED])
1437 CLEAR_FLAG (tmp, FLAG_DAMNED); 1413 tmp->clr_flag (FLAG_DAMNED);
1438 1414
1439 CLEAR_FLAG (tmp, FLAG_CURSED); 1415 tmp->clr_flag (FLAG_CURSED);
1440 CLEAR_FLAG (tmp, FLAG_KNOWN_CURSED); 1416 tmp->clr_flag (FLAG_KNOWN_CURSED);
1441 tmp->value = 0; /* Still can't sell it */ 1417 tmp->value = 0; /* Still can't sell it */
1442 1418
1443 if (object *pl = tmp->visible_to ()) 1419 if (object *pl = tmp->visible_to ())
1444 esrv_update_item (UPD_FLAGS, pl, tmp); 1420 esrv_update_item (UPD_FLAGS, pl, tmp);
1445 } 1421 }
1470 1446
1471 int num_ident = max (1, spell->stats.dam + SP_level_dam_adjust (caster, spell)); 1447 int num_ident = max (1, spell->stats.dam + SP_level_dam_adjust (caster, spell));
1472 1448
1473 for (tmp = op->inv; tmp; tmp = tmp->below) 1449 for (tmp = op->inv; tmp; tmp = tmp->below)
1474 { 1450 {
1475 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !tmp->invisible && need_identify (tmp)) 1451 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && tmp->need_identify ())
1476 { 1452 {
1477 identify (tmp); 1453 identify (tmp);
1478 1454
1479 if (op->type == PLAYER) 1455 if (op->type == PLAYER)
1480 { 1456 {
1494 * was not fully used. 1470 * was not fully used.
1495 */ 1471 */
1496 if (num_ident) 1472 if (num_ident)
1497 { 1473 {
1498 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp; tmp = tmp->above) 1474 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp; tmp = tmp->above)
1499 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !tmp->invisible && need_identify (tmp)) 1475 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && tmp->need_identify ())
1500 { 1476 {
1501 identify (tmp); 1477 identify (tmp);
1502 1478
1503 if (object *pl = tmp->visible_to ()) 1479 if (object *pl = tmp->visible_to ())
1504 { 1480 {
1544 range = spell->range + SP_level_range_adjust (caster, spell); 1520 range = spell->range + SP_level_range_adjust (caster, spell);
1545 1521
1546 if (!skill) 1522 if (!skill)
1547 skill = caster; 1523 skill = caster;
1548 1524
1525 dynbuf buf;
1549 unordered_mapwalk (op, -range, -range, range, range) 1526 unordered_mapwalk (buf, op, -range, -range, range, range)
1550 { 1527 {
1551 /* For most of the detections, we only detect objects above the 1528 /* For most of the detections, we only detect objects above the
1552 * floor. But this is not true for show invisible. 1529 * floor. But this is not true for show invisible.
1553 * Basically, we just go and find the top object and work 1530 * Basically, we just go and find the top object and work
1554 * down - that is easier than working up. 1531 * down - that is easier than working up.
1555 */ 1532 */
1556 1533
1557 for (last = NULL, tmp = m->at (nx, ny).bot; tmp; tmp = tmp->above) 1534 for (last = 0, tmp = m->at (nx, ny).bot; tmp; tmp = tmp->above)
1558 last = tmp; 1535 last = tmp;
1559 1536
1560 /* Shouldn't happen, but if there are no objects on a space, this 1537 /* Shouldn't happen, but if there are no objects on a space, this
1561 * would happen. 1538 * would happen.
1562 */ 1539 */
1563 if (!last) 1540 if (!last)
1564 continue; 1541 continue;
1565 1542
1566 done_one = 0; 1543 done_one = 0;
1567 floor = 0; 1544 floor = 0;
1568 detect = NULL; 1545 detect = 0;
1569 for (tmp = last; tmp; tmp = tmp->below) 1546 for (tmp = last; tmp; tmp = tmp->below)
1570 { 1547 {
1571 /* show invisible */ 1548 /* show invisible */
1572 if (QUERY_FLAG (spell, FLAG_MAKE_INVIS) && 1549 if (spell->flag [FLAG_MAKE_INVIS]
1573 /* Might there be other objects that we can make visible? */ 1550 /* Might there be other objects that we can make visible? */
1574 (tmp->invisible && (QUERY_FLAG (tmp, FLAG_MONSTER) 1551 && (tmp->invisible && (tmp->flag [FLAG_MONSTER]
1575 || (tmp->type == PLAYER && !QUERY_FLAG (tmp, FLAG_WIZ)) 1552 || (tmp->type == PLAYER && !tmp->flag [FLAG_WIZ])
1576 || tmp->type == CF_HANDLE 1553 || tmp->type == T_HANDLE
1577 || tmp->type == TRAPDOOR 1554 || tmp->type == TRAPDOOR
1578 || tmp->type == EXIT 1555 || tmp->type == EXIT
1579 || tmp->type == HOLE 1556 || tmp->type == HOLE
1580 || tmp->type == BUTTON 1557 || tmp->type == BUTTON
1581 || tmp->type == TELEPORTER 1558 || tmp->type == TELEPORTER
1582 || tmp->type == GATE 1559 || tmp->type == GATE
1583 || tmp->type == LOCKED_DOOR 1560 || tmp->type == LOCKED_DOOR
1584 || tmp->type == WEAPON 1561 || tmp->type == WEAPON
1585 || tmp->type == ALTAR 1562 || tmp->type == ALTAR
1586 || tmp->type == SIGN 1563 || (tmp->type == SIGN && tmp->face != magicmouth_face)
1587 || tmp->type == TRIGGER_PEDESTAL 1564 || tmp->type == TRIGGER_PEDESTAL
1588 || tmp->type == SPECIAL_KEY 1565 || tmp->type == SPECIAL_KEY
1589 || tmp->type == TREASURE 1566 || tmp->type == TREASURE
1590 || tmp->type == BOOK 1567 || tmp->type == BOOK
1591 || tmp->type == HOLY_ALTAR 1568 || tmp->type == HOLY_ALTAR
1592 || tmp->type == CONTAINER))) 1569 || tmp->type == CONTAINER)))
1593 { 1570 {
1571 printf ("show inv %s\n", tmp->debug_desc());//D
1594 if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4) 1572 if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4)
1595 { 1573 {
1596 tmp->invisible = 0; 1574 tmp->invisible = 0;
1597 done_one = 1; 1575 done_one = 1;
1598 } 1576 }
1599 } 1577 }
1600 1578
1601 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR)) 1579 if (tmp->flag [FLAG_IS_FLOOR])
1602 floor = 1; 1580 floor = 1;
1603 1581
1604 /* All detections below this point don't descend beneath the floor, 1582 /* All detections below this point don't descend beneath the floor,
1605 * so just continue on. We could be clever and look at the type of 1583 * so just continue on. We could be clever and look at the type of
1606 * detection to completely break out if we don't care about objects beneath 1584 * detection to completely break out if we don't care about objects beneath
1615 * difficult to see what object is magical/cursed, so the 1593 * difficult to see what object is magical/cursed, so the
1616 * effect wouldn't be as apparent. 1594 * effect wouldn't be as apparent.
1617 */ 1595 */
1618 1596
1619 /* detect magic */ 1597 /* detect magic */
1620 if (QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL) && 1598 if (spell->flag [FLAG_KNOWN_MAGICAL]
1621 !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && is_magical (tmp)) 1599 && !tmp->flag [FLAG_KNOWN_MAGICAL]
1600 && !tmp->flag [FLAG_IDENTIFIED]
1601 && tmp->need_identify ()
1602 && is_magical (tmp))
1622 { 1603 {
1623 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL); 1604 tmp->set_flag (FLAG_KNOWN_MAGICAL);
1624 /* make runes more visibile */ 1605 /* make runes more visible */
1625 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC) 1606 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC)
1626 tmp->stats.Cha /= 4; 1607 tmp->stats.Cha /= 4;
1627 1608
1628 done_one = 1; 1609 done_one = 1;
1629 } 1610 }
1630 1611
1631 /* detect monster */ 1612 /* detect monster */
1632 if (QUERY_FLAG (spell, FLAG_MONSTER) && (QUERY_FLAG (tmp, FLAG_MONSTER) || tmp->type == PLAYER)) 1613 if (spell->flag [FLAG_MONSTER] && (tmp->flag [FLAG_MONSTER] || tmp->type == PLAYER))
1633 { 1614 {
1634 done_one = 2; 1615 done_one = 2;
1635 1616
1636 if (!detect) 1617 if (!detect)
1637 detect = tmp; 1618 detect = tmp;
1639 1620
1640 /* Basically, if race is set in the spell, then the creatures race must 1621 /* Basically, if race is set in the spell, then the creatures race must
1641 * match that. if the spell race is set to GOD, then the gods opposing 1622 * match that. if the spell race is set to GOD, then the gods opposing
1642 * race must match. 1623 * race must match.
1643 */ 1624 */
1644 if (spell->race && QUERY_FLAG (tmp, FLAG_MONSTER) && tmp->race && 1625 if (spell->race && tmp->flag [FLAG_MONSTER] && tmp->race &&
1645 ((spell->race == shstr_GOD && god && god->slaying.contains (tmp->race)) || 1626 ((spell->race == shstr_GOD && god && god->slaying.contains (tmp->race)) ||
1646 spell->race.contains (tmp->race))) 1627 spell->race.contains (tmp->race)))
1647 { 1628 {
1648 done_one = 2; 1629 done_one = 2;
1649 1630
1650 if (!detect) 1631 if (!detect)
1651 detect = tmp; 1632 detect = tmp;
1652 } 1633 }
1653 1634
1654 if (QUERY_FLAG (spell, FLAG_KNOWN_CURSED) && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED) && 1635 if (spell->flag [FLAG_KNOWN_CURSED]
1655 (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))) 1636 && !tmp->flag [FLAG_KNOWN_CURSED]
1637 && tmp->need_identify ()
1638 && (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]))
1656 { 1639 {
1657 SET_FLAG (tmp, FLAG_KNOWN_CURSED); 1640 tmp->set_flag (FLAG_KNOWN_CURSED);
1658 done_one = 1; 1641 done_one = 1;
1642 }
1643
1644 // Do mining detection spell:
1645 if (spell->last_sp == 1) // 1 - detect any vein
1646 {
1647 if (tmp->type == VEIN)
1648 {
1649 if (tmp->other_arch)
1650 {
1651 if (!detect)
1652 detect = tmp->other_arch;
1653 done_one = 2;
1654 }
1655 else
1656 done_one = 1;
1657 }
1659 } 1658 }
1660 } /* for stack of objects on this space */ 1659 } /* for stack of objects on this space */
1661 1660
1662 /* Code here puts an effect of the spell on the space, so you can see 1661 /* Code here puts an effect of the spell on the space, so you can see
1663 * where the magic is. 1662 * where the magic is.
1664 */ 1663 */
1665 if (done_one) 1664 if (done_one)
1666 { 1665 {
1667 object *detect_ob = arch_to_object (spell->other_arch); 1666 object *detect_ob = spell->other_arch->instance ();
1668 1667
1669 /* if this is set, we want to copy the face */ 1668 /* if this is set, we want to copy the face */
1670 if (done_one == 2 && detect) 1669 if (done_one == 2 && detect)
1671 { 1670 {
1672 detect_ob->face = detect->face; 1671 detect_ob->face = detect->face;
1673 detect_ob->animation_id = detect->animation_id; 1672 detect_ob->animation_id = detect->animation_id;
1674 detect_ob->anim_speed = detect->anim_speed; 1673 detect_ob->anim_speed = detect->anim_speed;
1675 detect_ob->last_anim = 0; 1674 detect_ob->last_anim = 0;
1676 /* by default, the detect_ob is already animated */ 1675 /* by default, the detect_ob is already animated */
1677 if (!QUERY_FLAG (detect, FLAG_ANIMATE)) 1676 if (!detect->flag [FLAG_ANIMATE])
1678 CLEAR_FLAG (detect_ob, FLAG_ANIMATE); 1677 detect_ob->clr_flag (FLAG_ANIMATE);
1679 } 1678 }
1680 1679
1681 m->insert (detect_ob, nx, ny, op); 1680 m->insert (detect_ob, nx, ny, op, INS_ON_TOP);
1682 } 1681 }
1683 } /* for processing the surrounding spaces */ 1682 } /* for processing the surrounding spaces */
1684 1683
1685 1684
1686 /* Now process objects in the players inventory if detect curse or magic */ 1685 /* Now process objects in the players inventory if detect curse or magic */
1687 if (QUERY_FLAG (spell, FLAG_KNOWN_CURSED) || QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL)) 1686 if (spell->flag [FLAG_KNOWN_CURSED] || spell->flag [FLAG_KNOWN_MAGICAL])
1688 { 1687 {
1689 done_one = 0; 1688 done_one = 0;
1690 1689
1691 for (tmp = op->inv; tmp; tmp = tmp->below) 1690 for (tmp = op->inv; tmp; tmp = tmp->below)
1692 { 1691 {
1693 if (!tmp->invisible && !QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1692 if (!tmp->invisible && !tmp->flag [FLAG_IDENTIFIED])
1694 { 1693 {
1695 if (QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL) && is_magical (tmp) && !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL)) 1694 if (spell->flag [FLAG_KNOWN_MAGICAL] && is_magical (tmp) && !tmp->flag [FLAG_KNOWN_MAGICAL])
1696 { 1695 {
1697 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL); 1696 tmp->set_flag (FLAG_KNOWN_MAGICAL);
1698 1697
1699 if (object *pl = tmp->visible_to ()) 1698 if (object *pl = tmp->visible_to ())
1700 esrv_update_item (UPD_FLAGS, pl, tmp); 1699 esrv_update_item (UPD_FLAGS, pl, tmp);
1701 } 1700 }
1702 1701
1703 if (QUERY_FLAG (spell, FLAG_KNOWN_CURSED) && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED) && 1702 if (spell->flag [FLAG_KNOWN_CURSED] && !tmp->flag [FLAG_KNOWN_CURSED] &&
1704 (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))) 1703 (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]))
1705 { 1704 {
1706 SET_FLAG (tmp, FLAG_KNOWN_CURSED); 1705 tmp->set_flag (FLAG_KNOWN_CURSED);
1707 1706
1708 if (object *pl = tmp->visible_to ()) 1707 if (object *pl = tmp->visible_to ())
1709 esrv_update_item (UPD_FLAGS, pl, tmp); 1708 esrv_update_item (UPD_FLAGS, pl, tmp);
1710 } 1709 }
1711 } /* if item is not identified */ 1710 } /* if item is not identified */
1771 mflags = get_map_flags (m, &m, x, y, &x, &y); 1770 mflags = get_map_flags (m, &m, x, y, &x, &y);
1772 1771
1773 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE) 1772 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE)
1774 { 1773 {
1775 for (plyr = GET_MAP_OB (m, x, y); plyr != NULL; plyr = plyr->above) 1774 for (plyr = GET_MAP_OB (m, x, y); plyr != NULL; plyr = plyr->above)
1776 if (plyr != op && QUERY_FLAG (plyr, FLAG_ALIVE)) 1775 if (plyr != op && plyr->flag [FLAG_ALIVE])
1777 break; 1776 break;
1778 } 1777 }
1779 1778
1780 1779
1781 /* If we did not find a player in the specified direction, transfer 1780 /* If we did not find a player in the specified direction, transfer
1782 * to anyone on top of us. This is used for the rune of transference mostly. 1781 * to anyone on top of us. This is used for the rune of transference mostly.
1783 */ 1782 */
1784 if (plyr == NULL) 1783 if (plyr == NULL)
1785 for (plyr = GET_MAP_OB (op->map, op->x, op->y); plyr != NULL; plyr = plyr->above) 1784 for (plyr = GET_MAP_OB (op->map, op->x, op->y); plyr != NULL; plyr = plyr->above)
1786 if (plyr != op && QUERY_FLAG (plyr, FLAG_ALIVE)) 1785 if (plyr != op && plyr->flag [FLAG_ALIVE])
1787 break; 1786 break;
1788 1787
1789 if (!plyr) 1788 if (!plyr)
1790 { 1789 {
1791 new_draw_info (NDI_BLACK, 0, op, "There is no one there."); 1790 op->failmsg ("There is no one there.");
1792 return 0; 1791 return 0;
1793 } 1792 }
1794 /* give sp */ 1793 /* give sp */
1795 if (spell->stats.dam > 0) 1794 if (spell->stats.dam > 0)
1796 { 1795 {
1808 if (rate > 95) 1807 if (rate > 95)
1809 rate = 95; 1808 rate = 95;
1810 1809
1811 sucked = (plyr->stats.sp * rate) / 100; 1810 sucked = (plyr->stats.sp * rate) / 100;
1812 plyr->stats.sp -= sucked; 1811 plyr->stats.sp -= sucked;
1813 if (QUERY_FLAG (op, FLAG_ALIVE)) 1812 if (op->flag [FLAG_ALIVE])
1814 { 1813 {
1815 /* Player doesn't get full credit */ 1814 /* Player doesn't get full credit */
1816 sucked = (sucked * rate) / 100; 1815 sucked = (sucked * rate) / 100;
1817 op->stats.sp += sucked; 1816 op->stats.sp += sucked;
1818 if (sucked > 0) 1817 if (sucked > 0)
1869 * monsters either. 1868 * monsters either.
1870 */ 1869 */
1871 1870
1872 if (head->attacktype & AT_MAGIC 1871 if (head->attacktype & AT_MAGIC
1873 && !(head->attacktype & AT_COUNTERSPELL) 1872 && !(head->attacktype & AT_COUNTERSPELL)
1874 && !QUERY_FLAG (head, FLAG_MONSTER) 1873 && !head->flag [FLAG_MONSTER]
1875 && (op->level > head->level)) 1874 && (op->level > head->level))
1876 head->destroy (); 1875 head->destroy ();
1877 else 1876 else
1878 switch (head->type) 1877 switch (head->type)
1879 { 1878 {
1880 case SPELL_EFFECT: 1879 case SPELL_EFFECT:
1881 // XXX: Don't affect floor spelleffects. See also XXX comment 1880 // XXX: Don't affect floor spelleffects. See also XXX comment
1882 // about sanctuary in spell_util.C 1881 // about sanctuary in spell_util.C
1883 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR)) 1882 if (tmp->flag [FLAG_IS_FLOOR])
1884 continue; 1883 continue;
1885 1884
1886 if (op->level > head->level) 1885 if (op->level > head->level)
1887 head->destroy (); 1886 head->destroy ();
1888 1887
1911 1910
1912 object *tmp, *god = find_god (determine_god (op)); 1911 object *tmp, *god = find_god (determine_god (op));
1913 1912
1914 if (!god) 1913 if (!god)
1915 { 1914 {
1916 new_draw_info (NDI_UNIQUE, 0, op, "You can't consecrate anything if you don't worship a god!"); 1915 op->failmsg ("You can't consecrate anything if you don't worship a god!");
1917 return 0; 1916 return 0;
1918 } 1917 }
1919 1918
1920 for (tmp = op->below; tmp; tmp = tmp->below) 1919 for (tmp = op->below; tmp; tmp = tmp->below)
1921 { 1920 {
1922 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR)) 1921 if (tmp->flag [FLAG_IS_FLOOR])
1923 break; 1922 break;
1924 if (tmp->type == HOLY_ALTAR) 1923 if (tmp->type == HOLY_ALTAR)
1925 { 1924 {
1926 1925
1927 if (tmp->level > casting_level (caster, spell)) 1926 if (tmp->level > casting_level (caster, spell))
1928 { 1927 {
1929 new_draw_info_format (NDI_UNIQUE, 0, op, "You are not powerful enough to reconsecrate the %s", &tmp->name); 1928 op->failmsgf ("You are not powerful enough to reconsecrate the %s", &tmp->name);
1930 return 0; 1929 return 0;
1931 } 1930 }
1932 else 1931 else
1933 { 1932 {
1934 /* If we got here, we are consecrating an altar */ 1933 /* If we got here, we are consecrating an altar */
1943 new_draw_info_format (NDI_UNIQUE, 0, op, "You consecrated the altar to %s!", &god->name); 1942 new_draw_info_format (NDI_UNIQUE, 0, op, "You consecrated the altar to %s!", &god->name);
1944 return 1; 1943 return 1;
1945 } 1944 }
1946 } 1945 }
1947 } 1946 }
1948 new_draw_info (NDI_UNIQUE, 0, op, "You are not standing over an altar!"); 1947
1948 op->failmsg ("You are not standing over an altar!");
1949 return 0; 1949 return 0;
1950} 1950}
1951 1951
1952/* animate_weapon - 1952/* animate_weapon -
1953 * Generalization of staff_to_snake. Makes a golem out of the caster's weapon. 1953 * Generalization of staff_to_snake. Makes a golem out of the caster's weapon.
1960 * player checks. MSW 2003-01-06 1960 * player checks. MSW 2003-01-06
1961 */ 1961 */
1962int 1962int
1963animate_weapon (object *op, object *caster, object *spell, int dir) 1963animate_weapon (object *op, object *caster, object *spell, int dir)
1964{ 1964{
1965 object *weapon, *tmp;
1966 char buf[MAX_BUF]; 1965 char buf[MAX_BUF];
1967 int a, i; 1966 int a, i;
1968 sint16 x, y; 1967 sint16 x, y;
1969 maptile *m; 1968 maptile *m;
1970 1969
1995 1994
1996 /* if there's no place to put the golem, abort */ 1995 /* if there's no place to put the golem, abort */
1997 if (dir < 0 || (get_map_flags (m, &m, x, y, &x, &y) & P_OUT_OF_MAP) 1996 if (dir < 0 || (get_map_flags (m, &m, x, y, &x, &y) & P_OUT_OF_MAP)
1998 || ((spell->other_arch->move_type & GET_MAP_MOVE_BLOCK (m, x, y)) == spell->other_arch->move_type)) 1997 || ((spell->other_arch->move_type & GET_MAP_MOVE_BLOCK (m, x, y)) == spell->other_arch->move_type))
1999 { 1998 {
2000 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); 1999 op->failmsg ("There is something in the way.");
2001 return 0; 2000 return 0;
2002 } 2001 }
2003 2002
2004 /* Use the weapon marked by the player. */ 2003 /* Use the weapon marked by the player. */
2005 weapon = find_marked_object (op); 2004 object *weapon = op->mark ();
2006 2005
2007 if (!weapon) 2006 if (!weapon)
2008 { 2007 {
2009 new_draw_info (NDI_BLACK, 0, op, "You must mark a weapon to use with this spell!"); 2008 op->failmsg ("You must mark a weapon to use with this spell!");
2010 return 0; 2009 return 0;
2011 } 2010 }
2012 2011
2013 if (spell->race && weapon->arch->archname != spell->race) 2012 if (spell->race && weapon->arch->archname != spell->race)
2014 { 2013 {
2015 new_draw_info (NDI_UNIQUE, 0, op, "The spell fails to transform your weapon."); 2014 op->failmsg ("The spell fails to transform your weapon.");
2016 return 0; 2015 return 0;
2017 } 2016 }
2018 2017
2019 if (weapon->type != WEAPON) 2018 if (weapon->type != WEAPON)
2020 { 2019 {
2021 new_draw_info (NDI_UNIQUE, 0, op, "You need to wield a weapon to animate it."); 2020 op->failmsg ("You need to wield a weapon to animate it.");
2022 return 0; 2021 return 0;
2023 } 2022 }
2024 2023
2025 if (QUERY_FLAG (weapon, FLAG_APPLIED)) 2024 if (weapon->flag [FLAG_APPLIED])
2026 { 2025 {
2027 new_draw_info_format (NDI_BLACK, 0, op, "You need to unequip %s before using it in this spell", query_name (weapon)); 2026 op->failmsgf ("You need to unequip %s before using it in this spell", query_name (weapon));
2028 return 0; 2027 return 0;
2029 } 2028 }
2030 2029
2031 weapon = weapon->split (); 2030 weapon = weapon->split ();
2032 2031
2033 /* create the golem object */ 2032 /* create the golem object */
2034 tmp = arch_to_object (spell->other_arch); 2033 object *tmp = spell->other_arch->instance ();
2035 2034
2036 /* if animated by a player, give the player control of the golem */ 2035 /* if animated by a player, give the player control of the golem */
2037 CLEAR_FLAG (tmp, FLAG_MONSTER); 2036 tmp->clr_flag (FLAG_MONSTER);
2038 tmp->stats.exp = 0; 2037 tmp->stats.exp = 0;
2039 add_friendly_object (tmp); 2038 add_friendly_object (tmp);
2040 tmp->type = GOLEM; 2039 tmp->type = GOLEM;
2041 tmp->set_owner (op); 2040 tmp->set_owner (op);
2042 op->contr->golem = tmp; 2041 op->contr->golem = tmp;
2044 2043
2045 /* Give the weapon to the golem now. A bit of a hack to check the 2044 /* Give the weapon to the golem now. A bit of a hack to check the
2046 * removed flag - it should only be set if weapon->split was 2045 * removed flag - it should only be set if weapon->split was
2047 * used above. 2046 * used above.
2048 */ 2047 */
2049 if (!QUERY_FLAG (weapon, FLAG_REMOVED)) 2048 if (!weapon->flag [FLAG_REMOVED])
2050 weapon->remove (); 2049 weapon->remove ();
2051 2050
2052 tmp->insert (weapon); 2051 tmp->insert (weapon);
2053 2052
2054 /* To do everything necessary to let a golem use the weapon is a pain, 2053 /* To do everything necessary to let a golem use the weapon is a pain,
2055 * so instead, just set it as equipped (otherwise, we need to update 2054 * so instead, just set it as equipped (otherwise, we need to update
2056 * body_info, skills, etc) 2055 * body_info, skills, etc)
2057 */ 2056 */
2058 SET_FLAG (tmp, FLAG_USE_WEAPON); 2057 tmp->set_flag (FLAG_USE_WEAPON);
2059 SET_FLAG (weapon, FLAG_APPLIED); 2058 weapon->set_flag (FLAG_APPLIED);
2060 tmp->update_stats (); 2059 tmp->update_stats ();
2061 2060
2062 /* There used to be 'odd' code that basically seemed to take the absolute 2061 /* There used to be 'odd' code that basically seemed to take the absolute
2063 * value of the weapon->magic an use that. IMO, that doesn't make sense - 2062 * value of the weapon->magic an use that. IMO, that doesn't make sense -
2064 * if you're using a crappy weapon, it shouldn't be as good. 2063 * if you're using a crappy weapon, it shouldn't be as good.
2084 2083
2085 /* attacktype */ 2084 /* attacktype */
2086 if (!tmp->attacktype) 2085 if (!tmp->attacktype)
2087 tmp->attacktype = AT_PHYSICAL; 2086 tmp->attacktype = AT_PHYSICAL;
2088 2087
2089 if (materialtype_t *mt = name_to_material (op->materialname))
2090 {
2091 for (i = 0; i < NROFATTACKS; i++) 2088 for (i = 0; i < NROFATTACKS; i++)
2092 tmp->resist[i] = 50 - (mt->save[i] * 5); 2089 tmp->resist[i] = 50 - (op->material->save[i] * 5);
2093 a = mt->save[0]; 2090
2094 } 2091 a = op->material->save[0];
2095 else
2096 {
2097 for (i = 0; i < NROFATTACKS; i++)
2098 tmp->resist[i] = 5;
2099 a = 10;
2100 }
2101 2092
2102 /* Set weapon's immunity */ 2093 /* Set weapon's immunity */
2103 tmp->resist[ATNR_CONFUSION] = 100; 2094 tmp->resist[ATNR_CONFUSION] = 100;
2104 tmp->resist[ATNR_POISON] = 100; 2095 tmp->resist[ATNR_POISON] = 100;
2105 tmp->resist[ATNR_SLOW] = 100; 2096 tmp->resist[ATNR_SLOW] = 100;
2132 tmp->state = weapon->state; 2123 tmp->state = weapon->state;
2133 tmp->flag [FLAG_ANIMATE] = weapon->flag [FLAG_ANIMATE]; 2124 tmp->flag [FLAG_ANIMATE] = weapon->flag [FLAG_ANIMATE];
2134 } 2125 }
2135 2126
2136 /* make experience increase in proportion to the strength of the summoned creature. */ 2127 /* make experience increase in proportion to the strength of the summoned creature. */
2137 tmp->stats.exp *= 1 + (MAX (spell->stats.maxgrace, spell->stats.sp) / casting_level (caster, spell)); 2128 tmp->stats.exp *= 1 + (max (spell->stats.maxgrace, spell->stats.sp) / casting_level (caster, spell));
2138 2129
2139 tmp->speed_left = -1; 2130 tmp->speed_left = -1;
2140 tmp->direction = dir; 2131 tmp->direction = dir;
2141 2132
2142 m->insert (tmp, x, y, op); 2133 m->insert (tmp, x, y, op);
2159 success = op->map->change_map_light (spell->stats.dam); 2150 success = op->map->change_map_light (spell->stats.dam);
2160 2151
2161 if (!success) 2152 if (!success)
2162 { 2153 {
2163 if (spell->stats.dam < 0) 2154 if (spell->stats.dam < 0)
2164 new_draw_info (NDI_UNIQUE, 0, op, "It can be no brighter here."); 2155 op->failmsg ("It can be no brighter here.");
2165 else 2156 else
2166 new_draw_info (NDI_UNIQUE, 0, op, "It can be no darker here."); 2157 op->failmsg ("It can be no darker here.");
2167 } 2158 }
2168 2159
2169 return success; 2160 return success;
2170} 2161}
2171 2162
2181 2172
2182 new_aura = present_arch_in_ob (spell->other_arch, op); 2173 new_aura = present_arch_in_ob (spell->other_arch, op);
2183 if (new_aura) 2174 if (new_aura)
2184 refresh = 1; 2175 refresh = 1;
2185 else 2176 else
2186 new_aura = arch_to_object (spell->other_arch); 2177 new_aura = spell->other_arch->instance ();
2187 2178
2188 new_aura->duration = spell->duration + 10 * SP_level_duration_adjust (caster, spell); 2179 new_aura->duration = spell->duration + 10 * SP_level_duration_adjust (caster, spell);
2189 2180
2190 new_aura->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); 2181 new_aura->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
2191 2182
2256 if (pos.normalise () && !(OB_TYPE_MOVE_BLOCK (env, pos->move_block))) 2247 if (pos.normalise () && !(OB_TYPE_MOVE_BLOCK (env, pos->move_block)))
2257 { 2248 {
2258 hit_map (aura, i, aura->attacktype, 0); 2249 hit_map (aura, i, aura->attacktype, 0);
2259 2250
2260 if (aura->other_arch) 2251 if (aura->other_arch)
2261 pos.insert (arch_to_object (aura->other_arch), aura); 2252 pos.insert (aura->other_arch->instance (), aura);
2262 } 2253 }
2263 } 2254 }
2264 2255
2265 /* put the aura back in the player's inventory */ 2256 /* put the aura back in the player's inventory */
2266 env->insert (aura); 2257 env->insert (aura);
2276 for (object *tmp = op->ms ().bot; tmp; tmp = tmp->above) 2267 for (object *tmp = op->ms ().bot; tmp; tmp = tmp->above)
2277 { 2268 {
2278 int atk_lev, def_lev; 2269 int atk_lev, def_lev;
2279 object *victim = tmp->head_ (); 2270 object *victim = tmp->head_ ();
2280 2271
2281 if (!QUERY_FLAG (victim, FLAG_MONSTER)) 2272 if (!victim->flag [FLAG_MONSTER])
2282 continue; 2273 continue;
2283 2274
2284 if (QUERY_FLAG (victim, FLAG_UNAGGRESSIVE)) 2275 if (victim->flag [FLAG_UNAGGRESSIVE])
2285 continue; 2276 continue;
2286 2277
2287 if (victim->stats.exp == 0) 2278 if (victim->stats.exp == 0)
2288 continue; 2279 continue;
2289 2280
2290 def_lev = MAX (1, victim->level); 2281 def_lev = max (1, victim->level);
2291 atk_lev = MAX (1, op->level); 2282 atk_lev = max (1, op->level);
2292 2283
2293 if (rndm (0, atk_lev - 1) > def_lev) 2284 if (rndm (0, atk_lev - 1) > def_lev)
2294 { 2285 {
2295 /* make this sucker peaceful. */ 2286 /* make this sucker peaceful. */
2296 2287
2305 victim->stats.sp = 0; 2296 victim->stats.sp = 0;
2306 victim->stats.grace = 0; 2297 victim->stats.grace = 0;
2307 victim->stats.Pow = 0; 2298 victim->stats.Pow = 0;
2308#endif 2299#endif
2309 victim->attack_movement = RANDO2; 2300 victim->attack_movement = RANDO2;
2310 SET_FLAG (victim, FLAG_UNAGGRESSIVE); 2301 victim->set_flag (FLAG_UNAGGRESSIVE);
2311 SET_FLAG (victim, FLAG_RUN_AWAY); 2302 victim->set_flag (FLAG_RUN_AWAY);
2312 SET_FLAG (victim, FLAG_RANDOM_MOVE); 2303 victim->set_flag (FLAG_RANDOM_MOVE);
2313 CLEAR_FLAG (victim, FLAG_MONSTER); 2304 victim->clr_flag (FLAG_MONSTER);
2314 2305
2315 if (victim->name) 2306 if (victim->name)
2316 new_draw_info_format (NDI_UNIQUE, 0, op->owner, "%s no longer feels like fighting.", &victim->name); 2307 new_draw_info_format (NDI_UNIQUE, 0, op->owner, "%s no longer feels like fighting.", &victim->name);
2317 } 2308 }
2318 } 2309 }
2324int 2315int
2325write_mark (object *op, object *spell, const char *msg) 2316write_mark (object *op, object *spell, const char *msg)
2326{ 2317{
2327 if (!msg || msg[0] == 0) 2318 if (!msg || msg[0] == 0)
2328 { 2319 {
2329 new_draw_info (NDI_UNIQUE, 0, op, "Write what?"); 2320 op->failmsg ("Write what?");
2330 return 0; 2321 return 0;
2331 } 2322 }
2332 2323
2333 if (strcasestr_local (msg, "endmsg")) 2324 if (!msg_is_safe (msg))
2334 { 2325 {
2335 new_draw_info (NDI_UNIQUE, 0, op, "Trying to cheat are we?"); 2326 op->failmsg ("Trying to cheat are we? H<@-signs are not allowed in marking runes.>");
2336 LOG (llevInfo, "write_rune: player %s tried to write bogus rune %s\n", &op->name, msg); 2327 LOG (llevInfo, "write_mark: player %s tried to write bogus rune %s\n", &op->name, msg);
2337 return 0; 2328 return 0;
2338 } 2329 }
2339 2330
2340 if (!spell->other_arch) 2331 if (!spell->other_arch)
2341 return 0; 2332 return 0;
2342 2333
2343 object *tmp = arch_to_object (spell->other_arch); 2334 object *tmp = spell->other_arch->instance ();
2344 2335
2345 tmp->race = op->name; /*Save the owner of the rune */ 2336 tmp->race = op->name; /*Save the owner of the rune */
2346 tmp->msg = msg; 2337 tmp->msg = msg;
2347 2338
2348 tmp->insert_at (op, op, INS_BELOW_ORIGINATOR); 2339 tmp->insert_at (op, op, INS_BELOW_ORIGINATOR);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines