Crossfire Server, Branch 1.12
R12190
|
00001 /* 00002 CrossFire, A Multiplayer game for X-windows 00003 00004 Copyright (C) 2007 Crossfire Development Team 00005 Copyright (C) 1992 Frank Tore Johansen 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 2 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software 00019 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00020 00021 The authors can be reached via e-mail at crossfire-devel@real-time.com 00022 */ 00023 00028 #include <global.h> 00029 #include <ob_methods.h> 00030 #include <ob_types.h> 00031 #include <sounds.h> 00032 #include <sproto.h> 00033 00034 static method_ret spellbook_type_apply(ob_methods *context, object *lighter, object *applier, int aflags); 00035 00039 void init_type_spellbook(void) { 00040 register_apply(SPELLBOOK, spellbook_type_apply); 00041 } 00042 00064 static method_ret spellbook_type_apply(ob_methods *context, object *book, object *applier, int aflags) { 00065 object *skapplier, *spell, *spell_skill; 00066 int read_level; 00067 char level[100]; 00068 00069 /* Must be applied by a player. */ 00070 if (applier->type == PLAYER) { 00071 if (QUERY_FLAG(applier, FLAG_BLIND)&&!QUERY_FLAG(applier, FLAG_WIZ)) { 00072 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_ERROR, 00073 "You are unable to read while blind.", NULL); 00074 return METHOD_OK; 00075 } 00076 00077 skapplier = find_skill_by_name(applier, book->skill); 00078 00079 /* need a literacy skill to learn spells. Also, having a literacy level 00080 * lower than the spell will make learning the spell more difficult */ 00081 if (!skapplier) { 00082 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_ERROR, 00083 "You can't read! Your attempt fails.", NULL); 00084 return METHOD_OK; 00085 } 00086 read_level = skapplier->level; 00087 00088 spell = book->inv; 00089 if (!spell) { 00090 LOG(llevError, "apply_spellbook: Book %s has no spell in it!\n", book->name); 00091 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE, 00092 "The spellbook symbols make no sense.", NULL); 00093 return METHOD_OK; 00094 } 00095 00096 if (QUERY_FLAG(book, FLAG_CURSED) || QUERY_FLAG(book, FLAG_DAMNED)) { 00097 char name[MAX_BUF]; 00098 /* Player made a mistake, let's shake her/him :) */ 00099 int failure = -35; 00100 00101 if (settings.spell_failure_effects == TRUE) 00102 failure = -rndm(35, 100); 00103 query_name(book, name, MAX_BUF); 00104 draw_ext_info_format(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_ERROR, 00105 "The %s was %s!", 00106 "The %s was %s!", 00107 name, QUERY_FLAG(book, FLAG_DAMNED) ? "damned" : "cursed"); 00108 scroll_failure(applier, failure, (spell->level+4)*7); 00109 if (QUERY_FLAG(book, FLAG_DAMNED) 00110 && check_spell_known(applier, spell->name) 00111 && die_roll(1, 10, applier, 1) < 2) 00112 /* Really unlucky player, better luck next time */ 00113 do_forget_spell(applier, spell->name); 00114 book = decrease_ob(book); 00115 if (book && (!QUERY_FLAG(book, FLAG_IDENTIFIED))) { 00116 /* Well, not everything is lost, player now knows the 00117 * book is cursed/damned. */ 00118 identify(book); 00119 if (book->env) 00120 esrv_update_item(UPD_FLAGS|UPD_NAME, applier, book); 00121 else 00122 applier->contr->socket.update_look = 1; 00123 } 00124 return METHOD_OK; 00125 } 00126 00127 if (QUERY_FLAG(book, FLAG_BLESSED)) 00128 read_level += 5; 00129 00130 if (spell->level > (read_level+10)) { 00131 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE, 00132 "You are unable to decipher the strange symbols.", NULL); 00133 return METHOD_OK; 00134 } 00135 00136 get_levelnumber(spell->level, level, sizeof(level)); 00137 draw_ext_info_format(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_SUCCESS, 00138 "The spellbook contains the %s level spell %s.", 00139 "The spellbook contains the %s level spell %s.", 00140 level, spell->name); 00141 00142 if (!QUERY_FLAG(book, FLAG_IDENTIFIED)) { 00143 identify(book); 00144 if (book->env) 00145 esrv_update_item(UPD_FLAGS|UPD_NAME, applier, book); 00146 else 00147 applier->contr->socket.update_look = 1; 00148 } 00149 00150 /* I removed the check for special_prayer_mark here - it didn't make 00151 * a lot of sense - special prayers are not found in spellbooks, and 00152 * if the player doesn't know the spell, doesn't make a lot of sense 00153 * that they would have a special prayer mark. 00154 */ 00155 if (check_spell_known(applier, spell->name)) { 00156 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE, 00157 "You already know that spell.\n", NULL); 00158 return METHOD_OK; 00159 } 00160 00161 if (spell->skill) { 00162 spell_skill = find_skill_by_name(applier, spell->skill); 00163 if (!spell_skill) { 00164 draw_ext_info_format(NDI_UNIQUE, 0, applier, 00165 MSG_TYPE_APPLY, MSG_TYPE_APPLY_ERROR, 00166 "You lack the skill %s to use this spell", 00167 "You lack the skill %s to use this spell", 00168 spell->skill); 00169 return METHOD_OK; 00170 } 00171 if (spell_skill->level < spell->level) { 00172 draw_ext_info_format(NDI_UNIQUE, 0, applier, 00173 MSG_TYPE_APPLY, MSG_TYPE_APPLY_ERROR, 00174 "You need to be level %d in %s to learn this spell.", 00175 "You need to be level %d in %s to learn this spell.", 00176 spell->level, spell->skill); 00177 return METHOD_OK; 00178 } 00179 } 00180 00181 /* Logic as follows 00182 * 00183 * 1- MU spells use Int to learn, Cleric spells use Wisdom 00184 * 00185 * 2- The learner's skill level in literacy adjusts the chance 00186 * to learn a spell. 00187 * 00188 * 3 -Automatically fail to learn if you read while confused 00189 * 00190 * Overall, chances are the same but a player will find having a high 00191 * literacy rate very useful! -b.t. 00192 */ 00193 if (QUERY_FLAG(applier, FLAG_CONFUSED)) { 00194 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE, 00195 "In your confused state you flub the wording of the text!", NULL); 00196 scroll_failure(applier, 0-random_roll(0, spell->level, applier, PREFER_LOW), MAX(spell->stats.sp, spell->stats.grace)); 00197 } else if (QUERY_FLAG(book, FLAG_STARTEQUIP) 00198 || (random_roll(0, 100, applier, PREFER_LOW)-(5*read_level)) < learn_spell[spell->stats.grace ? applier->stats.Wis : applier->stats.Int]) { 00199 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_SUCCESS, 00200 "You succeed in learning the spell!", NULL); 00201 do_learn_spell(applier, spell, 0); 00202 00203 /* xp gain to literacy for spell learning */ 00204 if (!QUERY_FLAG(book, FLAG_STARTEQUIP)) 00205 change_exp(applier, calc_skill_exp(applier, book, skapplier), skapplier->skill, 0); 00206 } else { 00207 play_sound_player_only(applier->contr, SOUND_TYPE_SPELL, book, 0, "fumble"); 00208 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE, 00209 "You fail to learn the spell.\n", NULL); 00210 } 00211 decrease_ob(book); 00212 } 00213 return METHOD_OK; 00214 }