btmux/autom4te.cache/
btmux/doc/.svn/
btmux/event/.svn/
btmux/game/.svn/
btmux/game/bin/.svn/
btmux/game/data/.svn/
btmux/game/logs/.svn/
btmux/game/maps/
btmux/game/maps/.svn/
btmux/game/maps/.svn/prop-base/
btmux/game/maps/.svn/props/
btmux/game/maps/.svn/text-base/
btmux/game/maps/.svn/wcprops/
btmux/game/mechs/
btmux/game/mechs/.svn/
btmux/game/mechs/.svn/prop-base/
btmux/game/mechs/.svn/props/
btmux/game/mechs/.svn/text-base/
btmux/game/mechs/.svn/wcprops/
btmux/game/text/.svn/
btmux/include/.svn/
btmux/misc/
btmux/misc/.svn/
btmux/misc/.svn/prop-base/
btmux/misc/.svn/props/
btmux/misc/.svn/text-base/
btmux/misc/.svn/wcprops/
btmux/python/
btmux/python/.svn/
btmux/python/.svn/prop-base/
btmux/python/.svn/props/
btmux/python/.svn/text-base/
btmux/python/.svn/wcprops/
btmux/src/.svn/prop-base/
btmux/src/.svn/props/
btmux/src/.svn/text-base/
btmux/src/.svn/wcprops/
btmux/src/hcode/.svn/
btmux/src/hcode/btech/
btmux/src/hcode/btech/.svn/
btmux/src/hcode/btech/.svn/prop-base/
btmux/src/hcode/btech/.svn/props/
btmux/src/hcode/btech/.svn/text-base/
btmux/src/hcode/btech/.svn/wcprops/
btmux/src/hcode/include/.svn/
/*
 * $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;
}