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.115 by root, Sun Nov 29 09:41:28 2009 UTC vs.
Revision 1.144 by root, Mon Nov 26 15:12:16 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 it under 8 * Deliantra is free software: you can redistribute it and/or modify it under
9 * the terms of the Affero GNU General Public License as published by the 9 * the terms of the Affero GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your 10 * Free Software Foundation, either version 3 of the License, or (at your
11 * 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 Affero GNU General Public License 18 * You should have received a copy of the Affero GNU General Public License
19 * and the GNU General Public License along with this program. If not, see 19 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>. 20 * <http://www.gnu.org/licenses/>.
21 * 21 *
22 * 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>
23 */ 23 */
24 24
25#include <global.h> 25#include <global.h>
26#include <object.h> 26#include <object.h>
58} 58}
59 59
60int 60int
61recharge (object *op, object *caster, object *spell_ob) 61recharge (object *op, object *caster, object *spell_ob)
62{ 62{
63 object *wand, *tmp;
64 int ncharges; 63 int ncharges;
65 64
66 wand = find_marked_object (op); 65 object *wand = op->mark ();
66
67 if (!wand || wand->type != WAND) 67 if (!wand || wand->type != WAND)
68 { 68 {
69 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.");
70 return 0; 70 return 0;
71 } 71 }
72
72 if (!(random_roll (0, 3, op, PREFER_HIGH))) 73 if (!(random_roll (0, 3, op, PREFER_HIGH)))
73 { 74 {
74 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));
75 op->play_sound (sound_find ("ob_explode")); 76 op->play_sound (sound_find ("ob_explode"));
76 wand->destroy (); 77 wand->destroy ();
77 tmp = get_archetype (shstr_fireball); 78 object *tmp = archetype::get (shstr_fireball);
78 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;
79 80
80 if (!tmp->stats.dam) 81 if (!tmp->stats.dam)
81 tmp->stats.dam = 1; 82 tmp->stats.dam = 1;
82 83
93 94
94 if (wand->inv && wand->inv->level) 95 if (wand->inv && wand->inv->level)
95 ncharges /= wand->inv->level; 96 ncharges /= wand->inv->level;
96 else 97 else
97 { 98 {
98 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));
99 return 0; 100 return 0;
100 } 101 }
101 102
102 if (!ncharges) 103 if (!ncharges)
103 ncharges = 1; 104 ncharges = 1;
104 105
105 wand->stats.food += ncharges; 106 wand->stats.food += ncharges;
106 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));
107 108
108 if (wand->arch && QUERY_FLAG (wand->arch, FLAG_ANIMATE)) 109 if (wand->arch && wand->arch->flag [FLAG_ANIMATE])
109 { 110 {
110 SET_FLAG (wand, FLAG_ANIMATE); 111 wand->set_flag (FLAG_ANIMATE);
111 wand->set_speed (wand->arch->speed); 112 wand->set_speed (wand->arch->speed);
112 } 113 }
113 114
114 return 1; 115 return 1;
115} 116}
129{ 130{
130 int bonus_plus = 0; 131 int bonus_plus = 0;
131 const char *missile_name = "arrow"; 132 const char *missile_name = "arrow";
132 133
133 for (object *tmp = op->inv; tmp; tmp = tmp->below) 134 for (object *tmp = op->inv; tmp; tmp = tmp->below)
134 if (tmp->type == BOW && QUERY_FLAG (tmp, FLAG_APPLIED)) 135 if (tmp->type == BOW && tmp->flag [FLAG_APPLIED])
135 missile_name = tmp->race; 136 missile_name = tmp->race;
136 137
137 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);
138 139
139 archetype *missile_arch = archetype::find (missile_name); 140 archetype *missile_arch = archetype::find (missile_name);
158 break; 159 break;
159 160
160 if (!al) 161 if (!al)
161 { 162 {
162 missile->destroy (); 163 missile->destroy ();
163 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);
164 return 0; 165 return 0;
165 } 166 }
166 167
167 if (al->item->slaying) 168 if (al->item->slaying)
168 { 169 {
169 missile->destroy (); 170 missile->destroy ();
170 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);
171 return 0; 172 return 0;
172 } 173 }
173 174
174 give_artifact_abilities (missile, al->item); 175 give_artifact_abilities (missile, al->item);
175 /* 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 -
193 194
194 missile->magic = missile_plus; 195 missile->magic = missile_plus;
195 /* Can't get any money for these objects */ 196 /* Can't get any money for these objects */
196 missile->value = 0; 197 missile->value = 0;
197 198
198 SET_FLAG (missile, FLAG_IDENTIFIED); 199 missile->set_flag (FLAG_IDENTIFIED);
199 200
200 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 ())
201 pick_up (op, missile); 206 pick_up (op, missile);
202 207
203 return 1; 208 return 1;
204} 209}
205
206 210
207/* allows the choice of what sort of food object to make. 211/* allows the choice of what sort of food object to make.
208 * 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*/
209int 213int
210cast_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)
257 /* 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
258 * know 262 * know
259 */ 263 */
260 if (!at) 264 if (!at)
261 { 265 {
262 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.");
263 return 0; 267 return 0;
264 } 268 }
265 269
266 food_value /= at->stats.food; 270 food_value /= at->stats.food;
267 new_op = arch_to_object (at); 271 new_op = at->instance ();
268 new_op->nrof = food_value; 272 new_op->nrof = food_value;
269 273
270 new_op->value = 0; 274 new_op->value = 0;
271 if (new_op->nrof < 1) 275 if (new_op->nrof < 1)
272 new_op->nrof = 1; 276 new_op->nrof = 1;
297 mflags = get_map_flags (m, &m, x, y, &x, &y); 301 mflags = get_map_flags (m, &m, x, y, &x, &y);
298 302
299 if (mflags & P_OUT_OF_MAP) 303 if (mflags & P_OUT_OF_MAP)
300 break; 304 break;
301 305
302 if (!QUERY_FLAG (op, FLAG_WIZCAST) && (mflags & P_NO_MAGIC)) 306 if (!op->flag [FLAG_WIZCAST] && (mflags & P_NO_MAGIC))
303 { 307 {
304 new_draw_info (NDI_UNIQUE, 0, op, "Something blocks your magic."); 308 new_draw_info (NDI_UNIQUE, 0, op, "Something blocks your magic.");
305 return 0; 309 return 0;
306 } 310 }
307 311
308 if (mflags & P_IS_ALIVE) 312 if (mflags & P_IS_ALIVE)
309 { 313 {
310 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)
311 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]))
312 { 316 {
313 new_draw_info (NDI_UNIQUE, 0, op, "You detect something."); 317 new_draw_info (NDI_UNIQUE, 0, op, "You detect something.");
314 if (tmp->head != NULL) 318 if (tmp->head != NULL)
315 tmp = tmp->head; 319 tmp = tmp->head;
316 examine_monster (op, tmp); 320 examine_monster (op, tmp);
339 if (pl->type == PLAYER) 343 if (pl->type == PLAYER)
340 { 344 {
341 /* If race isn't set, then invisible unless it is undead */ 345 /* If race isn't set, then invisible unless it is undead */
342 if (!pl->contr->invis_race) 346 if (!pl->contr->invis_race)
343 { 347 {
344 if (QUERY_FLAG (mon, FLAG_UNDEAD)) 348 if (mon->flag [FLAG_UNDEAD])
345 return 0; 349 return 0;
346 350
347 return 1; 351 return 1;
348 } 352 }
349 353
380int 384int
381cast_invisible (object *op, object *caster, object *spell_ob) 385cast_invisible (object *op, object *caster, object *spell_ob)
382{ 386{
383 if (op->invisible > 1000) 387 if (op->invisible > 1000)
384 { 388 {
385 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");
386 return 0; 390 return 0;
387 } 391 }
388 392
389 /* 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
390 * and if statement or two. 394 * and if statement or two.
391 */ 395 */
392 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
393 /* max duration */ 398 /* limit duration */
394 if (op->invisible > 1000) 399 min_it (op->invisible, 1000);
395 op->invisible = 1000;
396 400
397 if (op->type == PLAYER) 401 if (op->type == PLAYER)
398 { 402 {
399 op->contr->invis_race = spell_ob->race; 403 op->contr->invis_race = spell_ob->race;
400 404
401 if (QUERY_FLAG (spell_ob, FLAG_MAKE_INVIS)) 405 if (spell_ob->flag [FLAG_MAKE_INVIS])
402 op->contr->tmp_invis = 0; 406 op->contr->tmp_invis = 0;
403 else 407 else
404 op->contr->tmp_invis = 1; 408 op->contr->tmp_invis = 1;
405
406 op->contr->hidden = 0;
407 } 409 }
408 410
409 if (makes_invisible_to (op, op)) 411 if (makes_invisible_to (op, op))
410 new_draw_info (NDI_UNIQUE, 0, op, "You can't see your hands!"); 412 new_draw_info (NDI_UNIQUE, 0, op, "You can't see your hands!");
411 else 413 else
448 // earth to dust tears down everything that can be torn down 450 // earth to dust tears down everything that can be torn down
449 for (object *next, *tmp = m->at (sx, sy).bot; tmp; tmp = next) 451 for (object *next, *tmp = m->at (sx, sy).bot; tmp; tmp = next)
450 { 452 {
451 next = tmp->above; 453 next = tmp->above;
452 454
453 if (QUERY_FLAG (tmp, FLAG_TEAR_DOWN)) 455 if (tmp->flag [FLAG_TEAR_DOWN])
454 hit_player (tmp, 9998, op, AT_PHYSICAL, 0); 456 hit_player (tmp, 9998, op, AT_PHYSICAL, 0);
455 } 457 }
456 } 458 }
457 459
458 return 1; 460 return 1;
460 462
461void 463void
462execute_word_of_recall (object *op) 464execute_word_of_recall (object *op)
463{ 465{
464 if (object *pl = op->in_player ()) 466 if (object *pl = op->in_player ())
465 {
466 if (pl->ms ().flags () & P_NO_CLERIC && !QUERY_FLAG (pl, FLAG_WIZCAST)) 467 if (pl->ms ().flags () & P_NO_CLERIC && !pl->flag [FLAG_WIZCAST])
467 new_draw_info (NDI_UNIQUE, 0, pl, "You feel something fizzle inside you."); 468 new_draw_info (NDI_UNIQUE, 0, pl, "You feel something fizzle inside you.");
468 else 469 else
469 pl->player_goto (op->slaying, op->stats.hp, op->stats.sp); 470 pl->player_goto (op->slaying, op->stats.hp, op->stats.sp);
470 }
471 471
472 op->destroy (); 472 op->destroy ();
473} 473}
474 474
475/* Word of recall causes the player to return 'home'. 475/* Word of recall causes the player to return 'home'.
477 * time delay effect. 477 * time delay effect.
478 */ 478 */
479int 479int
480cast_word_of_recall (object *op, object *caster, object *spell_ob) 480cast_word_of_recall (object *op, object *caster, object *spell_ob)
481{ 481{
482 object *dummy; 482 if (!op->is_player ())
483 int time;
484
485 if (op->type != PLAYER)
486 return 0; 483 return 0;
487 484
488 if (find_obj_by_type_subtype (op, SPELL_EFFECT, SP_WORD_OF_RECALL)) 485 if (find_obj_by_type_subtype (op, SPELL_EFFECT, SP_WORD_OF_RECALL))
489 { 486 {
490 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you."); 487 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you.");
491 return 1; 488 return 1;
492 } 489 }
493 490
494 dummy = get_archetype (FORCE_NAME); 491 object *dummy = archetype::get (FORCE_NAME);
495 492
496 if (!dummy)
497 {
498 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
499 LOG (llevError, "cast_word_of_recall: get_archetype(force) failed!\n");
500 return 0;
501 }
502
503 time = spell_ob->duration - SP_level_duration_adjust (caster, spell_ob); 493 int time = max (1, spell_ob->duration - SP_level_duration_adjust (caster, spell_ob));
504 if (time < 1)
505 time = 1;
506 494
507 /* value of speed really doesn't make much difference, as long as it is 495 /* value of speed really doesn't make much difference, as long as it is
508 * positive. Lower value may be useful so that the problem doesn't 496 * positive. Lower value may be useful so that the problem doesn't
509 * do anything really odd if it say a -1000 or something. 497 * do anything really odd if it say a -1000 or something.
510 */ 498 */
511 dummy->set_speed (0.002); 499 dummy->set_speed (0.002);
512 dummy->speed_left = -dummy->speed * time; 500 dummy->speed_left = -dummy->speed * time;
513 dummy->type = SPELL_EFFECT; 501 dummy->type = SPELL_EFFECT;
514 dummy->subtype = SP_WORD_OF_RECALL; 502 dummy->subtype = SP_WORD_OF_RECALL;
515 503 dummy->slaying = op->contr->savebed_map;
516 /* If we could take advantage of enter_player_savebed() here, it would be 504 dummy->stats.hp = op->contr->bed_x;
517 * nice, but until the map load fails, we can't. 505 dummy->stats.sp = op->contr->bed_y;
518 */
519 EXIT_PATH (dummy) = op->contr->savebed_map;
520 EXIT_X (dummy) = op->contr->bed_x;
521 EXIT_Y (dummy) = op->contr->bed_y;
522 506
523 op->insert (dummy); 507 op->insert (dummy);
524 508
525 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you."); 509 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you.");
526 510
594 for (int i = 0; i < NUM_STATS; i++) 578 for (int i = 0; i < NUM_STATS; i++)
595 if (tmp->stats.stat (i) < 0) 579 if (tmp->stats.stat (i) < 0)
596 buf.printf (" - Your %s is depleted by %d.\n", statname[i], -tmp->stats.stat (i)); 580 buf.printf (" - Your %s is depleted by %d.\n", statname[i], -tmp->stats.stat (i));
597 } 581 }
598 582
599 if (is_dragon_pl (op)) 583 if (op->is_dragon ())
600 /* now grab the 'dragon_ability'-force from the player's inventory */ 584 /* now grab the 'dragon_ability'-force from the player's inventory */
601 for (tmp = op->inv; tmp; tmp = tmp->below) 585 for (tmp = op->inv; tmp; tmp = tmp->below)
602 { 586 {
603 if (tmp->type == FORCE && tmp->arch->archname == shstr_dragon_ability_force) 587 if (tmp->type == FORCE && tmp->arch->archname == shstr_dragon_ability_force)
604 { 588 {
645 629
646 if ((spell_ob->move_block || x != op->x || y != op->y) && 630 if ((spell_ob->move_block || x != op->x || y != op->y) &&
647 (get_map_flags (m, &m, x, y, &x, &y) & (P_OUT_OF_MAP | P_IS_ALIVE) || 631 (get_map_flags (m, &m, x, y, &x, &y) & (P_OUT_OF_MAP | P_IS_ALIVE) ||
648 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK (m, x, y)) == spell_ob->move_block))) 632 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK (m, x, y)) == spell_ob->move_block)))
649 { 633 {
650 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way."); 634 op->failmsg ("Something is in the way.");
651 return 0; 635 return 0;
652 } 636 }
653 637
654 if (spell_ob->other_arch) 638 if (spell_ob->other_arch)
655 tmp = arch_to_object (spell_ob->other_arch); 639 tmp = spell_ob->other_arch->instance ();
656 else if (spell_ob->race) 640 else if (spell_ob->race)
657 { 641 {
658 char buf1[MAX_BUF]; 642 char buf1[MAX_BUF];
659 643
660 sprintf (buf1, spell_ob->race, dir); 644 sprintf (buf1, spell_ob->race, dir);
664 LOG (llevError, "summon_wall: Unable to find archetype %s\n", buf1); 648 LOG (llevError, "summon_wall: Unable to find archetype %s\n", buf1);
665 new_draw_info (NDI_UNIQUE, 0, op, "This spell is broken."); 649 new_draw_info (NDI_UNIQUE, 0, op, "This spell is broken.");
666 return 0; 650 return 0;
667 } 651 }
668 652
669 tmp = arch_to_object (at); 653 tmp = at->instance ();
670 } 654 }
671 else 655 else
672 { 656 {
673 LOG (llevError, "magic_wall: spell %s lacks other_arch\n", &spell_ob->name); 657 LOG (llevError, "magic_wall: spell %s lacks other_arch\n", &spell_ob->name);
674 return 0; 658 return 0;
679 tmp->attacktype = spell_ob->attacktype; 663 tmp->attacktype = spell_ob->attacktype;
680 tmp->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob); 664 tmp->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
681 tmp->stats.dam = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob); 665 tmp->stats.dam = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob);
682 tmp->range = 0; 666 tmp->range = 0;
683 } 667 }
684 else if (QUERY_FLAG (tmp, FLAG_ALIVE)) 668 else if (tmp->flag [FLAG_ALIVE])
685 { 669 {
686 tmp->stats.hp = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob); 670 tmp->stats.hp = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
687 tmp->stats.maxhp = tmp->stats.hp; 671 tmp->stats.maxhp = tmp->stats.hp;
688 } 672 }
689 673
690 if (QUERY_FLAG (spell_ob, FLAG_IS_USED_UP) || QUERY_FLAG (tmp, FLAG_IS_USED_UP)) 674 if (spell_ob->flag [FLAG_IS_USED_UP] || tmp->flag [FLAG_IS_USED_UP])
691 { 675 {
692 tmp->stats.food = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob); 676 tmp->stats.food = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
693 SET_FLAG (tmp, FLAG_IS_USED_UP); 677 tmp->set_flag (FLAG_IS_USED_UP);
694 } 678 }
695 679
696 if (QUERY_FLAG (spell_ob, FLAG_TEAR_DOWN)) 680 if (spell_ob->flag [FLAG_TEAR_DOWN])
697 { 681 {
698 tmp->stats.hp = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob); 682 tmp->stats.hp = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob);
699 tmp->stats.maxhp = tmp->stats.hp; 683 tmp->stats.maxhp = tmp->stats.hp;
700 SET_FLAG (tmp, FLAG_TEAR_DOWN); 684 tmp->set_flag (FLAG_TEAR_DOWN);
701 SET_FLAG (tmp, FLAG_ALIVE); 685 tmp->set_flag (FLAG_ALIVE);
702 } 686 }
703 687
704 /* This can't really hurt - if the object doesn't kill anything, 688 /* This can't really hurt - if the object doesn't kill anything,
705 * these fields just won't be used. Do not set the owner for 689 * these fields just won't be used. Do not set the owner for
706 * earthwalls, though, so they survive restarts. 690 * earthwalls, though, so they survive restarts.
718 return 0; 702 return 0;
719 } 703 }
720 704
721 /* If this is a spellcasting wall, need to insert the spell object */ 705 /* If this is a spellcasting wall, need to insert the spell object */
722 if (tmp->other_arch && tmp->other_arch->type == SPELL) 706 if (tmp->other_arch && tmp->other_arch->type == SPELL)
723 insert_ob_in_ob (arch_to_object (tmp->other_arch), tmp); 707 insert_ob_in_ob (tmp->other_arch->instance (), tmp);
724 708
725 /* This code causes the wall to extend some distance in 709 /* This code causes the wall to extend some distance in
726 * each direction, or until an obstruction is encountered. 710 * each direction, or until an obstruction is encountered.
727 * posblocked and negblocked help determine how far the 711 * posblocked and negblocked help determine how far the
728 * created wall can extend, it won't go extend through 712 * created wall can extend, it won't go extend through
748 object *tmp2 = tmp->clone (); 732 object *tmp2 = tmp->clone ();
749 m->insert (tmp2, x, y, op); 733 m->insert (tmp2, x, y, op);
750 734
751 /* If this is a spellcasting wall, need to insert the spell object */ 735 /* If this is a spellcasting wall, need to insert the spell object */
752 if (tmp2->other_arch && tmp2->other_arch->type == SPELL) 736 if (tmp2->other_arch && tmp2->other_arch->type == SPELL)
753 tmp2->insert (arch_to_object (tmp2->other_arch)); 737 tmp2->insert (tmp2->other_arch->instance ());
754 738
755 } 739 }
756 else 740 else
757 posblocked = 1; 741 posblocked = 1;
758 742
765 { 749 {
766 object *tmp2 = tmp->clone (); 750 object *tmp2 = tmp->clone ();
767 m->insert (tmp2, x, y, op); 751 m->insert (tmp2, x, y, op);
768 752
769 if (tmp2->other_arch && tmp2->other_arch->type == SPELL) 753 if (tmp2->other_arch && tmp2->other_arch->type == SPELL)
770 tmp2->insert (arch_to_object (tmp2->other_arch)); 754 tmp2->insert (tmp2->other_arch->instance ());
771 } 755 }
772 else 756 else
773 negblocked = 1; 757 negblocked = 1;
774 } 758 }
775 759
776 if (QUERY_FLAG (tmp, FLAG_BLOCKSVIEW)) 760 if (tmp->flag [FLAG_BLOCKSVIEW])
777 update_all_los (op->map, op->x, op->y); 761 update_all_los (op->map, op->x, op->y);
778 762
779 return 1; 763 return 1;
780} 764}
781 765
790 if (op->type != PLAYER) 774 if (op->type != PLAYER)
791 return 0; 775 return 0;
792 776
793 if (!dir) 777 if (!dir)
794 { 778 {
795 new_draw_info (NDI_UNIQUE, 0, op, "In what direction?"); 779 op->failmsg ("In what direction?");
796 return 0; 780 return 0;
797 } 781 }
798 782
799 /* Given the new outdoor maps, can't let players dimension door for 783 /* Given the new outdoor maps, can't let players dimension door for
800 * ever, so put limits in. 784 * ever, so put limits in.
805 { 789 {
806 int count = atoi (spellparam); 790 int count = atoi (spellparam);
807 791
808 if (count > maxdist) 792 if (count > maxdist)
809 { 793 {
810 new_draw_info (NDI_UNIQUE, 0, op, "You can't dimension door that far!"); 794 op->failmsg ("You can't dimension door that far!");
811 return 0; 795 return 0;
812 } 796 }
813 797
814 for (dist = 0; dist < count; dist++) 798 for (dist = 0; dist < count; dist++)
815 { 799 {
876 break; 860 break;
877 861
878 } 862 }
879 if (!dist) 863 if (!dist)
880 { 864 {
881 new_draw_info (NDI_UNIQUE, 0, op, "Your spell failed!\n"); 865 op->failmsg ("Your spell failed!\n");
882 return 0; 866 return 0;
883 } 867 }
884 } 868 }
885 869
886 /* Actually move the player now */ 870 /* Actually move the player now */
1002 tmp->stats.grace = tmp->stats.maxgrace; 986 tmp->stats.grace = tmp->stats.maxgrace;
1003 success = 1; 987 success = 1;
1004 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!"); 988 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!");
1005 } 989 }
1006 990
1007 if (spell->stats.food && tmp->stats.food < 999) 991 if (spell->stats.food && tmp->stats.food < MAX_FOOD)
1008 { 992 {
1009 tmp->stats.food += spell->stats.food; 993 tmp->stats.food += spell->stats.food;
1010 994 min_it (tmp->stats.food, MAX_FOOD);
1011 if (tmp->stats.food > 999)
1012 tmp->stats.food = 999;
1013 995
1014 success = 1; 996 success = 1;
1015 /* We could do something a bit better like the messages for healing above */ 997 /* We could do something a bit better like the messages for healing above */
1016 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel your belly fill with food"); 998 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel your belly fill with food");
1017 } 999 }
1064 break; 1046 break;
1065 } 1047 }
1066 else if (spell_ob->race && spell_ob->race == tmp2->name) 1048 else if (spell_ob->race && spell_ob->race == tmp2->name)
1067 { 1049 {
1068 if (!silent) 1050 if (!silent)
1069 new_draw_info_format (NDI_UNIQUE, 0, op,
1070 "You can not cast %s while %s is in effect", 1051 op->failmsgf ("You can not cast %s while %s is in effect",
1071 &spell_ob->name, &tmp2->name_pl); 1052 &spell_ob->name, &tmp2->name_pl);
1072 1053
1073 return 0; 1054 return 0;
1074 } 1055 }
1075 } 1056 }
1076 } 1057 }
1092 1073
1093 new_draw_info_format (NDI_UNIQUE, 0, op, 1074 new_draw_info_format (NDI_UNIQUE, 0, op,
1094 "You create an aura of magical force. H<The effect will last for about %.10g seconds.>", 1075 "You create an aura of magical force. H<The effect will last for about %.10g seconds.>",
1095 TICK2TIME (duration)); 1076 TICK2TIME (duration));
1096 1077
1097 force = get_archetype (FORCE_NAME); 1078 force = archetype::get (FORCE_NAME);
1098 force->subtype = FORCE_CHANGE_ABILITY; 1079 force->subtype = FORCE_CHANGE_ABILITY;
1099 force->duration = duration; 1080 force->duration = duration;
1100 1081
1101 if (spell_ob->race) 1082 if (spell_ob->race)
1102 force->name = spell_ob->race; 1083 force->name = spell_ob->race;
1105 1086
1106 force->name_pl = spell_ob->name; 1087 force->name_pl = spell_ob->name;
1107 1088
1108 force->speed = 1.0; 1089 force->speed = 1.0;
1109 force->speed_left = -1.0; 1090 force->speed_left = -1.0;
1110 SET_FLAG (force, FLAG_APPLIED); 1091 force->set_flag (FLAG_APPLIED);
1111 1092
1112 /* Now start processing the effects. First, protections */ 1093 /* Now start processing the effects. First, protections */
1113 for (i = 0; i < NROFATTACKS; i++) 1094 for (i = 0; i < NROFATTACKS; i++)
1114 {
1115 if (spell_ob->resist[i]) 1095 if (spell_ob->resist[i])
1116 {
1117 force->resist[i] = spell_ob->resist[i] + SP_level_dam_adjust (caster, spell_ob); 1096 force->resist[i] = min (100, spell_ob->resist[i] + SP_level_dam_adjust (caster, spell_ob));
1118 if (force->resist[i] > 100)
1119 force->resist[i] = 100;
1120 }
1121 }
1122 1097
1123 if (spell_ob->stats.hp) 1098 if (spell_ob->stats.hp)
1124 force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust (caster, spell_ob); 1099 force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust (caster, spell_ob);
1125 1100
1126 if (tmp->type == PLAYER) 1101 if (tmp->type == PLAYER)
1145 } 1120 }
1146 } 1121 }
1147 1122
1148 force->move_type = spell_ob->move_type; 1123 force->move_type = spell_ob->move_type;
1149 1124
1150 if (QUERY_FLAG (spell_ob, FLAG_SEE_IN_DARK)) 1125 if (spell_ob->flag [FLAG_SEE_IN_DARK])
1151 SET_FLAG (force, FLAG_SEE_IN_DARK); 1126 force->set_flag (FLAG_SEE_IN_DARK);
1152 1127
1153 if (QUERY_FLAG (spell_ob, FLAG_XRAYS)) 1128 if (spell_ob->flag [FLAG_XRAYS])
1154 SET_FLAG (force, FLAG_XRAYS); 1129 force->set_flag (FLAG_XRAYS);
1155 1130
1156 /* Haste/bonus speed */ 1131 /* Haste/bonus speed */
1157 if (spell_ob->stats.exp) 1132 if (spell_ob->stats.exp)
1158 { 1133 {
1159 if (op->speed > 0.5f) 1134 if (op->speed > 0.5f)
1212 } 1187 }
1213 } 1188 }
1214 1189
1215 if (force == NULL) 1190 if (force == NULL)
1216 { 1191 {
1217 force = get_archetype (FORCE_NAME); 1192 force = archetype::get (FORCE_NAME);
1218 force->subtype = FORCE_CHANGE_ABILITY; 1193 force->subtype = FORCE_CHANGE_ABILITY;
1219 if (spell_ob->race) 1194 if (spell_ob->race)
1220 force->name = spell_ob->race; 1195 force->name = spell_ob->race;
1221 else 1196 else
1222 force->name = spell_ob->name; 1197 force->name = spell_ob->name;
1237 { 1212 {
1238 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect."); 1213 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect.");
1239 } 1214 }
1240 return 0; 1215 return 0;
1241 } 1216 }
1217
1242 force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50; 1218 force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50;
1243 force->speed = 1.0; 1219 force->speed = 1.0;
1244 force->speed_left = -1.0; 1220 force->speed_left = -1.0;
1245 SET_FLAG (force, FLAG_APPLIED); 1221 force->set_flag (FLAG_APPLIED);
1246 1222
1247 if (!god) 1223 if (!god)
1248 { 1224 {
1249 new_draw_info (NDI_UNIQUE, 0, op, "Your blessing seems empty."); 1225 new_draw_info (NDI_UNIQUE, 0, op, "Your blessing seems empty.");
1250 } 1226 }
1282 1258
1283/* Alchemy code by Mark Wedel 1259/* Alchemy code by Mark Wedel
1284 * 1260 *
1285 * This code adds a new spell, called alchemy. Alchemy will turn 1261 * This code adds a new spell, called alchemy. Alchemy will turn
1286 * objects to pyrite ("false gold"), henceforth called gold nuggets. 1262 * objects to pyrite ("false gold"), henceforth called gold nuggets.
1287 * 1263 *
1288 * The value of the gold nuggets being about 90% of that of the item 1264 * The value of the gold nuggets being about 90% of that of the item
1289 * itself. It uses the value of the object before charisma adjustments, 1265 * itself. It uses the value of the object before charisma adjustments,
1290 * because the nuggets themselves will be will be adjusted by charisma 1266 * because the nuggets themselves will be will be adjusted by charisma
1291 * when sold. 1267 * when sold.
1292 * 1268 *
1304 * the nuggets, alchemy the gold from that, etc. 1280 * the nuggets, alchemy the gold from that, etc.
1305 * Otherwise, give 9 silver on the gold for other objects, 1281 * Otherwise, give 9 silver on the gold for other objects,
1306 * so that it would still be more affordable to haul 1282 * so that it would still be more affordable to haul
1307 * the stuff back to town. 1283 * the stuff back to town.
1308 */ 1284 */
1309 if (QUERY_FLAG (obj, FLAG_UNPAID)) 1285 if (obj->flag [FLAG_UNPAID])
1310 value = 0; 1286 value = 0;
1311 else if (obj->type == MONEY || obj->type == GEM) 1287 else if (obj->type == MONEY || obj->type == GEM)
1312 value /= 3; 1288 value /= 3;
1313 else 1289 else
1314 value = value * 9 / 10; 1290 value = value * 9 / 10;
1368 1344
1369 for (object *next, *tmp = mp->at (nx, ny).bot; tmp; tmp = next) 1345 for (object *next, *tmp = mp->at (nx, ny).bot; tmp; tmp = next)
1370 { 1346 {
1371 next = tmp->above; 1347 next = tmp->above;
1372 1348
1373 if (tmp->weight > 0 && !QUERY_FLAG (tmp, FLAG_NO_PICK) && 1349 if (tmp->weight > 0 && !tmp->flag [FLAG_NO_PICK] &&
1374 !QUERY_FLAG (tmp, FLAG_ALIVE) && !QUERY_FLAG (tmp, FLAG_IS_CAULDRON)) 1350 !tmp->flag [FLAG_ALIVE] && !tmp->flag [FLAG_IS_CAULDRON])
1375 { 1351 {
1376 if (tmp->inv) 1352 if (tmp->inv)
1377 { 1353 {
1378 object *next1, *tmp1; 1354 object *next1, *tmp1;
1379 1355
1380 for (tmp1 = tmp->inv; tmp1; tmp1 = next1) 1356 for (tmp1 = tmp->inv; tmp1; tmp1 = next1)
1381 { 1357 {
1382 next1 = tmp1->below; 1358 next1 = tmp1->below;
1383 if (tmp1->weight > 0 && !QUERY_FLAG (tmp1, FLAG_NO_PICK) && 1359 if (tmp1->weight > 0 && !tmp1->flag [FLAG_NO_PICK] &&
1384 !QUERY_FLAG (tmp1, FLAG_ALIVE) && !QUERY_FLAG (tmp1, FLAG_IS_CAULDRON)) 1360 !tmp1->flag [FLAG_ALIVE] && !tmp1->flag [FLAG_IS_CAULDRON])
1385 alchemy_object (tmp1, value, weight); 1361 alchemy_object (tmp1, value, weight);
1386 } 1362 }
1387 } 1363 }
1388 1364
1389 alchemy_object (tmp, value, weight); 1365 alchemy_object (tmp, value, weight);
1394 } 1370 }
1395 1371
1396 value -= rndm (value >> 4); 1372 value -= rndm (value >> 4);
1397 value = min (value, value_max); 1373 value = min (value, value_max);
1398 1374
1399 for (int i = 0; i < sizeof (nugget) / sizeof (nugget [0]); ++i) 1375 for (int i = 0; i < array_length (nugget); ++i)
1400 if (int nrof = value / nugget [i]->value) 1376 if (int nrof = value / nugget [i]->value)
1401 { 1377 {
1402 value -= nrof * nugget[i]->value; 1378 value -= nrof * nugget[i]->value;
1403 1379
1404 object *tmp = arch_to_object (nugget[i]); 1380 object *tmp = nugget[i]->instance ();
1405 tmp->nrof = nrof; 1381 tmp->nrof = nrof;
1406 tmp->flag [FLAG_IDENTIFIED] = true; 1382 tmp->flag [FLAG_IDENTIFIED] = true;
1407 op->map->insert (tmp, x, y, op, 0); 1383 op->map->insert (tmp, x, y, op, 0);
1408 } 1384 }
1409 1385
1422int 1398int
1423remove_curse (object *op, object *caster, object *spell) 1399remove_curse (object *op, object *caster, object *spell)
1424{ 1400{
1425 int success = 0, was_one = 0; 1401 int success = 0, was_one = 0;
1426 1402
1403 int num_uncurse = max (1, spell->stats.dam + SP_level_dam_adjust (caster, spell));
1404
1405 op->splay_marked ();
1406
1407 int typeflag = spell->last_sp ? FLAG_DAMNED : FLAG_CURSED;
1408
1427 for (object *tmp = op->inv; tmp; tmp = tmp->below) 1409 for (object *tmp = op->inv; tmp && num_uncurse; tmp = tmp->below)
1428 if (QUERY_FLAG (tmp, FLAG_APPLIED) && 1410 if (!tmp->invisible && tmp->flag [typeflag])
1429 ((QUERY_FLAG (tmp, FLAG_CURSED) && QUERY_FLAG (spell, FLAG_CURSED)) ||
1430 (QUERY_FLAG (tmp, FLAG_DAMNED) && QUERY_FLAG (spell, FLAG_DAMNED))))
1431 { 1411 {
1432 was_one++; 1412 ++was_one;
1433 1413
1434 if (tmp->level <= casting_level (caster, spell)) 1414 if (tmp->level <= casting_level (caster, spell))
1435 { 1415 {
1436 success++; 1416 ++success;
1437 if (QUERY_FLAG (spell, FLAG_DAMNED)) 1417 --num_uncurse;
1438 CLEAR_FLAG (tmp, FLAG_DAMNED);
1439 1418
1440 CLEAR_FLAG (tmp, FLAG_CURSED); 1419 tmp->clr_flag (typeflag);
1441 CLEAR_FLAG (tmp, FLAG_KNOWN_CURSED); 1420 tmp->clr_flag (FLAG_CURSED);
1421 tmp->clr_flag (FLAG_KNOWN_CURSED);
1442 tmp->value = 0; /* Still can't sell it */ 1422 tmp->value = 0; /* Still can't sell it */
1443 1423
1444 if (object *pl = tmp->visible_to ()) 1424 if (object *pl = tmp->visible_to ())
1445 esrv_update_item (UPD_FLAGS, pl, tmp); 1425 esrv_update_item (UPD_FLAGS, pl, tmp);
1446 } 1426 }
1447 } 1427 }
1448 1428
1449 if (op->type == PLAYER) 1429 if (op->type == PLAYER)
1450 { 1430 {
1451 if (success) 1431 if (success)
1452 new_draw_info (NDI_UNIQUE, 0, op, "You feel like some of your items are looser now."); 1432 new_draw_info (NDI_UNIQUE, 0, op, "You realise that some of your items look shinier now. H<You successfully removed some curses.>");
1453 else 1433 else
1454 { 1434 {
1455 if (was_one) 1435 if (was_one)
1456 new_draw_info (NDI_UNIQUE, 0, op, "You failed to remove the curse."); 1436 new_draw_info (NDI_UNIQUE, 0, op, "You failed to remove any curse. H<The spell was not strong enough.>");
1457 else 1437 else
1458 new_draw_info (NDI_UNIQUE, 0, op, "You are not using any cursed items."); 1438 new_draw_info (NDI_UNIQUE, 0, op, "You are not having any cursed items. H<Epic fail.>");
1459 } 1439 }
1460 } 1440 }
1461 1441
1462 return success; 1442 return success;
1463} 1443}
1464 1444
1465/* Identifies objects in the players inventory/on the ground */ 1445/* Identifies objects in the players inventory/on the ground */
1466int 1446int
1467cast_identify (object *op, object *caster, object *spell) 1447cast_identify (object *op, object *caster, object *spell)
1468{ 1448{
1469 object *tmp;
1470 dynbuf_text &buf = msg_dynbuf; buf.clear (); 1449 dynbuf_text &buf = msg_dynbuf; buf.clear ();
1471 1450
1472 int num_ident = max (1, spell->stats.dam + SP_level_dam_adjust (caster, spell)); 1451 int num_ident = max (1, spell->stats.dam + SP_level_dam_adjust (caster, spell));
1473 1452
1453 op->splay_marked ();
1454
1474 for (tmp = op->inv; tmp; tmp = tmp->below) 1455 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1475 { 1456 {
1476 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !tmp->invisible && need_identify (tmp)) 1457 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && tmp->need_identify ())
1477 { 1458 {
1478 identify (tmp); 1459 identify (tmp);
1479 1460
1480 if (op->type == PLAYER) 1461 if (op->type == PLAYER)
1481 { 1462 {
1494 * stuff on the floor. Only identify stuff on the floor if the spell 1475 * stuff on the floor. Only identify stuff on the floor if the spell
1495 * was not fully used. 1476 * was not fully used.
1496 */ 1477 */
1497 if (num_ident) 1478 if (num_ident)
1498 { 1479 {
1499 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp; tmp = tmp->above) 1480 for (object *tmp = GET_MAP_OB (op->map, op->x, op->y); tmp; tmp = tmp->above)
1500 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !tmp->invisible && need_identify (tmp)) 1481 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && tmp->need_identify ())
1501 { 1482 {
1502 identify (tmp); 1483 identify (tmp);
1503 1484
1504 if (object *pl = tmp->visible_to ()) 1485 if (object *pl = tmp->visible_to ())
1505 { 1486 {
1531 1512
1532int 1513int
1533cast_detection (object *op, object *caster, object *spell, object *skill) 1514cast_detection (object *op, object *caster, object *spell, object *skill)
1534{ 1515{
1535 object *tmp, *last, *god, *detect; 1516 object *tmp, *last, *god, *detect;
1536 int done_one, range, mflags, floor, level; 1517 int done_one, range, floor, level;
1537 sint16 x, y, nx, ny; 1518 sint16 x, y, nx, ny;
1538 maptile *m; 1519 maptile *m;
1539 1520
1540 /* We precompute some values here so that we don't have to keep 1521 /* We precompute some values here so that we don't have to keep
1541 * doing it over and over again. 1522 * doing it over and over again.
1545 range = spell->range + SP_level_range_adjust (caster, spell); 1526 range = spell->range + SP_level_range_adjust (caster, spell);
1546 1527
1547 if (!skill) 1528 if (!skill)
1548 skill = caster; 1529 skill = caster;
1549 1530
1531 dynbuf buf;
1550 unordered_mapwalk (op, -range, -range, range, range) 1532 unordered_mapwalk (buf, op, -range, -range, range, range)
1551 { 1533 {
1552 /* For most of the detections, we only detect objects above the 1534 /* For most of the detections, we only detect objects above the
1553 * floor. But this is not true for show invisible. 1535 * floor. But this is not true for show invisible.
1554 * Basically, we just go and find the top object and work 1536 * Basically, we just go and find the top object and work
1555 * down - that is easier than working up. 1537 * down - that is easier than working up.
1556 */ 1538 */
1557 1539
1558 for (last = NULL, tmp = m->at (nx, ny).bot; tmp; tmp = tmp->above) 1540 for (last = 0, tmp = m->at (nx, ny).bot; tmp; tmp = tmp->above)
1559 last = tmp; 1541 last = tmp;
1560 1542
1561 /* Shouldn't happen, but if there are no objects on a space, this 1543 /* Shouldn't happen, but if there are no objects on a space, this
1562 * would happen. 1544 * would happen.
1563 */ 1545 */
1564 if (!last) 1546 if (!last)
1565 continue; 1547 continue;
1566 1548
1567 done_one = 0; 1549 done_one = 0;
1568 floor = 0; 1550 floor = 0;
1569 detect = NULL; 1551 detect = 0;
1570 for (tmp = last; tmp; tmp = tmp->below) 1552 for (tmp = last; tmp; tmp = tmp->below)
1571 { 1553 {
1572 /* show invisible */ 1554 /* show invisible */
1573 if (QUERY_FLAG (spell, FLAG_MAKE_INVIS) && 1555 if (spell->flag [FLAG_MAKE_INVIS]
1574 /* Might there be other objects that we can make visible? */ 1556 /* Might there be other objects that we can make visible? */
1575 (tmp->invisible && (QUERY_FLAG (tmp, FLAG_MONSTER) 1557 && (tmp->invisible && (tmp->flag [FLAG_MONSTER]
1576 || (tmp->type == PLAYER && !QUERY_FLAG (tmp, FLAG_WIZ)) 1558 || (tmp->type == PLAYER && !tmp->flag [FLAG_WIZ])
1577 || tmp->type == T_HANDLE 1559 || tmp->type == T_HANDLE
1578 || tmp->type == TRAPDOOR 1560 || tmp->type == TRAPDOOR
1579 || tmp->type == EXIT 1561 || tmp->type == EXIT
1580 || tmp->type == HOLE 1562 || tmp->type == HOLE
1581 || tmp->type == BUTTON 1563 || tmp->type == BUTTON
1582 || tmp->type == TELEPORTER 1564 || tmp->type == TELEPORTER
1583 || tmp->type == GATE 1565 || tmp->type == GATE
1584 || tmp->type == LOCKED_DOOR 1566 || tmp->type == LOCKED_DOOR
1585 || tmp->type == WEAPON 1567 || tmp->type == WEAPON
1586 || tmp->type == ALTAR 1568 || tmp->type == ALTAR
1587 || tmp->type == SIGN 1569 || (tmp->type == SIGN && tmp->face != magicmouth_face)
1588 || tmp->type == TRIGGER_PEDESTAL 1570 || tmp->type == TRIGGER_PEDESTAL
1589 || tmp->type == SPECIAL_KEY 1571 || tmp->type == SPECIAL_KEY
1590 || tmp->type == TREASURE 1572 || tmp->type == TREASURE
1591 || tmp->type == BOOK 1573 || tmp->type == BOOK
1592 || tmp->type == HOLY_ALTAR 1574 || tmp->type == HOLY_ALTAR
1593 || tmp->type == CONTAINER))) 1575 || tmp->type == CONTAINER)))
1594 { 1576 {
1577 printf ("show inv %s\n", tmp->debug_desc());//D
1595 if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4) 1578 if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4)
1596 { 1579 {
1597 tmp->invisible = 0; 1580 tmp->invisible = 0;
1598 done_one = 1; 1581 done_one = 1;
1599 } 1582 }
1600 } 1583 }
1601 1584
1602 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR)) 1585 if (tmp->flag [FLAG_IS_FLOOR])
1603 floor = 1; 1586 floor = 1;
1604 1587
1605 /* All detections below this point don't descend beneath the floor, 1588 /* All detections below this point don't descend beneath the floor,
1606 * so just continue on. We could be clever and look at the type of 1589 * so just continue on. We could be clever and look at the type of
1607 * detection to completely break out if we don't care about objects beneath 1590 * detection to completely break out if we don't care about objects beneath
1616 * difficult to see what object is magical/cursed, so the 1599 * difficult to see what object is magical/cursed, so the
1617 * effect wouldn't be as apparent. 1600 * effect wouldn't be as apparent.
1618 */ 1601 */
1619 1602
1620 /* detect magic */ 1603 /* detect magic */
1621 if (QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL) && 1604 if (spell->flag [FLAG_KNOWN_MAGICAL]
1622 !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && is_magical (tmp)) 1605 && !tmp->flag [FLAG_KNOWN_MAGICAL]
1606 && !tmp->flag [FLAG_IDENTIFIED]
1607 && tmp->need_identify ()
1608 && is_magical (tmp))
1623 { 1609 {
1624 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL); 1610 tmp->set_flag (FLAG_KNOWN_MAGICAL);
1625 /* make runes more visibile */ 1611 /* make runes more visible */
1626 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC) 1612 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC)
1627 tmp->stats.Cha /= 4; 1613 tmp->stats.Cha /= 4;
1628 1614
1629 done_one = 1; 1615 done_one = 1;
1630 } 1616 }
1631 1617
1632 /* detect monster */ 1618 /* detect monster */
1633 if (QUERY_FLAG (spell, FLAG_MONSTER) && (QUERY_FLAG (tmp, FLAG_MONSTER) || tmp->type == PLAYER)) 1619 if (spell->flag [FLAG_MONSTER] && (tmp->flag [FLAG_MONSTER] || tmp->type == PLAYER))
1634 { 1620 {
1635 done_one = 2; 1621 done_one = 2;
1636 1622
1637 if (!detect) 1623 if (!detect)
1638 detect = tmp; 1624 detect = tmp;
1640 1626
1641 /* Basically, if race is set in the spell, then the creatures race must 1627 /* Basically, if race is set in the spell, then the creatures race must
1642 * match that. if the spell race is set to GOD, then the gods opposing 1628 * match that. if the spell race is set to GOD, then the gods opposing
1643 * race must match. 1629 * race must match.
1644 */ 1630 */
1645 if (spell->race && QUERY_FLAG (tmp, FLAG_MONSTER) && tmp->race && 1631 if (spell->race && tmp->flag [FLAG_MONSTER] && tmp->race &&
1646 ((spell->race == shstr_GOD && god && god->slaying.contains (tmp->race)) || 1632 ((spell->race == shstr_GOD && god && god->slaying.contains (tmp->race)) ||
1647 spell->race.contains (tmp->race))) 1633 spell->race.contains (tmp->race)))
1648 { 1634 {
1649 done_one = 2; 1635 done_one = 2;
1650 1636
1651 if (!detect) 1637 if (!detect)
1652 detect = tmp; 1638 detect = tmp;
1653 } 1639 }
1654 1640
1655 if (QUERY_FLAG (spell, FLAG_KNOWN_CURSED) && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED) && 1641 if (spell->flag [FLAG_KNOWN_CURSED]
1656 (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))) 1642 && !tmp->flag [FLAG_KNOWN_CURSED]
1643 && tmp->need_identify ()
1644 && (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]))
1657 { 1645 {
1658 SET_FLAG (tmp, FLAG_KNOWN_CURSED); 1646 tmp->set_flag (FLAG_KNOWN_CURSED);
1659 done_one = 1; 1647 done_one = 1;
1648 }
1649
1650 // Do mining detection spell:
1651 if (spell->last_sp == 1) // 1 - detect any vein
1652 {
1653 if (tmp->type == VEIN)
1654 {
1655 if (tmp->other_arch)
1656 {
1657 if (!detect)
1658 detect = tmp->other_arch;
1659 done_one = 2;
1660 }
1661 else
1662 done_one = 1;
1663 }
1660 } 1664 }
1661 } /* for stack of objects on this space */ 1665 } /* for stack of objects on this space */
1662 1666
1663 /* Code here puts an effect of the spell on the space, so you can see 1667 /* Code here puts an effect of the spell on the space, so you can see
1664 * where the magic is. 1668 * where the magic is.
1665 */ 1669 */
1666 if (done_one) 1670 if (done_one)
1667 { 1671 {
1668 object *detect_ob = arch_to_object (spell->other_arch); 1672 object *detect_ob = spell->other_arch->instance ();
1669 1673
1670 /* if this is set, we want to copy the face */ 1674 /* if this is set, we want to copy the face */
1671 if (done_one == 2 && detect) 1675 if (done_one == 2 && detect)
1672 { 1676 {
1673 detect_ob->face = detect->face; 1677 detect_ob->face = detect->face;
1674 detect_ob->animation_id = detect->animation_id; 1678 detect_ob->animation_id = detect->animation_id;
1675 detect_ob->anim_speed = detect->anim_speed; 1679 detect_ob->anim_speed = detect->anim_speed;
1676 detect_ob->last_anim = 0; 1680 detect_ob->last_anim = 0;
1677 /* by default, the detect_ob is already animated */ 1681 /* by default, the detect_ob is already animated */
1678 if (!QUERY_FLAG (detect, FLAG_ANIMATE)) 1682 if (!detect->flag [FLAG_ANIMATE])
1679 CLEAR_FLAG (detect_ob, FLAG_ANIMATE); 1683 detect_ob->clr_flag (FLAG_ANIMATE);
1680 } 1684 }
1681 1685
1682 m->insert (detect_ob, nx, ny, op); 1686 m->insert (detect_ob, nx, ny, op, INS_ON_TOP);
1683 } 1687 }
1684 } /* for processing the surrounding spaces */ 1688 } /* for processing the surrounding spaces */
1685 1689
1686 1690
1687 /* Now process objects in the players inventory if detect curse or magic */ 1691 /* Now process objects in the players inventory if detect curse or magic */
1688 if (QUERY_FLAG (spell, FLAG_KNOWN_CURSED) || QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL)) 1692 if (spell->flag [FLAG_KNOWN_CURSED] || spell->flag [FLAG_KNOWN_MAGICAL])
1689 { 1693 {
1690 done_one = 0; 1694 done_one = 0;
1691 1695
1692 for (tmp = op->inv; tmp; tmp = tmp->below) 1696 for (tmp = op->inv; tmp; tmp = tmp->below)
1693 { 1697 {
1694 if (!tmp->invisible && !QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1698 if (!tmp->invisible && !tmp->flag [FLAG_IDENTIFIED])
1695 { 1699 {
1696 if (QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL) && is_magical (tmp) && !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL)) 1700 if (spell->flag [FLAG_KNOWN_MAGICAL] && is_magical (tmp) && !tmp->flag [FLAG_KNOWN_MAGICAL])
1697 { 1701 {
1698 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL); 1702 tmp->set_flag (FLAG_KNOWN_MAGICAL);
1699 1703
1700 if (object *pl = tmp->visible_to ()) 1704 if (object *pl = tmp->visible_to ())
1701 esrv_update_item (UPD_FLAGS, pl, tmp); 1705 esrv_update_item (UPD_FLAGS, pl, tmp);
1702 } 1706 }
1703 1707
1704 if (QUERY_FLAG (spell, FLAG_KNOWN_CURSED) && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED) && 1708 if (spell->flag [FLAG_KNOWN_CURSED] && !tmp->flag [FLAG_KNOWN_CURSED] &&
1705 (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))) 1709 (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]))
1706 { 1710 {
1707 SET_FLAG (tmp, FLAG_KNOWN_CURSED); 1711 tmp->set_flag (FLAG_KNOWN_CURSED);
1708 1712
1709 if (object *pl = tmp->visible_to ()) 1713 if (object *pl = tmp->visible_to ())
1710 esrv_update_item (UPD_FLAGS, pl, tmp); 1714 esrv_update_item (UPD_FLAGS, pl, tmp);
1711 } 1715 }
1712 } /* if item is not identified */ 1716 } /* if item is not identified */
1772 mflags = get_map_flags (m, &m, x, y, &x, &y); 1776 mflags = get_map_flags (m, &m, x, y, &x, &y);
1773 1777
1774 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE) 1778 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE)
1775 { 1779 {
1776 for (plyr = GET_MAP_OB (m, x, y); plyr != NULL; plyr = plyr->above) 1780 for (plyr = GET_MAP_OB (m, x, y); plyr != NULL; plyr = plyr->above)
1777 if (plyr != op && QUERY_FLAG (plyr, FLAG_ALIVE)) 1781 if (plyr != op && plyr->flag [FLAG_ALIVE])
1778 break; 1782 break;
1779 } 1783 }
1780 1784
1781 1785
1782 /* If we did not find a player in the specified direction, transfer 1786 /* If we did not find a player in the specified direction, transfer
1783 * to anyone on top of us. This is used for the rune of transference mostly. 1787 * to anyone on top of us. This is used for the rune of transference mostly.
1784 */ 1788 */
1785 if (plyr == NULL) 1789 if (plyr == NULL)
1786 for (plyr = GET_MAP_OB (op->map, op->x, op->y); plyr != NULL; plyr = plyr->above) 1790 for (plyr = GET_MAP_OB (op->map, op->x, op->y); plyr != NULL; plyr = plyr->above)
1787 if (plyr != op && QUERY_FLAG (plyr, FLAG_ALIVE)) 1791 if (plyr != op && plyr->flag [FLAG_ALIVE])
1788 break; 1792 break;
1789 1793
1790 if (!plyr) 1794 if (!plyr)
1791 { 1795 {
1792 new_draw_info (NDI_BLACK, 0, op, "There is no one there."); 1796 op->failmsg ("There is no one there.");
1793 return 0; 1797 return 0;
1794 } 1798 }
1795 /* give sp */ 1799 /* give sp */
1796 if (spell->stats.dam > 0) 1800 if (spell->stats.dam > 0)
1797 { 1801 {
1809 if (rate > 95) 1813 if (rate > 95)
1810 rate = 95; 1814 rate = 95;
1811 1815
1812 sucked = (plyr->stats.sp * rate) / 100; 1816 sucked = (plyr->stats.sp * rate) / 100;
1813 plyr->stats.sp -= sucked; 1817 plyr->stats.sp -= sucked;
1814 if (QUERY_FLAG (op, FLAG_ALIVE)) 1818 if (op->flag [FLAG_ALIVE])
1815 { 1819 {
1816 /* Player doesn't get full credit */ 1820 /* Player doesn't get full credit */
1817 sucked = (sucked * rate) / 100; 1821 sucked = (sucked * rate) / 100;
1818 op->stats.sp += sucked; 1822 op->stats.sp += sucked;
1819 if (sucked > 0) 1823 if (sucked > 0)
1870 * monsters either. 1874 * monsters either.
1871 */ 1875 */
1872 1876
1873 if (head->attacktype & AT_MAGIC 1877 if (head->attacktype & AT_MAGIC
1874 && !(head->attacktype & AT_COUNTERSPELL) 1878 && !(head->attacktype & AT_COUNTERSPELL)
1875 && !QUERY_FLAG (head, FLAG_MONSTER) 1879 && !head->flag [FLAG_MONSTER]
1876 && (op->level > head->level)) 1880 && (op->level > head->level))
1877 head->destroy (); 1881 head->destroy ();
1878 else 1882 else
1879 switch (head->type) 1883 switch (head->type)
1880 { 1884 {
1881 case SPELL_EFFECT: 1885 case SPELL_EFFECT:
1882 // XXX: Don't affect floor spelleffects. See also XXX comment 1886 // XXX: Don't affect floor spelleffects. See also XXX comment
1883 // about sanctuary in spell_util.C 1887 // about sanctuary in spell_util.C
1884 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR)) 1888 if (tmp->flag [FLAG_IS_FLOOR])
1885 continue; 1889 continue;
1886 1890
1887 if (op->level > head->level) 1891 if (op->level > head->level)
1888 head->destroy (); 1892 head->destroy ();
1889 1893
1912 1916
1913 object *tmp, *god = find_god (determine_god (op)); 1917 object *tmp, *god = find_god (determine_god (op));
1914 1918
1915 if (!god) 1919 if (!god)
1916 { 1920 {
1917 new_draw_info (NDI_UNIQUE, 0, op, "You can't consecrate anything if you don't worship a god!"); 1921 op->failmsg ("You can't consecrate anything if you don't worship a god!");
1918 return 0; 1922 return 0;
1919 } 1923 }
1920 1924
1921 for (tmp = op->below; tmp; tmp = tmp->below) 1925 for (tmp = op->below; tmp; tmp = tmp->below)
1922 { 1926 {
1923 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR)) 1927 if (tmp->flag [FLAG_IS_FLOOR])
1924 break; 1928 break;
1925 if (tmp->type == HOLY_ALTAR) 1929 if (tmp->type == HOLY_ALTAR)
1926 { 1930 {
1927 1931
1928 if (tmp->level > casting_level (caster, spell)) 1932 if (tmp->level > casting_level (caster, spell))
1929 { 1933 {
1930 new_draw_info_format (NDI_UNIQUE, 0, op, "You are not powerful enough to reconsecrate the %s", &tmp->name); 1934 op->failmsgf ("You are not powerful enough to reconsecrate the %s", &tmp->name);
1931 return 0; 1935 return 0;
1932 } 1936 }
1933 else 1937 else
1934 { 1938 {
1935 /* If we got here, we are consecrating an altar */ 1939 /* If we got here, we are consecrating an altar */
1944 new_draw_info_format (NDI_UNIQUE, 0, op, "You consecrated the altar to %s!", &god->name); 1948 new_draw_info_format (NDI_UNIQUE, 0, op, "You consecrated the altar to %s!", &god->name);
1945 return 1; 1949 return 1;
1946 } 1950 }
1947 } 1951 }
1948 } 1952 }
1949 new_draw_info (NDI_UNIQUE, 0, op, "You are not standing over an altar!"); 1953
1954 op->failmsg ("You are not standing over an altar!");
1950 return 0; 1955 return 0;
1951} 1956}
1952 1957
1953/* animate_weapon - 1958/* animate_weapon -
1954 * Generalization of staff_to_snake. Makes a golem out of the caster's weapon. 1959 * Generalization of staff_to_snake. Makes a golem out of the caster's weapon.
1961 * player checks. MSW 2003-01-06 1966 * player checks. MSW 2003-01-06
1962 */ 1967 */
1963int 1968int
1964animate_weapon (object *op, object *caster, object *spell, int dir) 1969animate_weapon (object *op, object *caster, object *spell, int dir)
1965{ 1970{
1966 object *weapon, *tmp;
1967 char buf[MAX_BUF]; 1971 char buf[MAX_BUF];
1968 int a, i; 1972 int a, i;
1969 sint16 x, y; 1973 sint16 x, y;
1970 maptile *m; 1974 maptile *m;
1971 1975
1996 2000
1997 /* if there's no place to put the golem, abort */ 2001 /* if there's no place to put the golem, abort */
1998 if (dir < 0 || (get_map_flags (m, &m, x, y, &x, &y) & P_OUT_OF_MAP) 2002 if (dir < 0 || (get_map_flags (m, &m, x, y, &x, &y) & P_OUT_OF_MAP)
1999 || ((spell->other_arch->move_type & GET_MAP_MOVE_BLOCK (m, x, y)) == spell->other_arch->move_type)) 2003 || ((spell->other_arch->move_type & GET_MAP_MOVE_BLOCK (m, x, y)) == spell->other_arch->move_type))
2000 { 2004 {
2001 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); 2005 op->failmsg ("There is something in the way.");
2002 return 0; 2006 return 0;
2003 } 2007 }
2004 2008
2005 /* Use the weapon marked by the player. */ 2009 /* Use the weapon marked by the player. */
2006 weapon = find_marked_object (op); 2010 object *weapon = op->mark ();
2007 2011
2008 if (!weapon) 2012 if (!weapon)
2009 { 2013 {
2010 new_draw_info (NDI_BLACK, 0, op, "You must mark a weapon to use with this spell!"); 2014 op->failmsg ("You must mark a weapon to use with this spell!");
2011 return 0; 2015 return 0;
2012 } 2016 }
2013 2017
2014 if (spell->race && weapon->arch->archname != spell->race) 2018 if (spell->race && weapon->arch->archname != spell->race)
2015 { 2019 {
2016 new_draw_info (NDI_UNIQUE, 0, op, "The spell fails to transform your weapon."); 2020 op->failmsg ("The spell fails to transform your weapon.");
2017 return 0; 2021 return 0;
2018 } 2022 }
2019 2023
2020 if (weapon->type != WEAPON) 2024 if (weapon->type != WEAPON)
2021 { 2025 {
2022 new_draw_info (NDI_UNIQUE, 0, op, "You need to wield a weapon to animate it."); 2026 op->failmsg ("You need to wield a weapon to animate it.");
2023 return 0; 2027 return 0;
2024 } 2028 }
2025 2029
2026 if (QUERY_FLAG (weapon, FLAG_APPLIED)) 2030 if (weapon->flag [FLAG_APPLIED])
2027 { 2031 {
2028 new_draw_info_format (NDI_BLACK, 0, op, "You need to unequip %s before using it in this spell", query_name (weapon)); 2032 op->failmsgf ("You need to unequip %s before using it in this spell", query_name (weapon));
2029 return 0; 2033 return 0;
2030 } 2034 }
2031 2035
2032 weapon = weapon->split (); 2036 weapon = weapon->split ();
2033 2037
2034 /* create the golem object */ 2038 /* create the golem object */
2035 tmp = arch_to_object (spell->other_arch); 2039 object *tmp = spell->other_arch->instance ();
2036 2040
2037 /* if animated by a player, give the player control of the golem */ 2041 /* if animated by a player, give the player control of the golem */
2038 CLEAR_FLAG (tmp, FLAG_MONSTER); 2042 tmp->clr_flag (FLAG_MONSTER);
2039 tmp->stats.exp = 0; 2043 tmp->stats.exp = 0;
2040 add_friendly_object (tmp); 2044 add_friendly_object (tmp);
2041 tmp->type = GOLEM; 2045 tmp->type = GOLEM;
2042 tmp->set_owner (op); 2046 tmp->set_owner (op);
2043 op->contr->golem = tmp; 2047 op->contr->golem = tmp;
2045 2049
2046 /* Give the weapon to the golem now. A bit of a hack to check the 2050 /* Give the weapon to the golem now. A bit of a hack to check the
2047 * removed flag - it should only be set if weapon->split was 2051 * removed flag - it should only be set if weapon->split was
2048 * used above. 2052 * used above.
2049 */ 2053 */
2050 if (!QUERY_FLAG (weapon, FLAG_REMOVED)) 2054 if (!weapon->flag [FLAG_REMOVED])
2051 weapon->remove (); 2055 weapon->remove ();
2052 2056
2053 tmp->insert (weapon); 2057 tmp->insert (weapon);
2054 2058
2055 /* To do everything necessary to let a golem use the weapon is a pain, 2059 /* To do everything necessary to let a golem use the weapon is a pain,
2056 * so instead, just set it as equipped (otherwise, we need to update 2060 * so instead, just set it as equipped (otherwise, we need to update
2057 * body_info, skills, etc) 2061 * body_info, skills, etc)
2058 */ 2062 */
2059 SET_FLAG (tmp, FLAG_USE_WEAPON); 2063 tmp->set_flag (FLAG_USE_WEAPON);
2060 SET_FLAG (weapon, FLAG_APPLIED); 2064 weapon->set_flag (FLAG_APPLIED);
2061 tmp->update_stats (); 2065 tmp->update_stats ();
2062 2066
2063 /* There used to be 'odd' code that basically seemed to take the absolute 2067 /* There used to be 'odd' code that basically seemed to take the absolute
2064 * value of the weapon->magic an use that. IMO, that doesn't make sense - 2068 * value of the weapon->magic an use that. IMO, that doesn't make sense -
2065 * if you're using a crappy weapon, it shouldn't be as good. 2069 * if you're using a crappy weapon, it shouldn't be as good.
2106 /* Improve weapon's armour value according to best save vs. physical of its material */ 2110 /* Improve weapon's armour value according to best save vs. physical of its material */
2107 2111
2108 if (a > 14) 2112 if (a > 14)
2109 a = 14; 2113 a = 14;
2110 2114
2111 tmp->resist[ATNR_PHYSICAL] = 100 - (int) ((100.0 - (float) tmp->resist[ATNR_PHYSICAL]) / (30.0 - 2.0 * a)); 2115 tmp->resist[ATNR_PHYSICAL] = 100 - (int) ((100.f - (float) tmp->resist[ATNR_PHYSICAL]) / (30.f - 2.f * a));
2112 2116
2113 /* Determine golem's speed */ 2117 /* Determine golem's speed */
2114 tmp->set_speed (min (3.33, 0.4 + 0.1 * SP_level_range_adjust (caster, spell))); 2118 tmp->set_speed (min (3.33f, 0.4f + 0.1f * SP_level_range_adjust (caster, spell)));
2115 2119
2116 if (!spell->race) 2120 if (!spell->race)
2117 { 2121 {
2118 sprintf (buf, "animated %s", &weapon->name); 2122 sprintf (buf, "animated %s", &weapon->name);
2119 tmp->name = buf; 2123 tmp->name = buf;
2152 success = op->map->change_map_light (spell->stats.dam); 2156 success = op->map->change_map_light (spell->stats.dam);
2153 2157
2154 if (!success) 2158 if (!success)
2155 { 2159 {
2156 if (spell->stats.dam < 0) 2160 if (spell->stats.dam < 0)
2157 new_draw_info (NDI_UNIQUE, 0, op, "It can be no brighter here."); 2161 op->failmsg ("It can be no brighter here.");
2158 else 2162 else
2159 new_draw_info (NDI_UNIQUE, 0, op, "It can be no darker here."); 2163 op->failmsg ("It can be no darker here.");
2160 } 2164 }
2161 2165
2162 return success; 2166 return success;
2163} 2167}
2164 2168
2174 2178
2175 new_aura = present_arch_in_ob (spell->other_arch, op); 2179 new_aura = present_arch_in_ob (spell->other_arch, op);
2176 if (new_aura) 2180 if (new_aura)
2177 refresh = 1; 2181 refresh = 1;
2178 else 2182 else
2179 new_aura = arch_to_object (spell->other_arch); 2183 new_aura = spell->other_arch->instance ();
2180 2184
2181 new_aura->duration = spell->duration + 10 * SP_level_duration_adjust (caster, spell); 2185 new_aura->duration = spell->duration + 10 * SP_level_duration_adjust (caster, spell);
2182 2186
2183 new_aura->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); 2187 new_aura->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
2184 2188
2249 if (pos.normalise () && !(OB_TYPE_MOVE_BLOCK (env, pos->move_block))) 2253 if (pos.normalise () && !(OB_TYPE_MOVE_BLOCK (env, pos->move_block)))
2250 { 2254 {
2251 hit_map (aura, i, aura->attacktype, 0); 2255 hit_map (aura, i, aura->attacktype, 0);
2252 2256
2253 if (aura->other_arch) 2257 if (aura->other_arch)
2254 pos.insert (arch_to_object (aura->other_arch), aura); 2258 pos.insert (aura->other_arch->instance (), aura);
2255 } 2259 }
2256 } 2260 }
2257 2261
2258 /* put the aura back in the player's inventory */ 2262 /* put the aura back in the player's inventory */
2259 env->insert (aura); 2263 env->insert (aura);
2269 for (object *tmp = op->ms ().bot; tmp; tmp = tmp->above) 2273 for (object *tmp = op->ms ().bot; tmp; tmp = tmp->above)
2270 { 2274 {
2271 int atk_lev, def_lev; 2275 int atk_lev, def_lev;
2272 object *victim = tmp->head_ (); 2276 object *victim = tmp->head_ ();
2273 2277
2274 if (!QUERY_FLAG (victim, FLAG_MONSTER)) 2278 if (!victim->flag [FLAG_MONSTER])
2275 continue; 2279 continue;
2276 2280
2277 if (QUERY_FLAG (victim, FLAG_UNAGGRESSIVE)) 2281 if (victim->flag [FLAG_UNAGGRESSIVE])
2278 continue; 2282 continue;
2279 2283
2280 if (victim->stats.exp == 0) 2284 if (victim->stats.exp == 0)
2281 continue; 2285 continue;
2282 2286
2298 victim->stats.sp = 0; 2302 victim->stats.sp = 0;
2299 victim->stats.grace = 0; 2303 victim->stats.grace = 0;
2300 victim->stats.Pow = 0; 2304 victim->stats.Pow = 0;
2301#endif 2305#endif
2302 victim->attack_movement = RANDO2; 2306 victim->attack_movement = RANDO2;
2303 SET_FLAG (victim, FLAG_UNAGGRESSIVE); 2307 victim->set_flag (FLAG_UNAGGRESSIVE);
2304 SET_FLAG (victim, FLAG_RUN_AWAY); 2308 victim->set_flag (FLAG_RUN_AWAY);
2305 SET_FLAG (victim, FLAG_RANDOM_MOVE); 2309 victim->set_flag (FLAG_RANDOM_MOVE);
2306 CLEAR_FLAG (victim, FLAG_MONSTER); 2310 victim->clr_flag (FLAG_MONSTER);
2307 2311
2308 if (victim->name) 2312 if (victim->name)
2309 new_draw_info_format (NDI_UNIQUE, 0, op->owner, "%s no longer feels like fighting.", &victim->name); 2313 new_draw_info_format (NDI_UNIQUE, 0, op->owner, "%s no longer feels like fighting.", &victim->name);
2310 } 2314 }
2311 } 2315 }
2317int 2321int
2318write_mark (object *op, object *spell, const char *msg) 2322write_mark (object *op, object *spell, const char *msg)
2319{ 2323{
2320 if (!msg || msg[0] == 0) 2324 if (!msg || msg[0] == 0)
2321 { 2325 {
2322 new_draw_info (NDI_UNIQUE, 0, op, "Write what?"); 2326 op->failmsg ("Write what?");
2323 return 0; 2327 return 0;
2324 } 2328 }
2325 2329
2326 if (!msg_is_safe (msg)) 2330 if (!msg_is_safe (msg))
2327 { 2331 {
2328 new_draw_info (NDI_UNIQUE, 0, op, "Trying to cheat are we?"); 2332 op->failmsg ("Trying to cheat are we? H<@-signs are not allowed in marking runes.>");
2329 LOG (llevInfo, "write_mark: player %s tried to write bogus rune %s\n", &op->name, msg); 2333 LOG (llevInfo, "write_mark: player %s tried to write bogus rune %s\n", &op->name, msg);
2330 return 0; 2334 return 0;
2331 } 2335 }
2332 2336
2333 if (!spell->other_arch) 2337 if (!spell->other_arch)
2334 return 0; 2338 return 0;
2335 2339
2336 object *tmp = arch_to_object (spell->other_arch); 2340 object *tmp = spell->other_arch->instance ();
2337 2341
2338 tmp->race = op->name; /*Save the owner of the rune */ 2342 tmp->race = op->name; /*Save the owner of the rune */
2339 tmp->msg = msg; 2343 tmp->msg = msg;
2340 2344
2341 tmp->insert_at (op, op, INS_BELOW_ORIGINATOR); 2345 tmp->insert_at (op, op, INS_BELOW_ORIGINATOR);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines