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.109 by sf-marcmagus, Sun Oct 11 01:35:52 2009 UTC vs.
Revision 1.143 by root, Mon Nov 12 03:48:34 2012 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,2012 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>
25#include <object.h> 26#include <object.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 = archetype::get (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 cast_create_obj (op, caster, missile, dir);
202
203 if (!dir
204 && op->type == PLAYER
205 && !missile->destroyed ())
200 pick_up (op, missile); 206 pick_up (op, missile);
201 207
202 return 1; 208 return 1;
203} 209}
204
205 210
206/* allows the choice of what sort of food object to make. 211/* allows the choice of what sort of food object to make.
207 * If spellparam is NULL, it will create food dependent on level --PeterM*/ 212 * If spellparam is NULL, it will create food dependent on level --PeterM*/
208int 213int
209cast_create_food (object *op, object *caster, object *spell_ob, int dir, const char *spellparam) 214cast_create_food (object *op, object *caster, object *spell_ob, int dir, const char *spellparam)
256 /* Pretty unlikely (there are some very low food items), but you never 261 /* Pretty unlikely (there are some very low food items), but you never
257 * know 262 * know
258 */ 263 */
259 if (!at) 264 if (!at)
260 { 265 {
261 new_draw_info (NDI_UNIQUE, 0, op, "You don't have enough experience to create any food."); 266 op->failmsgf ("You don't have enough experience to create any food.");
262 return 0; 267 return 0;
263 } 268 }
264 269
265 food_value /= at->stats.food; 270 food_value /= at->stats.food;
266 new_op = arch_to_object (at); 271 new_op = at->instance ();
267 new_op->nrof = food_value; 272 new_op->nrof = food_value;
268 273
269 new_op->value = 0; 274 new_op->value = 0;
270 if (new_op->nrof < 1) 275 if (new_op->nrof < 1)
271 new_op->nrof = 1; 276 new_op->nrof = 1;
296 mflags = get_map_flags (m, &m, x, y, &x, &y); 301 mflags = get_map_flags (m, &m, x, y, &x, &y);
297 302
298 if (mflags & P_OUT_OF_MAP) 303 if (mflags & P_OUT_OF_MAP)
299 break; 304 break;
300 305
301 if (!QUERY_FLAG (op, FLAG_WIZCAST) && (mflags & P_NO_MAGIC)) 306 if (!op->flag [FLAG_WIZCAST] && (mflags & P_NO_MAGIC))
302 { 307 {
303 new_draw_info (NDI_UNIQUE, 0, op, "Something blocks your magic."); 308 new_draw_info (NDI_UNIQUE, 0, op, "Something blocks your magic.");
304 return 0; 309 return 0;
305 } 310 }
306 311
307 if (mflags & P_IS_ALIVE) 312 if (mflags & P_IS_ALIVE)
308 { 313 {
309 for (tmp = GET_MAP_OB (m, x, y); tmp; tmp = tmp->above) 314 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))) 315 if (tmp->flag [FLAG_ALIVE] && (tmp->type == PLAYER || tmp->flag [FLAG_MONSTER]))
311 { 316 {
312 new_draw_info (NDI_UNIQUE, 0, op, "You detect something."); 317 new_draw_info (NDI_UNIQUE, 0, op, "You detect something.");
313 if (tmp->head != NULL) 318 if (tmp->head != NULL)
314 tmp = tmp->head; 319 tmp = tmp->head;
315 examine_monster (op, tmp); 320 examine_monster (op, tmp);
338 if (pl->type == PLAYER) 343 if (pl->type == PLAYER)
339 { 344 {
340 /* If race isn't set, then invisible unless it is undead */ 345 /* If race isn't set, then invisible unless it is undead */
341 if (!pl->contr->invis_race) 346 if (!pl->contr->invis_race)
342 { 347 {
343 if (QUERY_FLAG (mon, FLAG_UNDEAD)) 348 if (mon->flag [FLAG_UNDEAD])
344 return 0; 349 return 0;
345 350
346 return 1; 351 return 1;
347 } 352 }
348 353
379int 384int
380cast_invisible (object *op, object *caster, object *spell_ob) 385cast_invisible (object *op, object *caster, object *spell_ob)
381{ 386{
382 if (op->invisible > 1000) 387 if (op->invisible > 1000)
383 { 388 {
384 new_draw_info (NDI_UNIQUE, 0, op, "You can not extend the duration of your invisibility any further"); 389 op->failmsg ("You can not extend the duration of your invisibility any further");
385 return 0; 390 return 0;
386 } 391 }
387 392
388 /* Remove the switch with 90% duplicate code - just handle the differences with 393 /* Remove the switch with 90% duplicate code - just handle the differences with
389 * and if statement or two. 394 * and if statement or two.
390 */ 395 */
391 op->invisible += spell_ob->duration + SP_level_duration_adjust (caster, spell_ob); 396 op->invisible += spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
397
392 /* max duration */ 398 /* limit duration */
393 if (op->invisible > 1000) 399 min_it (op->invisible, 1000);
394 op->invisible = 1000;
395 400
396 if (op->type == PLAYER) 401 if (op->type == PLAYER)
397 { 402 {
398 op->contr->invis_race = spell_ob->race; 403 op->contr->invis_race = spell_ob->race;
399 404
400 if (QUERY_FLAG (spell_ob, FLAG_MAKE_INVIS)) 405 if (spell_ob->flag [FLAG_MAKE_INVIS])
401 op->contr->tmp_invis = 0; 406 op->contr->tmp_invis = 0;
402 else 407 else
403 op->contr->tmp_invis = 1; 408 op->contr->tmp_invis = 1;
404 409
405 op->contr->hidden = 0; 410 op->contr->hidden = 0;
447 // earth to dust tears down everything that can be torn down 452 // earth to dust tears down everything that can be torn down
448 for (object *next, *tmp = m->at (sx, sy).bot; tmp; tmp = next) 453 for (object *next, *tmp = m->at (sx, sy).bot; tmp; tmp = next)
449 { 454 {
450 next = tmp->above; 455 next = tmp->above;
451 456
452 if (QUERY_FLAG (tmp, FLAG_TEAR_DOWN)) 457 if (tmp->flag [FLAG_TEAR_DOWN])
453 hit_player (tmp, 9998, op, AT_PHYSICAL, 0); 458 hit_player (tmp, 9998, op, AT_PHYSICAL, 0);
454 } 459 }
455 } 460 }
456 461
457 return 1; 462 return 1;
459 464
460void 465void
461execute_word_of_recall (object *op) 466execute_word_of_recall (object *op)
462{ 467{
463 if (object *pl = op->in_player ()) 468 if (object *pl = op->in_player ())
464 {
465 if (pl->ms ().flags () & P_NO_CLERIC && !QUERY_FLAG (pl, FLAG_WIZCAST)) 469 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."); 470 new_draw_info (NDI_UNIQUE, 0, pl, "You feel something fizzle inside you.");
467 else 471 else
468 pl->player_goto (op->slaying, op->stats.hp, op->stats.sp); 472 pl->player_goto (op->slaying, op->stats.hp, op->stats.sp);
469 }
470 473
471 op->destroy (); 474 op->destroy ();
472} 475}
473 476
474/* Word of recall causes the player to return 'home'. 477/* Word of recall causes the player to return 'home'.
476 * time delay effect. 479 * time delay effect.
477 */ 480 */
478int 481int
479cast_word_of_recall (object *op, object *caster, object *spell_ob) 482cast_word_of_recall (object *op, object *caster, object *spell_ob)
480{ 483{
481 object *dummy; 484 if (!op->is_player ())
482 int time;
483
484 if (op->type != PLAYER)
485 return 0; 485 return 0;
486 486
487 if (find_obj_by_type_subtype (op, SPELL_EFFECT, SP_WORD_OF_RECALL)) 487 if (find_obj_by_type_subtype (op, SPELL_EFFECT, SP_WORD_OF_RECALL))
488 { 488 {
489 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you."); 489 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you.");
490 return 1; 490 return 1;
491 } 491 }
492 492
493 dummy = get_archetype (FORCE_NAME); 493 object *dummy = archetype::get (FORCE_NAME);
494 494
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); 495 int time = max (1, spell_ob->duration - SP_level_duration_adjust (caster, spell_ob));
503 if (time < 1)
504 time = 1;
505 496
506 /* value of speed really doesn't make much difference, as long as it is 497 /* 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 498 * positive. Lower value may be useful so that the problem doesn't
508 * do anything really odd if it say a -1000 or something. 499 * do anything really odd if it say a -1000 or something.
509 */ 500 */
510 dummy->set_speed (0.002); 501 dummy->set_speed (0.002);
511 dummy->speed_left = -dummy->speed * time; 502 dummy->speed_left = -dummy->speed * time;
512 dummy->type = SPELL_EFFECT; 503 dummy->type = SPELL_EFFECT;
513 dummy->subtype = SP_WORD_OF_RECALL; 504 dummy->subtype = SP_WORD_OF_RECALL;
514 505 dummy->slaying = op->contr->savebed_map;
515 /* If we could take advantage of enter_player_savebed() here, it would be 506 dummy->stats.hp = op->contr->bed_x;
516 * nice, but until the map load fails, we can't. 507 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 508
522 op->insert (dummy); 509 op->insert (dummy);
523 510
524 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you."); 511 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you.");
525 512
564 551
565int 552int
566perceive_self (object *op) 553perceive_self (object *op)
567{ 554{
568 const char *cp = describe_item (op, op); 555 const char *cp = describe_item (op, op);
569 archetype *at = archetype::find (ARCH_DEPLETION); 556 archetype *at = archetype::find (shstr_depletion);
570 557
571 dynbuf_text &buf = msg_dynbuf; buf.clear (); 558 dynbuf_text &buf = msg_dynbuf; buf.clear ();
572 559
573 if (!op->is_player ()) 560 if (!op->is_player ())
574 return 0; 561 return 0;
593 for (int i = 0; i < NUM_STATS; i++) 580 for (int i = 0; i < NUM_STATS; i++)
594 if (tmp->stats.stat (i) < 0) 581 if (tmp->stats.stat (i) < 0)
595 buf.printf (" - Your %s is depleted by %d.\n", statname[i], -tmp->stats.stat (i)); 582 buf.printf (" - Your %s is depleted by %d.\n", statname[i], -tmp->stats.stat (i));
596 } 583 }
597 584
598 if (is_dragon_pl (op)) 585 if (op->is_dragon ())
599 /* now grab the 'dragon_ability'-force from the player's inventory */ 586 /* now grab the 'dragon_ability'-force from the player's inventory */
600 for (tmp = op->inv; tmp; tmp = tmp->below) 587 for (tmp = op->inv; tmp; tmp = tmp->below)
601 { 588 {
602 if (tmp->type == FORCE && tmp->arch->archname == shstr_dragon_ability_force) 589 if (tmp->type == FORCE && tmp->arch->archname == shstr_dragon_ability_force)
603 { 590 {
644 631
645 if ((spell_ob->move_block || x != op->x || y != op->y) && 632 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) || 633 (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))) 634 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK (m, x, y)) == spell_ob->move_block)))
648 { 635 {
649 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way."); 636 op->failmsg ("Something is in the way.");
650 return 0; 637 return 0;
651 } 638 }
652 639
653 if (spell_ob->other_arch) 640 if (spell_ob->other_arch)
654 tmp = arch_to_object (spell_ob->other_arch); 641 tmp = spell_ob->other_arch->instance ();
655 else if (spell_ob->race) 642 else if (spell_ob->race)
656 { 643 {
657 char buf1[MAX_BUF]; 644 char buf1[MAX_BUF];
658 645
659 sprintf (buf1, spell_ob->race, dir); 646 sprintf (buf1, spell_ob->race, dir);
663 LOG (llevError, "summon_wall: Unable to find archetype %s\n", buf1); 650 LOG (llevError, "summon_wall: Unable to find archetype %s\n", buf1);
664 new_draw_info (NDI_UNIQUE, 0, op, "This spell is broken."); 651 new_draw_info (NDI_UNIQUE, 0, op, "This spell is broken.");
665 return 0; 652 return 0;
666 } 653 }
667 654
668 tmp = arch_to_object (at); 655 tmp = at->instance ();
669 } 656 }
670 else 657 else
671 { 658 {
672 LOG (llevError, "magic_wall: spell %s lacks other_arch\n", &spell_ob->name); 659 LOG (llevError, "magic_wall: spell %s lacks other_arch\n", &spell_ob->name);
673 return 0; 660 return 0;
678 tmp->attacktype = spell_ob->attacktype; 665 tmp->attacktype = spell_ob->attacktype;
679 tmp->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob); 666 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); 667 tmp->stats.dam = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob);
681 tmp->range = 0; 668 tmp->range = 0;
682 } 669 }
683 else if (QUERY_FLAG (tmp, FLAG_ALIVE)) 670 else if (tmp->flag [FLAG_ALIVE])
684 { 671 {
685 tmp->stats.hp = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob); 672 tmp->stats.hp = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
686 tmp->stats.maxhp = tmp->stats.hp; 673 tmp->stats.maxhp = tmp->stats.hp;
687 } 674 }
688 675
689 if (QUERY_FLAG (spell_ob, FLAG_IS_USED_UP) || QUERY_FLAG (tmp, FLAG_IS_USED_UP)) 676 if (spell_ob->flag [FLAG_IS_USED_UP] || tmp->flag [FLAG_IS_USED_UP])
690 { 677 {
691 tmp->stats.food = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob); 678 tmp->stats.food = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
692 SET_FLAG (tmp, FLAG_IS_USED_UP); 679 tmp->set_flag (FLAG_IS_USED_UP);
693 } 680 }
694 681
695 if (QUERY_FLAG (spell_ob, FLAG_TEAR_DOWN)) 682 if (spell_ob->flag [FLAG_TEAR_DOWN])
696 { 683 {
697 tmp->stats.hp = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob); 684 tmp->stats.hp = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob);
698 tmp->stats.maxhp = tmp->stats.hp; 685 tmp->stats.maxhp = tmp->stats.hp;
699 SET_FLAG (tmp, FLAG_TEAR_DOWN); 686 tmp->set_flag (FLAG_TEAR_DOWN);
700 SET_FLAG (tmp, FLAG_ALIVE); 687 tmp->set_flag (FLAG_ALIVE);
701 } 688 }
702 689
703 /* This can't really hurt - if the object doesn't kill anything, 690 /* 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 691 * these fields just won't be used. Do not set the owner for
705 * earthwalls, though, so they survive restarts. 692 * earthwalls, though, so they survive restarts.
717 return 0; 704 return 0;
718 } 705 }
719 706
720 /* If this is a spellcasting wall, need to insert the spell object */ 707 /* If this is a spellcasting wall, need to insert the spell object */
721 if (tmp->other_arch && tmp->other_arch->type == SPELL) 708 if (tmp->other_arch && tmp->other_arch->type == SPELL)
722 insert_ob_in_ob (arch_to_object (tmp->other_arch), tmp); 709 insert_ob_in_ob (tmp->other_arch->instance (), tmp);
723 710
724 /* This code causes the wall to extend some distance in 711 /* This code causes the wall to extend some distance in
725 * each direction, or until an obstruction is encountered. 712 * each direction, or until an obstruction is encountered.
726 * posblocked and negblocked help determine how far the 713 * posblocked and negblocked help determine how far the
727 * created wall can extend, it won't go extend through 714 * created wall can extend, it won't go extend through
747 object *tmp2 = tmp->clone (); 734 object *tmp2 = tmp->clone ();
748 m->insert (tmp2, x, y, op); 735 m->insert (tmp2, x, y, op);
749 736
750 /* If this is a spellcasting wall, need to insert the spell object */ 737 /* If this is a spellcasting wall, need to insert the spell object */
751 if (tmp2->other_arch && tmp2->other_arch->type == SPELL) 738 if (tmp2->other_arch && tmp2->other_arch->type == SPELL)
752 tmp2->insert (arch_to_object (tmp2->other_arch)); 739 tmp2->insert (tmp2->other_arch->instance ());
753 740
754 } 741 }
755 else 742 else
756 posblocked = 1; 743 posblocked = 1;
757 744
764 { 751 {
765 object *tmp2 = tmp->clone (); 752 object *tmp2 = tmp->clone ();
766 m->insert (tmp2, x, y, op); 753 m->insert (tmp2, x, y, op);
767 754
768 if (tmp2->other_arch && tmp2->other_arch->type == SPELL) 755 if (tmp2->other_arch && tmp2->other_arch->type == SPELL)
769 tmp2->insert (arch_to_object (tmp2->other_arch)); 756 tmp2->insert (tmp2->other_arch->instance ());
770 } 757 }
771 else 758 else
772 negblocked = 1; 759 negblocked = 1;
773 } 760 }
774 761
775 if (QUERY_FLAG (tmp, FLAG_BLOCKSVIEW)) 762 if (tmp->flag [FLAG_BLOCKSVIEW])
776 update_all_los (op->map, op->x, op->y); 763 update_all_los (op->map, op->x, op->y);
777 764
778 return 1; 765 return 1;
779} 766}
780 767
789 if (op->type != PLAYER) 776 if (op->type != PLAYER)
790 return 0; 777 return 0;
791 778
792 if (!dir) 779 if (!dir)
793 { 780 {
794 new_draw_info (NDI_UNIQUE, 0, op, "In what direction?"); 781 op->failmsg ("In what direction?");
795 return 0; 782 return 0;
796 } 783 }
797 784
798 /* Given the new outdoor maps, can't let players dimension door for 785 /* Given the new outdoor maps, can't let players dimension door for
799 * ever, so put limits in. 786 * ever, so put limits in.
804 { 791 {
805 int count = atoi (spellparam); 792 int count = atoi (spellparam);
806 793
807 if (count > maxdist) 794 if (count > maxdist)
808 { 795 {
809 new_draw_info (NDI_UNIQUE, 0, op, "You can't dimension door that far!"); 796 op->failmsg ("You can't dimension door that far!");
810 return 0; 797 return 0;
811 } 798 }
812 799
813 for (dist = 0; dist < count; dist++) 800 for (dist = 0; dist < count; dist++)
814 { 801 {
875 break; 862 break;
876 863
877 } 864 }
878 if (!dist) 865 if (!dist)
879 { 866 {
880 new_draw_info (NDI_UNIQUE, 0, op, "Your spell failed!\n"); 867 op->failmsg ("Your spell failed!\n");
881 return 0; 868 return 0;
882 } 869 }
883 } 870 }
884 871
885 /* Actually move the player now */ 872 /* 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))) 873 if (!(op = op->map->insert (op, op->x + freearr_x[dir] * dist, op->y + freearr_y[dir] * dist, op)))
887 return 1; 874 return 1;
888 875
889 op->speed_left = -FABS (op->speed) * 5; /* Freeze them for a short while */ 876 op->speed_left = -5. * op->speed; /* Freeze them for a short while */
877
890 return 1; 878 return 1;
891} 879}
892 880
893/* cast_heal: Heals something. 881/* cast_heal: Heals something.
894 * op is the caster. 882 * op is the caster.
949 if (cure_disease (tmp, op, spell)) 937 if (cure_disease (tmp, op, spell))
950 success = 1; 938 success = 1;
951 939
952 if (spell->attacktype & AT_POISON) 940 if (spell->attacktype & AT_POISON)
953 { 941 {
954 at = archetype::find ("poisoning"); 942 at = archetype::find (shstr_poisoning);
955 poison = present_arch_in_ob (at, tmp); 943 poison = present_arch_in_ob (at, tmp);
956 if (poison) 944 if (poison)
957 { 945 {
958 success = 1; 946 success = 1;
959 new_draw_info (NDI_UNIQUE, 0, tmp, "Your body feels cleansed"); 947 new_draw_info (NDI_UNIQUE, 0, tmp, "Your body feels cleansed");
961 } 949 }
962 } 950 }
963 951
964 if (spell->attacktype & AT_CONFUSION) 952 if (spell->attacktype & AT_CONFUSION)
965 { 953 {
966 poison = present_in_ob_by_name (FORCE, "confusion", tmp); 954 poison = present_in_ob_by_name (FORCE, shstr_confusion, tmp);
967 if (poison) 955 if (poison)
968 { 956 {
969 success = 1; 957 success = 1;
970 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer"); 958 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer");
971 poison->duration = 1; 959 poison->duration = 1;
972 } 960 }
973 } 961 }
974 962
975 if (spell->attacktype & AT_BLIND) 963 if (spell->attacktype & AT_BLIND)
976 { 964 {
977 at = archetype::find ("blindness"); 965 at = archetype::find (shstr_blindness);
978 poison = present_arch_in_ob (at, tmp); 966 poison = present_arch_in_ob (at, tmp);
979 if (poison) 967 if (poison)
980 { 968 {
981 success = 1; 969 success = 1;
982 new_draw_info (NDI_UNIQUE, 0, tmp, "Your vision begins to return."); 970 new_draw_info (NDI_UNIQUE, 0, tmp, "Your vision begins to return.");
1000 tmp->stats.grace = tmp->stats.maxgrace; 988 tmp->stats.grace = tmp->stats.maxgrace;
1001 success = 1; 989 success = 1;
1002 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!"); 990 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!");
1003 } 991 }
1004 992
1005 if (spell->stats.food && tmp->stats.food < 999) 993 if (spell->stats.food && tmp->stats.food < MAX_FOOD)
1006 { 994 {
1007 tmp->stats.food += spell->stats.food; 995 tmp->stats.food += spell->stats.food;
1008 996 min_it (tmp->stats.food, MAX_FOOD);
1009 if (tmp->stats.food > 999)
1010 tmp->stats.food = 999;
1011 997
1012 success = 1; 998 success = 1;
1013 /* We could do something a bit better like the messages for healing above */ 999 /* 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"); 1000 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel your belly fill with food");
1015 } 1001 }
1062 break; 1048 break;
1063 } 1049 }
1064 else if (spell_ob->race && spell_ob->race == tmp2->name) 1050 else if (spell_ob->race && spell_ob->race == tmp2->name)
1065 { 1051 {
1066 if (!silent) 1052 if (!silent)
1067 new_draw_info_format (NDI_UNIQUE, 0, op,
1068 "You can not cast %s while %s is in effect", 1053 op->failmsgf ("You can not cast %s while %s is in effect",
1069 &spell_ob->name, &tmp2->name_pl); 1054 &spell_ob->name, &tmp2->name_pl);
1070 1055
1071 return 0; 1056 return 0;
1072 } 1057 }
1073 } 1058 }
1074 } 1059 }
1090 1075
1091 new_draw_info_format (NDI_UNIQUE, 0, op, 1076 new_draw_info_format (NDI_UNIQUE, 0, op,
1092 "You create an aura of magical force. H<The effect will last for about %.10g seconds.>", 1077 "You create an aura of magical force. H<The effect will last for about %.10g seconds.>",
1093 TICK2TIME (duration)); 1078 TICK2TIME (duration));
1094 1079
1095 force = get_archetype (FORCE_NAME); 1080 force = archetype::get (FORCE_NAME);
1096 force->subtype = FORCE_CHANGE_ABILITY; 1081 force->subtype = FORCE_CHANGE_ABILITY;
1097 force->duration = duration; 1082 force->duration = duration;
1098 1083
1099 if (spell_ob->race) 1084 if (spell_ob->race)
1100 force->name = spell_ob->race; 1085 force->name = spell_ob->race;
1103 1088
1104 force->name_pl = spell_ob->name; 1089 force->name_pl = spell_ob->name;
1105 1090
1106 force->speed = 1.0; 1091 force->speed = 1.0;
1107 force->speed_left = -1.0; 1092 force->speed_left = -1.0;
1108 SET_FLAG (force, FLAG_APPLIED); 1093 force->set_flag (FLAG_APPLIED);
1109 1094
1110 /* Now start processing the effects. First, protections */ 1095 /* Now start processing the effects. First, protections */
1111 for (i = 0; i < NROFATTACKS; i++) 1096 for (i = 0; i < NROFATTACKS; i++)
1112 {
1113 if (spell_ob->resist[i]) 1097 if (spell_ob->resist[i])
1114 {
1115 force->resist[i] = spell_ob->resist[i] + SP_level_dam_adjust (caster, spell_ob); 1098 force->resist[i] = min (100, spell_ob->resist[i] + SP_level_dam_adjust (caster, spell_ob));
1116 if (force->resist[i] > 100)
1117 force->resist[i] = 100;
1118 }
1119 }
1120 1099
1121 if (spell_ob->stats.hp) 1100 if (spell_ob->stats.hp)
1122 force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust (caster, spell_ob); 1101 force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust (caster, spell_ob);
1123 1102
1124 if (tmp->type == PLAYER) 1103 if (tmp->type == PLAYER)
1143 } 1122 }
1144 } 1123 }
1145 1124
1146 force->move_type = spell_ob->move_type; 1125 force->move_type = spell_ob->move_type;
1147 1126
1148 if (QUERY_FLAG (spell_ob, FLAG_SEE_IN_DARK)) 1127 if (spell_ob->flag [FLAG_SEE_IN_DARK])
1149 SET_FLAG (force, FLAG_SEE_IN_DARK); 1128 force->set_flag (FLAG_SEE_IN_DARK);
1150 1129
1151 if (QUERY_FLAG (spell_ob, FLAG_XRAYS)) 1130 if (spell_ob->flag [FLAG_XRAYS])
1152 SET_FLAG (force, FLAG_XRAYS); 1131 force->set_flag (FLAG_XRAYS);
1153 1132
1154 /* Haste/bonus speed */ 1133 /* Haste/bonus speed */
1155 if (spell_ob->stats.exp) 1134 if (spell_ob->stats.exp)
1156 { 1135 {
1157 if (op->speed > 0.5f) 1136 if (op->speed > 0.5f)
1210 } 1189 }
1211 } 1190 }
1212 1191
1213 if (force == NULL) 1192 if (force == NULL)
1214 { 1193 {
1215 force = get_archetype (FORCE_NAME); 1194 force = archetype::get (FORCE_NAME);
1216 force->subtype = FORCE_CHANGE_ABILITY; 1195 force->subtype = FORCE_CHANGE_ABILITY;
1217 if (spell_ob->race) 1196 if (spell_ob->race)
1218 force->name = spell_ob->race; 1197 force->name = spell_ob->race;
1219 else 1198 else
1220 force->name = spell_ob->name; 1199 force->name = spell_ob->name;
1235 { 1214 {
1236 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect."); 1215 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect.");
1237 } 1216 }
1238 return 0; 1217 return 0;
1239 } 1218 }
1219
1240 force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50; 1220 force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50;
1241 force->speed = 1.0; 1221 force->speed = 1.0;
1242 force->speed_left = -1.0; 1222 force->speed_left = -1.0;
1243 SET_FLAG (force, FLAG_APPLIED); 1223 force->set_flag (FLAG_APPLIED);
1244 1224
1245 if (!god) 1225 if (!god)
1246 { 1226 {
1247 new_draw_info (NDI_UNIQUE, 0, op, "Your blessing seems empty."); 1227 new_draw_info (NDI_UNIQUE, 0, op, "Your blessing seems empty.");
1248 } 1228 }
1249 else 1229 else
1250 { 1230 {
1251 /* Only give out good benefits, and put a max on it */ 1231 /* Only give out good benefits, and put a max on it */
1252 for (i = 0; i < NROFATTACKS; i++) 1232 for (i = 0; i < NROFATTACKS; i++)
1253 {
1254 if (god->resist[i] > 0) 1233 if (god->resist[i] > 0)
1255 {
1256 force->resist[i] = MIN (god->resist[i], spell_ob->resist[ATNR_GODPOWER]); 1234 force->resist[i] = min (god->resist[i], spell_ob->resist[ATNR_GODPOWER]);
1257 } 1235
1258 }
1259 force->path_attuned |= god->path_attuned; 1236 force->path_attuned |= god->path_attuned;
1260 1237
1261 if (spell_ob->attacktype) 1238 if (spell_ob->attacktype)
1262 force->slaying = god->slaying; 1239 force->slaying = god->slaying;
1263 1240
1283 1260
1284/* Alchemy code by Mark Wedel 1261/* Alchemy code by Mark Wedel
1285 * 1262 *
1286 * This code adds a new spell, called alchemy. Alchemy will turn 1263 * This code adds a new spell, called alchemy. Alchemy will turn
1287 * objects to pyrite ("false gold"), henceforth called gold nuggets. 1264 * objects to pyrite ("false gold"), henceforth called gold nuggets.
1288 * 1265 *
1289 * The value of the gold nuggets being about 90% of that of the item 1266 * The value of the gold nuggets being about 90% of that of the item
1290 * itself. It uses the value of the object before charisma adjustments, 1267 * itself. It uses the value of the object before charisma adjustments,
1291 * because the nuggets themselves will be will be adjusted by charisma 1268 * because the nuggets themselves will be will be adjusted by charisma
1292 * when sold. 1269 * when sold.
1293 * 1270 *
1305 * the nuggets, alchemy the gold from that, etc. 1282 * the nuggets, alchemy the gold from that, etc.
1306 * Otherwise, give 9 silver on the gold for other objects, 1283 * Otherwise, give 9 silver on the gold for other objects,
1307 * so that it would still be more affordable to haul 1284 * so that it would still be more affordable to haul
1308 * the stuff back to town. 1285 * the stuff back to town.
1309 */ 1286 */
1310 if (QUERY_FLAG (obj, FLAG_UNPAID)) 1287 if (obj->flag [FLAG_UNPAID])
1311 value = 0; 1288 value = 0;
1312 else if (obj->type == MONEY || obj->type == GEM) 1289 else if (obj->type == MONEY || obj->type == GEM)
1313 value /= 3; 1290 value /= 3;
1314 else 1291 else
1315 value = value * 9 / 10; 1292 value = value * 9 / 10;
1328 if (op->type != PLAYER) 1305 if (op->type != PLAYER)
1329 return 0; 1306 return 0;
1330 1307
1331 archetype *nugget[3]; 1308 archetype *nugget[3];
1332 1309
1333 nugget[0] = archetype::find ("pyrite3"); 1310 nugget[0] = archetype::find (shstr_pyrite3);
1334 nugget[1] = archetype::find ("pyrite2"); 1311 nugget[1] = archetype::find (shstr_pyrite2);
1335 nugget[2] = archetype::find ("pyrite"); 1312 nugget[2] = archetype::find (shstr_pyrite);
1336 1313
1337 /* Put a maximum weight of items that can be alchemised. Limits the power 1314 /* Put a maximum weight of items that can be alchemised. Limits the power
1338 * some, and also prevents people from alchemising every table/chair/clock 1315 * some, and also prevents people from alchemising every table/chair/clock
1339 * in sight 1316 * in sight
1340 */ 1317 */
1369 1346
1370 for (object *next, *tmp = mp->at (nx, ny).bot; tmp; tmp = next) 1347 for (object *next, *tmp = mp->at (nx, ny).bot; tmp; tmp = next)
1371 { 1348 {
1372 next = tmp->above; 1349 next = tmp->above;
1373 1350
1374 if (tmp->weight > 0 && !QUERY_FLAG (tmp, FLAG_NO_PICK) && 1351 if (tmp->weight > 0 && !tmp->flag [FLAG_NO_PICK] &&
1375 !QUERY_FLAG (tmp, FLAG_ALIVE) && !QUERY_FLAG (tmp, FLAG_IS_CAULDRON)) 1352 !tmp->flag [FLAG_ALIVE] && !tmp->flag [FLAG_IS_CAULDRON])
1376 { 1353 {
1377 if (tmp->inv) 1354 if (tmp->inv)
1378 { 1355 {
1379 object *next1, *tmp1; 1356 object *next1, *tmp1;
1380 1357
1381 for (tmp1 = tmp->inv; tmp1; tmp1 = next1) 1358 for (tmp1 = tmp->inv; tmp1; tmp1 = next1)
1382 { 1359 {
1383 next1 = tmp1->below; 1360 next1 = tmp1->below;
1384 if (tmp1->weight > 0 && !QUERY_FLAG (tmp1, FLAG_NO_PICK) && 1361 if (tmp1->weight > 0 && !tmp1->flag [FLAG_NO_PICK] &&
1385 !QUERY_FLAG (tmp1, FLAG_ALIVE) && !QUERY_FLAG (tmp1, FLAG_IS_CAULDRON)) 1362 !tmp1->flag [FLAG_ALIVE] && !tmp1->flag [FLAG_IS_CAULDRON])
1386 alchemy_object (tmp1, value, weight); 1363 alchemy_object (tmp1, value, weight);
1387 } 1364 }
1388 } 1365 }
1389 1366
1390 alchemy_object (tmp, value, weight); 1367 alchemy_object (tmp, value, weight);
1395 } 1372 }
1396 1373
1397 value -= rndm (value >> 4); 1374 value -= rndm (value >> 4);
1398 value = min (value, value_max); 1375 value = min (value, value_max);
1399 1376
1400 for (int i = 0; i < sizeof (nugget) / sizeof (nugget [0]); ++i) 1377 for (int i = 0; i < array_length (nugget); ++i)
1401 if (int nrof = value / nugget [i]->value) 1378 if (int nrof = value / nugget [i]->value)
1402 { 1379 {
1403 value -= nrof * nugget[i]->value; 1380 value -= nrof * nugget[i]->value;
1404 1381
1405 object *tmp = arch_to_object (nugget[i]); 1382 object *tmp = nugget[i]->instance ();
1406 tmp->nrof = nrof; 1383 tmp->nrof = nrof;
1407 tmp->flag [FLAG_IDENTIFIED] = true; 1384 tmp->flag [FLAG_IDENTIFIED] = true;
1408 op->map->insert (tmp, x, y, op, 0); 1385 op->map->insert (tmp, x, y, op, 0);
1409 } 1386 }
1410 1387
1423int 1400int
1424remove_curse (object *op, object *caster, object *spell) 1401remove_curse (object *op, object *caster, object *spell)
1425{ 1402{
1426 int success = 0, was_one = 0; 1403 int success = 0, was_one = 0;
1427 1404
1405 int num_uncurse = max (1, spell->stats.dam + SP_level_dam_adjust (caster, spell));
1406
1407 op->splay_marked ();
1408
1409 int typeflag = spell->last_sp ? FLAG_DAMNED : FLAG_CURSED;
1410
1428 for (object *tmp = op->inv; tmp; tmp = tmp->below) 1411 for (object *tmp = op->inv; tmp && num_uncurse; tmp = tmp->below)
1429 if (QUERY_FLAG (tmp, FLAG_APPLIED) && 1412 if (!tmp->invisible && tmp->flag [typeflag])
1430 ((QUERY_FLAG (tmp, FLAG_CURSED) && QUERY_FLAG (spell, FLAG_CURSED)) ||
1431 (QUERY_FLAG (tmp, FLAG_DAMNED) && QUERY_FLAG (spell, FLAG_DAMNED))))
1432 { 1413 {
1433 was_one++; 1414 ++was_one;
1434 1415
1435 if (tmp->level <= casting_level (caster, spell)) 1416 if (tmp->level <= casting_level (caster, spell))
1436 { 1417 {
1437 success++; 1418 ++success;
1438 if (QUERY_FLAG (spell, FLAG_DAMNED)) 1419 --num_uncurse;
1439 CLEAR_FLAG (tmp, FLAG_DAMNED);
1440 1420
1441 CLEAR_FLAG (tmp, FLAG_CURSED); 1421 tmp->clr_flag (typeflag);
1442 CLEAR_FLAG (tmp, FLAG_KNOWN_CURSED); 1422 tmp->clr_flag (FLAG_CURSED);
1423 tmp->clr_flag (FLAG_KNOWN_CURSED);
1443 tmp->value = 0; /* Still can't sell it */ 1424 tmp->value = 0; /* Still can't sell it */
1444 1425
1445 if (object *pl = tmp->visible_to ()) 1426 if (object *pl = tmp->visible_to ())
1446 esrv_update_item (UPD_FLAGS, pl, tmp); 1427 esrv_update_item (UPD_FLAGS, pl, tmp);
1447 } 1428 }
1448 } 1429 }
1449 1430
1450 if (op->type == PLAYER) 1431 if (op->type == PLAYER)
1451 { 1432 {
1452 if (success) 1433 if (success)
1453 new_draw_info (NDI_UNIQUE, 0, op, "You feel like some of your items are looser now."); 1434 new_draw_info (NDI_UNIQUE, 0, op, "You realise that some of your items look shinier now. H<You successfully removed some curses.>");
1454 else 1435 else
1455 { 1436 {
1456 if (was_one) 1437 if (was_one)
1457 new_draw_info (NDI_UNIQUE, 0, op, "You failed to remove the curse."); 1438 new_draw_info (NDI_UNIQUE, 0, op, "You failed to remove any curse. H<The spell was not strong enough.>");
1458 else 1439 else
1459 new_draw_info (NDI_UNIQUE, 0, op, "You are not using any cursed items."); 1440 new_draw_info (NDI_UNIQUE, 0, op, "You are not having any cursed items. H<Epic fail.>");
1460 } 1441 }
1461 } 1442 }
1462 1443
1463 return success; 1444 return success;
1464} 1445}
1465 1446
1466/* Identifies objects in the players inventory/on the ground */ 1447/* Identifies objects in the players inventory/on the ground */
1467int 1448int
1468cast_identify (object *op, object *caster, object *spell) 1449cast_identify (object *op, object *caster, object *spell)
1469{ 1450{
1470 object *tmp;
1471 dynbuf_text &buf = msg_dynbuf; buf.clear (); 1451 dynbuf_text &buf = msg_dynbuf; buf.clear ();
1472 1452
1473 int num_ident = max (1, spell->stats.dam + SP_level_dam_adjust (caster, spell)); 1453 int num_ident = max (1, spell->stats.dam + SP_level_dam_adjust (caster, spell));
1474 1454
1455 op->splay_marked ();
1456
1475 for (tmp = op->inv; tmp; tmp = tmp->below) 1457 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1476 { 1458 {
1477 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !tmp->invisible && need_identify (tmp)) 1459 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && tmp->need_identify ())
1478 { 1460 {
1479 identify (tmp); 1461 identify (tmp);
1480 1462
1481 if (op->type == PLAYER) 1463 if (op->type == PLAYER)
1482 { 1464 {
1495 * stuff on the floor. Only identify stuff on the floor if the spell 1477 * stuff on the floor. Only identify stuff on the floor if the spell
1496 * was not fully used. 1478 * was not fully used.
1497 */ 1479 */
1498 if (num_ident) 1480 if (num_ident)
1499 { 1481 {
1500 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp; tmp = tmp->above) 1482 for (object *tmp = GET_MAP_OB (op->map, op->x, op->y); tmp; tmp = tmp->above)
1501 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !tmp->invisible && need_identify (tmp)) 1483 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && tmp->need_identify ())
1502 { 1484 {
1503 identify (tmp); 1485 identify (tmp);
1504 1486
1505 if (object *pl = tmp->visible_to ()) 1487 if (object *pl = tmp->visible_to ())
1506 { 1488 {
1532 1514
1533int 1515int
1534cast_detection (object *op, object *caster, object *spell, object *skill) 1516cast_detection (object *op, object *caster, object *spell, object *skill)
1535{ 1517{
1536 object *tmp, *last, *god, *detect; 1518 object *tmp, *last, *god, *detect;
1537 int done_one, range, mflags, floor, level; 1519 int done_one, range, floor, level;
1538 sint16 x, y, nx, ny; 1520 sint16 x, y, nx, ny;
1539 maptile *m; 1521 maptile *m;
1540 1522
1541 /* We precompute some values here so that we don't have to keep 1523 /* We precompute some values here so that we don't have to keep
1542 * doing it over and over again. 1524 * doing it over and over again.
1546 range = spell->range + SP_level_range_adjust (caster, spell); 1528 range = spell->range + SP_level_range_adjust (caster, spell);
1547 1529
1548 if (!skill) 1530 if (!skill)
1549 skill = caster; 1531 skill = caster;
1550 1532
1533 dynbuf buf;
1551 unordered_mapwalk (op, -range, -range, range, range) 1534 unordered_mapwalk (buf, op, -range, -range, range, range)
1552 { 1535 {
1553 /* For most of the detections, we only detect objects above the 1536 /* For most of the detections, we only detect objects above the
1554 * floor. But this is not true for show invisible. 1537 * floor. But this is not true for show invisible.
1555 * Basically, we just go and find the top object and work 1538 * Basically, we just go and find the top object and work
1556 * down - that is easier than working up. 1539 * down - that is easier than working up.
1557 */ 1540 */
1558 1541
1559 for (last = NULL, tmp = m->at (nx, ny).bot; tmp; tmp = tmp->above) 1542 for (last = 0, tmp = m->at (nx, ny).bot; tmp; tmp = tmp->above)
1560 last = tmp; 1543 last = tmp;
1561 1544
1562 /* Shouldn't happen, but if there are no objects on a space, this 1545 /* Shouldn't happen, but if there are no objects on a space, this
1563 * would happen. 1546 * would happen.
1564 */ 1547 */
1565 if (!last) 1548 if (!last)
1566 continue; 1549 continue;
1567 1550
1568 done_one = 0; 1551 done_one = 0;
1569 floor = 0; 1552 floor = 0;
1570 detect = NULL; 1553 detect = 0;
1571 for (tmp = last; tmp; tmp = tmp->below) 1554 for (tmp = last; tmp; tmp = tmp->below)
1572 { 1555 {
1573 /* show invisible */ 1556 /* show invisible */
1574 if (QUERY_FLAG (spell, FLAG_MAKE_INVIS) && 1557 if (spell->flag [FLAG_MAKE_INVIS]
1575 /* Might there be other objects that we can make visible? */ 1558 /* Might there be other objects that we can make visible? */
1576 (tmp->invisible && (QUERY_FLAG (tmp, FLAG_MONSTER) 1559 && (tmp->invisible && (tmp->flag [FLAG_MONSTER]
1577 || (tmp->type == PLAYER && !QUERY_FLAG (tmp, FLAG_WIZ)) 1560 || (tmp->type == PLAYER && !tmp->flag [FLAG_WIZ])
1578 || tmp->type == CF_HANDLE 1561 || tmp->type == T_HANDLE
1579 || tmp->type == TRAPDOOR 1562 || tmp->type == TRAPDOOR
1580 || tmp->type == EXIT 1563 || tmp->type == EXIT
1581 || tmp->type == HOLE 1564 || tmp->type == HOLE
1582 || tmp->type == BUTTON 1565 || tmp->type == BUTTON
1583 || tmp->type == TELEPORTER 1566 || tmp->type == TELEPORTER
1584 || tmp->type == GATE 1567 || tmp->type == GATE
1585 || tmp->type == LOCKED_DOOR 1568 || tmp->type == LOCKED_DOOR
1586 || tmp->type == WEAPON 1569 || tmp->type == WEAPON
1587 || tmp->type == ALTAR 1570 || tmp->type == ALTAR
1588 || tmp->type == SIGN 1571 || (tmp->type == SIGN && tmp->face != magicmouth_face)
1589 || tmp->type == TRIGGER_PEDESTAL 1572 || tmp->type == TRIGGER_PEDESTAL
1590 || tmp->type == SPECIAL_KEY 1573 || tmp->type == SPECIAL_KEY
1591 || tmp->type == TREASURE 1574 || tmp->type == TREASURE
1592 || tmp->type == BOOK 1575 || tmp->type == BOOK
1593 || tmp->type == HOLY_ALTAR 1576 || tmp->type == HOLY_ALTAR
1594 || tmp->type == CONTAINER))) 1577 || tmp->type == CONTAINER)))
1595 { 1578 {
1579 printf ("show inv %s\n", tmp->debug_desc());//D
1596 if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4) 1580 if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4)
1597 { 1581 {
1598 tmp->invisible = 0; 1582 tmp->invisible = 0;
1599 done_one = 1; 1583 done_one = 1;
1600 } 1584 }
1601 } 1585 }
1602 1586
1603 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR)) 1587 if (tmp->flag [FLAG_IS_FLOOR])
1604 floor = 1; 1588 floor = 1;
1605 1589
1606 /* All detections below this point don't descend beneath the floor, 1590 /* All detections below this point don't descend beneath the floor,
1607 * so just continue on. We could be clever and look at the type of 1591 * so just continue on. We could be clever and look at the type of
1608 * detection to completely break out if we don't care about objects beneath 1592 * detection to completely break out if we don't care about objects beneath
1617 * difficult to see what object is magical/cursed, so the 1601 * difficult to see what object is magical/cursed, so the
1618 * effect wouldn't be as apparent. 1602 * effect wouldn't be as apparent.
1619 */ 1603 */
1620 1604
1621 /* detect magic */ 1605 /* detect magic */
1622 if (QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL) && 1606 if (spell->flag [FLAG_KNOWN_MAGICAL]
1623 !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && is_magical (tmp)) 1607 && !tmp->flag [FLAG_KNOWN_MAGICAL]
1608 && !tmp->flag [FLAG_IDENTIFIED]
1609 && tmp->need_identify ()
1610 && is_magical (tmp))
1624 { 1611 {
1625 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL); 1612 tmp->set_flag (FLAG_KNOWN_MAGICAL);
1626 /* make runes more visibile */ 1613 /* make runes more visible */
1627 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC) 1614 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC)
1628 tmp->stats.Cha /= 4; 1615 tmp->stats.Cha /= 4;
1629 1616
1630 done_one = 1; 1617 done_one = 1;
1631 } 1618 }
1632 1619
1633 /* detect monster */ 1620 /* detect monster */
1634 if (QUERY_FLAG (spell, FLAG_MONSTER) && (QUERY_FLAG (tmp, FLAG_MONSTER) || tmp->type == PLAYER)) 1621 if (spell->flag [FLAG_MONSTER] && (tmp->flag [FLAG_MONSTER] || tmp->type == PLAYER))
1635 { 1622 {
1636 done_one = 2; 1623 done_one = 2;
1637 1624
1638 if (!detect) 1625 if (!detect)
1639 detect = tmp; 1626 detect = tmp;
1641 1628
1642 /* Basically, if race is set in the spell, then the creatures race must 1629 /* Basically, if race is set in the spell, then the creatures race must
1643 * match that. if the spell race is set to GOD, then the gods opposing 1630 * match that. if the spell race is set to GOD, then the gods opposing
1644 * race must match. 1631 * race must match.
1645 */ 1632 */
1646 if (spell->race && QUERY_FLAG (tmp, FLAG_MONSTER) && tmp->race && 1633 if (spell->race && tmp->flag [FLAG_MONSTER] && tmp->race &&
1647 ((spell->race == shstr_GOD && god && god->slaying.contains (tmp->race)) || 1634 ((spell->race == shstr_GOD && god && god->slaying.contains (tmp->race)) ||
1648 spell->race.contains (tmp->race))) 1635 spell->race.contains (tmp->race)))
1649 { 1636 {
1650 done_one = 2; 1637 done_one = 2;
1651 1638
1652 if (!detect) 1639 if (!detect)
1653 detect = tmp; 1640 detect = tmp;
1654 } 1641 }
1655 1642
1656 if (QUERY_FLAG (spell, FLAG_KNOWN_CURSED) && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED) && 1643 if (spell->flag [FLAG_KNOWN_CURSED]
1657 (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))) 1644 && !tmp->flag [FLAG_KNOWN_CURSED]
1645 && tmp->need_identify ()
1646 && (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]))
1658 { 1647 {
1659 SET_FLAG (tmp, FLAG_KNOWN_CURSED); 1648 tmp->set_flag (FLAG_KNOWN_CURSED);
1660 done_one = 1; 1649 done_one = 1;
1650 }
1651
1652 // Do mining detection spell:
1653 if (spell->last_sp == 1) // 1 - detect any vein
1654 {
1655 if (tmp->type == VEIN)
1656 {
1657 if (tmp->other_arch)
1658 {
1659 if (!detect)
1660 detect = tmp->other_arch;
1661 done_one = 2;
1662 }
1663 else
1664 done_one = 1;
1665 }
1661 } 1666 }
1662 } /* for stack of objects on this space */ 1667 } /* for stack of objects on this space */
1663 1668
1664 /* Code here puts an effect of the spell on the space, so you can see 1669 /* Code here puts an effect of the spell on the space, so you can see
1665 * where the magic is. 1670 * where the magic is.
1666 */ 1671 */
1667 if (done_one) 1672 if (done_one)
1668 { 1673 {
1669 object *detect_ob = arch_to_object (spell->other_arch); 1674 object *detect_ob = spell->other_arch->instance ();
1670 1675
1671 /* if this is set, we want to copy the face */ 1676 /* if this is set, we want to copy the face */
1672 if (done_one == 2 && detect) 1677 if (done_one == 2 && detect)
1673 { 1678 {
1674 detect_ob->face = detect->face; 1679 detect_ob->face = detect->face;
1675 detect_ob->animation_id = detect->animation_id; 1680 detect_ob->animation_id = detect->animation_id;
1676 detect_ob->anim_speed = detect->anim_speed; 1681 detect_ob->anim_speed = detect->anim_speed;
1677 detect_ob->last_anim = 0; 1682 detect_ob->last_anim = 0;
1678 /* by default, the detect_ob is already animated */ 1683 /* by default, the detect_ob is already animated */
1679 if (!QUERY_FLAG (detect, FLAG_ANIMATE)) 1684 if (!detect->flag [FLAG_ANIMATE])
1680 CLEAR_FLAG (detect_ob, FLAG_ANIMATE); 1685 detect_ob->clr_flag (FLAG_ANIMATE);
1681 } 1686 }
1682 1687
1683 m->insert (detect_ob, nx, ny, op); 1688 m->insert (detect_ob, nx, ny, op, INS_ON_TOP);
1684 } 1689 }
1685 } /* for processing the surrounding spaces */ 1690 } /* for processing the surrounding spaces */
1686 1691
1687 1692
1688 /* Now process objects in the players inventory if detect curse or magic */ 1693 /* Now process objects in the players inventory if detect curse or magic */
1689 if (QUERY_FLAG (spell, FLAG_KNOWN_CURSED) || QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL)) 1694 if (spell->flag [FLAG_KNOWN_CURSED] || spell->flag [FLAG_KNOWN_MAGICAL])
1690 { 1695 {
1691 done_one = 0; 1696 done_one = 0;
1692 1697
1693 for (tmp = op->inv; tmp; tmp = tmp->below) 1698 for (tmp = op->inv; tmp; tmp = tmp->below)
1694 { 1699 {
1695 if (!tmp->invisible && !QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1700 if (!tmp->invisible && !tmp->flag [FLAG_IDENTIFIED])
1696 { 1701 {
1697 if (QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL) && is_magical (tmp) && !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL)) 1702 if (spell->flag [FLAG_KNOWN_MAGICAL] && is_magical (tmp) && !tmp->flag [FLAG_KNOWN_MAGICAL])
1698 { 1703 {
1699 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL); 1704 tmp->set_flag (FLAG_KNOWN_MAGICAL);
1700 1705
1701 if (object *pl = tmp->visible_to ()) 1706 if (object *pl = tmp->visible_to ())
1702 esrv_update_item (UPD_FLAGS, pl, tmp); 1707 esrv_update_item (UPD_FLAGS, pl, tmp);
1703 } 1708 }
1704 1709
1705 if (QUERY_FLAG (spell, FLAG_KNOWN_CURSED) && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED) && 1710 if (spell->flag [FLAG_KNOWN_CURSED] && !tmp->flag [FLAG_KNOWN_CURSED] &&
1706 (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))) 1711 (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]))
1707 { 1712 {
1708 SET_FLAG (tmp, FLAG_KNOWN_CURSED); 1713 tmp->set_flag (FLAG_KNOWN_CURSED);
1709 1714
1710 if (object *pl = tmp->visible_to ()) 1715 if (object *pl = tmp->visible_to ())
1711 esrv_update_item (UPD_FLAGS, pl, tmp); 1716 esrv_update_item (UPD_FLAGS, pl, tmp);
1712 } 1717 }
1713 } /* if item is not identified */ 1718 } /* if item is not identified */
1773 mflags = get_map_flags (m, &m, x, y, &x, &y); 1778 mflags = get_map_flags (m, &m, x, y, &x, &y);
1774 1779
1775 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE) 1780 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE)
1776 { 1781 {
1777 for (plyr = GET_MAP_OB (m, x, y); plyr != NULL; plyr = plyr->above) 1782 for (plyr = GET_MAP_OB (m, x, y); plyr != NULL; plyr = plyr->above)
1778 if (plyr != op && QUERY_FLAG (plyr, FLAG_ALIVE)) 1783 if (plyr != op && plyr->flag [FLAG_ALIVE])
1779 break; 1784 break;
1780 } 1785 }
1781 1786
1782 1787
1783 /* If we did not find a player in the specified direction, transfer 1788 /* If we did not find a player in the specified direction, transfer
1784 * to anyone on top of us. This is used for the rune of transference mostly. 1789 * to anyone on top of us. This is used for the rune of transference mostly.
1785 */ 1790 */
1786 if (plyr == NULL) 1791 if (plyr == NULL)
1787 for (plyr = GET_MAP_OB (op->map, op->x, op->y); plyr != NULL; plyr = plyr->above) 1792 for (plyr = GET_MAP_OB (op->map, op->x, op->y); plyr != NULL; plyr = plyr->above)
1788 if (plyr != op && QUERY_FLAG (plyr, FLAG_ALIVE)) 1793 if (plyr != op && plyr->flag [FLAG_ALIVE])
1789 break; 1794 break;
1790 1795
1791 if (!plyr) 1796 if (!plyr)
1792 { 1797 {
1793 new_draw_info (NDI_BLACK, 0, op, "There is no one there."); 1798 op->failmsg ("There is no one there.");
1794 return 0; 1799 return 0;
1795 } 1800 }
1796 /* give sp */ 1801 /* give sp */
1797 if (spell->stats.dam > 0) 1802 if (spell->stats.dam > 0)
1798 { 1803 {
1810 if (rate > 95) 1815 if (rate > 95)
1811 rate = 95; 1816 rate = 95;
1812 1817
1813 sucked = (plyr->stats.sp * rate) / 100; 1818 sucked = (plyr->stats.sp * rate) / 100;
1814 plyr->stats.sp -= sucked; 1819 plyr->stats.sp -= sucked;
1815 if (QUERY_FLAG (op, FLAG_ALIVE)) 1820 if (op->flag [FLAG_ALIVE])
1816 { 1821 {
1817 /* Player doesn't get full credit */ 1822 /* Player doesn't get full credit */
1818 sucked = (sucked * rate) / 100; 1823 sucked = (sucked * rate) / 100;
1819 op->stats.sp += sucked; 1824 op->stats.sp += sucked;
1820 if (sucked > 0) 1825 if (sucked > 0)
1871 * monsters either. 1876 * monsters either.
1872 */ 1877 */
1873 1878
1874 if (head->attacktype & AT_MAGIC 1879 if (head->attacktype & AT_MAGIC
1875 && !(head->attacktype & AT_COUNTERSPELL) 1880 && !(head->attacktype & AT_COUNTERSPELL)
1876 && !QUERY_FLAG (head, FLAG_MONSTER) 1881 && !head->flag [FLAG_MONSTER]
1877 && (op->level > head->level)) 1882 && (op->level > head->level))
1878 head->destroy (); 1883 head->destroy ();
1879 else 1884 else
1880 switch (head->type) 1885 switch (head->type)
1881 { 1886 {
1882 case SPELL_EFFECT: 1887 case SPELL_EFFECT:
1883 // XXX: Don't affect floor spelleffects. See also XXX comment 1888 // XXX: Don't affect floor spelleffects. See also XXX comment
1884 // about sanctuary in spell_util.C 1889 // about sanctuary in spell_util.C
1885 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR)) 1890 if (tmp->flag [FLAG_IS_FLOOR])
1886 continue; 1891 continue;
1887 1892
1888 if (op->level > head->level) 1893 if (op->level > head->level)
1889 head->destroy (); 1894 head->destroy ();
1890 1895
1913 1918
1914 object *tmp, *god = find_god (determine_god (op)); 1919 object *tmp, *god = find_god (determine_god (op));
1915 1920
1916 if (!god) 1921 if (!god)
1917 { 1922 {
1918 new_draw_info (NDI_UNIQUE, 0, op, "You can't consecrate anything if you don't worship a god!"); 1923 op->failmsg ("You can't consecrate anything if you don't worship a god!");
1919 return 0; 1924 return 0;
1920 } 1925 }
1921 1926
1922 for (tmp = op->below; tmp; tmp = tmp->below) 1927 for (tmp = op->below; tmp; tmp = tmp->below)
1923 { 1928 {
1924 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR)) 1929 if (tmp->flag [FLAG_IS_FLOOR])
1925 break; 1930 break;
1926 if (tmp->type == HOLY_ALTAR) 1931 if (tmp->type == HOLY_ALTAR)
1927 { 1932 {
1928 1933
1929 if (tmp->level > casting_level (caster, spell)) 1934 if (tmp->level > casting_level (caster, spell))
1930 { 1935 {
1931 new_draw_info_format (NDI_UNIQUE, 0, op, "You are not powerful enough to reconsecrate the %s", &tmp->name); 1936 op->failmsgf ("You are not powerful enough to reconsecrate the %s", &tmp->name);
1932 return 0; 1937 return 0;
1933 } 1938 }
1934 else 1939 else
1935 { 1940 {
1936 /* If we got here, we are consecrating an altar */ 1941 /* If we got here, we are consecrating an altar */
1945 new_draw_info_format (NDI_UNIQUE, 0, op, "You consecrated the altar to %s!", &god->name); 1950 new_draw_info_format (NDI_UNIQUE, 0, op, "You consecrated the altar to %s!", &god->name);
1946 return 1; 1951 return 1;
1947 } 1952 }
1948 } 1953 }
1949 } 1954 }
1950 new_draw_info (NDI_UNIQUE, 0, op, "You are not standing over an altar!"); 1955
1956 op->failmsg ("You are not standing over an altar!");
1951 return 0; 1957 return 0;
1952} 1958}
1953 1959
1954/* animate_weapon - 1960/* animate_weapon -
1955 * Generalization of staff_to_snake. Makes a golem out of the caster's weapon. 1961 * Generalization of staff_to_snake. Makes a golem out of the caster's weapon.
1962 * player checks. MSW 2003-01-06 1968 * player checks. MSW 2003-01-06
1963 */ 1969 */
1964int 1970int
1965animate_weapon (object *op, object *caster, object *spell, int dir) 1971animate_weapon (object *op, object *caster, object *spell, int dir)
1966{ 1972{
1967 object *weapon, *tmp;
1968 char buf[MAX_BUF]; 1973 char buf[MAX_BUF];
1969 int a, i; 1974 int a, i;
1970 sint16 x, y; 1975 sint16 x, y;
1971 maptile *m; 1976 maptile *m;
1972 1977
1997 2002
1998 /* if there's no place to put the golem, abort */ 2003 /* if there's no place to put the golem, abort */
1999 if (dir < 0 || (get_map_flags (m, &m, x, y, &x, &y) & P_OUT_OF_MAP) 2004 if (dir < 0 || (get_map_flags (m, &m, x, y, &x, &y) & P_OUT_OF_MAP)
2000 || ((spell->other_arch->move_type & GET_MAP_MOVE_BLOCK (m, x, y)) == spell->other_arch->move_type)) 2005 || ((spell->other_arch->move_type & GET_MAP_MOVE_BLOCK (m, x, y)) == spell->other_arch->move_type))
2001 { 2006 {
2002 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); 2007 op->failmsg ("There is something in the way.");
2003 return 0; 2008 return 0;
2004 } 2009 }
2005 2010
2006 /* Use the weapon marked by the player. */ 2011 /* Use the weapon marked by the player. */
2007 weapon = find_marked_object (op); 2012 object *weapon = op->mark ();
2008 2013
2009 if (!weapon) 2014 if (!weapon)
2010 { 2015 {
2011 new_draw_info (NDI_BLACK, 0, op, "You must mark a weapon to use with this spell!"); 2016 op->failmsg ("You must mark a weapon to use with this spell!");
2012 return 0; 2017 return 0;
2013 } 2018 }
2014 2019
2015 if (spell->race && weapon->arch->archname != spell->race) 2020 if (spell->race && weapon->arch->archname != spell->race)
2016 { 2021 {
2017 new_draw_info (NDI_UNIQUE, 0, op, "The spell fails to transform your weapon."); 2022 op->failmsg ("The spell fails to transform your weapon.");
2018 return 0; 2023 return 0;
2019 } 2024 }
2020 2025
2021 if (weapon->type != WEAPON) 2026 if (weapon->type != WEAPON)
2022 { 2027 {
2023 new_draw_info (NDI_UNIQUE, 0, op, "You need to wield a weapon to animate it."); 2028 op->failmsg ("You need to wield a weapon to animate it.");
2024 return 0; 2029 return 0;
2025 } 2030 }
2026 2031
2027 if (QUERY_FLAG (weapon, FLAG_APPLIED)) 2032 if (weapon->flag [FLAG_APPLIED])
2028 { 2033 {
2029 new_draw_info_format (NDI_BLACK, 0, op, "You need to unequip %s before using it in this spell", query_name (weapon)); 2034 op->failmsgf ("You need to unequip %s before using it in this spell", query_name (weapon));
2030 return 0; 2035 return 0;
2031 } 2036 }
2032 2037
2033 weapon = weapon->split (); 2038 weapon = weapon->split ();
2034 2039
2035 /* create the golem object */ 2040 /* create the golem object */
2036 tmp = arch_to_object (spell->other_arch); 2041 object *tmp = spell->other_arch->instance ();
2037 2042
2038 /* if animated by a player, give the player control of the golem */ 2043 /* if animated by a player, give the player control of the golem */
2039 CLEAR_FLAG (tmp, FLAG_MONSTER); 2044 tmp->clr_flag (FLAG_MONSTER);
2040 tmp->stats.exp = 0; 2045 tmp->stats.exp = 0;
2041 add_friendly_object (tmp); 2046 add_friendly_object (tmp);
2042 tmp->type = GOLEM; 2047 tmp->type = GOLEM;
2043 tmp->set_owner (op); 2048 tmp->set_owner (op);
2044 op->contr->golem = tmp; 2049 op->contr->golem = tmp;
2046 2051
2047 /* Give the weapon to the golem now. A bit of a hack to check the 2052 /* Give the weapon to the golem now. A bit of a hack to check the
2048 * removed flag - it should only be set if weapon->split was 2053 * removed flag - it should only be set if weapon->split was
2049 * used above. 2054 * used above.
2050 */ 2055 */
2051 if (!QUERY_FLAG (weapon, FLAG_REMOVED)) 2056 if (!weapon->flag [FLAG_REMOVED])
2052 weapon->remove (); 2057 weapon->remove ();
2053 2058
2054 tmp->insert (weapon); 2059 tmp->insert (weapon);
2055 2060
2056 /* To do everything necessary to let a golem use the weapon is a pain, 2061 /* To do everything necessary to let a golem use the weapon is a pain,
2057 * so instead, just set it as equipped (otherwise, we need to update 2062 * so instead, just set it as equipped (otherwise, we need to update
2058 * body_info, skills, etc) 2063 * body_info, skills, etc)
2059 */ 2064 */
2060 SET_FLAG (tmp, FLAG_USE_WEAPON); 2065 tmp->set_flag (FLAG_USE_WEAPON);
2061 SET_FLAG (weapon, FLAG_APPLIED); 2066 weapon->set_flag (FLAG_APPLIED);
2062 tmp->update_stats (); 2067 tmp->update_stats ();
2063 2068
2064 /* There used to be 'odd' code that basically seemed to take the absolute 2069 /* There used to be 'odd' code that basically seemed to take the absolute
2065 * value of the weapon->magic an use that. IMO, that doesn't make sense - 2070 * value of the weapon->magic an use that. IMO, that doesn't make sense -
2066 * if you're using a crappy weapon, it shouldn't be as good. 2071 * if you're using a crappy weapon, it shouldn't be as good.
2086 2091
2087 /* attacktype */ 2092 /* attacktype */
2088 if (!tmp->attacktype) 2093 if (!tmp->attacktype)
2089 tmp->attacktype = AT_PHYSICAL; 2094 tmp->attacktype = AT_PHYSICAL;
2090 2095
2091 if (materialtype_t *mt = name_to_material (op->materialname))
2092 {
2093 for (i = 0; i < NROFATTACKS; i++) 2096 for (i = 0; i < NROFATTACKS; i++)
2094 tmp->resist[i] = 50 - (mt->save[i] * 5); 2097 tmp->resist[i] = 50 - (op->material->save[i] * 5);
2095 a = mt->save[0]; 2098
2096 } 2099 a = op->material->save[0];
2097 else
2098 {
2099 for (i = 0; i < NROFATTACKS; i++)
2100 tmp->resist[i] = 5;
2101 a = 10;
2102 }
2103 2100
2104 /* Set weapon's immunity */ 2101 /* Set weapon's immunity */
2105 tmp->resist[ATNR_CONFUSION] = 100; 2102 tmp->resist[ATNR_CONFUSION] = 100;
2106 tmp->resist[ATNR_POISON] = 100; 2103 tmp->resist[ATNR_POISON] = 100;
2107 tmp->resist[ATNR_SLOW] = 100; 2104 tmp->resist[ATNR_SLOW] = 100;
2115 /* Improve weapon's armour value according to best save vs. physical of its material */ 2112 /* Improve weapon's armour value according to best save vs. physical of its material */
2116 2113
2117 if (a > 14) 2114 if (a > 14)
2118 a = 14; 2115 a = 14;
2119 2116
2120 tmp->resist[ATNR_PHYSICAL] = 100 - (int) ((100.0 - (float) tmp->resist[ATNR_PHYSICAL]) / (30.0 - 2.0 * a)); 2117 tmp->resist[ATNR_PHYSICAL] = 100 - (int) ((100.f - (float) tmp->resist[ATNR_PHYSICAL]) / (30.f - 2.f * a));
2121 2118
2122 /* Determine golem's speed */ 2119 /* Determine golem's speed */
2123 tmp->set_speed (min (3.33, 0.4 + 0.1 * SP_level_range_adjust (caster, spell))); 2120 tmp->set_speed (min (3.33f, 0.4f + 0.1f * SP_level_range_adjust (caster, spell)));
2124 2121
2125 if (!spell->race) 2122 if (!spell->race)
2126 { 2123 {
2127 sprintf (buf, "animated %s", &weapon->name); 2124 sprintf (buf, "animated %s", &weapon->name);
2128 tmp->name = buf; 2125 tmp->name = buf;
2134 tmp->state = weapon->state; 2131 tmp->state = weapon->state;
2135 tmp->flag [FLAG_ANIMATE] = weapon->flag [FLAG_ANIMATE]; 2132 tmp->flag [FLAG_ANIMATE] = weapon->flag [FLAG_ANIMATE];
2136 } 2133 }
2137 2134
2138 /* make experience increase in proportion to the strength of the summoned creature. */ 2135 /* make experience increase in proportion to the strength of the summoned creature. */
2139 tmp->stats.exp *= 1 + (MAX (spell->stats.maxgrace, spell->stats.sp) / casting_level (caster, spell)); 2136 tmp->stats.exp *= 1 + (max (spell->stats.maxgrace, spell->stats.sp) / casting_level (caster, spell));
2140 2137
2141 tmp->speed_left = -1; 2138 tmp->speed_left = -1;
2142 tmp->direction = dir; 2139 tmp->direction = dir;
2143 2140
2144 m->insert (tmp, x, y, op); 2141 m->insert (tmp, x, y, op);
2161 success = op->map->change_map_light (spell->stats.dam); 2158 success = op->map->change_map_light (spell->stats.dam);
2162 2159
2163 if (!success) 2160 if (!success)
2164 { 2161 {
2165 if (spell->stats.dam < 0) 2162 if (spell->stats.dam < 0)
2166 new_draw_info (NDI_UNIQUE, 0, op, "It can be no brighter here."); 2163 op->failmsg ("It can be no brighter here.");
2167 else 2164 else
2168 new_draw_info (NDI_UNIQUE, 0, op, "It can be no darker here."); 2165 op->failmsg ("It can be no darker here.");
2169 } 2166 }
2170 2167
2171 return success; 2168 return success;
2172} 2169}
2173 2170
2183 2180
2184 new_aura = present_arch_in_ob (spell->other_arch, op); 2181 new_aura = present_arch_in_ob (spell->other_arch, op);
2185 if (new_aura) 2182 if (new_aura)
2186 refresh = 1; 2183 refresh = 1;
2187 else 2184 else
2188 new_aura = arch_to_object (spell->other_arch); 2185 new_aura = spell->other_arch->instance ();
2189 2186
2190 new_aura->duration = spell->duration + 10 * SP_level_duration_adjust (caster, spell); 2187 new_aura->duration = spell->duration + 10 * SP_level_duration_adjust (caster, spell);
2191 2188
2192 new_aura->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); 2189 new_aura->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
2193 2190
2258 if (pos.normalise () && !(OB_TYPE_MOVE_BLOCK (env, pos->move_block))) 2255 if (pos.normalise () && !(OB_TYPE_MOVE_BLOCK (env, pos->move_block)))
2259 { 2256 {
2260 hit_map (aura, i, aura->attacktype, 0); 2257 hit_map (aura, i, aura->attacktype, 0);
2261 2258
2262 if (aura->other_arch) 2259 if (aura->other_arch)
2263 pos.insert (arch_to_object (aura->other_arch), aura); 2260 pos.insert (aura->other_arch->instance (), aura);
2264 } 2261 }
2265 } 2262 }
2266 2263
2267 /* put the aura back in the player's inventory */ 2264 /* put the aura back in the player's inventory */
2268 env->insert (aura); 2265 env->insert (aura);
2278 for (object *tmp = op->ms ().bot; tmp; tmp = tmp->above) 2275 for (object *tmp = op->ms ().bot; tmp; tmp = tmp->above)
2279 { 2276 {
2280 int atk_lev, def_lev; 2277 int atk_lev, def_lev;
2281 object *victim = tmp->head_ (); 2278 object *victim = tmp->head_ ();
2282 2279
2283 if (!QUERY_FLAG (victim, FLAG_MONSTER)) 2280 if (!victim->flag [FLAG_MONSTER])
2284 continue; 2281 continue;
2285 2282
2286 if (QUERY_FLAG (victim, FLAG_UNAGGRESSIVE)) 2283 if (victim->flag [FLAG_UNAGGRESSIVE])
2287 continue; 2284 continue;
2288 2285
2289 if (victim->stats.exp == 0) 2286 if (victim->stats.exp == 0)
2290 continue; 2287 continue;
2291 2288
2292 def_lev = MAX (1, victim->level); 2289 def_lev = max (1, victim->level);
2293 atk_lev = MAX (1, op->level); 2290 atk_lev = max (1, op->level);
2294 2291
2295 if (rndm (0, atk_lev - 1) > def_lev) 2292 if (rndm (0, atk_lev - 1) > def_lev)
2296 { 2293 {
2297 /* make this sucker peaceful. */ 2294 /* make this sucker peaceful. */
2298 2295
2307 victim->stats.sp = 0; 2304 victim->stats.sp = 0;
2308 victim->stats.grace = 0; 2305 victim->stats.grace = 0;
2309 victim->stats.Pow = 0; 2306 victim->stats.Pow = 0;
2310#endif 2307#endif
2311 victim->attack_movement = RANDO2; 2308 victim->attack_movement = RANDO2;
2312 SET_FLAG (victim, FLAG_UNAGGRESSIVE); 2309 victim->set_flag (FLAG_UNAGGRESSIVE);
2313 SET_FLAG (victim, FLAG_RUN_AWAY); 2310 victim->set_flag (FLAG_RUN_AWAY);
2314 SET_FLAG (victim, FLAG_RANDOM_MOVE); 2311 victim->set_flag (FLAG_RANDOM_MOVE);
2315 CLEAR_FLAG (victim, FLAG_MONSTER); 2312 victim->clr_flag (FLAG_MONSTER);
2316 2313
2317 if (victim->name) 2314 if (victim->name)
2318 new_draw_info_format (NDI_UNIQUE, 0, op->owner, "%s no longer feels like fighting.", &victim->name); 2315 new_draw_info_format (NDI_UNIQUE, 0, op->owner, "%s no longer feels like fighting.", &victim->name);
2319 } 2316 }
2320 } 2317 }
2326int 2323int
2327write_mark (object *op, object *spell, const char *msg) 2324write_mark (object *op, object *spell, const char *msg)
2328{ 2325{
2329 if (!msg || msg[0] == 0) 2326 if (!msg || msg[0] == 0)
2330 { 2327 {
2331 new_draw_info (NDI_UNIQUE, 0, op, "Write what?"); 2328 op->failmsg ("Write what?");
2332 return 0; 2329 return 0;
2333 } 2330 }
2334 2331
2335 if (!msg_is_safe (msg)) 2332 if (!msg_is_safe (msg))
2336 { 2333 {
2337 new_draw_info (NDI_UNIQUE, 0, op, "Trying to cheat are we?"); 2334 op->failmsg ("Trying to cheat are we? H<@-signs are not allowed in marking runes.>");
2338 LOG (llevInfo, "write_mark: player %s tried to write bogus rune %s\n", &op->name, msg); 2335 LOG (llevInfo, "write_mark: player %s tried to write bogus rune %s\n", &op->name, msg);
2339 return 0; 2336 return 0;
2340 } 2337 }
2341 2338
2342 if (!spell->other_arch) 2339 if (!spell->other_arch)
2343 return 0; 2340 return 0;
2344 2341
2345 object *tmp = arch_to_object (spell->other_arch); 2342 object *tmp = spell->other_arch->instance ();
2346 2343
2347 tmp->race = op->name; /*Save the owner of the rune */ 2344 tmp->race = op->name; /*Save the owner of the rune */
2348 tmp->msg = msg; 2345 tmp->msg = msg;
2349 2346
2350 tmp->insert_at (op, op, INS_BELOW_ORIGINATOR); 2347 tmp->insert_at (op, op, INS_BELOW_ORIGINATOR);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines