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.54 by root, Mon May 28 21:28:36 2007 UTC vs.
Revision 1.69 by root, Thu Aug 23 17:17:41 2007 UTC

3 * 3 *
4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team 4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 7 *
8 * Crossfire TRT is free software; you can redistribute it and/or modify it 8 * Crossfire TRT is free software: you can redistribute it and/or modify
9 * under the terms of the GNU General Public License as published by the Free 9 * it under the terms of the GNU General Public License as published by
10 * Software Foundation; either version 2 of the License, or (at your option) 10 * the Free Software Foundation, either version 3 of the License, or
11 * any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, but 13 * This program is distributed in the hope that it will be useful,
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License along 18 * You should have received a copy of the GNU General Public License
19 * with Crossfire TRT; if not, write to the Free Software Foundation, Inc. 51 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * 20 *
22 * The authors can be reached via e-mail to <crossfire@schmorp.de> 21 * The authors can be reached via e-mail to <crossfire@schmorp.de>
23 */ 22 */
24 23
25#include <global.h> 24#include <global.h>
70 return 0; 69 return 0;
71 } 70 }
72 if (!(random_roll (0, 3, op, PREFER_HIGH))) 71 if (!(random_roll (0, 3, op, PREFER_HIGH)))
73 { 72 {
74 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s vibrates violently, then explodes!", query_name (wand)); 73 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s vibrates violently, then explodes!", query_name (wand));
75 play_sound_map (op->map, op->x, op->y, SOUND_OB_EXPLODE); 74 op->play_sound (sound_find ("ob_explode"));
76 esrv_del_item (op->contr, wand->count); 75 esrv_del_item (op->contr, wand->count);
77 wand->destroy (); 76 wand->destroy ();
78 tmp = get_archetype ("fireball"); 77 tmp = get_archetype ("fireball");
79 tmp->stats.dam = (spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob)) / 10; 78 tmp->stats.dam = (spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob)) / 10;
80 79
104 ncharges = 1; 103 ncharges = 1;
105 104
106 wand->stats.food += ncharges; 105 wand->stats.food += ncharges;
107 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s glows with power.", query_name (wand)); 106 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s glows with power.", query_name (wand));
108 107
109 if (wand->arch && QUERY_FLAG (&wand->arch->clone, FLAG_ANIMATE)) 108 if (wand->arch && QUERY_FLAG (wand->arch, FLAG_ANIMATE))
110 { 109 {
111 SET_FLAG (wand, FLAG_ANIMATE); 110 SET_FLAG (wand, FLAG_ANIMATE);
112 wand->set_speed (wand->arch->clone.speed); 111 wand->set_speed (wand->arch->speed);
113 } 112 }
114 113
115 return 1; 114 return 1;
116} 115}
117 116
123 * great a plus, the default is used. 122 * great a plus, the default is used.
124 * The # of arrows created also goes up with level, so if a 30th level mage 123 * The # of arrows created also goes up with level, so if a 30th level mage
125 * wants LOTS of arrows, and doesn't care what the plus is he could 124 * wants LOTS of arrows, and doesn't care what the plus is he could
126 * create nonnmagic arrows, or even -1, etc... 125 * create nonnmagic arrows, or even -1, etc...
127 */ 126 */
128
129int 127int
130cast_create_missile (object *op, object *caster, object *spell, int dir, const char *stringarg) 128cast_create_missile (object *op, object *caster, object *spell, int dir, const char *stringarg)
131{ 129{
132 int missile_plus = 0, bonus_plus = 0; 130 int missile_plus = 0, bonus_plus = 0;
133 const char *missile_name; 131 const char *missile_name;
224 if (stringarg) 222 if (stringarg)
225 { 223 {
226 at = find_archetype_by_object_type_name (FOOD, stringarg); 224 at = find_archetype_by_object_type_name (FOOD, stringarg);
227 if (at == NULL) 225 if (at == NULL)
228 at = find_archetype_by_object_type_name (DRINK, stringarg); 226 at = find_archetype_by_object_type_name (DRINK, stringarg);
229 if (at == NULL || at->clone.stats.food > food_value) 227 if (at == NULL || at->stats.food > food_value)
230 stringarg = NULL; 228 stringarg = NULL;
231 } 229 }
232 230
233 if (!stringarg) 231 if (!stringarg)
234 { 232 {
240 * We don't use flesh types because the weight values of those need 238 * We don't use flesh types because the weight values of those need
241 * to be altered from the donor. 239 * to be altered from the donor.
242 */ 240 */
243 241
244 /* We assume the food items don't have multiple parts */ 242 /* We assume the food items don't have multiple parts */
245 for (at_tmp = first_archetype; at_tmp != NULL; at_tmp = at_tmp->next) 243 for_all_archetypes (at_tmp)
246 { 244 {
247 if (at_tmp->clone.type == FOOD || at_tmp->clone.type == DRINK) 245 if (at_tmp->type == FOOD || at_tmp->type == DRINK)
248 { 246 {
249 /* Basically, if the food value is something that is creatable 247 /* Basically, if the food value is something that is creatable
250 * under the limits of the spell and it is higher than 248 * under the limits of the spell and it is higher than
251 * the item we have now, take it instead. 249 * the item we have now, take it instead.
252 */ 250 */
253 if (at_tmp->clone.stats.food <= food_value && (!at || at_tmp->clone.stats.food > at->clone.stats.food)) 251 if (at_tmp->stats.food <= food_value
252 && (!at
253 || at_tmp->stats.food > at->stats.food
254 || (at_tmp->stats.food == at->stats.food
255 && at_tmp->weight < at->weight)))
254 at = at_tmp; 256 at = at_tmp;
255 } 257 }
256 } 258 }
257 } 259 }
260
258 /* 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
259 * know 262 * know
260 */ 263 */
261 if (!at) 264 if (!at)
262 { 265 {
263 new_draw_info (NDI_UNIQUE, 0, op, "You don't have enough experience to create any food."); 266 new_draw_info (NDI_UNIQUE, 0, op, "You don't have enough experience to create any food.");
264 return 0; 267 return 0;
265 } 268 }
266 269
267 food_value /= at->clone.stats.food; 270 food_value /= at->stats.food;
268 new_op = arch_to_object (at); 271 new_op = arch_to_object (at);
269 new_op->nrof = food_value; 272 new_op->nrof = food_value;
270 273
271 new_op->value = 0; 274 new_op->value = 0;
272 if (new_op->nrof < 1) 275 if (new_op->nrof < 1)
287 if (!dir) 290 if (!dir)
288 { 291 {
289 examine_monster (op, op); 292 examine_monster (op, op);
290 return 1; 293 return 1;
291 } 294 }
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 * freearr_x[dir], y = op->y + r * freearr_y[dir];
296 300
316 examine_monster (op, tmp); 320 examine_monster (op, tmp);
317 return 1; 321 return 1;
318 } 322 }
319 } 323 }
320 } 324 }
325
321 new_draw_info (NDI_UNIQUE, 0, op, "You detect nothing."); 326 new_draw_info (NDI_UNIQUE, 0, op, "You detect nothing.");
322 return 1; 327 return 1;
323} 328}
324
325 329
326/* This checks to see if 'pl' is invisible to 'mon'. 330/* This checks to see if 'pl' is invisible to 'mon'.
327 * does race check, undead check, etc 331 * does race check, undead check, etc
328 * Returns TRUE if mon can't see pl, false 332 * Returns TRUE if mon can't see pl, false
329 * otherwise. This doesn't check range, walls, etc. It 333 * otherwise. This doesn't check range, walls, etc. It
331 * pl is invisible. 335 * pl is invisible.
332 */ 336 */
333int 337int
334makes_invisible_to (object *pl, object *mon) 338makes_invisible_to (object *pl, object *mon)
335{ 339{
336
337 if (!pl->invisible) 340 if (!pl->invisible)
338 return 0; 341 return 0;
342
339 if (pl->type == PLAYER) 343 if (pl->type == PLAYER)
340 { 344 {
341 /* If race isn't set, then invisible unless it is undead */ 345 /* If race isn't set, then invisible unless it is undead */
342 if (!pl->contr->invis_race) 346 if (!pl->contr->invis_race)
343 { 347 {
344 if (QUERY_FLAG (mon, FLAG_UNDEAD)) 348 if (QUERY_FLAG (mon, FLAG_UNDEAD))
345 return 0; 349 return 0;
350
346 return 1; 351 return 1;
347 } 352 }
353
348 /* invis_race is set if we get here */ 354 /* invis_race is set if we get here */
349 if (!strcmp (pl->contr->invis_race, "undead") && is_true_undead (mon)) 355 if (!strcmp (pl->contr->invis_race, "undead") && is_true_undead (mon))
350 return 1; 356 return 1;
357
351 /* No race, can't be invisible to it */ 358 /* No race, can't be invisible to it */
352 if (!mon->race) 359 if (!mon->race)
353 return 0; 360 return 0;
361
354 if (strstr (mon->race, pl->contr->invis_race)) 362 if (strstr (mon->race, pl->contr->invis_race))
355 return 1; 363 return 1;
364
356 /* Nothing matched above, return 0 */ 365 /* Nothing matched above, return 0 */
357 return 0; 366 return 0;
358 } 367 }
359 else 368 else
360 { 369 {
565} 574}
566 575
567int 576int
568perceive_self (object *op) 577perceive_self (object *op)
569{ 578{
570 char buf[MAX_BUF];
571 const char *cp = describe_item (op, op); 579 const char *cp = describe_item (op, op);
572 archetype *at = archetype::find (ARCH_DEPLETION); 580 archetype *at = archetype::find (ARCH_DEPLETION);
573 object *tmp;
574 int i;
575 581
582 dynbuf_text buf;
583
584 if (player *pl = op->contr)
585 if (object *race = archetype::find (op->race))
586 buf << "You are a " << (pl->gender ? "female" : "male") << " " << &race->name << ".\n";
587
576 tmp = find_god (determine_god (op)); 588 if (object *god = find_god (determine_god (op)))
577 if (tmp) 589 buf << "You worship " << &god->name << ".\n";
578 new_draw_info_format (NDI_UNIQUE, 0, op, "You worship %s", &tmp->name);
579 else 590 else
580 new_draw_info (NDI_UNIQUE, 0, op, "You worship no god"); 591 buf << "You worship no god.\n";
581 592
582 tmp = present_arch_in_ob (at, op); 593 object *tmp = present_arch_in_ob (at, op);
583 594
584 if (*cp == '\0' && tmp == NULL) 595 if (*cp == '\0' && tmp == NULL)
585 new_draw_info (NDI_UNIQUE, 0, op, "You feel very mundane"); 596 buf << "You feel very mundane. ";
586 else 597 else
587 { 598 {
588 new_draw_info (NDI_UNIQUE, 0, op, "You have:"); 599 buf << "You have: " << cp << ".\n";
589 new_draw_info (NDI_UNIQUE, 0, op, cp);
590 600
591 if (tmp) 601 if (tmp)
592 for (i = 0; i < NUM_STATS; i++) 602 for (int i = 0; i < NUM_STATS; i++)
593 if (tmp->stats.stat (i) < 0) 603 if (tmp->stats.stat (i) < 0)
594 new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s is depleted by %d", statname[i], -tmp->stats.stat (i)); 604 buf.printf ("Your %s is depleted by %d.\n", statname[i], -tmp->stats.stat (i));
595 } 605 }
596 606
597 if (is_dragon_pl (op)) 607 if (is_dragon_pl (op))
598 {
599 /* now grab the 'dragon_ability'-force from the player's inventory */ 608 /* now grab the 'dragon_ability'-force from the player's inventory */
600 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 609 for (tmp = op->inv; tmp; tmp = tmp->below)
601 { 610 {
602 if (tmp->type == FORCE && !strcmp (tmp->arch->name, "dragon_ability_force")) 611 if (tmp->type == FORCE && tmp->arch->archname == shstr_dragon_ability_force)
603 { 612 {
604 if (tmp->stats.exp == 0) 613 if (tmp->stats.exp == 0)
605 sprintf (buf, "Your metabolism isn't focused on anything."); 614 buf << "Your metabolism isn't focused on anything.\n";
606 else 615 else
607 sprintf (buf, "Your metabolism is focused on %s.", change_resist_msg[tmp->stats.exp]); 616 buf << "Your metabolism is focused on " << change_resist_msg[tmp->stats.exp] << ".\n";
608 617
609 new_draw_info (NDI_UNIQUE, 0, op, buf);
610 break; 618 break;
611 } 619 }
612 } 620 }
613 } 621
622 buf << '\0'; // zero-terminate
623
624 new_draw_info (NDI_UNIQUE, 0, op, buf.linearise ());
614 625
615 return 1; 626 return 1;
616} 627}
617 628
618/* This creates magic walls. Really, it can create most any object, 629/* This creates magic walls. Really, it can create most any object,
716 new_draw_info_format (NDI_UNIQUE, 0, op, "Something destroys your %s", name); 727 new_draw_info_format (NDI_UNIQUE, 0, op, "Something destroys your %s", name);
717 return 0; 728 return 0;
718 } 729 }
719 730
720 /* If this is a spellcasting wall, need to insert the spell object */ 731 /* If this is a spellcasting wall, need to insert the spell object */
721 if (tmp->other_arch && tmp->other_arch->clone.type == SPELL) 732 if (tmp->other_arch && tmp->other_arch->type == SPELL)
722 insert_ob_in_ob (arch_to_object (tmp->other_arch), tmp); 733 insert_ob_in_ob (arch_to_object (tmp->other_arch), tmp);
723 734
724 /* This code causes the wall to extend some distance in 735 /* This code causes the wall to extend some distance in
725 * each direction, or until an obstruction is encountered. 736 * each direction, or until an obstruction is encountered.
726 * posblocked and negblocked help determine how far the 737 * posblocked and negblocked help determine how far the
746 { 757 {
747 object *tmp2 = tmp->clone (); 758 object *tmp2 = tmp->clone ();
748 m->insert (tmp2, x, y, op); 759 m->insert (tmp2, x, y, op);
749 760
750 /* If this is a spellcasting wall, need to insert the spell object */ 761 /* If this is a spellcasting wall, need to insert the spell object */
751 if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL) 762 if (tmp2->other_arch && tmp2->other_arch->type == SPELL)
752 tmp2->insert (arch_to_object (tmp2->other_arch)); 763 tmp2->insert (arch_to_object (tmp2->other_arch));
753 764
754 } 765 }
755 else 766 else
756 posblocked = 1; 767 posblocked = 1;
763 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK (m, x, y)) != spell_ob->move_block) && !negblocked) 774 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK (m, x, y)) != spell_ob->move_block) && !negblocked)
764 { 775 {
765 object *tmp2 = tmp->clone (); 776 object *tmp2 = tmp->clone ();
766 m->insert (tmp2, x, y, op); 777 m->insert (tmp2, x, y, op);
767 778
768 if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL) 779 if (tmp2->other_arch && tmp2->other_arch->type == SPELL)
769 tmp2->insert (arch_to_object (tmp2->other_arch)); 780 tmp2->insert (arch_to_object (tmp2->other_arch));
770 } 781 }
771 else 782 else
772 negblocked = 1; 783 negblocked = 1;
773 } 784 }
1014 } 1025 }
1015 1026
1016 return success; 1027 return success;
1017} 1028}
1018 1029
1019
1020/* This is used for the spells that gain stats. There are no spells 1030/* This is used for the spells that gain stats. There are no spells
1021 * right now that icnrease wis/int/pow on a temp basis, so no 1031 * right now that icnrease wis/int/pow on a temp basis, so no
1022 * good comments for those. 1032 * good comments for those.
1023 */ 1033 */
1024static const char *const no_gain_msgs[NUM_STATS] = { 1034static const char *const no_gain_msgs[NUM_STATS] = {
1025 "You grow no stronger.", 1035 "You grow no stronger.",
1026 "You grow no more agile.", 1036 "You grow no more agile.",
1027 "You don't feel any healthier.", 1037 "You don't feel any healthier.",
1028 "no wis", 1038 "You didn't grow any more intelligent.",
1039 "You do not feel any wiser.",
1040 "You don't feel any more powerful."
1029 "You are no easier to look at.", 1041 "You are no easier to look at.",
1030 "no int",
1031 "no pow"
1032}; 1042};
1033 1043
1034int 1044int
1035cast_change_ability (object *op, object *caster, object *spell_ob, int dir, int silent) 1045cast_change_ability (object *op, object *caster, object *spell_ob, int dir, int silent)
1036{ 1046{
1087 } 1097 }
1088 else 1098 else
1089 { 1099 {
1090 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect."); 1100 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect.");
1091 } 1101 }
1102
1092 return 1; 1103 return 1;
1093 } 1104 }
1105
1094 force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50; 1106 force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50;
1095 force->speed = 1.0; 1107 force->speed = 1.0;
1096 force->speed_left = -1.0; 1108 force->speed_left = -1.0;
1097 SET_FLAG (force, FLAG_APPLIED); 1109 SET_FLAG (force, FLAG_APPLIED);
1098 1110
1104 force->resist[i] = spell_ob->resist[i] + SP_level_dam_adjust (caster, spell_ob); 1116 force->resist[i] = spell_ob->resist[i] + SP_level_dam_adjust (caster, spell_ob);
1105 if (force->resist[i] > 100) 1117 if (force->resist[i] > 100)
1106 force->resist[i] = 100; 1118 force->resist[i] = 100;
1107 } 1119 }
1108 } 1120 }
1121
1109 if (spell_ob->stats.hp) 1122 if (spell_ob->stats.hp)
1110 force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust (caster, spell_ob); 1123 force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust (caster, spell_ob);
1111 1124
1112 if (tmp->type == PLAYER) 1125 if (tmp->type == PLAYER)
1113 { 1126 {
1153 force->attacktype = spell_ob->attacktype; 1166 force->attacktype = spell_ob->attacktype;
1154 1167
1155 insert_ob_in_ob (force, tmp); 1168 insert_ob_in_ob (force, tmp);
1156 change_abil (tmp, force); /* Mostly to display any messages */ 1169 change_abil (tmp, force); /* Mostly to display any messages */
1157 tmp->update_stats (); 1170 tmp->update_stats ();
1171
1158 return 1; 1172 return 1;
1159} 1173}
1160 1174
1161/* This used to be part of cast_change_ability, but it really didn't make 1175/* This used to be part of cast_change_ability, but it really didn't make
1162 * a lot of sense, since most of the values it derives are from the god 1176 * a lot of sense, since most of the values it derives are from the god
1163 * of the caster. 1177 * of the caster.
1164 */ 1178 */
1165
1166int 1179int
1167cast_bless (object *op, object *caster, object *spell_ob, int dir) 1180cast_bless (object *op, object *caster, object *spell_ob, int dir)
1168{ 1181{
1169 int i; 1182 int i;
1170 object *god = find_god (determine_god (op)), *tmp2, *force = NULL, *tmp; 1183 object *god = find_god (determine_god (op)), *tmp2, *force = NULL, *tmp;
1268} 1281}
1269 1282
1270/* Alchemy code by Mark Wedel 1283/* Alchemy code by Mark Wedel
1271 * 1284 *
1272 * This code adds a new spell, called alchemy. Alchemy will turn 1285 * This code adds a new spell, called alchemy. Alchemy will turn
1273 * objects to gold nuggets, the value of the gold nuggets being 1286 * objects to pyrite ("false gold"), henceforth called gold nuggets.
1274 * about 90% of that of the item itself. It uses the value of the
1275 * object before charisma adjustments, because the nuggets themselves
1276 * will be will be adjusted by charisma when sold.
1277 * 1287 *
1278 * Large nuggets are worth 25 gp each (base). You will always get 1288 * The value of the gold nuggets being about 90% of that of the item
1279 * the maximum number of large nuggets you could get. 1289 * itself. It uses the value of the object before charisma adjustments,
1280 * Small nuggets are worth 1 gp each (base). You will get from 0 1290 * because the nuggets themselves will be will be adjusted by charisma
1281 * to the max amount of small nuggets as you could get. 1291 * when sold.
1282 *
1283 * For example, if an item is worth 110 gold, you will get
1284 * 4 large nuggets, and from 0-10 small nuggets.
1285 * 1292 *
1286 * There is also a chance (1:30) that you will get nothing at all 1293 * There is also a chance (1:30) that you will get nothing at all
1287 * for the object. There is also a maximum weight that will be 1294 * for the object. There is also a maximum weight that will be
1288 * alchemised. 1295 * alchemised.
1289 */ 1296 */
1312 total_weight += obj->total_weight (); 1319 total_weight += obj->total_weight ();
1313 1320
1314 obj->destroy (); 1321 obj->destroy ();
1315} 1322}
1316 1323
1317static void
1318update_map (object *op, maptile *m, int small_nuggets, object *small, int large_nuggets, object *large, int x, int y)
1319{
1320 int flag = 0;
1321
1322 /* Put any nuggets below the player, but we can only pass this
1323 * flag if we are on the same space as the player
1324 */
1325 if (x == op->x && y == op->y && op->map == m)
1326 flag = INS_BELOW_ORIGINATOR;
1327
1328 if (small_nuggets)
1329 {
1330 object *tmp = small->clone ();
1331 tmp->nrof = small_nuggets;
1332 m->insert (tmp, x, y, op, flag);
1333 }
1334
1335 if (large_nuggets)
1336 {
1337 object *tmp = large->clone ();
1338 tmp->nrof = large_nuggets;
1339 m->insert (tmp, x, y, op, flag);
1340 }
1341
1342 if (object *pl = m->at (x, y).player ())
1343 if (pl->contr->ns)
1344 pl->contr->ns->look_position = 0;
1345}
1346
1347int 1324int
1348alchemy (object *op, object *caster, object *spell_ob) 1325alchemy (object *op, object *caster, object *spell_ob)
1349{ 1326{
1350 if (op->type != PLAYER) 1327 if (op->type != PLAYER)
1351 return 0; 1328 return 0;
1352 1329
1353 object *large = get_archetype ("largenugget"); 1330 archetype *nugget[3];
1354 object *small = get_archetype ("smallnugget"); 1331
1332 nugget[0] = archetype::find ("pyrite3");
1333 nugget[1] = archetype::find ("pyrite2");
1334 nugget[2] = archetype::find ("pyrite");
1355 1335
1356 /* Put a maximum weight of items that can be alchemised. Limits the power 1336 /* Put a maximum weight of items that can be alchemised. Limits the power
1357 * some, and also prevents people from alchemising every table/chair/clock 1337 * some, and also prevents people from alchemising every table/chair/clock
1358 * in sight 1338 * in sight
1359 */ 1339 */
1411 if (weight > weight_max) 1391 if (weight > weight_max)
1412 break; 1392 break;
1413 } 1393 }
1414 } 1394 }
1415 1395
1396 value -= rndm (value >> 4);
1416 value = min (value, value_max); 1397 value = min (value, value_max);
1417 1398
1418 uint64 count = value / large->value; 1399 for (int i = 0; i < sizeof (nugget) / sizeof (nugget [0]); ++i)
1419 int large_nuggets = count; 1400 if (int nrof = value / nugget [i]->value)
1420 value -= count * large->value;
1421
1422 count = value / small->value;
1423 int small_nuggets = count;
1424
1425 /* Insert all the nuggets at one time. This probably saves time, but
1426 * it also prevents us from alcheming nuggets that were just created
1427 * with this spell.
1428 */ 1401 {
1429 update_map (op, mp, small_nuggets, small, large_nuggets, large, nx, ny); 1402 value -= nrof * nugget[i]->value;
1403
1404 object *tmp = arch_to_object (nugget[i]);
1405 tmp->nrof = nrof;
1406 tmp->flag [FLAG_IDENTIFIED] = true;
1407 op->map->insert (tmp, x, y, op, 0);
1408 }
1430 1409
1431 if (weight > weight_max) 1410 if (weight > weight_max)
1432 goto bailout; 1411 goto bailout;
1433 } 1412 }
1434 } 1413 }
1435 1414
1436bailout: 1415bailout:
1437 large->destroy ();
1438 small->destroy ();
1439 return 1; 1416 return 1;
1440} 1417}
1441 1418
1442 1419
1443/* This function removes the cursed/damned status on equipped 1420/* This function removes the cursed/damned status on equipped
1991 object *weapon, *tmp; 1968 object *weapon, *tmp;
1992 char buf[MAX_BUF]; 1969 char buf[MAX_BUF];
1993 int a, i; 1970 int a, i;
1994 sint16 x, y; 1971 sint16 x, y;
1995 maptile *m; 1972 maptile *m;
1996 materialtype_t *mt;
1997 1973
1998 if (!spell->other_arch) 1974 if (!spell->other_arch)
1999 { 1975 {
2000 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!"); 1976 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
2001 LOG (llevError, "animate_weapon failed: spell %s missing other_arch!\n", &spell->name); 1977 LOG (llevError, "animate_weapon failed: spell %s missing other_arch!\n", &spell->name);
2020 x = op->x + freearr_x[dir]; 1996 x = op->x + freearr_x[dir];
2021 y = op->y + freearr_y[dir]; 1997 y = op->y + freearr_y[dir];
2022 1998
2023 /* if there's no place to put the golem, abort */ 1999 /* if there's no place to put the golem, abort */
2024 if ((dir == -1) || (get_map_flags (m, &m, x, y, &x, &y) & P_OUT_OF_MAP) || 2000 if ((dir == -1) || (get_map_flags (m, &m, x, y, &x, &y) & P_OUT_OF_MAP) ||
2025 ((spell->other_arch->clone.move_type & GET_MAP_MOVE_BLOCK (m, x, y)) == spell->other_arch->clone.move_type)) 2001 ((spell->other_arch->move_type & GET_MAP_MOVE_BLOCK (m, x, y)) == spell->other_arch->move_type))
2026 { 2002 {
2027 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); 2003 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way.");
2028 return 0; 2004 return 0;
2029 } 2005 }
2030 2006
2034 if (!weapon) 2010 if (!weapon)
2035 { 2011 {
2036 new_draw_info (NDI_BLACK, 0, op, "You must mark a weapon to use with this spell!"); 2012 new_draw_info (NDI_BLACK, 0, op, "You must mark a weapon to use with this spell!");
2037 return 0; 2013 return 0;
2038 } 2014 }
2039 if (spell->race && strcmp (weapon->arch->name, spell->race)) 2015 if (spell->race && strcmp (weapon->arch->archname, spell->race))
2040 { 2016 {
2041 new_draw_info (NDI_UNIQUE, 0, op, "The spell fails to transform your weapon."); 2017 new_draw_info (NDI_UNIQUE, 0, op, "The spell fails to transform your weapon.");
2042 return 0; 2018 return 0;
2043 } 2019 }
2044 if (weapon->type != WEAPON) 2020 if (weapon->type != WEAPON)
2113 2089
2114 /* attacktype */ 2090 /* attacktype */
2115 if (!tmp->attacktype) 2091 if (!tmp->attacktype)
2116 tmp->attacktype = AT_PHYSICAL; 2092 tmp->attacktype = AT_PHYSICAL;
2117 2093
2118 mt = NULL;
2119 if (op->materialname != NULL)
2120 mt = name_to_material (op->materialname); 2094 if (materialtype_t *mt = name_to_material (op->materialname))
2121 if (mt != NULL)
2122 { 2095 {
2123 for (i = 0; i < NROFATTACKS; i++) 2096 for (i = 0; i < NROFATTACKS; i++)
2124 tmp->resist[i] = 50 - (mt->save[i] * 5); 2097 tmp->resist[i] = 50 - (mt->save[i] * 5);
2125 a = mt->save[0]; 2098 a = mt->save[0];
2126 } 2099 }
2128 { 2101 {
2129 for (i = 0; i < NROFATTACKS; i++) 2102 for (i = 0; i < NROFATTACKS; i++)
2130 tmp->resist[i] = 5; 2103 tmp->resist[i] = 5;
2131 a = 10; 2104 a = 10;
2132 } 2105 }
2106
2133 /* Set weapon's immunity */ 2107 /* Set weapon's immunity */
2134 tmp->resist[ATNR_CONFUSION] = 100; 2108 tmp->resist[ATNR_CONFUSION] = 100;
2135 tmp->resist[ATNR_POISON] = 100; 2109 tmp->resist[ATNR_POISON] = 100;
2136 tmp->resist[ATNR_SLOW] = 100; 2110 tmp->resist[ATNR_SLOW] = 100;
2137 tmp->resist[ATNR_PARALYZE] = 100; 2111 tmp->resist[ATNR_PARALYZE] = 100;
2143 2117
2144 /* Improve weapon's armour value according to best save vs. physical of its material */ 2118 /* Improve weapon's armour value according to best save vs. physical of its material */
2145 2119
2146 if (a > 14) 2120 if (a > 14)
2147 a = 14; 2121 a = 14;
2122
2148 tmp->resist[ATNR_PHYSICAL] = 100 - (int) ((100.0 - (float) tmp->resist[ATNR_PHYSICAL]) / (30.0 - 2.0 * a)); 2123 tmp->resist[ATNR_PHYSICAL] = 100 - (int) ((100.0 - (float) tmp->resist[ATNR_PHYSICAL]) / (30.0 - 2.0 * a));
2149 2124
2150 /* Determine golem's speed */ 2125 /* Determine golem's speed */
2151 tmp->set_speed (min (3.33, 0.4 + 0.1 * SP_level_range_adjust (caster, spell))); 2126 tmp->set_speed (min (3.33, 0.4 + 0.1 * SP_level_range_adjust (caster, spell)));
2152 2127

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines