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.124 by root, Sun Apr 11 00:34:06 2010 UTC vs.
Revision 1.143 by root, Mon Nov 12 03:48:34 2012 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992 Frank Tore Johansen 6 * Copyright (©) 1992 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 8 * Deliantra is free software: you can redistribute it and/or modify it under
9 * the terms of the Affero GNU General Public License as published by the 9 * the terms of the Affero GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your 10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the Affero GNU General Public License 18 * You should have received a copy of the Affero GNU General Public License
19 * and the GNU General Public License along with this program. If not, see 19 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>. 20 * <http://www.gnu.org/licenses/>.
21 * 21 *
22 * The authors can be reached via e-mail to <support@deliantra.net> 22 * The authors can be reached via e-mail to <support@deliantra.net>
23 */ 23 */
24 24
25#include <global.h> 25#include <global.h>
26#include <object.h> 26#include <object.h>
58} 58}
59 59
60int 60int
61recharge (object *op, object *caster, object *spell_ob) 61recharge (object *op, object *caster, object *spell_ob)
62{ 62{
63 object *wand, *tmp;
64 int ncharges; 63 int ncharges;
65 64
66 wand = find_marked_object (op); 65 object *wand = op->mark ();
66
67 if (!wand || wand->type != WAND) 67 if (!wand || wand->type != WAND)
68 { 68 {
69 new_draw_info (NDI_UNIQUE, 0, op, "You need to mark the wand you want to recharge."); 69 op->failmsg ("You need to mark the wand you want to recharge.");
70 return 0; 70 return 0;
71 } 71 }
72
72 if (!(random_roll (0, 3, op, PREFER_HIGH))) 73 if (!(random_roll (0, 3, op, PREFER_HIGH)))
73 { 74 {
74 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s vibrates violently, then explodes!", query_name (wand)); 75 op->failmsgf ("The %s vibrates violently, then explodes!", query_name (wand));
75 op->play_sound (sound_find ("ob_explode")); 76 op->play_sound (sound_find ("ob_explode"));
76 wand->destroy (); 77 wand->destroy ();
77 tmp = get_archetype (shstr_fireball); 78 object *tmp = archetype::get (shstr_fireball);
78 tmp->stats.dam = (spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob)) / 10; 79 tmp->stats.dam = (spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob)) / 10;
79 80
80 if (!tmp->stats.dam) 81 if (!tmp->stats.dam)
81 tmp->stats.dam = 1; 82 tmp->stats.dam = 1;
82 83
93 94
94 if (wand->inv && wand->inv->level) 95 if (wand->inv && wand->inv->level)
95 ncharges /= wand->inv->level; 96 ncharges /= wand->inv->level;
96 else 97 else
97 { 98 {
98 new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s is broken.", query_name (wand)); 99 op->failmsgf ("Your %s is broken.", query_name (wand));
99 return 0; 100 return 0;
100 } 101 }
101 102
102 if (!ncharges) 103 if (!ncharges)
103 ncharges = 1; 104 ncharges = 1;
158 break; 159 break;
159 160
160 if (!al) 161 if (!al)
161 { 162 {
162 missile->destroy (); 163 missile->destroy ();
163 new_draw_info_format (NDI_UNIQUE, 0, op, "No such object %ss of %s", missile_name, spellparam); 164 op->failmsgf ("No such object %ss of %s", missile_name, spellparam);
164 return 0; 165 return 0;
165 } 166 }
166 167
167 if (al->item->slaying) 168 if (al->item->slaying)
168 { 169 {
169 missile->destroy (); 170 missile->destroy ();
170 new_draw_info_format (NDI_UNIQUE, 0, op, "You are not allowed to create %ss of %s", missile_name, spellparam); 171 op->failmsgf ("You are not allowed to create %ss of %s", missile_name, spellparam);
171 return 0; 172 return 0;
172 } 173 }
173 174
174 give_artifact_abilities (missile, al->item); 175 give_artifact_abilities (missile, al->item);
175 /* These special arrows cost something extra. Don't have them also be magical - 176 /* These special arrows cost something extra. Don't have them also be magical -
195 /* Can't get any money for these objects */ 196 /* Can't get any money for these objects */
196 missile->value = 0; 197 missile->value = 0;
197 198
198 missile->set_flag (FLAG_IDENTIFIED); 199 missile->set_flag (FLAG_IDENTIFIED);
199 200
200 if (!cast_create_obj (op, caster, missile, dir) && op->type == PLAYER && !missile->destroyed ()) 201 cast_create_obj (op, caster, missile, dir);
202
203 if (!dir
204 && op->type == PLAYER
205 && !missile->destroyed ())
201 pick_up (op, missile); 206 pick_up (op, missile);
202 207
203 return 1; 208 return 1;
204} 209}
205
206 210
207/* allows the choice of what sort of food object to make. 211/* allows the choice of what sort of food object to make.
208 * If spellparam is NULL, it will create food dependent on level --PeterM*/ 212 * If spellparam is NULL, it will create food dependent on level --PeterM*/
209int 213int
210cast_create_food (object *op, object *caster, object *spell_ob, int dir, const char *spellparam) 214cast_create_food (object *op, object *caster, object *spell_ob, int dir, const char *spellparam)
257 /* Pretty unlikely (there are some very low food items), but you never 261 /* Pretty unlikely (there are some very low food items), but you never
258 * know 262 * know
259 */ 263 */
260 if (!at) 264 if (!at)
261 { 265 {
262 new_draw_info (NDI_UNIQUE, 0, op, "You don't have enough experience to create any food."); 266 op->failmsgf ("You don't have enough experience to create any food.");
263 return 0; 267 return 0;
264 } 268 }
265 269
266 food_value /= at->stats.food; 270 food_value /= at->stats.food;
267 new_op = at->instance (); 271 new_op = at->instance ();
380int 384int
381cast_invisible (object *op, object *caster, object *spell_ob) 385cast_invisible (object *op, object *caster, object *spell_ob)
382{ 386{
383 if (op->invisible > 1000) 387 if (op->invisible > 1000)
384 { 388 {
385 new_draw_info (NDI_UNIQUE, 0, op, "You can not extend the duration of your invisibility any further"); 389 op->failmsg ("You can not extend the duration of your invisibility any further");
386 return 0; 390 return 0;
387 } 391 }
388 392
389 /* Remove the switch with 90% duplicate code - just handle the differences with 393 /* Remove the switch with 90% duplicate code - just handle the differences with
390 * and if statement or two. 394 * and if statement or two.
391 */ 395 */
392 op->invisible += spell_ob->duration + SP_level_duration_adjust (caster, spell_ob); 396 op->invisible += spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
397
393 /* max duration */ 398 /* limit duration */
394 if (op->invisible > 1000) 399 min_it (op->invisible, 1000);
395 op->invisible = 1000;
396 400
397 if (op->type == PLAYER) 401 if (op->type == PLAYER)
398 { 402 {
399 op->contr->invis_race = spell_ob->race; 403 op->contr->invis_race = spell_ob->race;
400 404
460 464
461void 465void
462execute_word_of_recall (object *op) 466execute_word_of_recall (object *op)
463{ 467{
464 if (object *pl = op->in_player ()) 468 if (object *pl = op->in_player ())
465 {
466 if (pl->ms ().flags () & P_NO_CLERIC && !pl->flag [FLAG_WIZCAST]) 469 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."); 470 new_draw_info (NDI_UNIQUE, 0, pl, "You feel something fizzle inside you.");
468 else 471 else
469 pl->player_goto (op->slaying, op->stats.hp, op->stats.sp); 472 pl->player_goto (op->slaying, op->stats.hp, op->stats.sp);
470 }
471 473
472 op->destroy (); 474 op->destroy ();
473} 475}
474 476
475/* Word of recall causes the player to return 'home'. 477/* Word of recall causes the player to return 'home'.
477 * time delay effect. 479 * time delay effect.
478 */ 480 */
479int 481int
480cast_word_of_recall (object *op, object *caster, object *spell_ob) 482cast_word_of_recall (object *op, object *caster, object *spell_ob)
481{ 483{
482 object *dummy; 484 if (!op->is_player ())
483 int time;
484
485 if (op->type != PLAYER)
486 return 0; 485 return 0;
487 486
488 if (find_obj_by_type_subtype (op, SPELL_EFFECT, SP_WORD_OF_RECALL)) 487 if (find_obj_by_type_subtype (op, SPELL_EFFECT, SP_WORD_OF_RECALL))
489 { 488 {
490 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you."); 489 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you.");
491 return 1; 490 return 1;
492 } 491 }
493 492
494 dummy = get_archetype (FORCE_NAME); 493 object *dummy = archetype::get (FORCE_NAME);
495 494
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); 495 int time = max (1, spell_ob->duration - SP_level_duration_adjust (caster, spell_ob));
504 if (time < 1)
505 time = 1;
506 496
507 /* value of speed really doesn't make much difference, as long as it is 497 /* value of speed really doesn't make much difference, as long as it is
508 * positive. Lower value may be useful so that the problem doesn't 498 * positive. Lower value may be useful so that the problem doesn't
509 * do anything really odd if it say a -1000 or something. 499 * do anything really odd if it say a -1000 or something.
510 */ 500 */
511 dummy->set_speed (0.002); 501 dummy->set_speed (0.002);
512 dummy->speed_left = -dummy->speed * time; 502 dummy->speed_left = -dummy->speed * time;
513 dummy->type = SPELL_EFFECT; 503 dummy->type = SPELL_EFFECT;
514 dummy->subtype = SP_WORD_OF_RECALL; 504 dummy->subtype = SP_WORD_OF_RECALL;
515 505 dummy->slaying = op->contr->savebed_map;
516 /* If we could take advantage of enter_player_savebed() here, it would be 506 dummy->stats.hp = op->contr->bed_x;
517 * nice, but until the map load fails, we can't. 507 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 508
523 op->insert (dummy); 509 op->insert (dummy);
524 510
525 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you."); 511 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you.");
526 512
645 631
646 if ((spell_ob->move_block || x != op->x || y != op->y) && 632 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) || 633 (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))) 634 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK (m, x, y)) == spell_ob->move_block)))
649 { 635 {
650 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way."); 636 op->failmsg ("Something is in the way.");
651 return 0; 637 return 0;
652 } 638 }
653 639
654 if (spell_ob->other_arch) 640 if (spell_ob->other_arch)
655 tmp = spell_ob->other_arch->instance (); 641 tmp = spell_ob->other_arch->instance ();
805 { 791 {
806 int count = atoi (spellparam); 792 int count = atoi (spellparam);
807 793
808 if (count > maxdist) 794 if (count > maxdist)
809 { 795 {
810 new_draw_info (NDI_UNIQUE, 0, op, "You can't dimension door that far!"); 796 op->failmsg ("You can't dimension door that far!");
811 return 0; 797 return 0;
812 } 798 }
813 799
814 for (dist = 0; dist < count; dist++) 800 for (dist = 0; dist < count; dist++)
815 { 801 {
876 break; 862 break;
877 863
878 } 864 }
879 if (!dist) 865 if (!dist)
880 { 866 {
881 new_draw_info (NDI_UNIQUE, 0, op, "Your spell failed!\n"); 867 op->failmsg ("Your spell failed!\n");
882 return 0; 868 return 0;
883 } 869 }
884 } 870 }
885 871
886 /* Actually move the player now */ 872 /* Actually move the player now */
1062 break; 1048 break;
1063 } 1049 }
1064 else if (spell_ob->race && spell_ob->race == tmp2->name) 1050 else if (spell_ob->race && spell_ob->race == tmp2->name)
1065 { 1051 {
1066 if (!silent) 1052 if (!silent)
1067 new_draw_info_format (NDI_UNIQUE, 0, op,
1068 "You can not cast %s while %s is in effect", 1053 op->failmsgf ("You can not cast %s while %s is in effect",
1069 &spell_ob->name, &tmp2->name_pl); 1054 &spell_ob->name, &tmp2->name_pl);
1070 1055
1071 return 0; 1056 return 0;
1072 } 1057 }
1073 } 1058 }
1074 } 1059 }
1090 1075
1091 new_draw_info_format (NDI_UNIQUE, 0, op, 1076 new_draw_info_format (NDI_UNIQUE, 0, op,
1092 "You create an aura of magical force. H<The effect will last for about %.10g seconds.>", 1077 "You create an aura of magical force. H<The effect will last for about %.10g seconds.>",
1093 TICK2TIME (duration)); 1078 TICK2TIME (duration));
1094 1079
1095 force = get_archetype (FORCE_NAME); 1080 force = archetype::get (FORCE_NAME);
1096 force->subtype = FORCE_CHANGE_ABILITY; 1081 force->subtype = FORCE_CHANGE_ABILITY;
1097 force->duration = duration; 1082 force->duration = duration;
1098 1083
1099 if (spell_ob->race) 1084 if (spell_ob->race)
1100 force->name = spell_ob->race; 1085 force->name = spell_ob->race;
1107 force->speed_left = -1.0; 1092 force->speed_left = -1.0;
1108 force->set_flag (FLAG_APPLIED); 1093 force->set_flag (FLAG_APPLIED);
1109 1094
1110 /* Now start processing the effects. First, protections */ 1095 /* Now start processing the effects. First, protections */
1111 for (i = 0; i < NROFATTACKS; i++) 1096 for (i = 0; i < NROFATTACKS; i++)
1112 {
1113 if (spell_ob->resist[i]) 1097 if (spell_ob->resist[i])
1114 {
1115 force->resist[i] = spell_ob->resist[i] + SP_level_dam_adjust (caster, spell_ob); 1098 force->resist[i] = min (100, spell_ob->resist[i] + SP_level_dam_adjust (caster, spell_ob));
1116 if (force->resist[i] > 100)
1117 force->resist[i] = 100;
1118 }
1119 }
1120 1099
1121 if (spell_ob->stats.hp) 1100 if (spell_ob->stats.hp)
1122 force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust (caster, spell_ob); 1101 force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust (caster, spell_ob);
1123 1102
1124 if (tmp->type == PLAYER) 1103 if (tmp->type == PLAYER)
1210 } 1189 }
1211 } 1190 }
1212 1191
1213 if (force == NULL) 1192 if (force == NULL)
1214 { 1193 {
1215 force = get_archetype (FORCE_NAME); 1194 force = archetype::get (FORCE_NAME);
1216 force->subtype = FORCE_CHANGE_ABILITY; 1195 force->subtype = FORCE_CHANGE_ABILITY;
1217 if (spell_ob->race) 1196 if (spell_ob->race)
1218 force->name = spell_ob->race; 1197 force->name = spell_ob->race;
1219 else 1198 else
1220 force->name = spell_ob->name; 1199 force->name = spell_ob->name;
1235 { 1214 {
1236 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect."); 1215 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect.");
1237 } 1216 }
1238 return 0; 1217 return 0;
1239 } 1218 }
1219
1240 force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50; 1220 force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50;
1241 force->speed = 1.0; 1221 force->speed = 1.0;
1242 force->speed_left = -1.0; 1222 force->speed_left = -1.0;
1243 force->set_flag (FLAG_APPLIED); 1223 force->set_flag (FLAG_APPLIED);
1244 1224
1280 1260
1281/* Alchemy code by Mark Wedel 1261/* Alchemy code by Mark Wedel
1282 * 1262 *
1283 * This code adds a new spell, called alchemy. Alchemy will turn 1263 * This code adds a new spell, called alchemy. Alchemy will turn
1284 * objects to pyrite ("false gold"), henceforth called gold nuggets. 1264 * objects to pyrite ("false gold"), henceforth called gold nuggets.
1285 * 1265 *
1286 * The value of the gold nuggets being about 90% of that of the item 1266 * The value of the gold nuggets being about 90% of that of the item
1287 * itself. It uses the value of the object before charisma adjustments, 1267 * itself. It uses the value of the object before charisma adjustments,
1288 * because the nuggets themselves will be will be adjusted by charisma 1268 * because the nuggets themselves will be will be adjusted by charisma
1289 * when sold. 1269 * when sold.
1290 * 1270 *
1392 } 1372 }
1393 1373
1394 value -= rndm (value >> 4); 1374 value -= rndm (value >> 4);
1395 value = min (value, value_max); 1375 value = min (value, value_max);
1396 1376
1397 for (int i = 0; i < sizeof (nugget) / sizeof (nugget [0]); ++i) 1377 for (int i = 0; i < array_length (nugget); ++i)
1398 if (int nrof = value / nugget [i]->value) 1378 if (int nrof = value / nugget [i]->value)
1399 { 1379 {
1400 value -= nrof * nugget[i]->value; 1380 value -= nrof * nugget[i]->value;
1401 1381
1402 object *tmp = nugget[i]->instance (); 1382 object *tmp = nugget[i]->instance ();
1420int 1400int
1421remove_curse (object *op, object *caster, object *spell) 1401remove_curse (object *op, object *caster, object *spell)
1422{ 1402{
1423 int success = 0, was_one = 0; 1403 int success = 0, was_one = 0;
1424 1404
1405 int num_uncurse = max (1, spell->stats.dam + SP_level_dam_adjust (caster, spell));
1406
1407 op->splay_marked ();
1408
1409 int typeflag = spell->last_sp ? FLAG_DAMNED : FLAG_CURSED;
1410
1425 for (object *tmp = op->inv; tmp; tmp = tmp->below) 1411 for (object *tmp = op->inv; tmp && num_uncurse; tmp = tmp->below)
1426 if (tmp->flag [FLAG_APPLIED] && 1412 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 { 1413 {
1430 was_one++; 1414 ++was_one;
1431 1415
1432 if (tmp->level <= casting_level (caster, spell)) 1416 if (tmp->level <= casting_level (caster, spell))
1433 { 1417 {
1434 success++; 1418 ++success;
1435 if (spell->flag [FLAG_DAMNED]) 1419 --num_uncurse;
1436 tmp->clr_flag (FLAG_DAMNED);
1437 1420
1421 tmp->clr_flag (typeflag);
1438 tmp->clr_flag (FLAG_CURSED); 1422 tmp->clr_flag (FLAG_CURSED);
1439 tmp->clr_flag (FLAG_KNOWN_CURSED); 1423 tmp->clr_flag (FLAG_KNOWN_CURSED);
1440 tmp->value = 0; /* Still can't sell it */ 1424 tmp->value = 0; /* Still can't sell it */
1441 1425
1442 if (object *pl = tmp->visible_to ()) 1426 if (object *pl = tmp->visible_to ())
1445 } 1429 }
1446 1430
1447 if (op->type == PLAYER) 1431 if (op->type == PLAYER)
1448 { 1432 {
1449 if (success) 1433 if (success)
1450 new_draw_info (NDI_UNIQUE, 0, op, "You feel like some of your items are looser now."); 1434 new_draw_info (NDI_UNIQUE, 0, op, "You realise that some of your items look shinier now. H<You successfully removed some curses.>");
1451 else 1435 else
1452 { 1436 {
1453 if (was_one) 1437 if (was_one)
1454 new_draw_info (NDI_UNIQUE, 0, op, "You failed to remove the curse."); 1438 new_draw_info (NDI_UNIQUE, 0, op, "You failed to remove any curse. H<The spell was not strong enough.>");
1455 else 1439 else
1456 new_draw_info (NDI_UNIQUE, 0, op, "You are not using any cursed items."); 1440 new_draw_info (NDI_UNIQUE, 0, op, "You are not having any cursed items. H<Epic fail.>");
1457 } 1441 }
1458 } 1442 }
1459 1443
1460 return success; 1444 return success;
1461} 1445}
1462 1446
1463/* Identifies objects in the players inventory/on the ground */ 1447/* Identifies objects in the players inventory/on the ground */
1464int 1448int
1465cast_identify (object *op, object *caster, object *spell) 1449cast_identify (object *op, object *caster, object *spell)
1466{ 1450{
1467 object *tmp;
1468 dynbuf_text &buf = msg_dynbuf; buf.clear (); 1451 dynbuf_text &buf = msg_dynbuf; buf.clear ();
1469 1452
1470 int num_ident = max (1, spell->stats.dam + SP_level_dam_adjust (caster, spell)); 1453 int num_ident = max (1, spell->stats.dam + SP_level_dam_adjust (caster, spell));
1471 1454
1455 op->splay_marked ();
1456
1472 for (tmp = op->inv; tmp; tmp = tmp->below) 1457 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1473 { 1458 {
1474 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && need_identify (tmp)) 1459 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && tmp->need_identify ())
1475 { 1460 {
1476 identify (tmp); 1461 identify (tmp);
1477 1462
1478 if (op->type == PLAYER) 1463 if (op->type == PLAYER)
1479 { 1464 {
1492 * stuff on the floor. Only identify stuff on the floor if the spell 1477 * stuff on the floor. Only identify stuff on the floor if the spell
1493 * was not fully used. 1478 * was not fully used.
1494 */ 1479 */
1495 if (num_ident) 1480 if (num_ident)
1496 { 1481 {
1497 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp; tmp = tmp->above) 1482 for (object *tmp = GET_MAP_OB (op->map, op->x, op->y); tmp; tmp = tmp->above)
1498 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && need_identify (tmp)) 1483 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && tmp->need_identify ())
1499 { 1484 {
1500 identify (tmp); 1485 identify (tmp);
1501 1486
1502 if (object *pl = tmp->visible_to ()) 1487 if (object *pl = tmp->visible_to ())
1503 { 1488 {
1529 1514
1530int 1515int
1531cast_detection (object *op, object *caster, object *spell, object *skill) 1516cast_detection (object *op, object *caster, object *spell, object *skill)
1532{ 1517{
1533 object *tmp, *last, *god, *detect; 1518 object *tmp, *last, *god, *detect;
1534 int done_one, range, mflags, floor, level; 1519 int done_one, range, floor, level;
1535 sint16 x, y, nx, ny; 1520 sint16 x, y, nx, ny;
1536 maptile *m; 1521 maptile *m;
1537 1522
1538 /* We precompute some values here so that we don't have to keep 1523 /* We precompute some values here so that we don't have to keep
1539 * doing it over and over again. 1524 * doing it over and over again.
1552 * floor. But this is not true for show invisible. 1537 * floor. But this is not true for show invisible.
1553 * Basically, we just go and find the top object and work 1538 * Basically, we just go and find the top object and work
1554 * down - that is easier than working up. 1539 * down - that is easier than working up.
1555 */ 1540 */
1556 1541
1557 for (last = NULL, tmp = m->at (nx, ny).bot; tmp; tmp = tmp->above) 1542 for (last = 0, tmp = m->at (nx, ny).bot; tmp; tmp = tmp->above)
1558 last = tmp; 1543 last = tmp;
1559 1544
1560 /* Shouldn't happen, but if there are no objects on a space, this 1545 /* Shouldn't happen, but if there are no objects on a space, this
1561 * would happen. 1546 * would happen.
1562 */ 1547 */
1563 if (!last) 1548 if (!last)
1564 continue; 1549 continue;
1565 1550
1566 done_one = 0; 1551 done_one = 0;
1567 floor = 0; 1552 floor = 0;
1568 detect = NULL; 1553 detect = 0;
1569 for (tmp = last; tmp; tmp = tmp->below) 1554 for (tmp = last; tmp; tmp = tmp->below)
1570 { 1555 {
1571 /* show invisible */ 1556 /* show invisible */
1572 if (spell->flag [FLAG_MAKE_INVIS] 1557 if (spell->flag [FLAG_MAKE_INVIS]
1573 /* Might there be other objects that we can make visible? */ 1558 /* Might there be other objects that we can make visible? */
1581 || tmp->type == TELEPORTER 1566 || tmp->type == TELEPORTER
1582 || tmp->type == GATE 1567 || tmp->type == GATE
1583 || tmp->type == LOCKED_DOOR 1568 || tmp->type == LOCKED_DOOR
1584 || tmp->type == WEAPON 1569 || tmp->type == WEAPON
1585 || tmp->type == ALTAR 1570 || tmp->type == ALTAR
1586 || tmp->type == SIGN 1571 || (tmp->type == SIGN && tmp->face != magicmouth_face)
1587 || tmp->type == TRIGGER_PEDESTAL 1572 || tmp->type == TRIGGER_PEDESTAL
1588 || tmp->type == SPECIAL_KEY 1573 || tmp->type == SPECIAL_KEY
1589 || tmp->type == TREASURE 1574 || tmp->type == TREASURE
1590 || tmp->type == BOOK 1575 || tmp->type == BOOK
1591 || tmp->type == HOLY_ALTAR 1576 || tmp->type == HOLY_ALTAR
1592 || tmp->type == CONTAINER))) 1577 || tmp->type == CONTAINER)))
1593 { 1578 {
1579 printf ("show inv %s\n", tmp->debug_desc());//D
1594 if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4) 1580 if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4)
1595 { 1581 {
1596 tmp->invisible = 0; 1582 tmp->invisible = 0;
1597 done_one = 1; 1583 done_one = 1;
1598 } 1584 }
1615 * difficult to see what object is magical/cursed, so the 1601 * difficult to see what object is magical/cursed, so the
1616 * effect wouldn't be as apparent. 1602 * effect wouldn't be as apparent.
1617 */ 1603 */
1618 1604
1619 /* detect magic */ 1605 /* detect magic */
1620 if (spell->flag [FLAG_KNOWN_MAGICAL] && 1606 if (spell->flag [FLAG_KNOWN_MAGICAL]
1621 !tmp->flag [FLAG_KNOWN_MAGICAL] && !tmp->flag [FLAG_IDENTIFIED] && is_magical (tmp)) 1607 && !tmp->flag [FLAG_KNOWN_MAGICAL]
1608 && !tmp->flag [FLAG_IDENTIFIED]
1609 && tmp->need_identify ()
1610 && is_magical (tmp))
1622 { 1611 {
1623 tmp->set_flag (FLAG_KNOWN_MAGICAL); 1612 tmp->set_flag (FLAG_KNOWN_MAGICAL);
1624 /* make runes more visible */ 1613 /* make runes more visible */
1625 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC) 1614 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC)
1626 tmp->stats.Cha /= 4; 1615 tmp->stats.Cha /= 4;
1649 1638
1650 if (!detect) 1639 if (!detect)
1651 detect = tmp; 1640 detect = tmp;
1652 } 1641 }
1653 1642
1654 if (spell->flag [FLAG_KNOWN_CURSED] && !tmp->flag [FLAG_KNOWN_CURSED] && 1643 if (spell->flag [FLAG_KNOWN_CURSED]
1644 && !tmp->flag [FLAG_KNOWN_CURSED]
1645 && tmp->need_identify ()
1655 (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED])) 1646 && (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]))
1656 { 1647 {
1657 tmp->set_flag (FLAG_KNOWN_CURSED); 1648 tmp->set_flag (FLAG_KNOWN_CURSED);
1658 done_one = 1; 1649 done_one = 1;
1659 } 1650 }
1660 1651
1802 if (plyr != op && plyr->flag [FLAG_ALIVE]) 1793 if (plyr != op && plyr->flag [FLAG_ALIVE])
1803 break; 1794 break;
1804 1795
1805 if (!plyr) 1796 if (!plyr)
1806 { 1797 {
1807 new_draw_info (NDI_BLACK, 0, op, "There is no one there."); 1798 op->failmsg ("There is no one there.");
1808 return 0; 1799 return 0;
1809 } 1800 }
1810 /* give sp */ 1801 /* give sp */
1811 if (spell->stats.dam > 0) 1802 if (spell->stats.dam > 0)
1812 { 1803 {
1927 1918
1928 object *tmp, *god = find_god (determine_god (op)); 1919 object *tmp, *god = find_god (determine_god (op));
1929 1920
1930 if (!god) 1921 if (!god)
1931 { 1922 {
1932 new_draw_info (NDI_UNIQUE, 0, op, "You can't consecrate anything if you don't worship a god!"); 1923 op->failmsg ("You can't consecrate anything if you don't worship a god!");
1933 return 0; 1924 return 0;
1934 } 1925 }
1935 1926
1936 for (tmp = op->below; tmp; tmp = tmp->below) 1927 for (tmp = op->below; tmp; tmp = tmp->below)
1937 { 1928 {
1940 if (tmp->type == HOLY_ALTAR) 1931 if (tmp->type == HOLY_ALTAR)
1941 { 1932 {
1942 1933
1943 if (tmp->level > casting_level (caster, spell)) 1934 if (tmp->level > casting_level (caster, spell))
1944 { 1935 {
1945 new_draw_info_format (NDI_UNIQUE, 0, op, "You are not powerful enough to reconsecrate the %s", &tmp->name); 1936 op->failmsgf ("You are not powerful enough to reconsecrate the %s", &tmp->name);
1946 return 0; 1937 return 0;
1947 } 1938 }
1948 else 1939 else
1949 { 1940 {
1950 /* If we got here, we are consecrating an altar */ 1941 /* If we got here, we are consecrating an altar */
1959 new_draw_info_format (NDI_UNIQUE, 0, op, "You consecrated the altar to %s!", &god->name); 1950 new_draw_info_format (NDI_UNIQUE, 0, op, "You consecrated the altar to %s!", &god->name);
1960 return 1; 1951 return 1;
1961 } 1952 }
1962 } 1953 }
1963 } 1954 }
1964 new_draw_info (NDI_UNIQUE, 0, op, "You are not standing over an altar!"); 1955
1956 op->failmsg ("You are not standing over an altar!");
1965 return 0; 1957 return 0;
1966} 1958}
1967 1959
1968/* animate_weapon - 1960/* animate_weapon -
1969 * Generalization of staff_to_snake. Makes a golem out of the caster's weapon. 1961 * Generalization of staff_to_snake. Makes a golem out of the caster's weapon.
1976 * player checks. MSW 2003-01-06 1968 * player checks. MSW 2003-01-06
1977 */ 1969 */
1978int 1970int
1979animate_weapon (object *op, object *caster, object *spell, int dir) 1971animate_weapon (object *op, object *caster, object *spell, int dir)
1980{ 1972{
1981 object *weapon, *tmp;
1982 char buf[MAX_BUF]; 1973 char buf[MAX_BUF];
1983 int a, i; 1974 int a, i;
1984 sint16 x, y; 1975 sint16 x, y;
1985 maptile *m; 1976 maptile *m;
1986 1977
2011 2002
2012 /* if there's no place to put the golem, abort */ 2003 /* if there's no place to put the golem, abort */
2013 if (dir < 0 || (get_map_flags (m, &m, x, y, &x, &y) & P_OUT_OF_MAP) 2004 if (dir < 0 || (get_map_flags (m, &m, x, y, &x, &y) & P_OUT_OF_MAP)
2014 || ((spell->other_arch->move_type & GET_MAP_MOVE_BLOCK (m, x, y)) == spell->other_arch->move_type)) 2005 || ((spell->other_arch->move_type & GET_MAP_MOVE_BLOCK (m, x, y)) == spell->other_arch->move_type))
2015 { 2006 {
2016 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); 2007 op->failmsg ("There is something in the way.");
2017 return 0; 2008 return 0;
2018 } 2009 }
2019 2010
2020 /* Use the weapon marked by the player. */ 2011 /* Use the weapon marked by the player. */
2021 weapon = find_marked_object (op); 2012 object *weapon = op->mark ();
2022 2013
2023 if (!weapon) 2014 if (!weapon)
2024 { 2015 {
2025 new_draw_info (NDI_BLACK, 0, op, "You must mark a weapon to use with this spell!"); 2016 op->failmsg ("You must mark a weapon to use with this spell!");
2026 return 0; 2017 return 0;
2027 } 2018 }
2028 2019
2029 if (spell->race && weapon->arch->archname != spell->race) 2020 if (spell->race && weapon->arch->archname != spell->race)
2030 { 2021 {
2031 new_draw_info (NDI_UNIQUE, 0, op, "The spell fails to transform your weapon."); 2022 op->failmsg ("The spell fails to transform your weapon.");
2032 return 0; 2023 return 0;
2033 } 2024 }
2034 2025
2035 if (weapon->type != WEAPON) 2026 if (weapon->type != WEAPON)
2036 { 2027 {
2037 new_draw_info (NDI_UNIQUE, 0, op, "You need to wield a weapon to animate it."); 2028 op->failmsg ("You need to wield a weapon to animate it.");
2038 return 0; 2029 return 0;
2039 } 2030 }
2040 2031
2041 if (weapon->flag [FLAG_APPLIED]) 2032 if (weapon->flag [FLAG_APPLIED])
2042 { 2033 {
2043 new_draw_info_format (NDI_BLACK, 0, op, "You need to unequip %s before using it in this spell", query_name (weapon)); 2034 op->failmsgf ("You need to unequip %s before using it in this spell", query_name (weapon));
2044 return 0; 2035 return 0;
2045 } 2036 }
2046 2037
2047 weapon = weapon->split (); 2038 weapon = weapon->split ();
2048 2039
2049 /* create the golem object */ 2040 /* create the golem object */
2050 tmp = spell->other_arch->instance (); 2041 object *tmp = spell->other_arch->instance ();
2051 2042
2052 /* if animated by a player, give the player control of the golem */ 2043 /* if animated by a player, give the player control of the golem */
2053 tmp->clr_flag (FLAG_MONSTER); 2044 tmp->clr_flag (FLAG_MONSTER);
2054 tmp->stats.exp = 0; 2045 tmp->stats.exp = 0;
2055 add_friendly_object (tmp); 2046 add_friendly_object (tmp);
2121 /* Improve weapon's armour value according to best save vs. physical of its material */ 2112 /* Improve weapon's armour value according to best save vs. physical of its material */
2122 2113
2123 if (a > 14) 2114 if (a > 14)
2124 a = 14; 2115 a = 14;
2125 2116
2126 tmp->resist[ATNR_PHYSICAL] = 100 - (int) ((100.0 - (float) tmp->resist[ATNR_PHYSICAL]) / (30.0 - 2.0 * a)); 2117 tmp->resist[ATNR_PHYSICAL] = 100 - (int) ((100.f - (float) tmp->resist[ATNR_PHYSICAL]) / (30.f - 2.f * a));
2127 2118
2128 /* Determine golem's speed */ 2119 /* Determine golem's speed */
2129 tmp->set_speed (min (3.33, 0.4 + 0.1 * SP_level_range_adjust (caster, spell))); 2120 tmp->set_speed (min (3.33f, 0.4f + 0.1f * SP_level_range_adjust (caster, spell)));
2130 2121
2131 if (!spell->race) 2122 if (!spell->race)
2132 { 2123 {
2133 sprintf (buf, "animated %s", &weapon->name); 2124 sprintf (buf, "animated %s", &weapon->name);
2134 tmp->name = buf; 2125 tmp->name = buf;
2167 success = op->map->change_map_light (spell->stats.dam); 2158 success = op->map->change_map_light (spell->stats.dam);
2168 2159
2169 if (!success) 2160 if (!success)
2170 { 2161 {
2171 if (spell->stats.dam < 0) 2162 if (spell->stats.dam < 0)
2172 new_draw_info (NDI_UNIQUE, 0, op, "It can be no brighter here."); 2163 op->failmsg ("It can be no brighter here.");
2173 else 2164 else
2174 new_draw_info (NDI_UNIQUE, 0, op, "It can be no darker here."); 2165 op->failmsg ("It can be no darker here.");
2175 } 2166 }
2176 2167
2177 return success; 2168 return success;
2178} 2169}
2179 2170
2332int 2323int
2333write_mark (object *op, object *spell, const char *msg) 2324write_mark (object *op, object *spell, const char *msg)
2334{ 2325{
2335 if (!msg || msg[0] == 0) 2326 if (!msg || msg[0] == 0)
2336 { 2327 {
2337 new_draw_info (NDI_UNIQUE, 0, op, "Write what?"); 2328 op->failmsg ("Write what?");
2338 return 0; 2329 return 0;
2339 } 2330 }
2340 2331
2341 if (!msg_is_safe (msg)) 2332 if (!msg_is_safe (msg))
2342 { 2333 {
2343 new_draw_info (NDI_UNIQUE, 0, op, "Trying to cheat are we?"); 2334 op->failmsg ("Trying to cheat are we? H<@-signs are not allowed in marking runes.>");
2344 LOG (llevInfo, "write_mark: player %s tried to write bogus rune %s\n", &op->name, msg); 2335 LOG (llevInfo, "write_mark: player %s tried to write bogus rune %s\n", &op->name, msg);
2345 return 0; 2336 return 0;
2346 } 2337 }
2347 2338
2348 if (!spell->other_arch) 2339 if (!spell->other_arch)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines