ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/spell_util.C
(Generate patch)

Comparing deliantra/server/server/spell_util.C (file contents):
Revision 1.13 by root, Tue Sep 12 17:23:02 2006 UTC vs.
Revision 1.27 by root, Mon Dec 25 11:25:50 2006 UTC

16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 20
21 The authors can be reached via e-mail at crossfire-devel@real-time.com 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
22*/ 22*/
23 23
24 24
25#include <global.h> 25#include <global.h>
26#include <spells.h> 26#include <spells.h>
119 } 119 }
120 120
121 i = 0; 121 i = 0;
122 while (spell_mapping[i]) 122 while (spell_mapping[i])
123 { 123 {
124 if (!find_archetype (spell_mapping[i])) 124 if (!archetype::find (spell_mapping[i]))
125 { 125 {
126 LOG (llevError, "Unable to find spell mapping %s (%i)\n", spell_mapping[i], i); 126 LOG (llevError, "Unable to find spell mapping %s (%i)\n", spell_mapping[i], i);
127 } 127 }
128 i++; 128 i++;
129 } 129 }
153/* pretty basic function - basically just takes 153/* pretty basic function - basically just takes
154 * an object, sets the x,y, and calls insert_ob_in_map 154 * an object, sets the x,y, and calls insert_ob_in_map
155 */ 155 */
156 156
157void 157void
158spell_effect (object *spob, int x, int y, mapstruct *map, object *originator) 158spell_effect (object *spob, int x, int y, maptile *map, object *originator)
159{ 159{
160 160
161 if (spob->other_arch != NULL) 161 if (spob->other_arch != NULL)
162 { 162 {
163 object *effect = arch_to_object (spob->other_arch); 163 object *effect = arch_to_object (spob->other_arch);
183min_casting_level (object *caster, object *spell) 183min_casting_level (object *caster, object *spell)
184{ 184{
185 int new_level; 185 int new_level;
186 186
187 if (caster->path_denied & spell->path_attuned) 187 if (caster->path_denied & spell->path_attuned)
188 {
189 /* This case is not a bug, just the fact that this function is
190 * usually called BEFORE checking for path_deny. -AV
191 */
192#if 0
193 LOG (llevError, "BUG: path_level_mod (arch %s, name %s): casting denied " "spell\n", caster->arch->name, caster->name);
194#endif
195 return 1; 188 return 1;
196 } 189
197 new_level = spell->level 190 new_level = spell->level
198 + ((caster->path_repelled & spell->path_attuned) ? +2 : 0) + ((caster->path_attuned & spell->path_attuned) ? -2 : 0); 191 + ((caster->path_repelled & spell->path_attuned) ? +2 : 0) + ((caster->path_attuned & spell->path_attuned) ? -2 : 0);
192
199 return (new_level < 1) ? 1 : new_level; 193 return (new_level < 1) ? 1 : new_level;
200} 194}
201 195
202 196
203/* This function returns the effective level the spell 197/* This function returns the effective level the spell
212{ 206{
213 int level = caster->level; 207 int level = caster->level;
214 208
215 /* If this is a player, try to find the matching skill */ 209 /* If this is a player, try to find the matching skill */
216 if (caster->type == PLAYER && spell->skill) 210 if (caster->type == PLAYER && spell->skill)
217 {
218 int i;
219
220 for (i = 0; i < NUM_SKILLS; i++) 211 for (int i = 0; i < NUM_SKILLS; i++)
221 if (caster->contr->last_skill_ob[i] && caster->contr->last_skill_ob[i]->skill == spell->skill) 212 if (caster->contr->last_skill_ob[i] && caster->contr->last_skill_ob[i]->skill == spell->skill)
222 { 213 {
223 level = caster->contr->last_skill_ob[i]->level; 214 level = caster->contr->last_skill_ob[i]->level;
224 break; 215 break;
225 } 216 }
226 }
227 217
228 /* if a rod is fired by a player, take the use_magic_item skill in consideration. */ 218 /* if a rod is fired by a player, take the use_magic_item skill in consideration. */
229 if (caster->type == ROD && caster->env && caster->env->type == PLAYER) 219 if (caster->type == ROD && caster->env && caster->env->type == PLAYER)
230 { 220 {
231 object *skill = find_skill_by_number (caster->env, SK_USE_MAGIC_ITEM); 221 object *skill = find_skill_by_number (caster->env, SK_USE_MAGIC_ITEM);
240 /* Always make this at least 1. If this is zero, we get divide by zero 230 /* Always make this at least 1. If this is zero, we get divide by zero
241 * errors in various places. 231 * errors in various places.
242 */ 232 */
243 if (level < 1) 233 if (level < 1)
244 level = 1; 234 level = 1;
235
245 return level; 236 return level;
246} 237}
247 238
248/* The following function scales the spellpoint cost of 239/* The following function scales the spellpoint cost of
249 * a spell by it's increased effectiveness. Some of the 240 * a spell by it's increased effectiveness. Some of the
444 * reflect_spell fails.) 435 * reflect_spell fails.)
445 * Caller should be sure it passes us valid map coordinates 436 * Caller should be sure it passes us valid map coordinates
446 * eg, updated for tiled maps. 437 * eg, updated for tiled maps.
447 */ 438 */
448int 439int
449reflwall (mapstruct *m, int x, int y, object *sp_op) 440reflwall (maptile *m, int x, int y, object *sp_op)
450{ 441{
451 object *op; 442 object *op;
452 443
453 if (OUT_OF_REAL_MAP (m, x, y)) 444 if (OUT_OF_REAL_MAP (m, x, y))
454 return 0; 445 return 0;
455 for (op = get_map_ob (m, x, y); op != NULL; op = op->above) 446 for (op = GET_MAP_OB (m, x, y); op != NULL; op = op->above)
456 if (QUERY_FLAG (op, FLAG_REFL_SPELL) && (!QUERY_FLAG (op, FLAG_ALIVE) || 447 if (QUERY_FLAG (op, FLAG_REFL_SPELL)
457 sp_op->type == LIGHTNING || (rndm (0, 99)) < 90 - (sp_op->level / 10))) 448 && (!QUERY_FLAG (op, FLAG_ALIVE)
449 || (rndm (0, 99)) < 90 - (sp_op->level / 10)))
458 return 1; 450 return 1;
459 451
460 return 0; 452 return 0;
461} 453}
462 454
468 * in. 460 * in.
469 */ 461 */
470int 462int
471cast_create_obj (object *op, object *caster, object *new_op, int dir) 463cast_create_obj (object *op, object *caster, object *new_op, int dir)
472{ 464{
473 mapstruct *m; 465 maptile *m;
474 sint16 sx, sy; 466 sint16 sx, sy;
475 467
476 if (dir && 468 if (dir &&
477 ((get_map_flags (op->map, &m, op->x + freearr_x[dir], op->y + freearr_y[dir], &sx, &sy) & P_OUT_OF_MAP) || 469 ((get_map_flags (op->map, &m, op->x + freearr_x[dir], op->y + freearr_y[dir], &sx, &sy) & P_OUT_OF_MAP) ||
478 OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy)))) 470 OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy))))
498 * does not have AT_MAGIC, then counterwalls do not effect the spell. 490 * does not have AT_MAGIC, then counterwalls do not effect the spell.
499 * 491 *
500 */ 492 */
501 493
502int 494int
503ok_to_put_more (mapstruct *m, sint16 x, sint16 y, object *op, int immune_stop) 495ok_to_put_more (maptile *m, sint16 x, sint16 y, object *op, int immune_stop)
504{ 496{
505 object *tmp; 497 object *tmp;
506 int mflags; 498 int mflags;
507 mapstruct *mp; 499 maptile *mp;
508 500
509 mp = m; 501 mp = m;
510 mflags = get_map_flags (m, &mp, x, y, &x, &y); 502 mflags = get_map_flags (m, &mp, x, y, &x, &y);
511 503
512 if (mflags & P_OUT_OF_MAP) 504 if (mflags & P_OUT_OF_MAP)
513 return 0; 505 return 0;
514 506
515 if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (mp, x, y))) 507 if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (mp, x, y)))
516 return 0; 508 return 0;
517 509
518 for (tmp = get_map_ob (mp, x, y); tmp != NULL; tmp = tmp->above) 510 for (tmp = GET_MAP_OB (mp, x, y); tmp != NULL; tmp = tmp->above)
519 { 511 {
520 /* If there is a counterspell on the space, and this 512 /* If there is a counterspell on the space, and this
521 * object is using magic, don't progress. I believe we could 513 * object is using magic, don't progress. I believe we could
522 * leave this out and let in progress, and other areas of the code 514 * leave this out and let in progress, and other areas of the code
523 * will then remove it, but that would seem to to use more 515 * will then remove it, but that would seem to to use more
578int 570int
579fire_arch_from_position (object *op, object *caster, sint16 x, sint16 y, int dir, object *spell) 571fire_arch_from_position (object *op, object *caster, sint16 x, sint16 y, int dir, object *spell)
580{ 572{
581 object *tmp; 573 object *tmp;
582 int mflags; 574 int mflags;
583 mapstruct *m; 575 maptile *m;
584 576
585 if (spell->other_arch == NULL) 577 if (spell->other_arch == NULL)
586 return 0; 578 return 0;
587 579
588 m = op->map; 580 m = op->map;
598 return 0; 590 return 0;
599 591
600 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (m, x, y))) 592 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (m, x, y)))
601 { 593 {
602 new_draw_info (NDI_UNIQUE, 0, op, "You can't cast the spell on top of a wall!\n"); 594 new_draw_info (NDI_UNIQUE, 0, op, "You can't cast the spell on top of a wall!\n");
603 free_object (tmp); 595 tmp->destroy ();
604 return 0; 596 return 0;
605 } 597 }
606
607
608 598
609 tmp->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); 599 tmp->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
610 tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell); 600 tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell);
611 /* code in time.c uses food for some things, duration for others */ 601 /* code in time.c uses food for some things, duration for others */
612 tmp->stats.food = tmp->duration; 602 tmp->stats.food = tmp->duration;
613 tmp->range = spell->range + SP_level_range_adjust (caster, spell); 603 tmp->range = spell->range + SP_level_range_adjust (caster, spell);
614 tmp->attacktype = spell->attacktype; 604 tmp->attacktype = spell->attacktype;
615 tmp->x = x; 605 tmp->x = x;
616 tmp->y = y; 606 tmp->y = y;
617 tmp->direction = dir; 607 tmp->direction = dir;
618 if (get_owner (op) != NULL) 608 if (op->owner != NULL)
619 copy_owner (tmp, op); 609 tmp->set_owner (op);
620 else 610 else
621 set_owner (tmp, op); 611 tmp->set_owner (op);
622 tmp->level = caster_level (caster, spell); 612 tmp->level = caster_level (caster, spell);
623 set_spell_skill (op, caster, spell, tmp); 613 set_spell_skill (op, caster, spell, tmp);
624 614
625 /* needed for AT_HOLYWORD,AT_GODPOWER stuff */ 615 /* needed for AT_HOLYWORD,AT_GODPOWER stuff */
626 if (tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER) 616 if (tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER)
678 668
679object * 669object *
680find_target_for_friendly_spell (object *op, int dir) 670find_target_for_friendly_spell (object *op, int dir)
681{ 671{
682 object *tmp; 672 object *tmp;
683 mapstruct *m; 673 maptile *m;
684 sint16 x, y; 674 sint16 x, y;
685 int mflags; 675 int mflags;
686 676
687 /* I don't really get this block - if op isn't a player or rune, 677 /* I don't really get this block - if op isn't a player or rune,
688 * we then make the owner of this object the target. 678 * we then make the owner of this object the target.
689 * The owner could very well be no where near op. 679 * The owner could very well be no where near op.
690 */ 680 */
691 if (op->type != PLAYER && op->type != RUNE) 681 if (op->type != PLAYER && op->type != RUNE)
692 { 682 {
693 tmp = get_owner (op); 683 tmp = op->owner;
694 /* If the owner does not exist, or is not a monster, than apply the spell 684 /* If the owner does not exist, or is not a monster, than apply the spell
695 * to the caster. 685 * to the caster.
696 */ 686 */
697 if (!tmp || !QUERY_FLAG (tmp, FLAG_MONSTER)) 687 if (!tmp || !QUERY_FLAG (tmp, FLAG_MONSTER))
698 tmp = op; 688 tmp = op;
704 y = op->y + freearr_y[dir]; 694 y = op->y + freearr_y[dir];
705 695
706 mflags = get_map_flags (m, &m, x, y, &x, &y); 696 mflags = get_map_flags (m, &m, x, y, &x, &y);
707 697
708 if (mflags & P_OUT_OF_MAP) 698 if (mflags & P_OUT_OF_MAP)
709 tmp = NULL; 699 tmp = 0;
710 else 700 else
711 { 701 tmp = m->at (x, y).player ();
712 for (tmp = get_map_ob (m, x, y); tmp != NULL; tmp = tmp->above)
713 if (tmp->type == PLAYER)
714 break;
715 }
716 } 702 }
703
717 /* didn't find a player there, look in current square for a player */ 704 /* didn't find a player there, look in current square for a player */
718 if (tmp == NULL) 705 if (!tmp)
719 for (tmp = get_map_ob (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above) 706 tmp = op->ms ().player ();
720 {
721 if (tmp->type == PLAYER)
722 break;
723 }
724 707
725 return tmp; 708 return tmp;
726} 709}
727 710
728 711
738 * any, otherwise -1. 721 * any, otherwise -1.
739 * note that exclude can be NULL, in which case all bets are off. 722 * note that exclude can be NULL, in which case all bets are off.
740 */ 723 */
741 724
742int 725int
743spell_find_dir (mapstruct *m, int x, int y, object *exclude) 726spell_find_dir (maptile *m, int x, int y, object *exclude)
744{ 727{
745 int i, max = SIZEOFFREE; 728 int i, max = SIZEOFFREE;
746 sint16 nx, ny; 729 sint16 nx, ny;
747 int owner_type = 0, mflags; 730 int owner_type = 0, mflags;
748 object *tmp; 731 object *tmp;
749 mapstruct *mp; 732 maptile *mp;
750 733
751 if (exclude && exclude->head) 734 if (exclude && exclude->head)
752 exclude = exclude->head; 735 exclude = exclude->head;
753 if (exclude && exclude->type) 736 if (exclude && exclude->type)
754 owner_type = exclude->type; 737 owner_type = exclude->type;
760 mp = m; 743 mp = m;
761 mflags = get_map_flags (m, &mp, nx, ny, &nx, &ny); 744 mflags = get_map_flags (m, &mp, nx, ny, &nx, &ny);
762 if (mflags & (P_OUT_OF_MAP | P_BLOCKSVIEW)) 745 if (mflags & (P_OUT_OF_MAP | P_BLOCKSVIEW))
763 continue; 746 continue;
764 747
765 tmp = get_map_ob (mp, nx, ny); 748 tmp = GET_MAP_OB (mp, nx, ny);
766 749
767 while (tmp != NULL && (((owner_type == PLAYER && 750 while (tmp != NULL && (((owner_type == PLAYER &&
768 !QUERY_FLAG (tmp, FLAG_MONSTER) && !QUERY_FLAG (tmp, FLAG_GENERATOR)) || 751 !QUERY_FLAG (tmp, FLAG_MONSTER) && !QUERY_FLAG (tmp, FLAG_GENERATOR)) ||
769 (owner_type != PLAYER && tmp->type != PLAYER)) || (tmp == exclude || (tmp->head && tmp->head == exclude)))) 752 (owner_type != PLAYER && tmp->type != PLAYER)) || (tmp == exclude || (tmp->head && tmp->head == exclude))))
770 tmp = tmp->above; 753 tmp = tmp->above;
789 archetype *at; 772 archetype *at;
790 int dir; 773 int dir;
791 774
792 /* Handle cases where we are passed a bogus mosntername */ 775 /* Handle cases where we are passed a bogus mosntername */
793 776
794 if ((at = find_archetype (monstername)) == NULL) 777 if ((at = archetype::find (monstername)) == NULL)
795 return; 778 return;
796 779
797 /* find a free square nearby 780 /* find a free square nearby
798 * first we check the closest square for free squares 781 * first we check the closest square for free squares
799 */ 782 */
966 if (failure <= -20 && failure > -40) /* wonder */ 949 if (failure <= -20 && failure > -40) /* wonder */
967 { 950 {
968 new_draw_info_format (NDI_UNIQUE, 0, op, "%s gives a sign to renew your faith.", godname); 951 new_draw_info_format (NDI_UNIQUE, 0, op, "%s gives a sign to renew your faith.", godname);
969 tmp = get_archetype (SPELL_WONDER); 952 tmp = get_archetype (SPELL_WONDER);
970 cast_cone (op, op, 0, tmp); 953 cast_cone (op, op, 0, tmp);
971 free_object (tmp); 954 tmp->destroy ();
972 } 955 }
973 956
974 else if (failure <= -40 && failure > -60) /* confusion */ 957 else if (failure <= -40 && failure > -60) /* confusion */
975 { 958 {
976 new_draw_info (NDI_UNIQUE, 0, op, "Your diety touches your mind!"); 959 new_draw_info (NDI_UNIQUE, 0, op, "Your diety touches your mind!");
1010 if (failure <= -20 && failure > -40) /* wonder */ 993 if (failure <= -20 && failure > -40) /* wonder */
1011 { 994 {
1012 new_draw_info (NDI_UNIQUE, 0, op, "Your spell causes an unexpected effect."); 995 new_draw_info (NDI_UNIQUE, 0, op, "Your spell causes an unexpected effect.");
1013 tmp = get_archetype (SPELL_WONDER); 996 tmp = get_archetype (SPELL_WONDER);
1014 cast_cone (op, op, 0, tmp); 997 cast_cone (op, op, 0, tmp);
1015 free_object (tmp); 998 tmp->destroy ();
1016 } 999 }
1017 1000
1018 else if (failure <= -40 && failure > -60) /* confusion */ 1001 else if (failure <= -40 && failure > -60) /* confusion */
1019 { 1002 {
1020 new_draw_info (NDI_UNIQUE, 0, op, "Your magic recoils on you, making you confused!"); 1003 new_draw_info (NDI_UNIQUE, 0, op, "Your magic recoils on you, making you confused!");
1075 /* Always cast spell on caster */ 1058 /* Always cast spell on caster */
1076 success = cast_spell (op, caster, dir, spell, stringarg); 1059 success = cast_spell (op, caster, dir, spell, stringarg);
1077 1060
1078 if (caster->contr->party == NULL) 1061 if (caster->contr->party == NULL)
1079 { 1062 {
1080 remove_ob (spell); 1063 spell->remove ();
1081 return success; 1064 return success;
1082 } 1065 }
1083 for (pl = first_player; pl != NULL; pl = pl->next) 1066 for_all_players (pl)
1084 if ((pl->ob->contr->party == caster->contr->party) && (on_same_map (pl->ob, caster))) 1067 if ((pl->ob->contr->party == caster->contr->party) && (on_same_map (pl->ob, caster)))
1085 { 1068 {
1086 cast_spell (pl->ob, caster, pl->ob->facing, spell, stringarg); 1069 cast_spell (pl->ob, caster, pl->ob->facing, spell, stringarg);
1087 } 1070 }
1088 remove_ob (spell); 1071 spell->remove ();
1089 return success; 1072 return success;
1090} 1073}
1091 1074
1092/* This is where the main dispatch when someone casts a spell. 1075/* This is where the main dispatch when someone casts a spell.
1093 * 1076 *
1143 } 1126 }
1144 1127
1145 /* if caster is a spell casting object, this normally shouldn't be 1128 /* if caster is a spell casting object, this normally shouldn't be
1146 * an issue, because they don't have any spellpaths set up. 1129 * an issue, because they don't have any spellpaths set up.
1147 */ 1130 */
1148 if (caster->path_denied & spell_ob->path_attuned) 1131 if (caster->path_denied & spell_ob->path_attuned && !QUERY_FLAG (caster, FLAG_WIZCAST))
1149 { 1132 {
1150 new_draw_info (NDI_UNIQUE, 0, op, "That spell path is denied to you."); 1133 new_draw_info (NDI_UNIQUE, 0, op, "That spell path is denied to you.");
1151 return 0; 1134 return 0;
1152 } 1135 }
1153 1136
1288 * spell is actually cast, it knows about the stringarg. 1271 * spell is actually cast, it knows about the stringarg.
1289 * necessary for the invoke command spells. 1272 * necessary for the invoke command spells.
1290 */ 1273 */
1291 if (stringarg) 1274 if (stringarg)
1292 { 1275 {
1293 op->spellarg = strdup_local (stringarg); 1276 op->spellarg = strdup (stringarg);
1294 } 1277 }
1295 else 1278 else
1296 op->spellarg = NULL; 1279 op->spellarg = NULL;
1297 return 0; 1280 return 0;
1298 } 1281 }
1688 break; 1671 break;
1689 1672
1690 case SP_MAGIC_MISSILE: 1673 case SP_MAGIC_MISSILE:
1691 if (QUERY_FLAG (victim, FLAG_ALIVE)) 1674 if (QUERY_FLAG (victim, FLAG_ALIVE))
1692 { 1675 {
1693 tag_t spell_tag = spell->count;
1694
1695 hit_player (victim, spell->stats.dam, spell, spell->attacktype, 1); 1676 hit_player (victim, spell->stats.dam, spell, spell->attacktype, 1);
1696 if (!was_destroyed (spell, spell_tag)) 1677
1697 { 1678 if (!spell->destroyed ())
1698 remove_ob (spell); 1679 spell->destroy ();
1699 free_object (spell);
1700 }
1701 } 1680 }
1702 break; 1681 break;
1703 1682
1704 case SP_MOVING_BALL: 1683 case SP_MOVING_BALL:
1705 if (QUERY_FLAG (victim, FLAG_ALIVE)) 1684 if (QUERY_FLAG (victim, FLAG_ALIVE))

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines