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.54 by root, Mon May 28 21:28:36 2007 UTC vs.
Revision 1.63 by root, Tue Jul 10 07:31:20 2007 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines