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.141 by root, Fri Jan 27 22:00:40 2012 UTC vs.
Revision 1.147 by root, Sat Sep 16 22:17:42 2017 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,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * 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 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>
196 /* Can't get any money for these objects */ 196 /* Can't get any money for these objects */
197 missile->value = 0; 197 missile->value = 0;
198 198
199 missile->set_flag (FLAG_IDENTIFIED); 199 missile->set_flag (FLAG_IDENTIFIED);
200 200
201 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 ())
202 pick_up (op, missile); 206 pick_up (op, missile);
203 207
204 return 1; 208 return 1;
205} 209}
206
207 210
208/* allows the choice of what sort of food object to make. 211/* allows the choice of what sort of food object to make.
209 * 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*/
210int 213int
211cast_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)
290 } 293 }
291 294
292 maxrange = spell_ob->range + SP_level_range_adjust (caster, spell_ob); 295 maxrange = spell_ob->range + SP_level_range_adjust (caster, spell_ob);
293 for (r = 1; r < maxrange; r++) 296 for (r = 1; r < maxrange; r++)
294 { 297 {
295 sint16 x = op->x + r * freearr_x[dir], y = op->y + r * freearr_y[dir]; 298 sint16 x = op->x + r * DIRX (dir), y = op->y + r * DIRY (dir);
296 299
297 m = op->map; 300 m = op->map;
298 mflags = get_map_flags (m, &m, x, y, &x, &y); 301 mflags = get_map_flags (m, &m, x, y, &x, &y);
299 302
300 if (mflags & P_OUT_OF_MAP) 303 if (mflags & P_OUT_OF_MAP)
401 404
402 if (spell_ob->flag [FLAG_MAKE_INVIS]) 405 if (spell_ob->flag [FLAG_MAKE_INVIS])
403 op->contr->tmp_invis = 0; 406 op->contr->tmp_invis = 0;
404 else 407 else
405 op->contr->tmp_invis = 1; 408 op->contr->tmp_invis = 1;
406
407 op->contr->hidden = 0;
408 } 409 }
409 410
410 if (makes_invisible_to (op, op)) 411 if (makes_invisible_to (op, op))
411 new_draw_info (NDI_UNIQUE, 0, op, "You can't see your hands!"); 412 new_draw_info (NDI_UNIQUE, 0, op, "You can't see your hands!");
412 else 413 else
470 471
471 op->destroy (); 472 op->destroy ();
472} 473}
473 474
474/* Word of recall causes the player to return 'home'. 475/* Word of recall causes the player to return 'home'.
475 * we put a force into the player object, so that there is a 476 * we put a force into the player object, so that there is a
476 * time delay effect. 477 * time delay effect.
477 */ 478 */
478int 479int
479cast_word_of_recall (object *op, object *caster, object *spell_ob) 480cast_word_of_recall (object *op, object *caster, object *spell_ob)
480{ 481{
618 x = op->x; 619 x = op->x;
619 y = op->y; 620 y = op->y;
620 } 621 }
621 else 622 else
622 { 623 {
623 x = op->x + freearr_x[dir]; 624 x = op->x + DIRX (dir);
624 y = op->y + freearr_y[dir]; 625 y = op->y + DIRY (dir);
625 } 626 }
626 627
627 m = op->map; 628 m = op->map;
628 629
629 if ((spell_ob->move_block || x != op->x || y != op->y) && 630 if ((spell_ob->move_block || x != op->x || y != op->y) &&
704 /* If this is a spellcasting wall, need to insert the spell object */ 705 /* If this is a spellcasting wall, need to insert the spell object */
705 if (tmp->other_arch && tmp->other_arch->type == SPELL) 706 if (tmp->other_arch && tmp->other_arch->type == SPELL)
706 insert_ob_in_ob (tmp->other_arch->instance (), tmp); 707 insert_ob_in_ob (tmp->other_arch->instance (), tmp);
707 708
708 /* This code causes the wall to extend some distance in 709 /* This code causes the wall to extend some distance in
709 * each direction, or until an obstruction is encountered. 710 * each direction, or until an obstruction is encountered.
710 * posblocked and negblocked help determine how far the 711 * posblocked and negblocked help determine how far the
711 * created wall can extend, it won't go extend through 712 * created wall can extend, it won't go extend through
712 * blocked spaces. 713 * blocked spaces.
713 */ 714 */
714 maxrange = spell_ob->range + SP_level_range_adjust (caster, spell_ob); 715 maxrange = spell_ob->range + SP_level_range_adjust (caster, spell_ob);
719 { 720 {
720 int dir2; 721 int dir2;
721 722
722 dir2 = (dir < 4) ? (dir + 2) : dir - 2; 723 dir2 = (dir < 4) ? (dir + 2) : dir - 2;
723 724
724 x = tmp->x + i * freearr_x[dir2]; 725 x = tmp->x + i * DIRX (dir2);
725 y = tmp->y + i * freearr_y[dir2]; 726 y = tmp->y + i * DIRY (dir2);
726 m = tmp->map; 727 m = tmp->map;
727 728
728 if (!(get_map_flags (m, &m, x, y, &x, &y) & (P_OUT_OF_MAP | P_IS_ALIVE)) && 729 if (!(get_map_flags (m, &m, x, y, &x, &y) & (P_OUT_OF_MAP | P_IS_ALIVE)) &&
729 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK (m, x, y)) != spell_ob->move_block) && !posblocked) 730 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK (m, x, y)) != spell_ob->move_block) && !posblocked)
730 { 731 {
737 738
738 } 739 }
739 else 740 else
740 posblocked = 1; 741 posblocked = 1;
741 742
742 x = tmp->x - i * freearr_x[dir2]; 743 x = tmp->x - i * DIRX (dir2);
743 y = tmp->y - i * freearr_y[dir2]; 744 y = tmp->y - i * DIRY (dir2);
744 m = tmp->map; 745 m = tmp->map;
745 746
746 if (!(get_map_flags (m, &m, x, y, &x, &y) & (P_OUT_OF_MAP | P_IS_ALIVE)) && 747 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) && !negblocked) 748 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK (m, x, y)) != spell_ob->move_block) && !negblocked)
748 { 749 {
794 return 0; 795 return 0;
795 } 796 }
796 797
797 for (dist = 0; dist < count; dist++) 798 for (dist = 0; dist < count; dist++)
798 { 799 {
799 mflags = get_map_flags (op->map, &m, op->x + freearr_x[dir] * (dist + 1), op->y + freearr_y[dir] * (dist + 1), &sx, &sy); 800 mflags = get_map_flags (op->map, &m, op->x + DIRX (dir) * (dist + 1), op->y + DIRY (dir) * (dist + 1), &sx, &sy);
800 801
801 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP)) 802 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP))
802 break; 803 break;
803 804
804 if ((mflags & P_BLOCKSVIEW) && OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy))) 805 if ((mflags & P_BLOCKSVIEW) && OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy)))
817 * by such squares). Also, there are probably treasure rooms and 818 * by such squares). Also, there are probably treasure rooms and
818 * lots of other maps that protect areas with no magic, but the 819 * lots of other maps that protect areas with no magic, but the
819 * areas themselves don't contain no magic spaces. 820 * areas themselves don't contain no magic spaces.
820 */ 821 */
821 /* This call here is really just to normalize the coordinates */ 822 /* This call here is really just to normalize the coordinates */
822 mflags = get_map_flags (op->map, &m, op->x + freearr_x[dir] * dist, op->y + freearr_y[dir] * dist, &sx, &sy); 823 mflags = get_map_flags (op->map, &m, op->x + DIRX (dir) * dist, op->y + DIRY (dir) * dist, &sx, &sy);
823 if (mflags & P_IS_ALIVE || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy))) 824 if (mflags & P_IS_ALIVE || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy)))
824 { 825 {
825 new_draw_info (NDI_UNIQUE, 0, op, "You cast your spell, but nothing happens.\n"); 826 new_draw_info (NDI_UNIQUE, 0, op, "You cast your spell, but nothing happens.\n");
826 return 1; /* Maybe the penalty should be more severe... */ 827 return 1; /* Maybe the penalty should be more severe... */
827 } 828 }
833 * spaces that blocked the players view. 834 * spaces that blocked the players view.
834 */ 835 */
835 836
836 for (dist = 0; dist < maxdist; dist++) 837 for (dist = 0; dist < maxdist; dist++)
837 { 838 {
838 mflags = get_map_flags (op->map, &m, op->x + freearr_x[dir] * (dist + 1), op->y + freearr_y[dir] * (dist + 1), &sx, &sy); 839 mflags = get_map_flags (op->map, &m, op->x + DIRX (dir) * (dist + 1), op->y + DIRY (dir) * (dist + 1), &sx, &sy);
839 840
840 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP)) 841 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP))
841 break; 842 break;
842 843
843 if ((mflags & P_BLOCKSVIEW) && OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy))) 844 if ((mflags & P_BLOCKSVIEW) && OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy)))
848 /* If the destination is blocked, keep backing up until we 849 /* If the destination is blocked, keep backing up until we
849 * find a place for the player. 850 * find a place for the player.
850 */ 851 */
851 for (; dist > 0; dist--) 852 for (; dist > 0; dist--)
852 { 853 {
853 if (get_map_flags (op->map, &m, op->x + freearr_x[dir] * dist, op->y + freearr_y[dir] * dist, 854 if (get_map_flags (op->map, &m, op->x + DIRX (dir) * dist, op->y + DIRY (dir) * dist,
854 &sx, &sy) & (P_OUT_OF_MAP | P_IS_ALIVE)) 855 &sx, &sy) & (P_OUT_OF_MAP | P_IS_ALIVE))
855 continue; 856 continue;
856 857
857 858
858 if (!OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy))) 859 if (!OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy)))
865 return 0; 866 return 0;
866 } 867 }
867 } 868 }
868 869
869 /* Actually move the player now */ 870 /* Actually move the player now */
870 if (!(op = op->map->insert (op, op->x + freearr_x[dir] * dist, op->y + freearr_y[dir] * dist, op))) 871 if (!(op = op->map->insert (op, op->x + DIRX (dir) * dist, op->y + DIRY (dir) * dist, op)))
871 return 1; 872 return 1;
872 873
873 op->speed_left = -5. * op->speed; /* Freeze them for a short while */ 874 op->speed_left = -5. * op->speed; /* Freeze them for a short while */
874 875
875 return 1; 876 return 1;
1257 1258
1258/* Alchemy code by Mark Wedel 1259/* Alchemy code by Mark Wedel
1259 * 1260 *
1260 * This code adds a new spell, called alchemy. Alchemy will turn 1261 * This code adds a new spell, called alchemy. Alchemy will turn
1261 * objects to pyrite ("false gold"), henceforth called gold nuggets. 1262 * objects to pyrite ("false gold"), henceforth called gold nuggets.
1262 * 1263 *
1263 * The value of the gold nuggets being about 90% of that of the item 1264 * The value of the gold nuggets being about 90% of that of the item
1264 * itself. It uses the value of the object before charisma adjustments, 1265 * itself. It uses the value of the object before charisma adjustments,
1265 * because the nuggets themselves will be will be adjusted by charisma 1266 * because the nuggets themselves will be will be adjusted by charisma
1266 * when sold. 1267 * when sold.
1267 * 1268 *
1767 sint16 x, y; 1768 sint16 x, y;
1768 maptile *m; 1769 maptile *m;
1769 int mflags; 1770 int mflags;
1770 1771
1771 m = op->map; 1772 m = op->map;
1772 x = op->x + freearr_x[dir]; 1773 x = op->x + DIRX (dir);
1773 y = op->y + freearr_y[dir]; 1774 y = op->y + DIRY (dir);
1774 1775
1775 mflags = get_map_flags (m, &m, x, y, &x, &y); 1776 mflags = get_map_flags (m, &m, x, y, &x, &y);
1776 1777
1777 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE) 1778 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE)
1778 { 1779 {
1842 object *tmp, *head, *next; 1843 object *tmp, *head, *next;
1843 int mflags; 1844 int mflags;
1844 maptile *m; 1845 maptile *m;
1845 sint16 sx, sy; 1846 sint16 sx, sy;
1846 1847
1847 sx = op->x + freearr_x[dir]; 1848 sx = op->x + DIRX (dir);
1848 sy = op->y + freearr_y[dir]; 1849 sy = op->y + DIRY (dir);
1849 m = op->map; 1850 m = op->map;
1850 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy); 1851 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy);
1851 if (mflags & P_OUT_OF_MAP) 1852 if (mflags & P_OUT_OF_MAP)
1852 return; 1853 return;
1853 1854
1866 1867
1867 /* don't attack our own spells */ 1868 /* don't attack our own spells */
1868 if (tmp->owner && tmp->owner == op->owner) 1869 if (tmp->owner && tmp->owner == op->owner)
1869 continue; 1870 continue;
1870 1871
1871 /* Basically, if the object is magical and not counterspell, 1872 /* Basically, if the object is magical and not counterspell,
1872 * we will more or less remove the object. Don't counterspell 1873 * we will more or less remove the object. Don't counterspell
1873 * monsters either. 1874 * monsters either.
1874 */ 1875 */
1875 1876
1876 if (head->attacktype & AT_MAGIC 1877 if (head->attacktype & AT_MAGIC
1877 && !(head->attacktype & AT_COUNTERSPELL) 1878 && !(head->attacktype & AT_COUNTERSPELL)
1878 && !head->flag [FLAG_MONSTER] 1879 && !head->flag [FLAG_MONSTER]
1952 1953
1953 op->failmsg ("You are not standing over an altar!"); 1954 op->failmsg ("You are not standing over an altar!");
1954 return 0; 1955 return 0;
1955} 1956}
1956 1957
1957/* animate_weapon - 1958/* animate_weapon -
1958 * Generalization of staff_to_snake. Makes a golem out of the caster's weapon. 1959 * Generalization of staff_to_snake. Makes a golem out of the caster's weapon.
1959 * The golem is based on the archetype specified, modified by the caster's level 1960 * The golem is based on the archetype specified, modified by the caster's level
1960 * and the attributes of the weapon. The weapon is inserted in the golem's 1961 * and the attributes of the weapon. The weapon is inserted in the golem's
1961 * inventory so that it falls to the ground when the golem dies. 1962 * inventory so that it falls to the ground when the golem dies.
1962 * This code was very odd - code early on would only let players use the spell, 1963 * This code was very odd - code early on would only let players use the spell,
1963 * yet the code wass full of player checks. I've presumed that the code 1964 * yet the code wass full of player checks. I've presumed that the code
1964 * that only let players use it was correct, and removed all the other 1965 * that only let players use it was correct, and removed all the other
1965 * player checks. MSW 2003-01-06 1966 * player checks. MSW 2003-01-06
1992 /* if no direction specified, pick one */ 1993 /* if no direction specified, pick one */
1993 if (!dir) 1994 if (!dir)
1994 dir = find_free_spot (spell->other_arch, op->map, op->x, op->y, 1, 9); 1995 dir = find_free_spot (spell->other_arch, op->map, op->x, op->y, 1, 9);
1995 1996
1996 m = op->map; 1997 m = op->map;
1997 x = op->x + freearr_x[dir]; 1998 x = op->x + DIRX (dir);
1998 y = op->y + freearr_y[dir]; 1999 y = op->y + DIRY (dir);
1999 2000
2000 /* if there's no place to put the golem, abort */ 2001 /* if there's no place to put the golem, abort */
2001 if (dir < 0 || (get_map_flags (m, &m, x, y, &x, &y) & P_OUT_OF_MAP) 2002 if (dir < 0 || (get_map_flags (m, &m, x, y, &x, &y) & P_OUT_OF_MAP)
2002 || ((spell->other_arch->move_type & GET_MAP_MOVE_BLOCK (m, x, y)) == spell->other_arch->move_type)) 2003 || ((spell->other_arch->move_type & GET_MAP_MOVE_BLOCK (m, x, y)) == spell->other_arch->move_type))
2003 { 2004 {
2203 2204
2204/* move aura function. An aura is a part of someone's inventory, 2205/* move aura function. An aura is a part of someone's inventory,
2205 * which he carries with him, but which acts on the map immediately 2206 * which he carries with him, but which acts on the map immediately
2206 * around him. 2207 * around him.
2207 * Aura parameters: 2208 * Aura parameters:
2208 * duration: duration counter. 2209 * duration: duration counter.
2209 * attacktype: aura's attacktype 2210 * attacktype: aura's attacktype
2210 * other_arch: archetype to drop where we attack 2211 * other_arch: archetype to drop where we attack
2211 */ 2212 */
2212void 2213void
2213move_aura (object *aura) 2214move_aura (object *aura)
2214{ 2215{
2215 /* auras belong in inventories */ 2216 /* auras belong in inventories */
2216 object *env = aura->env; 2217 object *env = aura->env;
2217 object *owner = aura->owner; 2218 object *owner = aura->owner;
2218 2219
2219 /* no matter what we've gotta remove the aura... 2220 /* no matter what we've gotta remove the aura...
2220 * we'll put it back if its time isn't up. 2221 * we'll put it back if its time isn't up.
2221 */ 2222 */
2222 aura->remove (); 2223 aura->remove ();
2223 2224
2224 /* exit if we're out of gas */ 2225 /* exit if we're out of gas */
2225 if (aura->duration-- < 0) 2226 if (aura->duration-- < 0)
2234 aura->destroy (); 2235 aura->destroy ();
2235 return; 2236 return;
2236 } 2237 }
2237 2238
2238 /* we need to jump out of the inventory for a bit 2239 /* we need to jump out of the inventory for a bit
2239 * in order to hit the map conveniently. 2240 * in order to hit the map conveniently.
2240 */ 2241 */
2241 aura->insert_at (env, aura); 2242 aura->insert_at (env, aura);
2242 2243
2243 for (int i = 1; i < 9; i++) 2244 for (int i = 1; i < 9; i++)
2244 { 2245 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines