28 Sep, 2008, Kline wrote in the 1st comment:
Votes: 0
Has anybody already ripped out the skill/spell const tables most Diku* muds use and replaced it with something more dynamic? I'm looking to head in this direction soon with my code but don't have many good ideas how to go about doing it, without utterly breaking how most of the game works – the fixed slot position numbers in the table for lookups. Easy to add elements in at the bottom, but you can't fully 'remove' something in the middle, just hide it.

Any good suggestions of one way to do this vs another?
28 Sep, 2008, elanthis wrote in the 2nd comment:
Votes: 0
Well, a "proper" fix could be done in four (relatively) easy steps.

First, make the tables static and remove their declarations from the headers. This means the tables can only be accessed from the source file they're located in.

Second, write new get_class/get_race/etc. functions that take an ID and return the appropriate entry (or log an error and return NULL if the ID is out of bounds).

Third, recompile and fix all the errors in the files that try to access the tables directly but can't. It's as easy as replacing race_table[expr] with get_race(expr) and so on. If you're any good with regular expressions, you should be able to make most (if not all) of the changes with a Perl one-liner.

Fourth, replace the fixed tables and simple lookup functions with code that dynamically loads the information from files and looks them up. You can't avoid holes in the numbering without major surgery on the system, but you can avoid any potential "loss" by using a sparse data structure instead of an array. The array will be fastest though, so you might consider just living with "holes" appearing when you delete an entry. You can of course re-use IDs.

If you're of sufficient skill with C and Perl/regexes, you could probably do all that in a single sitting.
28 Sep, 2008, Davion wrote in the 3rd comment:
Votes: 0
Kline said:
Easy to add elements in at the bottom, but you can't fully 'remove' something in the middle, just hide it.
Any good suggestions of one way to do this vs another?

If you want to remove something from an array, you're kind of stuck copying the array, and leaving out the deleted. It's definitely not the worst solution if you want to stick with the array.
28 Sep, 2008, quixadhal wrote in the 4th comment:
Votes: 0
Is this the thing you're talking about?

struct spell_info_type {
char castable; /* Is it a castable spell? */
char useable; /* Is it a useable skill? */
char *name; /* Text name of spell */
void (*spell_pointer) (char level, struct char_data * ch,
char *arg, int type,
struct char_data * tar_ch,
struct obj_data * tar_obj);
char delay; /* Heartbeats until ready for next */
unsigned char min_mana; /* Amount of mana used by a spell */
unsigned char max_mana;
char minimum_position; /* Position for caster */
short int targets; /* See below for use with TAR_XXX */
char generic_level; /* Level for generic teachings */
int generic_classes; /* Classes allowed to learn generic skills */
char min_level[ABS_MAX_LVL]; /* Level required for the various classes */
/* Possible Targets:
* bit 1 : PC/NPC in room
* bit 2 : PC/NPC in world
* bit 3 : Object held
* bit 4 : Object in inventory
* bit 5 : Object in room
* bit 6 : Object in world
* bit 7 : If fighting, and no argument, select tar_char as self
* bit 8 : If fighting, and no argument, select tar_char as victim (fighting)
* bit 9 : If no argument, select self, if argument check that it IS self.

My game forked from DikuMUD Gamma and the original admins cobbled lots of bits and pieces from all kinds of places into their own stuff, so I'm not entirely sure what's "normal" and what's a frankensystem. :)

Oh, just saw elanthis' reply… if you're talking about the numbers being fixed array positions, then yes… switching to function lookups is the way to go about it. It doesn't matter what you use for a backend store (arrays, lists, a database), as long as you either don't reuse ID's unless you know nothing else relies on 37 being "Shocking Grasp", or you always pass string arguments and spend the extra cycles to strcmp() them.