/* * $Id: mech.partnames.c,v 1.4 2005/06/30 18:37:37 av1-op Exp $ * * Author: Markus Stenberg <fingon@iki.fi> * * Copyright (c) 1996 Markus Stenberg * Copyright (c) 1998-2002 Thomas Wouters * Copyright (c) 2000-2002 Cord Awtry * All rights reserved * * Created: Sat Oct 5 14:38:09 1996 fingon * Last modified: Mon Aug 18 20:43:06 1997 fingon * */ #include <stdio.h> #include <string.h> #include "mech.h" #include "htab.h" #include "create.h" #include "mech.partnames.h" void list_hashstat(dbref player, const char *tab_name, HASHTAB * htab); /* Main idea: Keep 2 sorted tables, one of shortform -> index longform -> index vlongform -> index Other index -> {short,long,vlong} form Index = ID + NUM_ITEMS * brand */ #define BRANDCOUNT 5 static PN *index_sorted[BRANDCOUNT + 1][NUM_ITEMS]; /* Sorted: short -> index, long -> index */ PN **short_sorted = NULL; PN **long_sorted = NULL; PN **vlong_sorted = NULL; int object_count; static void insert_sorted_brandname(int ind, PN * e) { int i, j; #define UGLY_SORT(b,a) \ for (i = 0 ; i < ind; i++) if (strcmp(e->a, b[i]->a)<0) break; \ for (j = ind ; j > i ; j--) b[j] = b[j-1]; b[i] = e UGLY_SORT(short_sorted, shorty); UGLY_SORT(long_sorted, longy); UGLY_SORT(vlong_sorted, vlongy); } extern char *part_figure_out_name(int i); extern char *part_figure_out_sname(int i); extern char *part_figure_out_shname(int i); extern char *GetPartBrandName(int, int); extern char *my_shortform(char *); int temp_brand_flag; static int create_brandname(int id, int b) { char buf[MBUF_SIZE]; char buf2[MBUF_SIZE]; char buf3[MBUF_SIZE]; char *c, *brn = NULL; PN *p; if (b) if (!(brn = GetPartBrandName(id, b))) return 0; temp_brand_flag = b; Create(p, PN, 1); /* \todo Remove this stupid #define and make the code readable */ #define SILLINESS(fun,val,fl) \ if (!(c=fun(id))) \ { free ((void *) p->val); free((void *) p); return 0; } \ if (b) \ { strcpy(buf2, c); \ if (fl) \ strcpy(buf3, my_shortform(brn)); \ sprintf(buf, "%s.%s", fl ? buf3 : brn, buf2); } \ else \ strcpy(buf, c); \ p->val = strdup(buf) SILLINESS(part_figure_out_name, vlongy, 0); SILLINESS(part_figure_out_sname, longy, 0); SILLINESS(part_figure_out_shname, shorty, 1); p->index = PACKED_PART(id, b); index_sorted[b][id] = p; return 1; } static HASHTAB short_hash, vlong_hash; void list_phashstats(dbref player) { list_hashstat(player, "Part:Short", &short_hash); list_hashstat(player, "Part:VLong", &vlong_hash); } void initialize_partname_tables() { int i, j, c = 0, m, n; char tmpbuf[MBUF_SIZE]; char *tmpc1, *tmpc2; bzero(index_sorted, sizeof(index_sorted)); for (j = 0; j <= BRANDCOUNT; j++) for (i = 0; i < NUM_ITEMS; i++) c += create_brandname(i, j); Create(short_sorted, PN *, c); Create(long_sorted, PN *, c); Create(vlong_sorted, PN *, c); /* bubble-sort 'em and insert to array */ i = 0; for (m = 0; m <= BRANDCOUNT; m++) for (n = 0; n < NUM_ITEMS; n++) if (index_sorted[m][n]) insert_sorted_brandname(i++, index_sorted[m][n]); hashinit(&short_hash, 20 * HASH_FACTOR); hashinit(&vlong_hash, 20 * HASH_FACTOR); #define DASH(fromval,tohash) \ for (tmpc1 = short_sorted[i]->fromval, tmpc2 = tmpbuf ; *tmpc1 ; tmpc1++, tmpc2++) \ *tmpc2 = ToLower(*tmpc1); \ *tmpc2 = 0; \ hashadd(tmpbuf, (int *) (i+1), &tohash); for (i = 0; i < c; i++) { DASH(shorty, short_hash); /* DASH(longy, long_hash); */ DASH(vlongy, vlong_hash); } object_count = c; } #define SILLY_GET(fun,value) \ char * fun (int i, int b) { if (!(index_sorted[b][i])) \ { if (b) return fun(i,0); else { SendError(tprintf("No index for %d/%d", i, b)); return NULL; } }\ return index_sorted[b][i]->value; } SILLY_GET(get_parts_short_name, shorty); SILLY_GET(get_parts_long_name, longy); SILLY_GET(get_parts_vlong_name, vlongy); #define wildcard_match quick_wild extern int wildcard_match(char *, char *); int find_matching_vlong_part(char *wc, int *ind, int *id, int *brand) { PN *p; char *tmpc1, *tmpc2; char tmpbuf[MBUF_SIZE]; int *i; if (ind && *ind >= 0) return 0; for (tmpc1 = wc, tmpc2 = tmpbuf; *tmpc1; tmpc1++, tmpc2++) { *tmpc2 = ToLower(*tmpc1); } *tmpc2 = 0; if ((i = hashfind(tmpbuf, &vlong_hash))) { if ((p = short_sorted[((int) i) - 1])) { if (ind) *ind = ((int) i); UNPACK_PART(p->index, *id, *brand); return 1; } } return 0; } int find_matching_long_part(char *wc, int *i, int *id, int *brand) { PN *p; for ((*i)++; *i < object_count; (*i)++) if (wildcard_match(wc, (p = long_sorted[*i])->longy)) { UNPACK_PART(p->index, *id, *brand); return 1; } return 0; } int find_matching_short_part(char *wc, int *ind, int *id, int *brand) { PN *p; char *tmpc1, *tmpc2; char tmpbuf[MBUF_SIZE]; int *i; if (*ind >= 0) return 0; for (tmpc1 = wc, tmpc2 = tmpbuf; *tmpc1; tmpc1++, tmpc2++) { *tmpc2 = ToLower(*tmpc1); } *tmpc2 = 0; if ((i = hashfind(tmpbuf, &short_hash))) { if ((p = short_sorted[((int) i) - 1])) { *ind = ((int) i); UNPACK_PART(p->index, *id, *brand); return 1; } } return 0; } void ListForms(dbref player, void *data, char *buffer) { int i; notify(player, "Listing of forms:"); for (i = 0; i < object_count; i++) notify(player, tprintf("%3d %-20s %-25s %s", i, short_sorted[i]->shorty, short_sorted[i]->longy, short_sorted[i]->vlongy)); } void fun_btpartmatch(char *buff, char **bufc, dbref player, dbref cause, char *fargs[], int nfargs, char *cargs[], int ncargs) { /* fargs[0] = name to match on */ /* Added check to see if anything was found, if not * send error message * Dany - 06/2005 */ int partindex = 0, id = 0, brand = 0; int part_count = 0; FUNCHECK(!WizR(player), "#-1 PERMISSION DENIED"); FUNCHECK(strlen(fargs[0]) >= MBUF_SIZE, "#-1 PARTNAME TOO LONG"); FUNCHECK(!fargs[0], "#-1 NEED PARTNAME"); partindex = -1; while (find_matching_short_part(fargs[0], &partindex, &id, &brand)) { safe_tprintf_str(buff, bufc, "%d ", PACKED_PART(id, brand)); part_count++; } partindex = 0; while (find_matching_long_part(fargs[0], &partindex, &id, &brand)) { safe_tprintf_str(buff, bufc, "%d ", PACKED_PART(id, brand)); part_count++; } partindex = -1; while (find_matching_vlong_part(fargs[0], &partindex, &id, &brand)) { safe_tprintf_str(buff, bufc, "%d ", PACKED_PART(id, brand)); part_count++; } if (part_count == 0) safe_tprintf_str(buff, bufc, "#-1 INVALID PARTNAME"); } void fun_btpartname(char *buff, char **bufc, dbref player, dbref cause, char *fargs[], int nfargs, char *cargs[], int ncargs) { /* fargs[0] = partnumer to find name for * fargs[1] = 'short', 'long' or 'vlong' */ int index; char *cptr; char *infostr; FUNCHECK(!WizR(player), "#-1 PERMISSION DENIED"); FUNCHECK(!fargs[0], "#-1 NEED PARTNAME"); index = strtol(fargs[0], &cptr, 10); FUNCHECK(cptr == fargs[0], "#-1 INVALID PART NUMBER"); infostr = partname_func(index, fargs[1][0]); safe_tprintf_str(buff, bufc, "%s", infostr); } char *partname_func(int index, int size) { static char buffer[MBUF_SIZE]; int id, brand; PN *p; UNPACK_PART(index, id, brand); if (brand < 0 || brand > BRANDCOUNT || id < 0) { snprintf(buffer, MBUF_SIZE, "%s", "#-1 INVALID PART NUMBER"); return buffer; } p = index_sorted[brand][id]; if (!p) { snprintf(buffer, MBUF_SIZE, "%s", "#-1 INVALID PART NUMBER"); return buffer; } switch (size) { case 's': case 'S': snprintf(buffer, MBUF_SIZE, "%s", p->shorty); break; case 'l': case 'L': snprintf(buffer, MBUF_SIZE, "%s", p->longy); break; case 'v': case 'V': snprintf(buffer, MBUF_SIZE, "%s", p->vlongy); break; default: snprintf(buffer, MBUF_SIZE, "%s", "#-1 INVALID NAME TYPE"); break; } return buffer; }