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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines