1 | /* |
1 | /* |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 | * |
3 | * |
4 | * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
4 | * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team |
5 | * Copyright (©) 2002 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 1992,2007 Frank Tore Johansen |
6 | * Copyright (©) 1992 Frank Tore Johansen |
7 | * |
7 | * |
8 | * Deliantra is free software: you can redistribute it and/or modify it under |
8 | * Deliantra is free software: you can redistribute it and/or modify it under |
9 | * the terms of the Affero GNU General Public License as published by the |
9 | * the terms of the Affero GNU General Public License as published by the |
10 | * Free Software Foundation, either version 3 of the License, or (at your |
10 | * Free Software Foundation, either version 3 of the License, or (at your |
11 | * option) any later version. |
11 | * option) any later version. |
… | |
… | |
262 | new_draw_info (NDI_UNIQUE, 0, op, "You don't have enough experience to create any food."); |
262 | new_draw_info (NDI_UNIQUE, 0, op, "You don't have enough experience to create any food."); |
263 | return 0; |
263 | return 0; |
264 | } |
264 | } |
265 | |
265 | |
266 | food_value /= at->stats.food; |
266 | food_value /= at->stats.food; |
267 | new_op = arch_to_object (at); |
267 | new_op = at->instance (); |
268 | new_op->nrof = food_value; |
268 | new_op->nrof = food_value; |
269 | |
269 | |
270 | new_op->value = 0; |
270 | new_op->value = 0; |
271 | if (new_op->nrof < 1) |
271 | if (new_op->nrof < 1) |
272 | new_op->nrof = 1; |
272 | new_op->nrof = 1; |
… | |
… | |
594 | for (int i = 0; i < NUM_STATS; i++) |
594 | for (int i = 0; i < NUM_STATS; i++) |
595 | if (tmp->stats.stat (i) < 0) |
595 | if (tmp->stats.stat (i) < 0) |
596 | buf.printf (" - Your %s is depleted by %d.\n", statname[i], -tmp->stats.stat (i)); |
596 | buf.printf (" - Your %s is depleted by %d.\n", statname[i], -tmp->stats.stat (i)); |
597 | } |
597 | } |
598 | |
598 | |
599 | if (is_dragon_pl (op)) |
599 | if (op->is_dragon ()) |
600 | /* now grab the 'dragon_ability'-force from the player's inventory */ |
600 | /* now grab the 'dragon_ability'-force from the player's inventory */ |
601 | for (tmp = op->inv; tmp; tmp = tmp->below) |
601 | for (tmp = op->inv; tmp; tmp = tmp->below) |
602 | { |
602 | { |
603 | if (tmp->type == FORCE && tmp->arch->archname == shstr_dragon_ability_force) |
603 | if (tmp->type == FORCE && tmp->arch->archname == shstr_dragon_ability_force) |
604 | { |
604 | { |
… | |
… | |
650 | new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way."); |
650 | new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way."); |
651 | return 0; |
651 | return 0; |
652 | } |
652 | } |
653 | |
653 | |
654 | if (spell_ob->other_arch) |
654 | if (spell_ob->other_arch) |
655 | tmp = arch_to_object (spell_ob->other_arch); |
655 | tmp = spell_ob->other_arch->instance (); |
656 | else if (spell_ob->race) |
656 | else if (spell_ob->race) |
657 | { |
657 | { |
658 | char buf1[MAX_BUF]; |
658 | char buf1[MAX_BUF]; |
659 | |
659 | |
660 | sprintf (buf1, spell_ob->race, dir); |
660 | sprintf (buf1, spell_ob->race, dir); |
… | |
… | |
664 | LOG (llevError, "summon_wall: Unable to find archetype %s\n", buf1); |
664 | LOG (llevError, "summon_wall: Unable to find archetype %s\n", buf1); |
665 | new_draw_info (NDI_UNIQUE, 0, op, "This spell is broken."); |
665 | new_draw_info (NDI_UNIQUE, 0, op, "This spell is broken."); |
666 | return 0; |
666 | return 0; |
667 | } |
667 | } |
668 | |
668 | |
669 | tmp = arch_to_object (at); |
669 | tmp = at->instance (); |
670 | } |
670 | } |
671 | else |
671 | else |
672 | { |
672 | { |
673 | LOG (llevError, "magic_wall: spell %s lacks other_arch\n", &spell_ob->name); |
673 | LOG (llevError, "magic_wall: spell %s lacks other_arch\n", &spell_ob->name); |
674 | return 0; |
674 | return 0; |
… | |
… | |
718 | return 0; |
718 | return 0; |
719 | } |
719 | } |
720 | |
720 | |
721 | /* If this is a spellcasting wall, need to insert the spell object */ |
721 | /* If this is a spellcasting wall, need to insert the spell object */ |
722 | if (tmp->other_arch && tmp->other_arch->type == SPELL) |
722 | if (tmp->other_arch && tmp->other_arch->type == SPELL) |
723 | insert_ob_in_ob (arch_to_object (tmp->other_arch), tmp); |
723 | insert_ob_in_ob (tmp->other_arch->instance (), tmp); |
724 | |
724 | |
725 | /* This code causes the wall to extend some distance in |
725 | /* This code causes the wall to extend some distance in |
726 | * each direction, or until an obstruction is encountered. |
726 | * each direction, or until an obstruction is encountered. |
727 | * posblocked and negblocked help determine how far the |
727 | * posblocked and negblocked help determine how far the |
728 | * created wall can extend, it won't go extend through |
728 | * created wall can extend, it won't go extend through |
… | |
… | |
748 | object *tmp2 = tmp->clone (); |
748 | object *tmp2 = tmp->clone (); |
749 | m->insert (tmp2, x, y, op); |
749 | m->insert (tmp2, x, y, op); |
750 | |
750 | |
751 | /* If this is a spellcasting wall, need to insert the spell object */ |
751 | /* If this is a spellcasting wall, need to insert the spell object */ |
752 | if (tmp2->other_arch && tmp2->other_arch->type == SPELL) |
752 | if (tmp2->other_arch && tmp2->other_arch->type == SPELL) |
753 | tmp2->insert (arch_to_object (tmp2->other_arch)); |
753 | tmp2->insert (tmp2->other_arch->instance ()); |
754 | |
754 | |
755 | } |
755 | } |
756 | else |
756 | else |
757 | posblocked = 1; |
757 | posblocked = 1; |
758 | |
758 | |
… | |
… | |
765 | { |
765 | { |
766 | object *tmp2 = tmp->clone (); |
766 | object *tmp2 = tmp->clone (); |
767 | m->insert (tmp2, x, y, op); |
767 | m->insert (tmp2, x, y, op); |
768 | |
768 | |
769 | if (tmp2->other_arch && tmp2->other_arch->type == SPELL) |
769 | if (tmp2->other_arch && tmp2->other_arch->type == SPELL) |
770 | tmp2->insert (arch_to_object (tmp2->other_arch)); |
770 | tmp2->insert (tmp2->other_arch->instance ()); |
771 | } |
771 | } |
772 | else |
772 | else |
773 | negblocked = 1; |
773 | negblocked = 1; |
774 | } |
774 | } |
775 | |
775 | |
… | |
… | |
1399 | for (int i = 0; i < sizeof (nugget) / sizeof (nugget [0]); ++i) |
1399 | for (int i = 0; i < sizeof (nugget) / sizeof (nugget [0]); ++i) |
1400 | if (int nrof = value / nugget [i]->value) |
1400 | if (int nrof = value / nugget [i]->value) |
1401 | { |
1401 | { |
1402 | value -= nrof * nugget[i]->value; |
1402 | value -= nrof * nugget[i]->value; |
1403 | |
1403 | |
1404 | object *tmp = arch_to_object (nugget[i]); |
1404 | object *tmp = nugget[i]->instance (); |
1405 | tmp->nrof = nrof; |
1405 | tmp->nrof = nrof; |
1406 | tmp->flag [FLAG_IDENTIFIED] = true; |
1406 | tmp->flag [FLAG_IDENTIFIED] = true; |
1407 | op->map->insert (tmp, x, y, op, 0); |
1407 | op->map->insert (tmp, x, y, op, 0); |
1408 | } |
1408 | } |
1409 | |
1409 | |
… | |
… | |
1545 | range = spell->range + SP_level_range_adjust (caster, spell); |
1545 | range = spell->range + SP_level_range_adjust (caster, spell); |
1546 | |
1546 | |
1547 | if (!skill) |
1547 | if (!skill) |
1548 | skill = caster; |
1548 | skill = caster; |
1549 | |
1549 | |
|
|
1550 | dynbuf buf; |
1550 | unordered_mapwalk (op, -range, -range, range, range) |
1551 | unordered_mapwalk (buf, op, -range, -range, range, range) |
1551 | { |
1552 | { |
1552 | /* For most of the detections, we only detect objects above the |
1553 | /* For most of the detections, we only detect objects above the |
1553 | * floor. But this is not true for show invisible. |
1554 | * floor. But this is not true for show invisible. |
1554 | * Basically, we just go and find the top object and work |
1555 | * Basically, we just go and find the top object and work |
1555 | * down - that is easier than working up. |
1556 | * down - that is easier than working up. |
… | |
… | |
1663 | /* Code here puts an effect of the spell on the space, so you can see |
1664 | /* Code here puts an effect of the spell on the space, so you can see |
1664 | * where the magic is. |
1665 | * where the magic is. |
1665 | */ |
1666 | */ |
1666 | if (done_one) |
1667 | if (done_one) |
1667 | { |
1668 | { |
1668 | object *detect_ob = arch_to_object (spell->other_arch); |
1669 | object *detect_ob = spell->other_arch->instance (); |
1669 | |
1670 | |
1670 | /* if this is set, we want to copy the face */ |
1671 | /* if this is set, we want to copy the face */ |
1671 | if (done_one == 2 && detect) |
1672 | if (done_one == 2 && detect) |
1672 | { |
1673 | { |
1673 | detect_ob->face = detect->face; |
1674 | detect_ob->face = detect->face; |
… | |
… | |
2030 | } |
2031 | } |
2031 | |
2032 | |
2032 | weapon = weapon->split (); |
2033 | weapon = weapon->split (); |
2033 | |
2034 | |
2034 | /* create the golem object */ |
2035 | /* create the golem object */ |
2035 | tmp = arch_to_object (spell->other_arch); |
2036 | tmp = spell->other_arch->instance (); |
2036 | |
2037 | |
2037 | /* if animated by a player, give the player control of the golem */ |
2038 | /* if animated by a player, give the player control of the golem */ |
2038 | CLEAR_FLAG (tmp, FLAG_MONSTER); |
2039 | CLEAR_FLAG (tmp, FLAG_MONSTER); |
2039 | tmp->stats.exp = 0; |
2040 | tmp->stats.exp = 0; |
2040 | add_friendly_object (tmp); |
2041 | add_friendly_object (tmp); |
… | |
… | |
2174 | |
2175 | |
2175 | new_aura = present_arch_in_ob (spell->other_arch, op); |
2176 | new_aura = present_arch_in_ob (spell->other_arch, op); |
2176 | if (new_aura) |
2177 | if (new_aura) |
2177 | refresh = 1; |
2178 | refresh = 1; |
2178 | else |
2179 | else |
2179 | new_aura = arch_to_object (spell->other_arch); |
2180 | new_aura = spell->other_arch->instance (); |
2180 | |
2181 | |
2181 | new_aura->duration = spell->duration + 10 * SP_level_duration_adjust (caster, spell); |
2182 | new_aura->duration = spell->duration + 10 * SP_level_duration_adjust (caster, spell); |
2182 | |
2183 | |
2183 | new_aura->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); |
2184 | new_aura->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); |
2184 | |
2185 | |
… | |
… | |
2249 | if (pos.normalise () && !(OB_TYPE_MOVE_BLOCK (env, pos->move_block))) |
2250 | if (pos.normalise () && !(OB_TYPE_MOVE_BLOCK (env, pos->move_block))) |
2250 | { |
2251 | { |
2251 | hit_map (aura, i, aura->attacktype, 0); |
2252 | hit_map (aura, i, aura->attacktype, 0); |
2252 | |
2253 | |
2253 | if (aura->other_arch) |
2254 | if (aura->other_arch) |
2254 | pos.insert (arch_to_object (aura->other_arch), aura); |
2255 | pos.insert (aura->other_arch->instance (), aura); |
2255 | } |
2256 | } |
2256 | } |
2257 | } |
2257 | |
2258 | |
2258 | /* put the aura back in the player's inventory */ |
2259 | /* put the aura back in the player's inventory */ |
2259 | env->insert (aura); |
2260 | env->insert (aura); |
… | |
… | |
2331 | } |
2332 | } |
2332 | |
2333 | |
2333 | if (!spell->other_arch) |
2334 | if (!spell->other_arch) |
2334 | return 0; |
2335 | return 0; |
2335 | |
2336 | |
2336 | object *tmp = arch_to_object (spell->other_arch); |
2337 | object *tmp = spell->other_arch->instance (); |
2337 | |
2338 | |
2338 | tmp->race = op->name; /*Save the owner of the rune */ |
2339 | tmp->race = op->name; /*Save the owner of the rune */ |
2339 | tmp->msg = msg; |
2340 | tmp->msg = msg; |
2340 | |
2341 | |
2341 | tmp->insert_at (op, op, INS_BELOW_ORIGINATOR); |
2342 | tmp->insert_at (op, op, INS_BELOW_ORIGINATOR); |