--- deliantra/server/common/arch.c 2006/02/03 07:11:30 1.1 +++ deliantra/server/common/arch.c 2006/03/13 21:00:22 1.2 @@ -34,6 +34,8 @@ /* IF set, does a little timing on the archetype load. */ #define TIME_ARCH_LOAD 0 +static void add_arch(archetype *at); + static archetype *arch_table[ARCHTABLE]; int arch_cmp=0; /* How many strcmp's */ int arch_search=0; /* How many searches */ @@ -71,6 +73,25 @@ return NULL; } +/** + * This function retrieves an archetype by type and name that appears during + * the game. It is basically the same as find_archetype_by_object_name() + * except that it considers only items of the given type. + */ +archetype *find_archetype_by_object_type_name(int type, const char *name) { + archetype *at; + + if (name == NULL) + return NULL; + + for (at = first_archetype; at != NULL; at = at->next) { + if (at->clone.type == type && strcmp(at->clone.name, name) == 0) + return at; + } + + return NULL; +} + /* This is a lot like the above function. Instead, we are trying to match * the arch->skill values. type is the type of object to match * against (eg, to only match against skills or only skill objects for example). @@ -615,16 +636,22 @@ hasharch(const char *str, int tablesize) { unsigned long hash = 0; int i = 0; - unsigned rot = 0; - const char *p; + const unsigned char *p; + /* use the one-at-a-time hash function, which supposedly is + * better than the djb2-like one used by perl5.005, but + * certainly is better then the bug used here before. + * see http://burtleburtle.net/bob/hash/doobs.html + */ for (p = str; i < MAXSTRING && *p; p++, i++) { - hash ^= (unsigned long) *p << rot; - rot += 2; - if (rot >= (sizeof(long) - sizeof(char)) * 8) - rot = 0; - } - return (hash % tablesize); + hash += *p; + hash += hash << 10; + hash ^= hash >> 6; + } + hash += hash << 3; + hash ^= hash >> 11; + hash += hash << 15; + return hash % tablesize; } /* @@ -660,7 +687,7 @@ * Adds an archetype to the hashtable. */ -void add_arch(archetype *at) { +static void add_arch(archetype *at) { int index=hasharch(at->name, ARCHTABLE),org_index=index; for(;;) { if(arch_table[index]==NULL) {