// THOUGHT:
// Disable the code for setup(), and the functions after it? If we're
// going to be inherited, it doesn't matter much, and will give the
// book the OPTION of not being invulnerable, etc...
//
// Okay, what IS a magic book?
// It holds wizard spells. (ALWAYS)
// It can't be torn. (ALWAYS)
// Its order is randomized from time to time (DEFAULT)
// It is indexed (table of contents) (DEFAULT)
// Index is in in "wizard spells" language (DEFAULT)
// Index has " Table of Contents " header (DEFAULT)
// Index is at start of book (DEFAULT)
// It has no title page. (DEFAULT)
// Title page is in "sizard spells" language (DEFAULT)
//
// The defaults are geared according to what I assume to be the most
// common set of needs for a spell book.
//
// Except for being torn & lifted, use the following keywords:
// "spell list",
// ({
// ({spell_file_name, spell_name}),
// // ...
// })
// This introduces spells. If {spell_name} is omitted, it is
// infered from the {spell_file_name}. E.g.,
// "/w/wendell/spells/enchant" is infered to be "enchant".
//
// ENHANCEMENT to consider:
// Allow language to be specified?
//
// "random", optional_boolean
// "no random", optional_boolean
// If you use ({"random", 0}), then you will force off
// randomization of the spell order. It defaults to on,
// currently.
//
// "index used", optional_boolean
// "no index used", optional_boolean
// This controls the existance of a table of contents into the
// spell book. Useful if you randomize the book but want (some)
// players to be able to quickly find what they are looking for.
//
// "index languge", language_name_string
// This allows the index to be written in an arbitrary language
// (needed to support the different discipline books). This way,
// a spell caster might be able to read the spells, but could have
// trouble reading the index for the spells.
//
// (IMPLICITLY TURNS ON "index used")
//
// "index header", header_string
// Normally, a typically badly spelled header line is put in the
// table of contents. You may wish to change this text, and this
// permits you to do that.
//
// (IMPLICITLY TURNS ON "index used")
//
// "index at head", optional_boolean
// Well, I sometimes call it the table of contents (which belongs
// at the head of the book). Other times, I call it the index,
// and one could argue that THAT should go at the tail. This lets
// you decide for yourself.
//
// (IMPLICITLY TURNS ON "index used")
//
// "title page used", optional_boolean
// "no title page used", optional_boolean
// Let you put in a title page (probably irrelavent, with the
// book's general read message & its long description).
//
// If both exist, title-page will ALWAYS come before the index
// page.
//
// "title page", text_string
// Will let you add a title page.
//
// (IMPLICITLY TURNS ON "title page used")
//
// "title page language"
// Will let you set the langugae for the title page.
//
// (IMPLICITLY TURNS ON "title page used")
//
//
//
// All of those things might be made configurble...but for now, they all
// hold.
//
// Originally, I thought this might be taken by clone_object(), but the
// use of that seems unlikely/rare enough that I'm just going to assume
// ineritance. clone_object() would be SLIGHLY more space conservative,
// but...(shrug) You can't easily duplicate the books, then, etc.
//
// inherit MAGIC_BOOK; // /std/magic-book
//
// /*** ... ***/
//
// void setup ()
// {
// reset_get ();
// set_short ("book");
// add_adjective ("mgic");
// /*** ... ***/
// book_add_spells (SPELL_LIST);
// }
//
inherit "/std/book";
int *build_order (int num)
{
int *ret;
int i;
ret = allocate (num);
for (i = 0; i < num; ++i)
ret [i] = i;
return (ret);
}
int *reorder (int *order)
{
int i;
int max;
for (i = 0, max = sizeof (order); i < max; ++i)
{
int tmp;
int swap;
swap = random (max);
tmp = order [swap];
order [swap] = order [i];
order [i] = tmp;
}
return (order);
}
string name_from_spell (mixed *spell)
{
string ret;
switch (sizeof (spell) )
{
case 0:
ret = " <ERROR> ";
break;
case 1:
{
string *filesys_bits;
filesys_bits = explode (spell [0], "/");
ret = filesys_bits [sizeof (filesys_bits) - 1];
break;
}
default:
ret = spell [1];
break;
}
return (ret);
}
mixed *spell_list;
int *order;
string index_header;
string index_lang;
int index_used;
int index_random;
int index_at_head;
int index_page;
string title_page;
string title_page_lang;
int title_page_used;
#define MAX(a,b) ( ( (a) < (b) ) ? (b) : (a) )
#define MIN(a,b) ( ( (a) > (b) ) ? (b) : (a) )
void book_do_config (mixed *config)
{
int spell;
int spells;
string spell_index;
int max_title_len;
int spell_start_page;
spell_list = ({ });
index_header = " Table of Contents ";
index_lang = "wizard spells";
index_used = 1;
index_random = 1;
index_at_head = 1;
title_page = "";
title_page_lang = "wizard spells";
title_page_used = 0;
{
int i;
int limit;
for (i = 0, limit = sizeof (config); i < limit; ++i)
{
string opt;
int opt_is_array;
mixed *opt_array;
opt_is_array = pointerp (config [i]);
if (!opt_is_array)
opt = config [i];
else
{
opt_array = config [i];
opt = opt_array [0];
}
switch (opt)
{
case "spell list":
spell_list = opt_array [1];
break;
case "random":
index_random = opt_is_array ? opt_array [1] : 1;
break;
case "no random":
index_random = opt_is_array ? opt_array [1] : 0;
break;
case "index used":
index_used = opt_is_array ? opt_array [1] : 1;
break;
case "no index used":
index_used = opt_is_array ? opt_array [1] : 0;
break;
case "index language":
index_lang = opt_array [1];
index_used = 1; // FORCE IT ON!
break;
case "index header":
index_header = opt_array [1];
index_used = 1; // FORCE IT ON!
break;
case "index at head":
index_at_head = opt_is_array ? opt_array [1] : 1;
index_used = 1; // FORCE IT ON!
break;
case "title page used":
title_page_used = opt_is_array ? opt_array [1] : 1;
break;
case "no title page used":
title_page_used = opt_is_array ? opt_array [1] : 0;
break;
case "title page":
title_page = opt_array [1];
title_page_used = 1; // FORCE IT ON!
break;
case "title page language":
title_page_lang = opt_array [1];
title_page_used = 1; // FORCE IT ON
break;
default:
break;
}
}
}
// JIC someone slipped us a non-0, non-1 value for these...
//
index_used = !!index_used;
title_page_used = !!title_page_used;
spell_start_page = 1;
if (index_used && index_at_head)
++spell_start_page;
if (title_page_used)
++spell_start_page;
if (index_at_head)
index_page = 1;
else
index_page = spells + spell_start_page - 1;
if (title_page_used)
++index_page;
spells = sizeof (spell_list);
order = build_order (spells);
if (index_random)
order = reorder (order);
set_no_pages (spells + index_used + title_page_used);
max_title_len = strlen (index_header);
spell_index = "";
for (spell = 0; spell < spells; ++spell)
{
string spell_name;
// SHOULD expand_spell_list() (write a new function) to fill
// in default info for spell name and spell language.
//
spell_name = name_from_spell (spell_list [order [spell] ]);
set_open_page (spell + spell_start_page);
add_read_mess (spell_list [order [spell] ], 0, "wizard spells", 10);
if (index_used)
{
spell_index +=
( (spell < 8) ? " " : " ")
+ (spell + spell_start_page)
+ " ... "
+ spell_name
+ "\n";
max_title_len = MAX (max_title_len, strlen (spell_name) + 9);
}
}
if ( index_used ) {
spell_index = "\n"+ spell_index;
for ( spell = 0; spell < ( max_title_len + 1 ) / 2; spell++ )
spell_index = "=-"+ spell_index;
spell_index = "\n"+ index_header +"\n-"+ spell_index;
set_open_page(index_page);
add_read_mess(spell_index, 0, index_lang, 10);
}
if( title_page_used ) {
set_open_page( 1 );
add_read_mess( title_page, 0, title_page_lang, 10 );
}
set_open_page (0);
}
// Misc. stuff...
int do_tear(int number) { return 0; }
int query_binding_force () { return 100; }