/****************************************************************************
* [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | \\._.// *
* -----------------------------------------------------------| (0...0) *
* SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by Derek Snider | ).:.( *
* -----------------------------------------------------------| {o o} *
* SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, | / ' ' \ *
* Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek, |~'~.VxvxV.~'~*
* Tricops and Fireblade | *
* ------------------------------------------------------------------------ *
* Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. *
* ------------------------------------------------------------------------ *
* Spell handling module *
****************************************************************************/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "mud.h"
/*
* Perform a binary search on a section of the skill table -Thoric
* Each different section of the skill table is sorted alphabetically
*
* Check for prefix matches.
*
* Made static by dchaley 2007-06-22. Nobody has any business calling the
* binary search directly; they should only use the skill_lookup or
* find_* functions. (A practical reason is that a bsearch call will
* prevent you from finding skills in the interval used for skills created
* after MUD boot.)
*/
static int bsearch_skill_prefix( const char *name, int first, int top )
{
int sn;
for( ;; )
{
sn = ( first + top ) >> 1;
if( !IS_VALID_SN( sn ) )
return -1;
if( LOWER( name[0] ) == LOWER( skill_table[sn]->name[0] ) && !str_prefix( name, skill_table[sn]->name ) )
return sn;
if( first >= top )
return -1;
if( strcasecmp( name, skill_table[sn]->name ) < 1 )
top = sn - 1;
else
first = sn + 1;
}
}
/*
* Perform a binary search on a section of the skill table -Thoric
* Each different section of the skill table is sorted alphabetically
*
* Check for exact matches only.
*
* Made static by dchaley 2007-06-22. Nobody has any business calling the
* binary search directly; they should only use the skill_lookup or
* find_* functions. (A practical reason is that a bsearch call will
* prevent you from finding skills in the interval used for skills created
* after MUD boot.)
*/
static int bsearch_skill_exact( const char *name, int first, int top )
{
int sn;
for( ;; )
{
sn = ( first + top ) >> 1;
if( !IS_VALID_SN( sn ) )
return -1;
if( !strcasecmp( name, skill_table[sn]->name ) )
return sn;
if( first >= top )
return -1;
if( strcasecmp( name, skill_table[sn]->name ) < 1 )
top = sn - 1;
else
first = sn + 1;
}
}
/*
* Lookup a skill by slot number.
* Used for object loading.
*/
int slot_lookup( int slot )
{
int sn;
if( slot <= 0 )
return -1;
for( sn = 0; sn < num_skills; ++sn )
if( slot == skill_table[sn]->slot )
return sn;
bug( "%s: bad slot %d.", __FUNCTION__, slot );
abort( );
}
/*
* Lookup a skill by name.
*
* First tries to find an exact match. Then looks for a prefix match.
* Rehauled by dchaley 2007-06-22.
*/
int skill_lookup( const char *name )
{
int sn;
// Try to find an exact match for this skill.
if( ( sn = bsearch_skill_exact( name, 0, num_sorted_skills - 1 ) ) == -1 )
{
// We failed to find an exact match;
// so try to find a prefix match.
if( ( sn = bsearch_skill_prefix( name, 0, num_sorted_skills - 1 ) ) == -1 )
{
// We failed to find the skill in the sorted skills. It is
// possible that the skill was added after the game booted;
// so try looking through the unsorted skills.
for( sn = num_sorted_skills; sn < num_skills; ++sn )
{
// have we reached the end of the skills?
if( !skill_table[sn] || !skill_table[sn]->name )
{
bug( "%s: WARNING: skill table entry %d had bad skill", __FUNCTION__, sn );
return -1;
}
// is this the one we want?
if( !str_prefix( name, skill_table[sn]->name ) )
return sn;
}
return -1;
}
}
return sn;
}