home *** CD-ROM | disk | FTP | other *** search
- /* splbook.cpp: routines for spell and spellbook manipulation
-
- Copyright (C) 1993, 1994 John-Marc Chandonia
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "splbook.hpp"
- #include "general.hpp"
-
- // get a spell description from the appropriate file
- void spell::get_desc() {
- char buffer[256];
- FILE *infile;
-
- if ((infile=fopen(source_file,"r"))==NULL)
- return;
-
- fsetpos(infile,&desc_pos);
-
- fgets_no_cr(buffer,256,infile);
- while ((strncmp(buffer,"-----",5)!=0) && (!feof(infile))) {
- add_desc(buffer);
- fgets_no_cr(buffer,256,infile);
- }
-
- fclose(infile);
-
- desc_loaded=true;
- }
-
- // kill off a spell's description
- void spell::kill_desc() {
- int i;
-
- for (i=0; i<lines; i++)
- delete(description[i]);
- lines=0;
-
- desc_loaded=false;
- }
-
- // search for a string in the description
- // if ignore_case, have string in upper case to save time!
- boolean spell::desc_search(char *str, boolean ignore_case) {
- int i;
- char *tmpstr;
-
- if (desc_loaded==false) get_desc();
- if (ignore_case) {
- for (i=0; i<lines; i++) {
- tmpstr=strdup(description[i]);
- upstr(tmpstr);
- if (strstr(tmpstr,str)!=0) return(true);
- }
- }
- else for (i=0; i<lines; i++)
- if (strstr(description[i],str)!=0) return(true);
-
- kill_desc();
-
- return(false);
- }
-
- spell::spell() {
- name=source=range=area=NULL;
- type=' ';
- level= -1;
- lines=0;
- desc_loaded=false;
- }
-
- spell::~spell() {
- if (name) delete(name);
- if (source) delete(source);
- if (source_file) delete(source_file);
- if (range) delete(range);
- if (area) delete(area);
- for (int i=0; i<lines; i++)
- delete(description[i]);
- }
-
- void spell::add_desc(char *x) {
- if (lines>255) return;
-
- // kluge to remove " " as a description... take out space.
- if ((strlen(x)==2) && (x[0]==' ')) {
- description[lines]=new char[strlen(x)];
- strcpy(description[lines++],x+1);
- }
- else {
- description[lines]=new char[strlen(x)+1];
- strcpy(description[lines++],x);
- }
- }
-
- magespell::magespell() {
- school=components=duration=casttime=save=NULL;
- reversible=false;
- type='M';
- };
-
- magespell::~magespell() {
- if (school) delete(school);
- if (components) delete(components);
- if (duration) delete(duration);
- if (casttime) delete(casttime);
- if (save) delete(save);
- };
-
- void magespell::print_stats() {
- printf("%s (%s)\r\n",name,school);
- if (reversible) printf("Reversible\r\n");
- printf(" from %s\r\n",source);
- printf("Range: %s\r\n",range);
- printf("Components: %s\r\n",components);
- printf("Duration: %s\r\n",duration);
- printf("Casting Time: %s\r\n",casttime);
- printf("Area of Effect: %s\r\n",area);
- printf("Saving Throw: %s\r\n",save);
- }
-
- void magespell::f_print(FILE *outfile) {
- if (desc_loaded==false) get_desc();
-
- fprintf(outfile,"%s (%s)\n",name,school);
- if (reversible) fprintf(outfile,"Reversible\n");
- if (source) fprintf(outfile," from %s\n",source);
- fprintf(outfile,"Level: %d\n",level);
- if (range) fprintf(outfile,"Range: %s\n",range);
- if (components) fprintf(outfile,"Components: %s\n",components);
- if (duration) fprintf(outfile,"Duration: %s\n",duration);
- if (casttime) fprintf(outfile,"Casting Time: %s\n",casttime);
- if (area) fprintf(outfile,"Area of Effect: %s\n",area);
- if (save) fprintf(outfile,"Saving Throw: %s\n",save);
- fprintf(outfile,"\n");
- for (int i=0; i<lines; i++)
- fprintf(outfile,"%s\n",description[i]);
-
- kill_desc();
- }
-
- void magespell::s_print(char *buffer) {
- int i;
-
- if (desc_loaded==false) get_desc();
-
- sprintf(buffer,"%s (%s)\n",name,school);
- i=strlen(buffer);
- if (reversible) sprintf(buffer+i,"Reversible\n");
- i=strlen(buffer);
- if (source) sprintf(buffer+i," from %s\n",source);
- i=strlen(buffer);
- sprintf(buffer+i,"Level: %d\n",level);
- i=strlen(buffer);
- if (range) sprintf(buffer+i,"Range: %s\n",range);
- i=strlen(buffer);
- if (components) sprintf(buffer+i,"Components: %s\n",components);
- i=strlen(buffer);
- if (duration) sprintf(buffer+i,"Duration: %s\n",duration);
- i=strlen(buffer);
- if (casttime) sprintf(buffer+i,"Casting Time: %s\n",casttime);
- i=strlen(buffer);
- if (area) sprintf(buffer+i,"Area of Effect: %s\n",area);
- i=strlen(buffer);
- if (save) sprintf(buffer+i,"Saving Throw: %s\n",save);
- i=strlen(buffer);
- sprintf(buffer+i," \n");
- i=strlen(buffer);
- for (int j=0; j<lines; j++) {
- if ((strlen(description[j])==0) ||
- ((strlen(description[j])==1) && (description[j][0]==' ')))
- sprintf(buffer+i," \n");
- else {
- sprintf(buffer+i,"%s ",description[j]);
- i=strlen(buffer);
- if ((j<lines-1) &&
- ((description[j+1][0]==' ') ||
- (strlen(description[j+1])<2) ||
- (description[j+1][0]=='\t')))
- sprintf(buffer+i," \n");
- }
- i=strlen(buffer);
- }
- kill_desc();
- }
-
- void magespell::f_print_header(FILE *outfile) {
- fprintf(outfile,"%17.17s ",name);
- if (reversible) fprintf(outfile,"(R) ");
- else fprintf(outfile," ");
- fprintf(outfile,"%5.5s ",casttime);
- fprintf(outfile,"%7.7s ",components);
- fprintf(outfile,"%15.15s ",range);
- fprintf(outfile,"%15.15s ",duration);
- fprintf(outfile,"%15.15s ",area);
- fprintf(outfile,"%4.4s ",save);
- fprintf(outfile,"\n");
- }
-
- void magespell::quicksave(FILE *outfile) {
- fprintf(outfile,"M\n");
- fprintf(outfile,"%s\n",name);
- fprintf(outfile,"%s\n",source_file);
- fprintf(outfile,"%s\n",school);
- if (reversible) fprintf(outfile,"R\n");
- else fprintf(outfile,"N\n");
- if (source) fprintf(outfile,"%s",source);
- fprintf(outfile,"\n");
- fprintf(outfile,"%d\n",level);
- fprintf(outfile,"%s\n",range);
- fprintf(outfile,"%s\n",components);
- fprintf(outfile,"%s\n",duration);
- fprintf(outfile,"%s\n",casttime);
- fprintf(outfile,"%s\n",area);
- fprintf(outfile,"%s\n",save);
- fprintf(outfile,"%d\n",lines);
- fwrite(&desc_pos,sizeof(fpos_t),1,outfile);
- }
-
- // load magespell, with "M" line already read
- void magespell::quickload(FILE *infile) {
- char buffer[256];
-
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) name = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) source_file = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) school = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]=='R') reversible=true;
- else reversible = false;
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) source = strdup(buffer);
- fgets(buffer,256,infile);
- sscanf(buffer,"%d",&level);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) range = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) components = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) duration = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) casttime = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) area = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) save = strdup(buffer);
- fgets(buffer,256,infile);
- sscanf(buffer,"%d",&lines);
- fread(&desc_pos,sizeof(fpos_t),1,infile);
- }
-
- void magespell::f_read(FILE *infile) {
- char buffer[256];
-
- do {
- fgets_no_cr(buffer,256,infile);
- } while ((strlen(buffer)<=1) && !feof(infile));
- if (feof(infile)) return;
-
- char *l=strrchr(buffer,'(');
- char *m=strrchr(buffer,')');
- if ((m==NULL) || (l==NULL)) {
- if (buffer[0]!=(char)0) name = strdup(buffer);
- }
- else {
- int namelen=strlen(buffer)-strlen(l);
- name=new char[namelen];
- name[namelen-1]=(char)0;
- strncpy(name,buffer,namelen-1);
- int schoollen=strlen(l)-strlen(m);
- school=new char[schoollen];
- school[schoollen-1]=(char)0;
- strncpy(school,l+1,schoollen-1);
- }
- fgets_no_cr(buffer,256,infile);
- if (strncmp(buffer,"Reversible",10)==0) {
- reversible=true;
- fgets_no_cr(buffer,256,infile);
- }
- while ((strlen(buffer)>2) && !feof(infile)) {
- if (strstr(buffer,"Range:"))
- range=strdup(buffer+7);
- else if (strstr(buffer,"Components:"))
- components=strdup(buffer+12);
- else if (strstr(buffer,"Duration:"))
- duration=strdup(buffer+10);
- else if (strstr(buffer,"Casting Time:"))
- casttime=strdup(buffer+14);
- else if (strstr(buffer,"Area of Effect:"))
- area=strdup(buffer+16);
- else if (strstr(buffer,"Saving Throw:"))
- save=strdup(buffer+14);
- else if (strstr(buffer,"School:"))
- school=strdup(buffer+8);
- else if (strstr(buffer," from "))
- source=strdup(buffer+7);
- else if (strstr(buffer,"Level:"))
- sscanf(buffer+7,"%d",&level);
-
- fgets_no_cr(buffer,256,infile);
- }
- fgetpos(infile,&desc_pos);
- while ((strncmp(buffer,"-----",5)!=0) && !feof(infile)) {
- fgets(buffer,256,infile);
- }
- }
-
- priestspell::priestspell() {
- sphere=NULL;
- type='P';
- };
-
- priestspell::~priestspell() {
- delete(sphere);
- };
-
- void priestspell::print_stats() {
- printf("%s (%s)\r\n",name,school);
- if (reversible) printf("Reversible\r\n");
- printf(" from %s\r\n",source);
- printf("Sphere: %s\r\n",sphere);
- printf("Range: %s\r\n",range);
- printf("Components: %s\r\n",components);
- printf("Duration: %s\r\n",duration);
- printf("Casting Time: %s\r\n",casttime);
- printf("Area of Effect: %s\r\n",area);
- printf("Saving Throw: %s\r\n",save);
- }
-
- void priestspell::f_print(FILE *outfile) {
- if (desc_loaded==false) get_desc();
-
- fprintf(outfile,"%s (%s)\n",name,school);
- if (reversible) fprintf(outfile,"Reversible\n");
- if (source) fprintf(outfile," from %s\n",source);
- fprintf(outfile,"Level: %d\n",level);
- if (sphere) fprintf(outfile,"Sphere: %s\n",sphere);
- if (range) fprintf(outfile,"Range: %s\n",range);
- if (components) fprintf(outfile,"Components: %s\n",components);
- if (duration) fprintf(outfile,"Duration: %s\n",duration);
- if (casttime) fprintf(outfile,"Casting Time: %s\n",casttime);
- if (area) fprintf(outfile,"Area of Effect: %s\n",area);
- if (save) fprintf(outfile,"Saving Throw: %s\n",save);
- fprintf(outfile,"\n");
- for (int i=0; i<lines; i++)
- fprintf(outfile,"%s\n",description[i]);
- kill_desc();
- }
-
- void priestspell::s_print(char *buffer) {
- int i;
-
- if (desc_loaded==false) get_desc();
-
- sprintf(buffer,"%s (%s)\n",name,school);
- i=strlen(buffer);
- if (reversible) sprintf(buffer+i,"Reversible\n");
- i=strlen(buffer);
- if (source) sprintf(buffer+i," from %s\n",source);
- i=strlen(buffer);
- sprintf(buffer+i,"Level: %d\n",level);
- i=strlen(buffer);
- if (sphere) sprintf(buffer+i,"Sphere: %s\n",sphere);
- i=strlen(buffer);
- if (range) sprintf(buffer+i,"Range: %s\n",range);
- i=strlen(buffer);
- if (components) sprintf(buffer+i,"Components: %s\n",components);
- i=strlen(buffer);
- if (duration) sprintf(buffer+i,"Duration: %s\n",duration);
- i=strlen(buffer);
- if (casttime) sprintf(buffer+i,"Casting Time: %s\n",casttime);
- i=strlen(buffer);
- if (area) sprintf(buffer+i,"Area of Effect: %s\n",area);
- i=strlen(buffer);
- if (save) sprintf(buffer+i,"Saving Throw: %s\n",save);
- i=strlen(buffer);
- sprintf(buffer+i," \n");
- i=strlen(buffer);
- for (int j=0; j<lines; j++) {
- if ((strlen(description[j])==0) ||
- ((strlen(description[j])==1) && (description[j][0]==' ')))
- sprintf(buffer+i," \n");
- else {
- sprintf(buffer+i,"%s ",description[j]);
- i=strlen(buffer);
- if ((j<lines-1) &&
- ((description[j+1][0]==' ') ||
- (strlen(description[j+1])<2) ||
- (description[j+1][0]=='\t')))
- sprintf(buffer+i," \n");
- }
- i=strlen(buffer);
- }
- kill_desc();
- }
-
- void priestspell::f_print_header(FILE *outfile) {
- fprintf(outfile,"%17.17s ",name);
- if (reversible) fprintf(outfile,"(R) ");
- else fprintf(outfile," ");
- fprintf(outfile,"15.15s ",school);
- fprintf(outfile,"%5.5s ",casttime);
- fprintf(outfile,"%7.7s ",components);
- fprintf(outfile,"%15.15s ",range);
- fprintf(outfile,"%15.15s ",duration);
- fprintf(outfile,"%15.15s ",area);
- fprintf(outfile,"%4.4s ",save);
- fprintf(outfile,"\n");
- }
-
- void priestspell::quicksave(FILE *outfile) {
- fprintf(outfile,"P\n");
- fprintf(outfile,"%s\n",name);
- fprintf(outfile,"%s\n",source_file);
- fprintf(outfile,"%s\n",school);
- fprintf(outfile,"%s\n",sphere);
- if (reversible) fprintf(outfile,"R\n");
- else fprintf(outfile,"N\n");
- if (source) fprintf(outfile,"%s",source);
- fprintf(outfile,"\n");
- fprintf(outfile,"%d\n",level);
- fprintf(outfile,"%s\n",range);
- fprintf(outfile,"%s\n",components);
- fprintf(outfile,"%s\n",duration);
- fprintf(outfile,"%s\n",casttime);
- fprintf(outfile,"%s\n",area);
- fprintf(outfile,"%s\n",save);
- fprintf(outfile,"%d\n",lines);
- fwrite(&desc_pos,sizeof(fpos_t),1,outfile);
- }
-
- // load priestspell, with "P" line already read
- void priestspell::quickload(FILE *infile) {
- char buffer[256];
-
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) name = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) source_file = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) school = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) sphere = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]=='R') reversible=true;
- else reversible = false;
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) source = strdup(buffer);
- fgets(buffer,256,infile);
- sscanf(buffer,"%d",&level);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) range = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) components = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) duration = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) casttime = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) area = strdup(buffer);
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) save = strdup(buffer);
- fgets(buffer,256,infile);
- sscanf(buffer,"%d",&lines);
- fread(&desc_pos,sizeof(fpos_t),1,infile);
- }
-
- void priestspell::f_read(FILE *infile) {
- char buffer[256];
-
- do {
- fgets_no_cr(buffer,256,infile);
- } while ((strlen(buffer)<=1) && !feof(infile));
- if (feof(infile)) return;
-
- char *l=strrchr(buffer,'(');
- char *m=strrchr(buffer,')');
- if ((m==NULL) || (l==NULL)) {
- if (buffer[0]!=(char)0) name = strdup(buffer);
- }
- else {
- int namelen=strlen(buffer)-strlen(l);
- name=new char[namelen];
- name[namelen-1]=(char)0;
- strncpy(name,buffer,namelen-1);
- int schoollen=strlen(l)-strlen(m);
- school=new char[schoollen];
- school[schoollen-1]=(char)0;
- strncpy(school,l+1,schoollen-1);
- }
- fgets_no_cr(buffer,256,infile);
- if (strncmp(buffer,"Reversible",10)==0) {
- reversible=true;
- fgets_no_cr(buffer,256,infile);
- }
- while ((strlen(buffer)>1) && !feof(infile)) {
- if (strstr(buffer,"Range:"))
- range=strdup(buffer+7);
- else if (strstr(buffer,"Components:"))
- components=strdup(buffer+12);
- else if (strstr(buffer,"Duration:"))
- duration=strdup(buffer+10);
- else if (strstr(buffer,"Casting Time:"))
- casttime=strdup(buffer+14);
- else if (strstr(buffer,"Area of Effect:"))
- area=strdup(buffer+16);
- else if (strstr(buffer,"Saving Throw:"))
- save=strdup(buffer+14);
- else if (strstr(buffer,"Sphere:"))
- sphere=strdup(buffer+8);
- else if (strstr(buffer,"School:"))
- school=strdup(buffer+8);
- else if (strstr(buffer," from "))
- source=strdup(buffer+7);
- else if (strstr(buffer,"Level:"))
- sscanf(buffer+7,"%d",&level);
-
- fgets_no_cr(buffer,256,infile);
- }
- fgetpos(infile,&desc_pos);
- while ((strncmp(buffer,"-----",5)!=0) && !feof(infile)) {
- fgets(buffer,256,infile);
- }
- }
-
- void priest_to_mage(magespell &y, priestspell &x) {
- if (x.name) y.name=strdup(x.name);
- y.level=x.level;
- if (x.range) y.range=strdup(x.range);
- if (x.area) y.area=strdup(x.area);
- if (x.source) y.source=strdup(x.source);
- if (x.source_file) y.source_file=strdup(x.source_file);
- y.desc_pos=x.desc_pos;
- if (x.school) y.school=strdup(x.school);
- if (x.duration) y.duration=strdup(x.duration);
- if (x.components) y.components=strdup(x.components);
- if (x.casttime) y.casttime=strdup(x.casttime);
- if (x.save) y.save=strdup(x.save);
- y.reversible=x.reversible;
- for (int i=0; i<x.lines; i++)
- y.add_desc(x.description[i]);
- }
-
- spellbook::spellbook() {
- first=last=NULL;
- name=NULL;
- }
-
- spellbook::spellbook(spellbook &s) {
- first=last=NULL;
- if (s.name) name=strdup(s.name);
- else name=NULL;
- *this += s;
- }
-
- spellbook::~spellbook() {
- spelllist *i=first;
- spelllist *j;
-
- while (i!=NULL) {
- j=i->next;
- delete i;
- i=j;
- }
- if (name) delete name;
- }
-
- spelllist *spellbook::add_spell(spell &x, spelllist *where) {
- spelllist *sl;
-
- sl=new spelllist;
-
- // spell is given.
- sl->s=&x;
-
- if (where==NULL) { // add at end.
- sl->next=NULL;
- sl->prev=last;
- if (last!=NULL) last->next=sl;
- if (first==NULL) first=sl;
- last=sl;
- } else { // add after "where"
- sl->next=where->next;
- sl->prev=where;
- if (where->next!=NULL) where->next->prev=sl;
- where->next=sl;
- if (where==last) last=sl;
- }
- return(sl);
- }
-
-
- // delete a spell given its spelllist entry
- void spellbook::del_spell(spelllist *sl) {
- if (sl->next!=NULL) sl->next->prev=sl->prev;
- if (sl->prev!=NULL) sl->prev->next=sl->next;
- if (first==sl) first=sl->next;
- if (last==sl) last=sl->prev;
- delete sl;
- }
-
- // find and delete one reference to spell x in book
- void spellbook::del_spell(spell &x) {
- spelllist *i;
-
- for (i=first; i!=NULL; i=i->next)
- if (i->s==&x) {
- del_spell(i);
- return;
- }
- }
-
- spellbook& spellbook::operator +=(spell &x) {
- add_spell(x);
- return(*this);
- }
-
- spellbook& spellbook::operator +=(spellbook &x) {
- for (spelllist *i=x.first; i!=NULL; i=i->next)
- add_spell(*(i->s));
- return(*this);
- }
-
- spellbook& spellbook::operator -=(spell &x) {
- del_spell(x);
- return(*this);
- }
-
- spellbook& spellbook::operator -=(spellbook &x) {
- for (spelllist *i=x.first; i!=NULL; i=i->next)
- del_spell(*(i->s));
- return(*this);
- }
-
- // read full spell listings; return number of spells that
- // contained errors.
- // return -1 if can't read the file
- int spellbook::read_book(char *filename) {
- FILE *infile;
- fpos_t pos;
- char buffer[256];
- int errors = 0;
-
- // clear out old book, if present.
- this->~spellbook();
- first=last=NULL;
- name=NULL;
- if ((infile=fopen(filename,"r"))==NULL) return(-1);
-
- // get spellbook name from first line of file, if there
- fgetpos(infile,&pos);
- fgets_no_cr(buffer,256,infile);
- if (strstr(buffer,"Title: ")==NULL) {
- name=NULL;
- fsetpos(infile,&pos);
- }
- else name=strdup(buffer+8);
-
- while (!feof(infile)) {
- priestspell *x;
- x = new priestspell;
- x->f_read(infile);
- if (x->level== -1) errors++;
- else {
- x->source_file=strdup(filename);
- if (x->sphere) add_spell(*x);
- else { // was actually a magespell.
- magespell *y;
- y=new magespell;
- priest_to_mage(*y,*x);
- add_spell(*y);
- delete x;
- }
- }
- }
- fclose(infile);
- return(errors);
- }
-
- boolean spellbook::quickload(char *filename) {
- FILE *infile;
- char buffer[256];
- priestspell *ps;
- magespell *ms;
-
- // clear out old book, if present.
- this->~spellbook();
- first=last=NULL;
- name=NULL;
- if ((infile=fopen(filename,"rb"))==NULL) return(false);
-
- // get spellbook name from first line of file
- fgets_no_cr(buffer,256,infile);
- if (buffer[0]!=(char)0) name=strdup(buffer);
- else name=NULL;
-
- fgets(buffer,256,infile);
- while (!feof(infile)) {
- if (buffer[0]=='M') {
- ms = new magespell;
- ms->quickload(infile);
- add_spell(*ms);
- }
- else {
- ps = new priestspell;
- ps->quickload(infile);
- add_spell(*ps);
- }
- fgets(buffer,256,infile);
- }
-
- fclose(infile);
- return(true);
- }
-
- boolean spellbook::quicksave(char *filename) {
- FILE *outfile;
-
- if ((outfile=fopen(filename,"wb"))==NULL) return(false);
-
- if (name) fprintf(outfile,"%s",name);
- fprintf(outfile,"\n");
-
- for (spelllist *i=first; i!=NULL; i=i->next)
- i->s->quicksave(outfile);
-
- fclose(outfile);
- return(true);
- }
-
- // look up a spell by title.
- spell *spellbook::lookup(char *sname) {
- for (spelllist *i=first; i!=NULL; i=i->next)
- if (strcmp(i->s->name,sname)==0) return(i->s);
- return(NULL);
- }
-
- // read spellbook from list of spells... return number of spells
- // not found in masterlist
- // return -1 if unopenable file.
- int spellbook::read_titles(char *filename, spellbook *masterlist) {
- FILE *infile;
- fpos_t pos;
- char buffer[256];
- int errors=0;
-
- // clear out old book, if present.
- this->~spellbook();
- first=last=NULL;
- name=NULL;
- if ((infile=fopen(filename,"r"))==NULL) return(-1);
-
- // get spellbook name from first line of file, if there
- fgetpos(infile,&pos);
- fgets_no_cr(buffer,256,infile);
- if (strstr(buffer,"Title: ")==NULL) {
- name=NULL;
- fsetpos(infile,&pos);
- }
- else name=strdup(buffer+8);
-
- while (!feof(infile)) {
- fgets_no_cr(buffer,256,infile);
- if (!feof(infile)) {
- spell *ns;
- ns=masterlist->lookup(buffer);
- if (ns==NULL) errors++;
- else add_spell(*ns);
- }
- }
- fclose(infile);
- return(errors);
- }
-
- // return 0 if OK, -1 if error.
- int spellbook::print_titles(char *filename) {
- FILE *outfile;
-
- if ((outfile=fopen(filename,"w"))==NULL)
- return(-1);
-
- if (name) fprintf(outfile,"Title: %s\n",name);
- else fprintf(outfile,"\n");
- for (spelllist *i=first; i!=NULL; i=i->next)
- fprintf(outfile,"%s\n",i->s->name);
-
- fclose(outfile);
- return(0);
- }
-
- // save an entire spellbook
- // return 0 if ok, -1 if error.
- int spellbook::print_book(char *filename) {
- FILE *outfile;
-
- if ((outfile=fopen(filename,"w"))==NULL)
- return(-1);
-
- if (name) fprintf(outfile,"Title: %s\n",name);
- for (spelllist *i=first; i!=NULL; i=i->next) {
- i->s->f_print(outfile);
- if (i->next!=NULL) fprintf(outfile,"-----\n");
- }
-
- fclose(outfile);
- return(0);
- }
-
- // print out abbreviated spellbook
- boolean spellbook::print_abbrev(char *filename) {
- FILE *outfile;
-
- if ((outfile=fopen(filename,"w"))==NULL)
- return(false);
-
- if (name) fprintf(outfile,"%s\n",name);
- else fprintf(outfile,"\n");
- for (spelllist *i=first; i!=NULL; i=i->next) {
- i->s->f_print_header(outfile);
- }
-
- fclose(outfile);
- return(true);
- }
-
- // read in a book, guessing if full or title list.
- // return # of spells unreadable.
- // return -1 if other error
- int spellbook::read(char *filename, spellbook *masterlist) {
- int rc;
-
- rc = read_book(filename);
- if (rc==0) return(0);
- this->~spellbook();
- first=last=NULL;
- name=NULL;
- if (masterlist) return(read_titles(filename,masterlist));
- else return(rc);
- }
-
- // get master list of spells from file
- spellbook *get_master_list(char *master_name) {
- spellbook *ml;
- spellbook *x;
- char buffer[256];
- FILE *infile;
-
- ml=new spellbook;
- if (ml==NULL) return(NULL);
- ml->name=strdup("Master Spell List");
- x=new spellbook;
- if (x==NULL) return(NULL);
-
- if ((infile=fopen(master_name,"r"))==NULL) return(NULL);
-
- while (!feof(infile)) {
- fgets_no_cr(buffer,256,infile);
- if ((!feof(infile)) && (buffer[0]!=';')) {
- x->read_book(buffer);
- (*ml)+=(*x);
- }
- }
-
- return(ml);
- }
-
-