00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00024
00025 #include "crogue.h"
00026 #include "export.h"
00027
00028 #define SPELL_TIME 4000
00029
00030 #define SPELL_INCREMENT 15
00031
00032 #define MAX_SPELL_TIME 9000
00033
00034
00035 static int numSpellsKnown(void);
00036 static int spellByIndex(int n);
00037 static void study_spell(int spell, int type);
00038 static void learn_spell(int spell);
00039 static void refresh_spell(int spell);
00040 static void spellbookString(int n, char *buf);
00041
00042 static const struct spelldesc **spell_list;
00043
00044
00045 sint study_book(ushort num_spells, ushort type, va_list spells)
00046 {
00047 const struct spelldesc *spell_data[16];
00048 int spellnum;
00049 int i;
00050 spell_list = spell_data;
00051
00052 if(w->playerclasses[w->plr.class].spellcasting[type] == 0)
00053 {
00054 if(type == SPELLTYPE_ARCANE)
00055 message(gettext("You don't understand the language."));
00056 else if(type == SPELLTYPE_DIVINE)
00057 message(gettext("This book is filled with religious mumbo-jumbo."));
00058 else if(type == SPELLTYPE_NECROMANCY)
00059 message(gettext("This book is filled with evil rituals."));
00060 return 0;
00061 }
00062
00063
00064 for(i=0; i<num_spells; i++)
00065 {
00066 spellnum = va_arg(spells, ulong);
00067 spell_data[i] = &w->spelldescs[spellnum];
00068 }
00069
00070 message(gettext("Study which spell?"));
00071 setTabStops(spell_menu_tabs);
00072 spellnum = UI_Menu_Pick(learn_spell_rect, num_spells, &spellbookString, 0);
00073 full_redraw();
00074
00075 if(spellnum < 0)
00076 {
00077 message(gettext("Never mind."));
00078 return 0;
00079 }
00080 else
00081 {
00082 study_spell(spell_data[spellnum]->num, type);
00083 return 1;
00084 }
00085 }
00086
00087
00088
00089 static void study_spell(int spell, int type)
00090 {
00091 int i;
00092 int read_success;
00093 int slots_used = 1;
00094
00095 if( w->spelldescs[spell].difficulty >
00096 (w->playerclasses[w->plr.class].spellcasting[type]
00097 + w->plr.extrinsic[STAT_WILLPOWER]/4) * w->plr.level / 3
00098 ||
00099 w->spelldescs[spell].pp_cost > w->plr.pps_max
00100 )
00101 read_success = 0;
00102 else
00103 read_success = 1;
00104
00105 if(w->plr.spellknowledge[spell] > (slong)(w->time) + SPELL_TIME + 500)
00106 {
00107 message(gettext("You know that spell practically by heart."));
00108 return;
00109 }
00110 else if(w->plr.spellknowledge[spell] > (slong)(w->time) + (SPELL_TIME/2))
00111 {
00112 message(gettext("You know that spell already."));
00113 return;
00114 }
00115 else if(w->plr.spellknowledge[spell] >= 0)
00116 {
00117 read_success = 1;
00118 slots_used = 0;
00119 }
00120
00121 if( read_success == 0 )
00122 {
00123 message(gettext("That spell is beyond your ability."));
00124 return;
00125 }
00126
00127 if( slots_used &&
00128 numSpellsKnown() >= (w->playerclasses[w->plr.class].spellcasting[type]
00129 * (w->plr.level+1))/20 )
00130 {
00131 if(w->plr.extrinsic[STAT_FLAGS] & STAT_FLAG_HALLUCINATING)
00132 message(gettext("Sorry, Mr. Osbourne, but my brain is full."));
00133 else
00134 message(gettext("You can't learn any more spells yet."));
00135 return;
00136 }
00137
00138 w->interrupt = 0;
00139 for(i=0; i<w->spelldescs[spell].difficulty; i++)
00140 {
00141 timepass(1);
00142 if(w->interrupt)
00143 {
00144 message(gettext("Your concentration is broken."));
00145 return;
00146 }
00147 }
00148
00149 if(slots_used)
00150 learn_spell(spell);
00151 else
00152 refresh_spell(spell);
00153 }
00154
00155
00156 static void refresh_spell(int spell)
00157 {
00158 w->plr.spellknowledge[spell] = (slong)(w->time + SPELL_TIME);
00159 message(gettext("You refresh your memory of the '%s' spell."),
00160 deref_file_ptr(w->spelldescs[spell].name));
00161 }
00162
00163
00164 static void learn_spell(int spell)
00165 {
00166 w->plr.spellknowledge[spell] = (slong)(w->time + SPELL_TIME);
00167 message(gettext("You learn the '%s' spell."),
00168 deref_file_ptr(w->spelldescs[spell].name));
00169 call_genericfunc(w->spelldescs[spell].learn_func);
00170 }
00171
00172
00173
00174 void init_spells(void)
00175 {
00176 int i;
00177
00178 w->plr.spellknowledge = debug_malloc( sizeof(slong)*w->desc.numspells );
00179
00180 for(i=0; i<w->desc.numspells; i++)
00181 w->plr.spellknowledge[i] = -1;
00182 }
00183
00184
00185 static int numSpellsKnown(void)
00186 {
00187 int i, n=0;
00188
00189 for(i=0; i<w->desc.numspells; i++)
00190 if(w->plr.spellknowledge[i] != -1) n++;
00191
00192 return n;
00193 }
00194
00195
00196 static int spellByIndex(int n)
00197 {
00198 int i;
00199
00200 for(i=0; n>=0; i++) {
00201 if(w->plr.spellknowledge[i] != -1)
00202 n--;
00203 }
00204
00205 return i-1;
00206 }
00207
00208
00209 static void spellString(int n, char *buf)
00210 {
00211 const struct spelldesc *s;
00212 const char *spell_status;
00213 int spell_index = spellByIndex(n);
00214
00215 s = &w->spelldescs[spell_index];
00216
00217 if(w->plr.spellknowledge[spell_index] > w->time + 800)
00218 spell_status = gettext("memorized");
00219 else if(w->plr.spellknowledge[spell_index] >= w->time)
00220 spell_status = gettext("known");
00221 else
00222 spell_status = gettext("forgotten");
00223
00224 #ifdef IS_CALCULATOR
00225 sprintf(buf, "%i\t%s\t" "%i " gettext("pp") "\t" "%s", (n+1)%10, (const char*)deref_file_ptr(s->name), s->pp_cost, spell_status);
00226 #else
00227 sprintf(buf, "%s\t" "%i " gettext("pp") "\t" "%s", (const char*)deref_file_ptr(s->name), s->pp_cost, spell_status);
00228 #endif
00229 }
00230
00231
00232 static void spellbookString(int n, char *buf)
00233 {
00234 const struct spelldesc *s;
00235
00236 s = spell_list[n];
00237
00238 #ifdef IS_CALCULATOR
00239 sprintf(buf, "%i\t%s\t%i " gettext("pp") "\t", (n+1)%10, (const char*)deref_file_ptr(s->name), s->pp_cost);
00240 #else
00241 sprintf(buf, "%s\t%i " gettext("pp") "\t", (const char*)deref_file_ptr(s->name), s->pp_cost);
00242 #endif
00243 }
00244
00245
00246
00247 void cast_spell(void)
00248 {
00249 int which;
00250
00251 if(!numSpellsKnown())
00252 {
00253 message(gettext("You don\'t know any spells."));
00254 return;
00255 }
00256
00257 if(w->plr.extrinsic[STAT_FLAGS] & STAT_FLAG_CONFUSED)
00258 {
00259 message(gettext("You are too confused to cast spells!"));
00260 return;
00261 }
00262
00263 setTabStops(spell_menu_tabs);
00264 which = UI_Menu_Pick( cast_spell_rect, numSpellsKnown(), &spellString, 0 );
00265 full_redraw();
00266
00267 if(which==-1)
00268 {
00269 message(gettext("Never mind."));
00270 return;
00271 }
00272
00273 which = spellByIndex(which);
00274
00275 if(w->plr.spellknowledge[which] < w->time)
00276 {
00277 message(gettext("You've forgotten that spell.\n"));
00278 return;
00279 }
00280
00281 if(w->plr.pps < w->spelldescs[which].pp_cost)
00282 {
00283 message(gettext("You don\'t have enough power to cast that spell."));
00284 return;
00285 }
00286 w->plr.spellknowledge[which]+=SPELL_INCREMENT*w->spelldescs[which].pp_cost;
00287 if(w->plr.spellknowledge[which] > w->time+MAX_SPELL_TIME)
00288 w->plr.spellknowledge[which] = w->time+MAX_SPELL_TIME;
00289 w->plr.pps -= w->spelldescs[which].pp_cost;
00290
00291 call_genericfunc(w->spelldescs[which].function);
00292
00293 timepass(1);
00294 }
00295
00296