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.125 by root, Sun Apr 11 04:41:44 2010 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,2009,2010 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 Mark Wedel & Crossfire Development Team 6 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992 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 op->failmsg ("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 if (!(random_roll (0, 3, op, PREFER_HIGH))) 74 if (!(random_roll (0, 3, op, PREFER_HIGH)))
74 { 75 {
75 op->failmsgf ("The %s vibrates violently, then explodes!", query_name (wand)); 76 op->failmsgf ("The %s vibrates violently, then explodes!", query_name (wand));
76 op->play_sound (sound_find ("ob_explode")); 77 op->play_sound (sound_find ("ob_explode"));
77 wand->destroy (); 78 wand->destroy ();
78 tmp = get_archetype (shstr_fireball); 79 object *tmp = archetype::get (shstr_fireball);
79 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;
80 81
81 if (!tmp->stats.dam) 82 if (!tmp->stats.dam)
82 tmp->stats.dam = 1; 83 tmp->stats.dam = 1;
83 84
196 /* Can't get any money for these objects */ 197 /* Can't get any money for these objects */
197 missile->value = 0; 198 missile->value = 0;
198 199
199 missile->set_flag (FLAG_IDENTIFIED); 200 missile->set_flag (FLAG_IDENTIFIED);
200 201
201 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 ())
202 pick_up (op, missile); 207 pick_up (op, missile);
203 208
204 return 1; 209 return 1;
205} 210}
206
207 211
208/* allows the choice of what sort of food object to make. 212/* allows the choice of what sort of food object to make.
209 * 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*/
210int 214int
211cast_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)
290 } 294 }
291 295
292 maxrange = spell_ob->range + SP_level_range_adjust (caster, spell_ob); 296 maxrange = spell_ob->range + SP_level_range_adjust (caster, spell_ob);
293 for (r = 1; r < maxrange; r++) 297 for (r = 1; r < maxrange; r++)
294 { 298 {
295 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);
296 300
297 m = op->map; 301 m = op->map;
298 mflags = get_map_flags (m, &m, x, y, &x, &y); 302 mflags = get_map_flags (m, &m, x, y, &x, &y);
299 303
300 if (mflags & P_OUT_OF_MAP) 304 if (mflags & P_OUT_OF_MAP)
389 393
390 /* 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
391 * and if statement or two. 395 * and if statement or two.
392 */ 396 */
393 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
394 /* max duration */ 399 /* limit duration */
395 if (op->invisible > 1000) 400 min_it (op->invisible, 1000);
396 op->invisible = 1000;
397 401
398 if (op->type == PLAYER) 402 if (op->type == PLAYER)
399 { 403 {
400 op->contr->invis_race = spell_ob->race; 404 op->contr->invis_race = spell_ob->race;
401 405
402 if (spell_ob->flag [FLAG_MAKE_INVIS]) 406 if (spell_ob->flag [FLAG_MAKE_INVIS])
403 op->contr->tmp_invis = 0; 407 op->contr->tmp_invis = 0;
404 else 408 else
405 op->contr->tmp_invis = 1; 409 op->contr->tmp_invis = 1;
406
407 op->contr->hidden = 0;
408 } 410 }
409 411
410 if (makes_invisible_to (op, op)) 412 if (makes_invisible_to (op, op))
411 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!");
412 else 414 else
461 463
462void 464void
463execute_word_of_recall (object *op) 465execute_word_of_recall (object *op)
464{ 466{
465 if (object *pl = op->in_player ()) 467 if (object *pl = op->in_player ())
466 {
467 if (pl->ms ().flags () & P_NO_CLERIC && !pl->flag [FLAG_WIZCAST]) 468 if (pl->ms ().flags () & P_NO_CLERIC && !pl->flag [FLAG_WIZCAST])
468 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.");
469 else 470 else
470 pl->player_goto (op->slaying, op->stats.hp, op->stats.sp); 471 pl->player_goto (op->slaying, op->stats.hp, op->stats.sp);
471 }
472 472
473 op->destroy (); 473 op->destroy ();
474} 474}
475 475
476/* Word of recall causes the player to return 'home'. 476/* Word of recall causes the player to return 'home'.
477 * 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
478 * time delay effect. 478 * time delay effect.
479 */ 479 */
480int 480int
481cast_word_of_recall (object *op, object *caster, object *spell_ob) 481cast_word_of_recall (object *op, object *caster, object *spell_ob)
482{ 482{
483 object *dummy; 483 if (!op->is_player ())
484 int time;
485
486 if (op->type != PLAYER)
487 return 0; 484 return 0;
488 485
489 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))
490 { 487 {
491 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.");
492 return 1; 489 return 1;
493 } 490 }
494 491
495 dummy = get_archetype (FORCE_NAME); 492 object *dummy = archetype::get (FORCE_NAME);
496 493
497 if (!dummy)
498 {
499 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
500 LOG (llevError, "cast_word_of_recall: get_archetype(force) failed!\n");
501 return 0;
502 }
503
504 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));
505 if (time < 1)
506 time = 1;
507 495
508 /* 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
509 * 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
510 * do anything really odd if it say a -1000 or something. 498 * do anything really odd if it say a -1000 or something.
511 */ 499 */
512 dummy->set_speed (0.002); 500 dummy->set_speed (0.002);
513 dummy->speed_left = -dummy->speed * time; 501 dummy->speed_left = -dummy->speed * time;
514 dummy->type = SPELL_EFFECT; 502 dummy->type = SPELL_EFFECT;
515 dummy->subtype = SP_WORD_OF_RECALL; 503 dummy->subtype = SP_WORD_OF_RECALL;
516 504 dummy->slaying = op->contr->savebed_map;
517 /* If we could take advantage of enter_player_savebed() here, it would be 505 dummy->stats.hp = op->contr->bed_x;
518 * nice, but until the map load fails, we can't. 506 dummy->stats.sp = op->contr->bed_y;
519 */
520 EXIT_PATH (dummy) = op->contr->savebed_map;
521 EXIT_X (dummy) = op->contr->bed_x;
522 EXIT_Y (dummy) = op->contr->bed_y;
523 507
524 op->insert (dummy); 508 op->insert (dummy);
525 509
526 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.");
527 511
636 x = op->x; 620 x = op->x;
637 y = op->y; 621 y = op->y;
638 } 622 }
639 else 623 else
640 { 624 {
641 x = op->x + freearr_x[dir]; 625 x = op->x + DIRX (dir);
642 y = op->y + freearr_y[dir]; 626 y = op->y + DIRY (dir);
643 } 627 }
644 628
645 m = op->map; 629 m = op->map;
646 630
647 if ((spell_ob->move_block || x != op->x || y != op->y) && 631 if ((spell_ob->move_block || x != op->x || y != op->y) &&
722 /* 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 */
723 if (tmp->other_arch && tmp->other_arch->type == SPELL) 707 if (tmp->other_arch && tmp->other_arch->type == SPELL)
724 insert_ob_in_ob (tmp->other_arch->instance (), tmp); 708 insert_ob_in_ob (tmp->other_arch->instance (), tmp);
725 709
726 /* This code causes the wall to extend some distance in 710 /* This code causes the wall to extend some distance in
727 * each direction, or until an obstruction is encountered. 711 * each direction, or until an obstruction is encountered.
728 * posblocked and negblocked help determine how far the 712 * posblocked and negblocked help determine how far the
729 * created wall can extend, it won't go extend through 713 * created wall can extend, it won't go extend through
730 * blocked spaces. 714 * blocked spaces.
731 */ 715 */
732 maxrange = spell_ob->range + SP_level_range_adjust (caster, spell_ob); 716 maxrange = spell_ob->range + SP_level_range_adjust (caster, spell_ob);
737 { 721 {
738 int dir2; 722 int dir2;
739 723
740 dir2 = (dir < 4) ? (dir + 2) : dir - 2; 724 dir2 = (dir < 4) ? (dir + 2) : dir - 2;
741 725
742 x = tmp->x + i * freearr_x[dir2]; 726 x = tmp->x + i * DIRX (dir2);
743 y = tmp->y + i * freearr_y[dir2]; 727 y = tmp->y + i * DIRY (dir2);
744 m = tmp->map; 728 m = tmp->map;
745 729
746 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)) &&
747 ((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)
748 { 732 {
755 739
756 } 740 }
757 else 741 else
758 posblocked = 1; 742 posblocked = 1;
759 743
760 x = tmp->x - i * freearr_x[dir2]; 744 x = tmp->x - i * DIRX (dir2);
761 y = tmp->y - i * freearr_y[dir2]; 745 y = tmp->y - i * DIRY (dir2);
762 m = tmp->map; 746 m = tmp->map;
763 747
764 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)) &&
765 ((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)
766 { 750 {
812 return 0; 796 return 0;
813 } 797 }
814 798
815 for (dist = 0; dist < count; dist++) 799 for (dist = 0; dist < count; dist++)
816 { 800 {
817 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);
818 802
819 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP)) 803 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP))
820 break; 804 break;
821 805
822 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)))
835 * by such squares). Also, there are probably treasure rooms and 819 * by such squares). Also, there are probably treasure rooms and
836 * 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
837 * areas themselves don't contain no magic spaces. 821 * areas themselves don't contain no magic spaces.
838 */ 822 */
839 /* This call here is really just to normalize the coordinates */ 823 /* This call here is really just to normalize the coordinates */
840 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);
841 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)))
842 { 826 {
843 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");
844 return 1; /* Maybe the penalty should be more severe... */ 828 return 1; /* Maybe the penalty should be more severe... */
845 } 829 }
851 * spaces that blocked the players view. 835 * spaces that blocked the players view.
852 */ 836 */
853 837
854 for (dist = 0; dist < maxdist; dist++) 838 for (dist = 0; dist < maxdist; dist++)
855 { 839 {
856 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);
857 841
858 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP)) 842 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP))
859 break; 843 break;
860 844
861 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)))
866 /* If the destination is blocked, keep backing up until we 850 /* If the destination is blocked, keep backing up until we
867 * find a place for the player. 851 * find a place for the player.
868 */ 852 */
869 for (; dist > 0; dist--) 853 for (; dist > 0; dist--)
870 { 854 {
871 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,
872 &sx, &sy) & (P_OUT_OF_MAP | P_IS_ALIVE)) 856 &sx, &sy) & (P_OUT_OF_MAP | P_IS_ALIVE))
873 continue; 857 continue;
874 858
875 859
876 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)))
883 return 0; 867 return 0;
884 } 868 }
885 } 869 }
886 870
887 /* Actually move the player now */ 871 /* Actually move the player now */
888 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)))
889 return 1; 873 return 1;
890 874
891 op->speed_left = -5. * op->speed; /* Freeze them for a short while */ 875 op->speed_left = -5. * op->speed; /* Freeze them for a short while */
892 876
893 return 1; 877 return 1;
1090 1074
1091 new_draw_info_format (NDI_UNIQUE, 0, op, 1075 new_draw_info_format (NDI_UNIQUE, 0, op,
1092 "You create an aura of magical force. H<The effect will last for about %.10g seconds.>", 1076 "You create an aura of magical force. H<The effect will last for about %.10g seconds.>",
1093 TICK2TIME (duration)); 1077 TICK2TIME (duration));
1094 1078
1095 force = get_archetype (FORCE_NAME); 1079 force = archetype::get (FORCE_NAME);
1096 force->subtype = FORCE_CHANGE_ABILITY; 1080 force->subtype = FORCE_CHANGE_ABILITY;
1097 force->duration = duration; 1081 force->duration = duration;
1098 1082
1099 if (spell_ob->race) 1083 if (spell_ob->race)
1100 force->name = spell_ob->race; 1084 force->name = spell_ob->race;
1107 force->speed_left = -1.0; 1091 force->speed_left = -1.0;
1108 force->set_flag (FLAG_APPLIED); 1092 force->set_flag (FLAG_APPLIED);
1109 1093
1110 /* Now start processing the effects. First, protections */ 1094 /* Now start processing the effects. First, protections */
1111 for (i = 0; i < NROFATTACKS; i++) 1095 for (i = 0; i < NROFATTACKS; i++)
1112 {
1113 if (spell_ob->resist[i]) 1096 if (spell_ob->resist[i])
1114 {
1115 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));
1116 if (force->resist[i] > 100)
1117 force->resist[i] = 100;
1118 }
1119 }
1120 1098
1121 if (spell_ob->stats.hp) 1099 if (spell_ob->stats.hp)
1122 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);
1123 1101
1124 if (tmp->type == PLAYER) 1102 if (tmp->type == PLAYER)
1210 } 1188 }
1211 } 1189 }
1212 1190
1213 if (force == NULL) 1191 if (force == NULL)
1214 { 1192 {
1215 force = get_archetype (FORCE_NAME); 1193 force = archetype::get (FORCE_NAME);
1216 force->subtype = FORCE_CHANGE_ABILITY; 1194 force->subtype = FORCE_CHANGE_ABILITY;
1217 if (spell_ob->race) 1195 if (spell_ob->race)
1218 force->name = spell_ob->race; 1196 force->name = spell_ob->race;
1219 else 1197 else
1220 force->name = spell_ob->name; 1198 force->name = spell_ob->name;
1235 { 1213 {
1236 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.");
1237 } 1215 }
1238 return 0; 1216 return 0;
1239 } 1217 }
1218
1240 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;
1241 force->speed = 1.0; 1220 force->speed = 1.0;
1242 force->speed_left = -1.0; 1221 force->speed_left = -1.0;
1243 force->set_flag (FLAG_APPLIED); 1222 force->set_flag (FLAG_APPLIED);
1244 1223
1280 1259
1281/* Alchemy code by Mark Wedel 1260/* Alchemy code by Mark Wedel
1282 * 1261 *
1283 * This code adds a new spell, called alchemy. Alchemy will turn 1262 * This code adds a new spell, called alchemy. Alchemy will turn
1284 * objects to pyrite ("false gold"), henceforth called gold nuggets. 1263 * objects to pyrite ("false gold"), henceforth called gold nuggets.
1285 * 1264 *
1286 * 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
1287 * itself. It uses the value of the object before charisma adjustments, 1266 * itself. It uses the value of the object before charisma adjustments,
1288 * because the nuggets themselves will be will be adjusted by charisma 1267 * because the nuggets themselves will be will be adjusted by charisma
1289 * when sold. 1268 * when sold.
1290 * 1269 *
1392 } 1371 }
1393 1372
1394 value -= rndm (value >> 4); 1373 value -= rndm (value >> 4);
1395 value = min (value, value_max); 1374 value = min (value, value_max);
1396 1375
1397 for (int i = 0; i < sizeof (nugget) / sizeof (nugget [0]); ++i) 1376 for (int i = 0; i < array_length (nugget); ++i)
1398 if (int nrof = value / nugget [i]->value) 1377 if (int nrof = value / nugget [i]->value)
1399 { 1378 {
1400 value -= nrof * nugget[i]->value; 1379 value -= nrof * nugget[i]->value;
1401 1380
1402 object *tmp = nugget[i]->instance (); 1381 object *tmp = nugget[i]->instance ();
1420int 1399int
1421remove_curse (object *op, object *caster, object *spell) 1400remove_curse (object *op, object *caster, object *spell)
1422{ 1401{
1423 int success = 0, was_one = 0; 1402 int success = 0, was_one = 0;
1424 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
1425 for (object *tmp = op->inv; tmp; tmp = tmp->below) 1410 for (object *tmp = op->inv; tmp && num_uncurse; tmp = tmp->below)
1426 if (tmp->flag [FLAG_APPLIED] && 1411 if (!tmp->invisible && tmp->flag [typeflag])
1427 ((tmp->flag [FLAG_CURSED] && spell->flag [FLAG_CURSED]) ||
1428 (tmp->flag [FLAG_DAMNED] && spell->flag [FLAG_DAMNED])))
1429 { 1412 {
1430 was_one++; 1413 ++was_one;
1431 1414
1432 if (tmp->level <= casting_level (caster, spell)) 1415 if (tmp->level <= casting_level (caster, spell))
1433 { 1416 {
1434 success++; 1417 ++success;
1435 if (spell->flag [FLAG_DAMNED]) 1418 --num_uncurse;
1436 tmp->clr_flag (FLAG_DAMNED);
1437 1419
1420 tmp->clr_flag (typeflag);
1438 tmp->clr_flag (FLAG_CURSED); 1421 tmp->clr_flag (FLAG_CURSED);
1439 tmp->clr_flag (FLAG_KNOWN_CURSED); 1422 tmp->clr_flag (FLAG_KNOWN_CURSED);
1440 tmp->value = 0; /* Still can't sell it */ 1423 tmp->value = 0; /* Still can't sell it */
1441 1424
1442 if (object *pl = tmp->visible_to ()) 1425 if (object *pl = tmp->visible_to ())
1445 } 1428 }
1446 1429
1447 if (op->type == PLAYER) 1430 if (op->type == PLAYER)
1448 { 1431 {
1449 if (success) 1432 if (success)
1450 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.>");
1451 else 1434 else
1452 { 1435 {
1453 if (was_one) 1436 if (was_one)
1454 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.>");
1455 else 1438 else
1456 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.>");
1457 } 1440 }
1458 } 1441 }
1459 1442
1460 return success; 1443 return success;
1461} 1444}
1462 1445
1463/* Identifies objects in the players inventory/on the ground */ 1446/* Identifies objects in the players inventory/on the ground */
1464int 1447int
1465cast_identify (object *op, object *caster, object *spell) 1448cast_identify (object *op, object *caster, object *spell)
1466{ 1449{
1467 object *tmp;
1468 dynbuf_text &buf = msg_dynbuf; buf.clear (); 1450 dynbuf_text &buf = msg_dynbuf; buf.clear ();
1469 1451
1470 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));
1471 1453
1454 op->splay_marked ();
1455
1472 for (tmp = op->inv; tmp; tmp = tmp->below) 1456 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1473 { 1457 {
1474 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && need_identify (tmp)) 1458 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && tmp->need_identify ())
1475 { 1459 {
1476 identify (tmp); 1460 identify (tmp);
1477 1461
1478 if (op->type == PLAYER) 1462 if (op->type == PLAYER)
1479 { 1463 {
1492 * 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
1493 * was not fully used. 1477 * was not fully used.
1494 */ 1478 */
1495 if (num_ident) 1479 if (num_ident)
1496 { 1480 {
1497 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)
1498 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && need_identify (tmp)) 1482 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && tmp->need_identify ())
1499 { 1483 {
1500 identify (tmp); 1484 identify (tmp);
1501 1485
1502 if (object *pl = tmp->visible_to ()) 1486 if (object *pl = tmp->visible_to ())
1503 { 1487 {
1529 1513
1530int 1514int
1531cast_detection (object *op, object *caster, object *spell, object *skill) 1515cast_detection (object *op, object *caster, object *spell, object *skill)
1532{ 1516{
1533 object *tmp, *last, *god, *detect; 1517 object *tmp, *last, *god, *detect;
1534 int done_one, range, mflags, floor, level; 1518 int done_one, range, floor, level;
1535 sint16 x, y, nx, ny; 1519 sint16 x, y, nx, ny;
1536 maptile *m; 1520 maptile *m;
1537 1521
1538 /* 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
1539 * doing it over and over again. 1523 * doing it over and over again.
1552 * floor. But this is not true for show invisible. 1536 * floor. But this is not true for show invisible.
1553 * Basically, we just go and find the top object and work 1537 * Basically, we just go and find the top object and work
1554 * down - that is easier than working up. 1538 * down - that is easier than working up.
1555 */ 1539 */
1556 1540
1557 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)
1558 last = tmp; 1542 last = tmp;
1559 1543
1560 /* 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
1561 * would happen. 1545 * would happen.
1562 */ 1546 */
1563 if (!last) 1547 if (!last)
1564 continue; 1548 continue;
1565 1549
1566 done_one = 0; 1550 done_one = 0;
1567 floor = 0; 1551 floor = 0;
1568 detect = NULL; 1552 detect = 0;
1569 for (tmp = last; tmp; tmp = tmp->below) 1553 for (tmp = last; tmp; tmp = tmp->below)
1570 { 1554 {
1571 /* show invisible */ 1555 /* show invisible */
1572 if (spell->flag [FLAG_MAKE_INVIS] 1556 if (spell->flag [FLAG_MAKE_INVIS]
1573 /* Might there be other objects that we can make visible? */ 1557 /* Might there be other objects that we can make visible? */
1581 || tmp->type == TELEPORTER 1565 || tmp->type == TELEPORTER
1582 || tmp->type == GATE 1566 || tmp->type == GATE
1583 || tmp->type == LOCKED_DOOR 1567 || tmp->type == LOCKED_DOOR
1584 || tmp->type == WEAPON 1568 || tmp->type == WEAPON
1585 || tmp->type == ALTAR 1569 || tmp->type == ALTAR
1586 || tmp->type == SIGN 1570 || (tmp->type == SIGN && tmp->face != magicmouth_face)
1587 || tmp->type == TRIGGER_PEDESTAL 1571 || tmp->type == TRIGGER_PEDESTAL
1588 || tmp->type == SPECIAL_KEY 1572 || tmp->type == SPECIAL_KEY
1589 || tmp->type == TREASURE 1573 || tmp->type == TREASURE
1590 || tmp->type == BOOK 1574 || tmp->type == BOOK
1591 || tmp->type == HOLY_ALTAR 1575 || tmp->type == HOLY_ALTAR
1592 || tmp->type == CONTAINER))) 1576 || tmp->type == CONTAINER)))
1593 { 1577 {
1578 printf ("show inv %s\n", tmp->debug_desc());//D
1594 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)
1595 { 1580 {
1596 tmp->invisible = 0; 1581 tmp->invisible = 0;
1597 done_one = 1; 1582 done_one = 1;
1598 } 1583 }
1615 * difficult to see what object is magical/cursed, so the 1600 * difficult to see what object is magical/cursed, so the
1616 * effect wouldn't be as apparent. 1601 * effect wouldn't be as apparent.
1617 */ 1602 */
1618 1603
1619 /* detect magic */ 1604 /* detect magic */
1620 if (spell->flag [FLAG_KNOWN_MAGICAL] && 1605 if (spell->flag [FLAG_KNOWN_MAGICAL]
1621 !tmp->flag [FLAG_KNOWN_MAGICAL] && !tmp->flag [FLAG_IDENTIFIED] && is_magical (tmp)) 1606 && !tmp->flag [FLAG_KNOWN_MAGICAL]
1607 && !tmp->flag [FLAG_IDENTIFIED]
1608 && tmp->need_identify ()
1609 && is_magical (tmp))
1622 { 1610 {
1623 tmp->set_flag (FLAG_KNOWN_MAGICAL); 1611 tmp->set_flag (FLAG_KNOWN_MAGICAL);
1624 /* make runes more visible */ 1612 /* make runes more visible */
1625 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC) 1613 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC)
1626 tmp->stats.Cha /= 4; 1614 tmp->stats.Cha /= 4;
1649 1637
1650 if (!detect) 1638 if (!detect)
1651 detect = tmp; 1639 detect = tmp;
1652 } 1640 }
1653 1641
1654 if (spell->flag [FLAG_KNOWN_CURSED] && !tmp->flag [FLAG_KNOWN_CURSED] && 1642 if (spell->flag [FLAG_KNOWN_CURSED]
1643 && !tmp->flag [FLAG_KNOWN_CURSED]
1644 && tmp->need_identify ()
1655 (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED])) 1645 && (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]))
1656 { 1646 {
1657 tmp->set_flag (FLAG_KNOWN_CURSED); 1647 tmp->set_flag (FLAG_KNOWN_CURSED);
1658 done_one = 1; 1648 done_one = 1;
1659 } 1649 }
1660 1650
1779 sint16 x, y; 1769 sint16 x, y;
1780 maptile *m; 1770 maptile *m;
1781 int mflags; 1771 int mflags;
1782 1772
1783 m = op->map; 1773 m = op->map;
1784 x = op->x + freearr_x[dir]; 1774 x = op->x + DIRX (dir);
1785 y = op->y + freearr_y[dir]; 1775 y = op->y + DIRY (dir);
1786 1776
1787 mflags = get_map_flags (m, &m, x, y, &x, &y); 1777 mflags = get_map_flags (m, &m, x, y, &x, &y);
1788 1778
1789 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE) 1779 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE)
1790 { 1780 {
1854 object *tmp, *head, *next; 1844 object *tmp, *head, *next;
1855 int mflags; 1845 int mflags;
1856 maptile *m; 1846 maptile *m;
1857 sint16 sx, sy; 1847 sint16 sx, sy;
1858 1848
1859 sx = op->x + freearr_x[dir]; 1849 sx = op->x + DIRX (dir);
1860 sy = op->y + freearr_y[dir]; 1850 sy = op->y + DIRY (dir);
1861 m = op->map; 1851 m = op->map;
1862 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy); 1852 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy);
1863 if (mflags & P_OUT_OF_MAP) 1853 if (mflags & P_OUT_OF_MAP)
1864 return; 1854 return;
1865 1855
1878 1868
1879 /* don't attack our own spells */ 1869 /* don't attack our own spells */
1880 if (tmp->owner && tmp->owner == op->owner) 1870 if (tmp->owner && tmp->owner == op->owner)
1881 continue; 1871 continue;
1882 1872
1883 /* Basically, if the object is magical and not counterspell, 1873 /* Basically, if the object is magical and not counterspell,
1884 * we will more or less remove the object. Don't counterspell 1874 * we will more or less remove the object. Don't counterspell
1885 * monsters either. 1875 * monsters either.
1886 */ 1876 */
1887 1877
1888 if (head->attacktype & AT_MAGIC 1878 if (head->attacktype & AT_MAGIC
1889 && !(head->attacktype & AT_COUNTERSPELL) 1879 && !(head->attacktype & AT_COUNTERSPELL)
1890 && !head->flag [FLAG_MONSTER] 1880 && !head->flag [FLAG_MONSTER]
1964 1954
1965 op->failmsg ("You are not standing over an altar!"); 1955 op->failmsg ("You are not standing over an altar!");
1966 return 0; 1956 return 0;
1967} 1957}
1968 1958
1969/* animate_weapon - 1959/* animate_weapon -
1970 * 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.
1971 * 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
1972 * 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
1973 * 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.
1974 * 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,
1975 * 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
1976 * 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
1977 * player checks. MSW 2003-01-06 1967 * player checks. MSW 2003-01-06
1978 */ 1968 */
1979int 1969int
1980animate_weapon (object *op, object *caster, object *spell, int dir) 1970animate_weapon (object *op, object *caster, object *spell, int dir)
1981{ 1971{
1982 object *weapon, *tmp;
1983 char buf[MAX_BUF]; 1972 char buf[MAX_BUF];
1984 int a, i; 1973 int a, i;
1985 sint16 x, y; 1974 sint16 x, y;
1986 maptile *m; 1975 maptile *m;
1987 1976
2005 /* if no direction specified, pick one */ 1994 /* if no direction specified, pick one */
2006 if (!dir) 1995 if (!dir)
2007 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);
2008 1997
2009 m = op->map; 1998 m = op->map;
2010 x = op->x + freearr_x[dir]; 1999 x = op->x + DIRX (dir);
2011 y = op->y + freearr_y[dir]; 2000 y = op->y + DIRY (dir);
2012 2001
2013 /* if there's no place to put the golem, abort */ 2002 /* if there's no place to put the golem, abort */
2014 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)
2015 || ((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))
2016 { 2005 {
2017 op->failmsg ("There is something in the way."); 2006 op->failmsg ("There is something in the way.");
2018 return 0; 2007 return 0;
2019 } 2008 }
2020 2009
2021 /* Use the weapon marked by the player. */ 2010 /* Use the weapon marked by the player. */
2022 weapon = find_marked_object (op); 2011 object *weapon = op->mark ();
2023 2012
2024 if (!weapon) 2013 if (!weapon)
2025 { 2014 {
2026 op->failmsg ("You must mark a weapon to use with this spell!"); 2015 op->failmsg ("You must mark a weapon to use with this spell!");
2027 return 0; 2016 return 0;
2046 } 2035 }
2047 2036
2048 weapon = weapon->split (); 2037 weapon = weapon->split ();
2049 2038
2050 /* create the golem object */ 2039 /* create the golem object */
2051 tmp = spell->other_arch->instance (); 2040 object *tmp = spell->other_arch->instance ();
2052 2041
2053 /* 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 */
2054 tmp->clr_flag (FLAG_MONSTER); 2043 tmp->clr_flag (FLAG_MONSTER);
2055 tmp->stats.exp = 0; 2044 tmp->stats.exp = 0;
2056 add_friendly_object (tmp); 2045 add_friendly_object (tmp);
2122 /* 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 */
2123 2112
2124 if (a > 14) 2113 if (a > 14)
2125 a = 14; 2114 a = 14;
2126 2115
2127 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));
2128 2117
2129 /* Determine golem's speed */ 2118 /* Determine golem's speed */
2130 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)));
2131 2120
2132 if (!spell->race) 2121 if (!spell->race)
2133 { 2122 {
2134 sprintf (buf, "animated %s", &weapon->name); 2123 sprintf (buf, "animated %s", &weapon->name);
2135 tmp->name = buf; 2124 tmp->name = buf;
2216 2205
2217/* 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,
2218 * 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
2219 * around him. 2208 * around him.
2220 * Aura parameters: 2209 * Aura parameters:
2221 * duration: duration counter. 2210 * duration: duration counter.
2222 * attacktype: aura's attacktype 2211 * attacktype: aura's attacktype
2223 * other_arch: archetype to drop where we attack 2212 * other_arch: archetype to drop where we attack
2224 */ 2213 */
2225void 2214void
2226move_aura (object *aura) 2215move_aura (object *aura)
2227{ 2216{
2228 /* auras belong in inventories */ 2217 /* auras belong in inventories */
2229 object *env = aura->env; 2218 object *env = aura->env;
2230 object *owner = aura->owner; 2219 object *owner = aura->owner;
2231 2220
2232 /* no matter what we've gotta remove the aura... 2221 /* no matter what we've gotta remove the aura...
2233 * we'll put it back if its time isn't up. 2222 * we'll put it back if its time isn't up.
2234 */ 2223 */
2235 aura->remove (); 2224 aura->remove ();
2236 2225
2237 /* exit if we're out of gas */ 2226 /* exit if we're out of gas */
2238 if (aura->duration-- < 0) 2227 if (aura->duration-- < 0)
2247 aura->destroy (); 2236 aura->destroy ();
2248 return; 2237 return;
2249 } 2238 }
2250 2239
2251 /* we need to jump out of the inventory for a bit 2240 /* we need to jump out of the inventory for a bit
2252 * in order to hit the map conveniently. 2241 * in order to hit the map conveniently.
2253 */ 2242 */
2254 aura->insert_at (env, aura); 2243 aura->insert_at (env, aura);
2255 2244
2256 for (int i = 1; i < 9; i++) 2245 for (int i = 1; i < 9; i++)
2257 { 2246 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines