On Fri, 21 Sep 2001, Edward wrote: > ... I went a complex but working way, ... True. Sort of. > its bulky for certain, but it is dynamic... There are much better ways of achieving the same from the user's point of view, without being nearly as taxing. From the user's point of view, there are ways of doing better. > [... snip do_list_playerinfo() ...] General rule: It's always a bad idea to shove more information at the player than he really needs. Let him choose his desired race. Let him choose his desired class. If he decides he wants to change his mind, let him backup and choose again. Newbies will be deterred by a bunch of stats and tables that don't make a whole lot of sense to them. Veterans have seen the schlock before and know who they want to be. No one benefits from having stats flung at them. You should present the character creation sequence as being near-linear: Choose Race <-> Choose Gender <-> Roll Stats <-> Choose Class Remember to permit people ways to go _back_ and to explore the system in greater detail (by providing extension help available from the menu). But do not throw the detail at them and have them start planning their character out. Let them _navigate_ the creation process to learn it. If the system is becoming too difficult to navigate and chart a reasonable path to, you need to go back to the original credo of game design: "I shall never deceive *myself* about the direction of the game." Gain some focus and trim away the fat. People don't like needlessly expansive games because that generally means: inconsistent, unbalanced, un-fun. Ask yourself if you're mindlessly repeating a formula to follow the direction of another game. That's generally just as bad an idea. > const char *def_classes[NUM_CLASSES][1]; Why are you doing this? char *def_classes[NUM_CLASSES]; if you really wanted to. But (IMO, of course) you don't. > for (i = 0; i < NUM_CLASSES; i++) > def_classes[i][0] = str_dup("NONE"); Bluntly: you don't want to do this. You're leaking memory everywhere in your function. str_dup() obviously does not do what you think it does. The only thing str_dup() does is take a given string and duplicates it in a new, dynamic string. This means it _allocates_ memory. If you don't free this memory, then it's simply not freed at all during the MUD process's lifespan. When exactly the memory is recycled for use by the system is determined by your platform. Sane platforms (generally meaning not Win32) will reclaim the memory when the process dies, but this is not true of some other systems that never reclaim the memory and you must reboot the machine before it reappears. Fortunately, the latter sort have the useful feature of _crashing_ (the machine) to remind you that you've consumed enormous amounts of memory and should reboot. > [... snip ...] Combine the comparison with the check. There's no reason to keep them separate. Pass d->character as a char_data pointer to your function, since that's all you're using anyway. After incorporating these changes your entire parse_general_class() function becomes: int parse_general_class(struct char_data *ch, char *arg) { int i; for (i = 0; i < NUM_CLASSES; i++) if (classes[i].allowed_races[(int)GET_RACE(ch)] && classes[i].stats_needed[R_STR] <= GET_STR(ch) && classes[i].stats_needed[R_INT] <= GET_INT(ch) && classes[i].stats_needed[R_WIS] <= GET_WIS(ch) && classes[i].stats_needed[R_DEX] <= GET_DEX(ch) && classes[i].stats_needed[R_CON] <= GET_CON(ch) && classes[i].stats_needed[R_CHA] <= GET_CHA(ch) && is_abbrev(arg, classes[i].name)) return (i); return (CLASS_UNDEFINED); } -dak -- +---------------------------------------------------------------+ | FAQ: http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html | | Archives: http://post.queensu.ca/listserv/wwwarch/circle.html | +---------------------------------------------------------------+
This archive was generated by hypermail 2b30 : 12/06/01 PST