/** * @@ Copyright (Wheel of Time Project) * * Wheel of Time (WoT) Mud System v0.1a * Copyright (c) 1998, by Gary McNickle * and Dark Harvest Systems * Based on ROM Mud, v2.4b4 by Russ Taylor * * By using any of the WoT source code, you agree to follow the terms of * usage and liscensing detailed in the file "liscense.wot" as well as any * and all liscensing required for ROM, Merc, and Diku Mud systems. */ /** * @@ Objective (data_h.c) * * This file contains the bulk of the /data/.dat file load/save routines. * */ #include #include #include #include #include #include #include #include "merc.h" #if defined(KEY) #undef KEY #endif #define KEY( literal, field, value ) \ if ( !str_cmp( string, literal ) ) \ { \ field = value; \ fMatch = TRUE; \ break; \ } void logf (char * fmt, ...) { char buf [2*MAX_STRING_LENGTH]; va_list args; va_start (args, fmt); vsnprintf (buf, 2*MAX_STRING_LENGTH, fmt, args); va_end (args); log_string (buf); } char *errmsg( int err ) { static char buf[13]; memset(buf, 0, 13); sprintf(buf, "%s", err == EEXIST ? "EEXIST" : err == EISDIR ? "EISDIR" : err == ETXTBSY ? "ETXTBSY" : err == EFAULT ? "EFAULT" : err == EACCES ? "EACCES" : err == ENAMETOOLONG ? "ENAMETOOLONG" : err == ENOENT ? "ENOENT" : err == ENOTDIR ? "ENOTDIR" : err == EMFILE ? "EMFILE" : err == ENFILE ? "ENFILE" : err == ENOMEM ? "ENOMEM" : err == EROFS ? "EROFS" : err == ELOOP ? "ELOOP" : err == ENOSPC ? "ENOSPC" : "(unknown)"); return buf; } /** Function: save_skills * Descr : Saves the skill_table to /data/skills.dat for later * : editing of appropriate fields (ie: not spell_fun or gsn) * Returns : TRUE/FALSE on success * Syntax : void * Written : v1.0 01/99 * Author : Gary McNickle */ bool save_skills( void ) { FILE *fp; char buf[MIL]; sh_int count; sh_int i; sprintf(buf, "%s%s", DATA_DIR, SKILL_DATA_FILE); if (!(fp=fopen(buf, "w"))) { logf("[%s] Could not open file %s in order to save skill table data.", errmsg(errno), buf); return FALSE; } fprintf(fp, "#\n"); fprintf(fp, "## Skill Table Data file\n## Written %s", ctime(¤t_time)); fprintf(fp, "## Contains %d skills.\n", MAX_SKILL); fprintf(fp, "## File Format\n#\n"); fprintf(fp, "# Skill // The Name of this skill.\n"); fprintf(fp, "# sLevels // The level each class may use this skill at.\n"); fprintf(fp, "# sRates // The rate at wich a class improves in this skill\n"); fprintf(fp, "# // and also the creation cost per class.\n"); fprintf(fp, "# Targets // Determines what/who this skill may be used on\n"); fprintf(fp, "# MinPos // The minimum position the user must be in to use this skill.\n"); fprintf(fp, "# MinMana // The recommended mana for this spell.\n"); fprintf(fp, "# Beats // The # of pulses to pause the user after using this skill.\n"); fprintf(fp, "# DamMsg // The damage message used when successful.\n"); fprintf(fp, "# MsgOff // The message sent to the user when the skill wears off.\n"); fprintf(fp, "# MsgObj // The message seen when the skill wears off of an object.\n"); fprintf(fp, "#\n"); for (count = 0; count < MAX_SKILL; count++) { if ( IS_SET(skill_table[count].flags, GROUP_CHANGED) ) REMOVE_BIT(skill_table[count].flags, GROUP_CHANGED); if ( skill_table[count].name ) { fprintf(fp, "Skill %s~\n", skill_table[count].name); fprintf(fp, "sLevels "); for (i=0; i < MAX_CLASS; i++) fprintf(fp, "%d ", skill_table[count].skill_level[i]); fprintf(fp, "\nsRates "); for (i=0; i < MAX_CLASS; i++) fprintf(fp, "%d ", skill_table[count].rating[i]); fprintf(fp, "\nTargets %d\n", skill_table[count].target); fprintf(fp, "MinPos %d\n", skill_table[count].minimum_position); fprintf(fp, "MinMana %d\n", skill_table[count].min_mana); fprintf(fp, "Beats %d\n", skill_table[count].beats); fprintf(fp, "DamMsg %s~\n", skill_table[count].noun_damage); fprintf(fp, "MsgOff %s~\n", skill_table[count].msg_off); fprintf(fp, "MsgObj %s~\n", skill_table[count].msg_obj); fprintf(fp, "sFlags %s\n\n", print_flags(skill_table[count].flags)); } } fprintf(fp, "\nEnd\n"); fclose(fp); return TRUE; } /** Function: load_skills * Descr : Reads saved skill data from /area/skills.dat and updates * : the skill_table. * Returns : TRUE/FALSE on success * Syntax : void * Written : v1.0 01/99 * Author : Gary McNickle */ bool load_skills( void ) { FILE *fp; char buf[MIL]; char *string; bool fMatch = FALSE; bool fFound = TRUE; int count = -1; sprintf(buf, "%s%s", DATA_DIR, "skills.dat"); if (!(fp=fopen(buf, "r"))) { logf("[%s] Could not open file %s in order to read skill data, creating.", errmsg(errno), buf); return save_skills(); } for (;;) { string = feof(fp) ? "End" : fread_word(fp); if (!str_cmp(string, "End")) { fMatch = TRUE; break; } fMatch = FALSE; if ( !fFound && str_cmp("Skill", string) ) continue; switch (string[0]) { case '#': fMatch = TRUE; fread_to_eol(fp); break; case 'B': KEY("Beats", skill_table[count].beats, fread_number(fp)); break; case 'D': KEY("DamMsg", skill_table[count].noun_damage, fread_string(fp)); break; case 'M': KEY("MinMana", skill_table[count].min_mana, fread_number(fp)); KEY("MinPos", skill_table[count].minimum_position, fread_number(fp)); KEY("MsgObj", skill_table[count].msg_obj, fread_string(fp)); KEY("MsgOff", skill_table[count].msg_off, fread_string(fp)); break; case 's': KEY("sFlags", skill_table[count].flags, fread_flag(fp)); if ( !str_cmp(string, "sLevels") ) { sh_int i; for(i=0; i < MAX_CLASS; i++) skill_table[count].skill_level[i] = fread_number(fp); fMatch = TRUE; break; } else if ( !str_cmp(string, "sRates") ) { sh_int i; for(i=0; i < MAX_CLASS; i++) skill_table[count].rating[i] = fread_number(fp); fMatch = TRUE; break; } break; case 'S': if ( !str_cmp(string, "Skill") ) { char *str; str = fread_string(fp); count = skill_lookup( str ); if ( count < 0 ) { fFound = FALSE; continue; } else fFound = TRUE; fMatch = TRUE; break; } break; case 'T': KEY("Targets", skill_table[count].target, fread_number(fp)); break; } /* end switch */ if ( !fMatch ) bugf("load_skills: Invalid key: %s", string); } fclose(fp); logf("Loaded Skill Data File."); return TRUE; } /** Function: load_groups * Descr : Reads in data/GROUP_FILE and sets the group_table accordingly * Returns : TRUE on success * Syntax : void * Written : v1.0 7/98 * Author : Gary McNickle */ bool load_groups( void ) { FILE *fp; char buf[MSL]; char *string; int group = -1; int skill = 0; int i = 0; bool fMatch = FALSE; sprintf(buf, "%s%s", DATA_DIR, GROUP_FILE); if ((fp = fopen(buf, "r")) == NULL) { logf("[%s] Could not open %s file for reading group data.", errmsg(errno), buf); return save_groups(); } memset( group_table, 0, sizeof(group_table[0]) * MAX_GROUP ); for (;;) { string = feof(fp) ? "End" : fread_word(fp); if (!str_cmp(string, "End")) break; switch (UPPER(string[0])) { case '#': fMatch = TRUE; fread_to_eol(fp); break; case 'G': group++; skill = 0; group_table[group].name = fread_string( fp ); fMatch = TRUE; break; case 'R': for (i=0; i < MAX_CLASS; i++) group_table[group].rating[i] = fread_number( fp ); fMatch = TRUE; break; case 'S': group_table[group].spells[skill] = fread_string( fp ); skill++; fMatch = TRUE; break; case 'F': group_table[group].flags = fread_flag( fp ); fMatch = TRUE; break; } } /* end: for(;;) */ if (!fMatch) bug("Fread_groups: no match.", 0); fclose(fp); logf("Loaded Group Data File."); return TRUE; } /* end: load_groups */ /** Function: save_groups * Descr : Saves the group data to a text file in ../data dir * Returns : TRUE on success * Syntax : void * Written : v1.0 7/98 * Author : Gary McNickle */ bool save_groups( void ) { FILE *fp; char buf[MIL]; int i = 0; sprintf(buf, "%s%s", DATA_DIR, GROUP_FILE); if (!(fp = fopen(buf, "w"))) { logf("[%s] Could not open file %s in order to save groups.", errmsg(errno), buf); return FALSE; } fprintf(fp, "#\n"); fprintf(fp, "## Group Table Data file\n## Written %s", ctime(¤t_time)); fprintf(fp, "## Contains %d groups.\n", MAX_GROUP); fprintf(fp, "## File Format\n#\n"); fprintf(fp, "# GROUP // The Name of this group.\n"); fprintf(fp, "# RATINGS // The class ratings for this group. \n"); fprintf(fp, "# SKILL // One of the skills contained within the group\n"); fprintf(fp, "# FLAGS // The flags for this group.\n"); fprintf(fp, "#\n"); for ( i = 0; i < MAX_GROUP; i++) { int x = 0; if ( group_table[i].name == NULL ) break; if ( IS_SET(group_table[i].flags, GROUP_DELETED) ) continue; if ( IS_SET(group_table[i].flags, GROUP_CHANGED) ) REMOVE_BIT(group_table[i].flags, GROUP_CHANGED); fprintf(fp, "GROUP\t%s~\n", group_table[i].name); fprintf(fp, "RATINGS\t"); for ( x = 0; x < MAX_CLASS; x++ ) fprintf(fp, "%d ", group_table[i].rating[x]); fprintf(fp, "\n"); x = 0; while ( group_table[i].spells[x] != NULL && x < MAX_IN_GROUP ) { fprintf(fp, "SKILL\t%s~\n", group_table[i].spells[x]); x++; } fprintf(fp, "FLAGS\t%s\n", print_flags( group_table[i].flags ) ); /* indicate end of group, next should follow another group */ fprintf(fp, "#0\n\n"); } fprintf(fp, "\nEnd\n"); fclose(fp); return TRUE; }