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.53 by root, Tue May 22 10:50:01 2007 UTC vs.
Revision 1.61 by root, Sun Jun 24 16:11:51 2007 UTC

1/* 1/*
2 * CrossFire, A Multiplayer game 2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 * 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team 4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * Crossfire TRT is free software; you can redistribute it and/or modify it
9 * it under the terms of the GNU General Public License as published by 9 * under the terms of the GNU General Public License as published by the Free
10 * the Free Software Foundation; either version 2 of the License, or 10 * Software Foundation; either version 2 of the License, or (at your option)
11 * (at your option) any later version. 11 * 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, but
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * GNU General Public License for more details. 16 * for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License along
19 * along with this program; if not, write to the Free Software 19 * with Crossfire TRT; if not, write to the Free Software Foundation, Inc. 51
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * 21 *
22 * The authors can be reached via e-mail at <crossfire@schmorp.de> 22 * The authors can be reached via e-mail to <crossfire@schmorp.de>
23 */ 23 */
24 24
25#include <global.h> 25#include <global.h>
26#include <object.h> 26#include <object.h>
27#include <living.h> 27#include <living.h>
104 ncharges = 1; 104 ncharges = 1;
105 105
106 wand->stats.food += ncharges; 106 wand->stats.food += ncharges;
107 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s glows with power.", query_name (wand)); 107 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s glows with power.", query_name (wand));
108 108
109 if (wand->arch && QUERY_FLAG (&wand->arch->clone, FLAG_ANIMATE)) 109 if (wand->arch && QUERY_FLAG (wand->arch, FLAG_ANIMATE))
110 { 110 {
111 SET_FLAG (wand, FLAG_ANIMATE); 111 SET_FLAG (wand, FLAG_ANIMATE);
112 wand->set_speed (wand->arch->clone.speed); 112 wand->set_speed (wand->arch->speed);
113 } 113 }
114 114
115 return 1; 115 return 1;
116} 116}
117 117
224 if (stringarg) 224 if (stringarg)
225 { 225 {
226 at = find_archetype_by_object_type_name (FOOD, stringarg); 226 at = find_archetype_by_object_type_name (FOOD, stringarg);
227 if (at == NULL) 227 if (at == NULL)
228 at = find_archetype_by_object_type_name (DRINK, stringarg); 228 at = find_archetype_by_object_type_name (DRINK, stringarg);
229 if (at == NULL || at->clone.stats.food > food_value) 229 if (at == NULL || at->stats.food > food_value)
230 stringarg = NULL; 230 stringarg = NULL;
231 } 231 }
232 232
233 if (!stringarg) 233 if (!stringarg)
234 { 234 {
240 * We don't use flesh types because the weight values of those need 240 * We don't use flesh types because the weight values of those need
241 * to be altered from the donor. 241 * to be altered from the donor.
242 */ 242 */
243 243
244 /* We assume the food items don't have multiple parts */ 244 /* We assume the food items don't have multiple parts */
245 for (at_tmp = first_archetype; at_tmp != NULL; at_tmp = at_tmp->next) 245 for_all_archetypes (at_tmp)
246 { 246 {
247 if (at_tmp->clone.type == FOOD || at_tmp->clone.type == DRINK) 247 if (at_tmp->type == FOOD || at_tmp->type == DRINK)
248 { 248 {
249 /* Basically, if the food value is something that is creatable 249 /* Basically, if the food value is something that is creatable
250 * under the limits of the spell and it is higher than 250 * under the limits of the spell and it is higher than
251 * the item we have now, take it instead. 251 * the item we have now, take it instead.
252 */ 252 */
253 if (at_tmp->clone.stats.food <= food_value && (!at || at_tmp->clone.stats.food > at->clone.stats.food)) 253 if (at_tmp->stats.food <= food_value
254 && (!at
255 || at_tmp->stats.food > at->stats.food
256 || (at_tmp->stats.food == at->stats.food
257 && at_tmp->weight < at->weight)))
254 at = at_tmp; 258 at = at_tmp;
255 } 259 }
256 } 260 }
257 } 261 }
258 /* Pretty unlikely (there are some very low food items), but you never 262 /* Pretty unlikely (there are some very low food items), but you never
262 { 266 {
263 new_draw_info (NDI_UNIQUE, 0, op, "You don't have enough experience to create any food."); 267 new_draw_info (NDI_UNIQUE, 0, op, "You don't have enough experience to create any food.");
264 return 0; 268 return 0;
265 } 269 }
266 270
267 food_value /= at->clone.stats.food; 271 food_value /= at->stats.food;
268 new_op = arch_to_object (at); 272 new_op = arch_to_object (at);
269 new_op->nrof = food_value; 273 new_op->nrof = food_value;
270 274
271 new_op->value = 0; 275 new_op->value = 0;
272 if (new_op->nrof < 1) 276 if (new_op->nrof < 1)
565} 569}
566 570
567int 571int
568perceive_self (object *op) 572perceive_self (object *op)
569{ 573{
570 char buf[MAX_BUF];
571 const char *cp = describe_item (op, op); 574 const char *cp = describe_item (op, op);
572 archetype *at = archetype::find (ARCH_DEPLETION); 575 archetype *at = archetype::find (ARCH_DEPLETION);
573 object *tmp;
574 int i;
575 576
577 dynbuf_text buf;
578
579 if (player *pl = op->contr)
580 if (object *race = archetype::find (op->race))
581 buf << "You are a " << (pl->gender ? "female" : "male") << " " << &race->name << ".\n";
582
576 tmp = find_god (determine_god (op)); 583 if (object *god = find_god (determine_god (op)))
577 if (tmp) 584 buf << "You worship " << &god->name << ".\n";
578 new_draw_info_format (NDI_UNIQUE, 0, op, "You worship %s", &tmp->name);
579 else 585 else
580 new_draw_info (NDI_UNIQUE, 0, op, "You worship no god"); 586 buf << "You worship no god.\n";
581 587
582 tmp = present_arch_in_ob (at, op); 588 object *tmp = present_arch_in_ob (at, op);
583 589
584 if (*cp == '\0' && tmp == NULL) 590 if (*cp == '\0' && tmp == NULL)
585 new_draw_info (NDI_UNIQUE, 0, op, "You feel very mundane"); 591 buf << "You feel very mundane. ";
586 else 592 else
587 { 593 {
588 new_draw_info (NDI_UNIQUE, 0, op, "You have:"); 594 buf << "You have: " << cp << ".\n";
589 new_draw_info (NDI_UNIQUE, 0, op, cp);
590 595
591 if (tmp) 596 if (tmp)
592 for (i = 0; i < NUM_STATS; i++) 597 for (int i = 0; i < NUM_STATS; i++)
593 if (tmp->stats.stat (i) < 0) 598 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)); 599 buf.printf ("Your %s is depleted by %d.\n", statname[i], -tmp->stats.stat (i));
595 } 600 }
596 601
597 if (is_dragon_pl (op)) 602 if (is_dragon_pl (op))
598 {
599 /* now grab the 'dragon_ability'-force from the player's inventory */ 603 /* now grab the 'dragon_ability'-force from the player's inventory */
600 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 604 for (tmp = op->inv; tmp; tmp = tmp->below)
601 { 605 {
602 if (tmp->type == FORCE && !strcmp (tmp->arch->name, "dragon_ability_force")) 606 if (tmp->type == FORCE && !strcmp (tmp->arch->archname, "dragon_ability_force"))
603 { 607 {
604 if (tmp->stats.exp == 0) 608 if (tmp->stats.exp == 0)
605 sprintf (buf, "Your metabolism isn't focused on anything."); 609 buf << "Your metabolism isn't focused on anything.\n";
606 else 610 else
607 sprintf (buf, "Your metabolism is focused on %s.", change_resist_msg[tmp->stats.exp]); 611 buf << "Your metabolism is focused on " << change_resist_msg[tmp->stats.exp] << ".\n";
608 612
609 new_draw_info (NDI_UNIQUE, 0, op, buf);
610 break; 613 break;
611 } 614 }
612 } 615 }
613 } 616
617 buf << '\0'; // zero-terminate
618
619 new_draw_info (NDI_UNIQUE, 0, op, buf.linearise ());
614 620
615 return 1; 621 return 1;
616} 622}
617 623
618/* This creates magic walls. Really, it can create most any object, 624/* 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); 722 new_draw_info_format (NDI_UNIQUE, 0, op, "Something destroys your %s", name);
717 return 0; 723 return 0;
718 } 724 }
719 725
720 /* If this is a spellcasting wall, need to insert the spell object */ 726 /* If this is a spellcasting wall, need to insert the spell object */
721 if (tmp->other_arch && tmp->other_arch->clone.type == SPELL) 727 if (tmp->other_arch && tmp->other_arch->type == SPELL)
722 insert_ob_in_ob (arch_to_object (tmp->other_arch), tmp); 728 insert_ob_in_ob (arch_to_object (tmp->other_arch), tmp);
723 729
724 /* This code causes the wall to extend some distance in 730 /* This code causes the wall to extend some distance in
725 * each direction, or until an obstruction is encountered. 731 * each direction, or until an obstruction is encountered.
726 * posblocked and negblocked help determine how far the 732 * posblocked and negblocked help determine how far the
746 { 752 {
747 object *tmp2 = tmp->clone (); 753 object *tmp2 = tmp->clone ();
748 m->insert (tmp2, x, y, op); 754 m->insert (tmp2, x, y, op);
749 755
750 /* If this is a spellcasting wall, need to insert the spell object */ 756 /* If this is a spellcasting wall, need to insert the spell object */
751 if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL) 757 if (tmp2->other_arch && tmp2->other_arch->type == SPELL)
752 tmp2->insert (arch_to_object (tmp2->other_arch)); 758 tmp2->insert (arch_to_object (tmp2->other_arch));
753 759
754 } 760 }
755 else 761 else
756 posblocked = 1; 762 posblocked = 1;
763 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK (m, x, y)) != spell_ob->move_block) && !negblocked) 769 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK (m, x, y)) != spell_ob->move_block) && !negblocked)
764 { 770 {
765 object *tmp2 = tmp->clone (); 771 object *tmp2 = tmp->clone ();
766 m->insert (tmp2, x, y, op); 772 m->insert (tmp2, x, y, op);
767 773
768 if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL) 774 if (tmp2->other_arch && tmp2->other_arch->type == SPELL)
769 tmp2->insert (arch_to_object (tmp2->other_arch)); 775 tmp2->insert (arch_to_object (tmp2->other_arch));
770 } 776 }
771 else 777 else
772 negblocked = 1; 778 negblocked = 1;
773 } 779 }
1014 } 1020 }
1015 1021
1016 return success; 1022 return success;
1017} 1023}
1018 1024
1019
1020/* This is used for the spells that gain stats. There are no spells 1025/* 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 1026 * right now that icnrease wis/int/pow on a temp basis, so no
1022 * good comments for those. 1027 * good comments for those.
1023 */ 1028 */
1024static const char *const no_gain_msgs[NUM_STATS] = { 1029static const char *const no_gain_msgs[NUM_STATS] = {
1025 "You grow no stronger.", 1030 "You grow no stronger.",
1026 "You grow no more agile.", 1031 "You grow no more agile.",
1027 "You don't feel any healthier.", 1032 "You don't feel any healthier.",
1028 "no wis", 1033 "You didn't grow any more intelligent.",
1034 "You do not feel any wiser.",
1035 "You don't feel any more powerful."
1029 "You are no easier to look at.", 1036 "You are no easier to look at.",
1030 "no int",
1031 "no pow"
1032}; 1037};
1033 1038
1034int 1039int
1035cast_change_ability (object *op, object *caster, object *spell_ob, int dir, int silent) 1040cast_change_ability (object *op, object *caster, object *spell_ob, int dir, int silent)
1036{ 1041{
1087 } 1092 }
1088 else 1093 else
1089 { 1094 {
1090 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect."); 1095 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect.");
1091 } 1096 }
1097
1092 return 1; 1098 return 1;
1093 } 1099 }
1100
1094 force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50; 1101 force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50;
1095 force->speed = 1.0; 1102 force->speed = 1.0;
1096 force->speed_left = -1.0; 1103 force->speed_left = -1.0;
1097 SET_FLAG (force, FLAG_APPLIED); 1104 SET_FLAG (force, FLAG_APPLIED);
1098 1105
1104 force->resist[i] = spell_ob->resist[i] + SP_level_dam_adjust (caster, spell_ob); 1111 force->resist[i] = spell_ob->resist[i] + SP_level_dam_adjust (caster, spell_ob);
1105 if (force->resist[i] > 100) 1112 if (force->resist[i] > 100)
1106 force->resist[i] = 100; 1113 force->resist[i] = 100;
1107 } 1114 }
1108 } 1115 }
1116
1109 if (spell_ob->stats.hp) 1117 if (spell_ob->stats.hp)
1110 force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust (caster, spell_ob); 1118 force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust (caster, spell_ob);
1111 1119
1112 if (tmp->type == PLAYER) 1120 if (tmp->type == PLAYER)
1113 { 1121 {
1153 force->attacktype = spell_ob->attacktype; 1161 force->attacktype = spell_ob->attacktype;
1154 1162
1155 insert_ob_in_ob (force, tmp); 1163 insert_ob_in_ob (force, tmp);
1156 change_abil (tmp, force); /* Mostly to display any messages */ 1164 change_abil (tmp, force); /* Mostly to display any messages */
1157 tmp->update_stats (); 1165 tmp->update_stats ();
1166
1158 return 1; 1167 return 1;
1159} 1168}
1160 1169
1161/* This used to be part of cast_change_ability, but it really didn't make 1170/* 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 1171 * a lot of sense, since most of the values it derives are from the god
1163 * of the caster. 1172 * of the caster.
1164 */ 1173 */
1165
1166int 1174int
1167cast_bless (object *op, object *caster, object *spell_ob, int dir) 1175cast_bless (object *op, object *caster, object *spell_ob, int dir)
1168{ 1176{
1169 int i; 1177 int i;
1170 object *god = find_god (determine_god (op)), *tmp2, *force = NULL, *tmp; 1178 object *god = find_god (determine_god (op)), *tmp2, *force = NULL, *tmp;
2020 x = op->x + freearr_x[dir]; 2028 x = op->x + freearr_x[dir];
2021 y = op->y + freearr_y[dir]; 2029 y = op->y + freearr_y[dir];
2022 2030
2023 /* if there's no place to put the golem, abort */ 2031 /* 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) || 2032 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)) 2033 ((spell->other_arch->move_type & GET_MAP_MOVE_BLOCK (m, x, y)) == spell->other_arch->move_type))
2026 { 2034 {
2027 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); 2035 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way.");
2028 return 0; 2036 return 0;
2029 } 2037 }
2030 2038
2034 if (!weapon) 2042 if (!weapon)
2035 { 2043 {
2036 new_draw_info (NDI_BLACK, 0, op, "You must mark a weapon to use with this spell!"); 2044 new_draw_info (NDI_BLACK, 0, op, "You must mark a weapon to use with this spell!");
2037 return 0; 2045 return 0;
2038 } 2046 }
2039 if (spell->race && strcmp (weapon->arch->name, spell->race)) 2047 if (spell->race && strcmp (weapon->arch->archname, spell->race))
2040 { 2048 {
2041 new_draw_info (NDI_UNIQUE, 0, op, "The spell fails to transform your weapon."); 2049 new_draw_info (NDI_UNIQUE, 0, op, "The spell fails to transform your weapon.");
2042 return 0; 2050 return 0;
2043 } 2051 }
2044 if (weapon->type != WEAPON) 2052 if (weapon->type != WEAPON)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines