/**************************************************************************** * [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; }