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.115 by root, Sun Nov 29 09:41:28 2009 UTC vs.
Revision 1.122 by root, Fri Apr 2 03:41:25 2010 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 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
1002 tmp->stats.grace = tmp->stats.maxgrace; 1002 tmp->stats.grace = tmp->stats.maxgrace;
1003 success = 1; 1003 success = 1;
1004 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!"); 1004 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!");
1005 } 1005 }
1006 1006
1007 if (spell->stats.food && tmp->stats.food < 999) 1007 if (spell->stats.food && tmp->stats.food < MAX_FOOD)
1008 { 1008 {
1009 tmp->stats.food += spell->stats.food; 1009 tmp->stats.food += spell->stats.food;
1010 1010 min_it (tmp->stats.food, MAX_FOOD);
1011 if (tmp->stats.food > 999)
1012 tmp->stats.food = 999;
1013 1011
1014 success = 1; 1012 success = 1;
1015 /* We could do something a bit better like the messages for healing above */ 1013 /* We could do something a bit better like the messages for healing above */
1016 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel your belly fill with food"); 1014 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel your belly fill with food");
1017 } 1015 }
1399 for (int i = 0; i < sizeof (nugget) / sizeof (nugget [0]); ++i) 1397 for (int i = 0; i < sizeof (nugget) / sizeof (nugget [0]); ++i)
1400 if (int nrof = value / nugget [i]->value) 1398 if (int nrof = value / nugget [i]->value)
1401 { 1399 {
1402 value -= nrof * nugget[i]->value; 1400 value -= nrof * nugget[i]->value;
1403 1401
1404 object *tmp = arch_to_object (nugget[i]); 1402 object *tmp = nugget[i]->instance ();
1405 tmp->nrof = nrof; 1403 tmp->nrof = nrof;
1406 tmp->flag [FLAG_IDENTIFIED] = true; 1404 tmp->flag [FLAG_IDENTIFIED] = true;
1407 op->map->insert (tmp, x, y, op, 0); 1405 op->map->insert (tmp, x, y, op, 0);
1408 } 1406 }
1409 1407
1545 range = spell->range + SP_level_range_adjust (caster, spell); 1543 range = spell->range + SP_level_range_adjust (caster, spell);
1546 1544
1547 if (!skill) 1545 if (!skill)
1548 skill = caster; 1546 skill = caster;
1549 1547
1548 dynbuf buf;
1550 unordered_mapwalk (op, -range, -range, range, range) 1549 unordered_mapwalk (buf, op, -range, -range, range, range)
1551 { 1550 {
1552 /* For most of the detections, we only detect objects above the 1551 /* For most of the detections, we only detect objects above the
1553 * floor. But this is not true for show invisible. 1552 * floor. But this is not true for show invisible.
1554 * Basically, we just go and find the top object and work 1553 * Basically, we just go and find the top object and work
1555 * down - that is easier than working up. 1554 * down - that is easier than working up.
1568 floor = 0; 1567 floor = 0;
1569 detect = NULL; 1568 detect = NULL;
1570 for (tmp = last; tmp; tmp = tmp->below) 1569 for (tmp = last; tmp; tmp = tmp->below)
1571 { 1570 {
1572 /* show invisible */ 1571 /* show invisible */
1573 if (QUERY_FLAG (spell, FLAG_MAKE_INVIS) && 1572 if (QUERY_FLAG (spell, FLAG_MAKE_INVIS)
1574 /* Might there be other objects that we can make visible? */ 1573 /* Might there be other objects that we can make visible? */
1575 (tmp->invisible && (QUERY_FLAG (tmp, FLAG_MONSTER) 1574 && (tmp->invisible && (QUERY_FLAG (tmp, FLAG_MONSTER)
1576 || (tmp->type == PLAYER && !QUERY_FLAG (tmp, FLAG_WIZ)) 1575 || (tmp->type == PLAYER && !QUERY_FLAG (tmp, FLAG_WIZ))
1577 || tmp->type == T_HANDLE 1576 || tmp->type == T_HANDLE
1578 || tmp->type == TRAPDOOR 1577 || tmp->type == TRAPDOOR
1579 || tmp->type == EXIT 1578 || tmp->type == EXIT
1580 || tmp->type == HOLE 1579 || tmp->type == HOLE
1581 || tmp->type == BUTTON 1580 || tmp->type == BUTTON
1582 || tmp->type == TELEPORTER 1581 || tmp->type == TELEPORTER
1583 || tmp->type == GATE 1582 || tmp->type == GATE
1584 || tmp->type == LOCKED_DOOR 1583 || tmp->type == LOCKED_DOOR
1585 || tmp->type == WEAPON 1584 || tmp->type == WEAPON
1586 || tmp->type == ALTAR 1585 || tmp->type == ALTAR
1587 || tmp->type == SIGN 1586 || tmp->type == SIGN
1588 || tmp->type == TRIGGER_PEDESTAL 1587 || tmp->type == TRIGGER_PEDESTAL
1589 || tmp->type == SPECIAL_KEY 1588 || tmp->type == SPECIAL_KEY
1590 || tmp->type == TREASURE 1589 || tmp->type == TREASURE
1591 || tmp->type == BOOK 1590 || tmp->type == BOOK
1592 || tmp->type == HOLY_ALTAR 1591 || tmp->type == HOLY_ALTAR
1593 || tmp->type == CONTAINER))) 1592 || tmp->type == CONTAINER)))
1594 { 1593 {
1595 if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4) 1594 if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4)
1596 { 1595 {
1597 tmp->invisible = 0; 1596 tmp->invisible = 0;
1598 done_one = 1; 1597 done_one = 1;
1620 /* detect magic */ 1619 /* detect magic */
1621 if (QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL) && 1620 if (QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL) &&
1622 !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && is_magical (tmp)) 1621 !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && is_magical (tmp))
1623 { 1622 {
1624 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL); 1623 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL);
1625 /* make runes more visibile */ 1624 /* make runes more visible */
1626 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC) 1625 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC)
1627 tmp->stats.Cha /= 4; 1626 tmp->stats.Cha /= 4;
1628 1627
1629 done_one = 1; 1628 done_one = 1;
1630 } 1629 }
1656 (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))) 1655 (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)))
1657 { 1656 {
1658 SET_FLAG (tmp, FLAG_KNOWN_CURSED); 1657 SET_FLAG (tmp, FLAG_KNOWN_CURSED);
1659 done_one = 1; 1658 done_one = 1;
1660 } 1659 }
1660
1661 // Do mining detection spell:
1662 if (spell->last_sp == 1) // 1 - detect any vein
1663 {
1664 if (tmp->type == VEIN)
1665 {
1666 if (tmp->other_arch)
1667 {
1668 if (!detect)
1669 detect = tmp->other_arch;
1670 done_one = 2;
1671 }
1672 else
1673 done_one = 1;
1674 }
1675 }
1661 } /* for stack of objects on this space */ 1676 } /* for stack of objects on this space */
1662 1677
1663 /* Code here puts an effect of the spell on the space, so you can see 1678 /* Code here puts an effect of the spell on the space, so you can see
1664 * where the magic is. 1679 * where the magic is.
1665 */ 1680 */
1666 if (done_one) 1681 if (done_one)
1667 { 1682 {
1668 object *detect_ob = arch_to_object (spell->other_arch); 1683 object *detect_ob = spell->other_arch->instance ();
1669 1684
1670 /* if this is set, we want to copy the face */ 1685 /* if this is set, we want to copy the face */
1671 if (done_one == 2 && detect) 1686 if (done_one == 2 && detect)
1672 { 1687 {
1673 detect_ob->face = detect->face; 1688 detect_ob->face = detect->face;
1677 /* by default, the detect_ob is already animated */ 1692 /* by default, the detect_ob is already animated */
1678 if (!QUERY_FLAG (detect, FLAG_ANIMATE)) 1693 if (!QUERY_FLAG (detect, FLAG_ANIMATE))
1679 CLEAR_FLAG (detect_ob, FLAG_ANIMATE); 1694 CLEAR_FLAG (detect_ob, FLAG_ANIMATE);
1680 } 1695 }
1681 1696
1682 m->insert (detect_ob, nx, ny, op); 1697 m->insert (detect_ob, nx, ny, op, INS_ON_TOP);
1683 } 1698 }
1684 } /* for processing the surrounding spaces */ 1699 } /* for processing the surrounding spaces */
1685 1700
1686 1701
1687 /* Now process objects in the players inventory if detect curse or magic */ 1702 /* Now process objects in the players inventory if detect curse or magic */
2030 } 2045 }
2031 2046
2032 weapon = weapon->split (); 2047 weapon = weapon->split ();
2033 2048
2034 /* create the golem object */ 2049 /* create the golem object */
2035 tmp = arch_to_object (spell->other_arch); 2050 tmp = spell->other_arch->instance ();
2036 2051
2037 /* if animated by a player, give the player control of the golem */ 2052 /* if animated by a player, give the player control of the golem */
2038 CLEAR_FLAG (tmp, FLAG_MONSTER); 2053 CLEAR_FLAG (tmp, FLAG_MONSTER);
2039 tmp->stats.exp = 0; 2054 tmp->stats.exp = 0;
2040 add_friendly_object (tmp); 2055 add_friendly_object (tmp);
2174 2189
2175 new_aura = present_arch_in_ob (spell->other_arch, op); 2190 new_aura = present_arch_in_ob (spell->other_arch, op);
2176 if (new_aura) 2191 if (new_aura)
2177 refresh = 1; 2192 refresh = 1;
2178 else 2193 else
2179 new_aura = arch_to_object (spell->other_arch); 2194 new_aura = spell->other_arch->instance ();
2180 2195
2181 new_aura->duration = spell->duration + 10 * SP_level_duration_adjust (caster, spell); 2196 new_aura->duration = spell->duration + 10 * SP_level_duration_adjust (caster, spell);
2182 2197
2183 new_aura->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); 2198 new_aura->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
2184 2199
2249 if (pos.normalise () && !(OB_TYPE_MOVE_BLOCK (env, pos->move_block))) 2264 if (pos.normalise () && !(OB_TYPE_MOVE_BLOCK (env, pos->move_block)))
2250 { 2265 {
2251 hit_map (aura, i, aura->attacktype, 0); 2266 hit_map (aura, i, aura->attacktype, 0);
2252 2267
2253 if (aura->other_arch) 2268 if (aura->other_arch)
2254 pos.insert (arch_to_object (aura->other_arch), aura); 2269 pos.insert (aura->other_arch->instance (), aura);
2255 } 2270 }
2256 } 2271 }
2257 2272
2258 /* put the aura back in the player's inventory */ 2273 /* put the aura back in the player's inventory */
2259 env->insert (aura); 2274 env->insert (aura);
2331 } 2346 }
2332 2347
2333 if (!spell->other_arch) 2348 if (!spell->other_arch)
2334 return 0; 2349 return 0;
2335 2350
2336 object *tmp = arch_to_object (spell->other_arch); 2351 object *tmp = spell->other_arch->instance ();
2337 2352
2338 tmp->race = op->name; /*Save the owner of the rune */ 2353 tmp->race = op->name; /*Save the owner of the rune */
2339 tmp->msg = msg; 2354 tmp->msg = msg;
2340 2355
2341 tmp->insert_at (op, op, INS_BELOW_ORIGINATOR); 2356 tmp->insert_at (op, op, INS_BELOW_ORIGINATOR);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines