rendered paste body/* * MudName Server v. 1.6 - A character name generator * Copyright (C) 1997-2001 Ragnar Hojland Espinosa <ragnar@ragnar-hojland.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "globals.h"enum { CAP_PS = 0, CAP_PMS, CAP_N, CAP_X, CAP_NA, CAP_NX, CAP_XA, CAP_LAST};enum { PART_PRE, PART_MID, PART_SUF, PART_NOUN, PART_NADJ, PART_ADJ};#define TRUE 1#define FALSE 0typedef unsigned char bool;char const *particle_files[] ={ "archaic", "eldar", "elf", "england", "exotic", "female-1", "female-2", "goblin", "greek", "hyboria", "jdh", "khuzdul", "male-1", "male-2", "male-3", "male-4", "name-1", "name-2", "new", "shadow", "took", 0};struct particles_t{ unsigned int count; char **list;};typedef struct particles_t particles_t;struct dictionary_t{ particles_t part_pre; particles_t part_mid; particles_t part_suf; particles_t part_noun; particles_t part_nadj; particles_t part_adj; bool capabilities[CAP_LAST]; unsigned int capability_count;};typedef struct dictionary_t dictionary_t;dictionary_t **dictionaries;unsigned int dictionary_count;int read_particles (particles_t* p, FILE *fp){ unsigned long startpos = ftell(fp); unsigned long lastpos; unsigned int count = 0; while (1) { char buf[8192]; lastpos = ftell (fp); fgets (buf, 8192, fp); if (feof (fp) || buf[0] == '#' || buf[0] == '\0') { break; } if (buf[0] == '\n') { continue; } if (p) { int i; for (i = 0; buf[i]; ++i) { if (buf[i] == '\n') { buf[i] = '\0'; break; } } p->list[count] = strdup (buf); } ++count; } clearerr (fp); fseek (fp, (p ? lastpos : startpos), SEEK_SET); return count;}void init_particles (particles_t* part){ part->count = 0; part->list = 0;}void init_dictionary (dictionary_t* dic) { init_particles (&dic->part_pre); init_particles (&dic->part_mid); init_particles (&dic->part_suf); init_particles (&dic->part_noun); init_particles (&dic->part_nadj); init_particles (&dic->part_adj);}void load_particles (particles_t* part, FILE *fp){ part->count = read_particles (NULL, fp); part->list = (char**) malloc (sizeof(char**) * part->count); read_particles (part, fp);}void set_capabilities (dictionary_t* d){ int c; for (c = 0; c < CAP_LAST; ++c) { d->capabilities[c] = FALSE; } if (d->part_pre.count && d->part_suf.count) { d->capabilities[CAP_PS] = TRUE; if (d->part_mid.count) { d->capabilities[CAP_PMS] = TRUE; } } if (d->part_noun.count) { d->capabilities[CAP_N] = TRUE; } if (d->part_nadj.count) { d->capabilities[CAP_X] = TRUE; } if (d->part_noun.count) { d->capabilities[CAP_N] = TRUE; } if (d->part_noun.count && d->part_adj.count) { d->capabilities[CAP_NA] = TRUE; } if (d->part_noun.count && d->part_nadj.count) { d->capabilities[CAP_NX] = TRUE; } if (d->part_nadj.count && d->part_adj.count) { d->capabilities[CAP_XA] = TRUE; } d->capability_count = 0; for (c = 0; c < CAP_LAST; ++c) { d->capability_count += d->capabilities[c]; }}int read_dictionary (dictionary_t* dic, FILE *fp){ init_dictionary (dic); while (1) { char buf[8192]; particles_t *p; fgets (buf, 8192, fp); if (feof (fp)) { break; } if (buf[0] == '\0' || buf[0] == '\n') { continue; } if (!strcmp (buf, "#PRE\n")) { p = &dic->part_pre; } else if (!strcmp (buf, "#MID\n")) { p = &dic->part_mid; } else if (!strcmp (buf, "#SUF\n")) { p = &dic->part_suf; } else if (!strcmp (buf, "#NOUN\n")) { p = &dic->part_noun; } else if (!strcmp (buf, "#NADJ\n")) { p = &dic->part_nadj; } else if (!strcmp (buf, "#ADJ\n")) { p = &dic->part_adj; } else { fprintf (logfile, "Unknown keyword: ``%s''\n", buf); return 1; } load_particles (p, fp); set_capabilities (dic); } return 0;}int load_dictionaries (char const *datadir){ int idx; dictionaries = NULL; dictionary_count = 0; for (idx = 0; particle_files[idx]; ++idx) { char buf[8192]; FILE *fp; dictionary_t *dic; snprintf (buf, 8192, "%s/%s", datadir, particle_files[idx]); fp = fopen (buf, "r"); if (!fp) { fprintf (logfile, "%s: couldn't open for reading, skipping\n", buf); } ++dictionary_count; if (!dictionaries) { dictionaries = (dictionary_t**) malloc (sizeof (dictionary_t**) * dictionary_count); } else { dictionaries = (dictionary_t**) realloc (dictionaries, sizeof (dictionary_t**) * dictionary_count); } dic = (dictionary_t*) malloc (sizeof (dictionary_t)); dictionaries[dictionary_count - 1] = dic; read_dictionary (dic, fp); fclose (fp); } return dictionary_count;}int rrand (int from, int to){ return from + (int) ((float)(to) * rand() / (RAND_MAX + 1.0));}char* random_particle (dictionary_t* d, unsigned int type){ int n; switch (type) { case PART_PRE: n = rrand (0, d->part_pre.count -1); return d->part_pre.list [n]; case PART_MID: return d->part_mid.list [rrand (0, d->part_mid.count - 1)]; case PART_SUF: return d->part_suf.list [rrand (0, d->part_suf.count - 1)]; case PART_NOUN: return d->part_noun.list[rrand (0, d->part_noun.count - 1)]; case PART_NADJ: return d->part_nadj.list[rrand (0, d->part_nadj.count - 1)]; case PART_ADJ: return d->part_adj.list [rrand (0, d->part_adj.count - 1)]; } return "random_particle";}void generate_name (int dict, char* dest, unsigned int len){ int cap, c; dictionary_t* d = dictionaries[dict]; cap = rrand (1, d->capability_count); for (c = 0; c < d->capability_count; ++c) { if (d->capabilities[c]) { --cap; } if (cap == 0) { break; } } cap = c; switch (cap) { case CAP_PS: case CAP_PMS: snprintf (dest, len, "%s%s%s", random_particle (d, PART_PRE), (cap == CAP_PMS ? random_particle (d, PART_MID) : ""), random_particle (d, PART_SUF)); break; case CAP_N: snprintf (dest, len, "%s%s", random_particle (d, PART_NOUN), random_particle (d, PART_NOUN)); break; case CAP_X: snprintf (dest, len, "%s%s", random_particle (d, PART_NADJ), random_particle (d, PART_NADJ)); break; case CAP_NA: snprintf (dest, len, "%s%s", random_particle (d, PART_NOUN), random_particle (d, PART_ADJ)); break; case CAP_XA: snprintf (dest, len, "%s%s", random_particle (d, PART_NOUN), random_particle (d, (rrand (0, 1) ? PART_ADJ : PART_NADJ) )); break; case CAP_NX: snprintf (dest, len, "%s%s", random_particle (d, (rrand (0, 1) ? PART_NOUN : PART_ADJ) ), random_particle (d, PART_ADJ)); break; } for (c = 0; dest[c]; ++c) { dest[c] = tolower (dest[c]); }}