ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/arch.C
Revision: 1.37
Committed: Mon Jan 15 21:06:18 2007 UTC (17 years, 4 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.36: +22 -22 lines
Log Message:
comments

File Contents

# User Rev Content
1 elmex 1.1 /*
2 pippijn 1.37 * CrossFire, A Multiplayer game for X-windows
3     *
4     * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
5     * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
6     * Copyright (C) 1992 Frank Tore Johansen
7     *
8     * This program is free software; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License as published by
10     * the Free Software Foundation; either version 2 of the License, or
11     * (at your option) any later version.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19     * along with this program; if not, write to the Free Software
20     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21     *
22     * The authors can be reached via e-mail at <crossfire@schmorp.de>
23     */
24 elmex 1.1
25 root 1.12 #include <cassert>
26    
27 elmex 1.1 #include <global.h>
28     #include <funcpoint.h>
29     #include <loader.h>
30    
31 root 1.26 #define USE_UNORDERED_MAP 0
32 elmex 1.1
33 root 1.26 #if USE_UNORDERED_MAP
34     # include <tr1/functional>
35     # include <tr1/unordered_map>
36     #endif
37 elmex 1.1
38 root 1.12 int arch_cmp = 0; /* How many strcmp's */
39     int arch_search = 0; /* How many searches */
40     int arch_init; /* True if doing arch initialization */
41 elmex 1.1
42     /* The naming of these functions is really poor - they are all
43     * pretty much named '.._arch_...', but they may more may not
44     * return archetypes. Some make the arch_to_object call, and thus
45     * return an object. Perhaps those should be called 'archob' functions
46     * to denote they return an object derived from the archetype.
47     * MSW 2003-04-29
48     */
49    
50 root 1.12 #if USE_UNORDERED_MAP
51     // the hashtable
52 root 1.18 typedef std::tr1::unordered_map
53     <
54     std::size_t,
55 root 1.26 arch_ptr,
56     std::tr1::hash<size_t>,
57 root 1.18 std::equal_to<size_t>,
58     slice_allocator< std::pair<const std::size_t, archetype *> >
59     true,
60     > HT;
61    
62     static HT ht;
63 root 1.26 #else
64     static arch_ptr arch_table[ARCHTABLE];
65 root 1.12 #endif
66    
67 elmex 1.1 /**
68     * GROS - This function retrieves an archetype given the name that appears
69     * during the game (for example, "writing pen" instead of "stylus").
70     * It does not use the hashtable system, but browse the whole archlist each time.
71     * I suggest not to use it unless you really need it because of performance issue.
72     * It is currently used by scripting extensions (create-object).
73     * Params:
74     * - name: the name we're searching for (ex: "writing pen");
75     * Return value:
76     * - the archetype found or null if nothing was found.
77     */
78 root 1.12 archetype *
79     find_archetype_by_object_name (const char *name)
80     {
81 root 1.20 archetype *at;
82 elmex 1.1
83 root 1.12 if (name == NULL)
84     return (archetype *) NULL;
85 elmex 1.1
86 root 1.12 for (at = first_archetype; at != NULL; at = at->next)
87     {
88     if (!strcmp (at->clone.name, name))
89     return at;
90 elmex 1.1 }
91 root 1.12 return NULL;
92 elmex 1.1 }
93    
94     /**
95     * This function retrieves an archetype by type and name that appears during
96     * the game. It is basically the same as find_archetype_by_object_name()
97     * except that it considers only items of the given type.
98     */
99 root 1.12 archetype *
100     find_archetype_by_object_type_name (int type, const char *name)
101     {
102 root 1.20 archetype *at;
103 elmex 1.1
104 root 1.12 if (name == NULL)
105     return NULL;
106 elmex 1.1
107 root 1.12 for (at = first_archetype; at != NULL; at = at->next)
108     {
109     if (at->clone.type == type && strcmp (at->clone.name, name) == 0)
110     return at;
111 elmex 1.1 }
112    
113 root 1.12 return NULL;
114 elmex 1.1 }
115    
116     /* This is a lot like the above function. Instead, we are trying to match
117     * the arch->skill values. type is the type of object to match
118     * against (eg, to only match against skills or only skill objects for example).
119     * If type is -1, ew don't match on type.
120     */
121 root 1.12 object *
122     get_archetype_by_skill_name (const char *skill, int type)
123     {
124 root 1.35 archetype *at;
125 elmex 1.1
126 root 1.35 if (skill)
127     for (at = first_archetype; at; at = at->next)
128 root 1.12 if (((type == -1) || (type == at->clone.type)) && (!strcmp (at->clone.skill, skill)))
129     return arch_to_object (at);
130 root 1.35
131     return 0;
132 elmex 1.1 }
133    
134     /* similiar to above - this returns the first archetype
135     * that matches both the type and subtype. type and subtype
136     * can be -1 to say ignore, but in this case, the match it does
137     * may not be very useful. This function is most useful when
138     * subtypes are known to be unique for a particular type
139     * (eg, skills)
140     */
141 root 1.12 archetype *
142     get_archetype_by_type_subtype (int type, int subtype)
143     {
144     archetype *
145     at;
146 elmex 1.1
147 root 1.12 for (at = first_archetype; at != NULL; at = at->next)
148     {
149     if (((type == -1) || (type == at->clone.type)) && (subtype == -1 || subtype == at->clone.subtype))
150     return at;
151 elmex 1.1 }
152 root 1.12 return NULL;
153 elmex 1.1 }
154    
155     /**
156     * GROS - this returns a new object given the name that appears during the game
157     * (for example, "writing pen" instead of "stylus").
158     * Params:
159     * - name: The name we're searching for (ex: "writing pen");
160     * Return value:
161     * - a corresponding object if found; a singularity object if not found.
162     * Note by MSW - it appears that it takes the full name and keeps
163     * shortening it until it finds a match. I re-wrote this so that it
164     * doesn't malloc it each time - not that this function is used much,
165     * but it otherwise had a big memory leak.
166     */
167 root 1.12 object *
168     get_archetype_by_object_name (const char *name)
169     {
170 root 1.17 archetype *at;
171     char tmpname[MAX_BUF];
172     int i;
173    
174     assign (tmpname, name);
175 root 1.12
176     for (i = strlen (tmpname); i > 0; i--)
177     {
178     tmpname[i] = 0;
179     at = find_archetype_by_object_name (tmpname);
180 root 1.17
181 root 1.35 if (at)
182 root 1.20 return arch_to_object (at);
183 elmex 1.1 }
184 root 1.17
185 root 1.12 return create_singularity (name);
186 elmex 1.1 }
187    
188     /* This is a subset of the parse_id command. Basically, name can be
189     * a string seperated lists of things to match, with certain keywords.
190     * pl is the player (only needed to set count properly)
191     * op is the item we are trying to match. Calling function takes care
192     * of what action might need to be done and if it is valid
193     * (pickup, drop, etc.) Return NONZERO if we have a match. A higher
194     * value means a better match. 0 means no match.
195     *
196     * Brief outline of the procedure:
197     * We take apart the name variable into the individual components.
198     * cases for 'all' and unpaid are pretty obvious.
199     * Next, we check for a count (either specified in name, or in the
200     * player object.)
201     * If count is 1, make a quick check on the name.
202     * IF count is >1, we need to make plural name. Return if match.
203     * Last, make a check on the full name.
204     */
205 root 1.12 int
206 root 1.15 item_matched_string (object *pl, object *op, const char *name)
207 elmex 1.1 {
208 root 1.22 char *cp, local_name[MAX_BUF];
209     int count, retval = 0;
210 root 1.15
211 root 1.12 strcpy (local_name, name); /* strtok is destructive to name */
212    
213     for (cp = strtok (local_name, ","); cp; cp = strtok (NULL, ","))
214     {
215     while (cp[0] == ' ')
216     ++cp; /* get rid of spaces */
217    
218     /* LOG(llevDebug,"Trying to match %s\n", cp); */
219     /* All is a very generic match - low match value */
220     if (!strcmp (cp, "all"))
221     return 1;
222    
223     /* unpaid is a little more specific */
224     if (!strcmp (cp, "unpaid") && QUERY_FLAG (op, FLAG_UNPAID))
225     return 2;
226     if (!strcmp (cp, "cursed") && QUERY_FLAG (op, FLAG_KNOWN_CURSED) && (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)))
227     return 2;
228    
229     if (!strcmp (cp, "unlocked") && !QUERY_FLAG (op, FLAG_INV_LOCKED))
230     return 2;
231    
232     /* Allow for things like '100 arrows' */
233     if ((count = atoi (cp)) != 0)
234     {
235     cp = strchr (cp, ' ');
236     while (cp && cp[0] == ' ')
237     ++cp; /* get rid of spaces */
238     }
239     else
240     {
241     if (pl->type == PLAYER)
242     count = pl->contr->count;
243     else
244     count = 0;
245     }
246    
247     if (!cp || cp[0] == '\0' || count < 0)
248     return 0;
249    
250    
251     /* The code here should go from highest retval to lowest. That
252     * is because of the 'else' handling - we don't want to match on
253     * something and set a low retval, even though it may match a higher retcal
254     * later. So keep it in descending order here, so we try for the best
255     * match first, and work downward.
256     */
257     if (!strcasecmp (cp, query_name (op)))
258     retval = 20;
259     else if (!strcasecmp (cp, query_short_name (op)))
260     retval = 18;
261     else if (!strcasecmp (cp, query_base_name (op, 0)))
262     retval = 16;
263     else if (!strcasecmp (cp, query_base_name (op, 1)))
264     retval = 16;
265     else if (op->custom_name && !strcasecmp (cp, op->custom_name))
266     retval = 15;
267     else if (!strncasecmp (cp, query_base_name (op, 0), strlen (cp)))
268     retval = 14;
269     else if (!strncasecmp (cp, query_base_name (op, 1), strlen (cp)))
270     retval = 14;
271     /* Do substring checks, so things like 'Str+1' will match.
272     * retval of these should perhaps be lower - they are lower
273     * then the specific strcasecmp aboves, but still higher than
274     * some other match criteria.
275     */
276     else if (strstr (query_base_name (op, 1), cp))
277     retval = 12;
278     else if (strstr (query_base_name (op, 0), cp))
279     retval = 12;
280     else if (strstr (query_short_name (op), cp))
281     retval = 12;
282     /* Check against plural/non plural based on count. */
283     else if (count > 1 && !strcasecmp (cp, op->name_pl))
284 root 1.23 retval = 6;
285 root 1.12 else if (count == 1 && !strcasecmp (op->name, cp))
286 root 1.23 retval = 6;
287 root 1.12 /* base name matched - not bad */
288     else if (strcasecmp (cp, op->name) == 0 && !count)
289     retval = 4;
290     /* Check for partial custom name, but give a real low priority */
291     else if (op->custom_name && strstr (op->custom_name, cp))
292     retval = 3;
293    
294     if (retval)
295     {
296     if (pl->type == PLAYER)
297     pl->contr->count = count;
298 root 1.23
299 root 1.12 return retval;
300 root 1.7 }
301 elmex 1.1 }
302 root 1.23
303 root 1.12 return 0;
304 elmex 1.1 }
305    
306     /*
307     * Initialises the internal linked list of archetypes (read from file).
308     * Then the global "empty_archetype" pointer is initialised.
309     * Then the blocksview[] array is initialised.
310     */
311    
312 root 1.12 void
313     init_archetypes (void)
314     { /* called from add_player() and edit() */
315     if (first_archetype != NULL) /* Only do this once */
316 elmex 1.1 return;
317 root 1.20
318 elmex 1.1 arch_init = 1;
319 root 1.12 load_archetypes ();
320 elmex 1.1 arch_init = 0;
321 root 1.20 empty_archetype = archetype::find ("empty_archetype");
322 root 1.15
323 elmex 1.1 /* init_blocksview();*/
324     }
325    
326     /*
327     * Stores debug-information about how efficient the hashtable
328     * used for archetypes has been in the static errmsg array.
329     */
330    
331 root 1.12 void
332 root 1.15 arch_info (object *op)
333 root 1.12 {
334     sprintf (errmsg, "%d searches and %d strcmp()'s", arch_search, arch_cmp);
335     new_draw_info (NDI_BLACK, 0, op, errmsg);
336 elmex 1.1 }
337    
338     /*
339     * Initialise the hashtable used by the archetypes.
340     */
341    
342 root 1.12 void
343     clear_archetable (void)
344     {
345     memset ((void *) arch_table, 0, ARCHTABLE * sizeof (archetype *));
346 elmex 1.1 }
347    
348     /*
349     * An alternative way to init the hashtable which is slower, but _works_...
350     */
351    
352 root 1.12 void
353     init_archetable (void)
354     {
355 root 1.22 archetype *at;
356 root 1.12
357     LOG (llevDebug, " Setting up archetable...\n");
358    
359     for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more)
360 root 1.26 at->hash_add ();
361 root 1.12
362     LOG (llevDebug, "done\n");
363 elmex 1.1 }
364    
365 root 1.12 void
366     free_all_archs (void)
367 elmex 1.1 {
368 root 1.22 archetype *at, *next;
369     int i = 0, f = 0;
370 elmex 1.1
371 root 1.12 for (at = first_archetype; at != NULL; at = next)
372     {
373     if (at->more)
374     next = at->more;
375     else
376     next = at->next;
377    
378 root 1.16 delete
379     at;
380    
381 root 1.12 i++;
382 elmex 1.1 }
383 root 1.26
384 root 1.12 LOG (llevDebug, "Freed %d archetypes, %d faces\n", i, f);
385 elmex 1.1 }
386    
387 root 1.14 archetype::archetype ()
388 root 1.12 {
389 root 1.29 CLEAR_FLAG (&clone, FLAG_FREED); /* This shouldn't matter, since copy_to */
390 root 1.15 SET_FLAG (&clone, FLAG_REMOVED); /* doesn't copy these flags... */
391 root 1.14 }
392 elmex 1.1
393 root 1.14 archetype::~archetype ()
394     {
395 elmex 1.1 }
396    
397     /*
398     * Reads/parses the archetype-file, and copies into a linked list
399     * of archetype-structures.
400     */
401 root 1.12 void
402     first_arch_pass (object_thawer & fp)
403     {
404 root 1.27 archetype *head = 0, *last_more = 0;
405 root 1.12
406 root 1.27 archetype *at = new archetype;
407     at->clone.arch = first_archetype = at;
408 root 1.12
409 root 1.14 while (int i = load_object (fp, &at->clone, 0))
410 root 1.12 {
411     at->clone.speed_left = (float) (-0.1);
412     /* copy the body_info to the body_used - this is only really
413     * need for monsters, but doesn't hurt to do it for everything.
414     * by doing so, when a monster is created, it has good starting
415     * values for the body_used info, so when items are created
416     * for it, they can be properly equipped.
417     */
418 root 1.14 memcpy (&at->clone.body_used, &at->clone.body_info, sizeof (at->clone.body_info));
419 root 1.12
420     switch (i)
421     {
422 root 1.15 case LL_NORMAL: /* A new archetype, just link it with the previous */
423     if (last_more != NULL)
424     last_more->next = at;
425     if (head != NULL)
426     head->next = at;
427     head = last_more = at;
428 elmex 1.1 #if 0
429 root 1.15 if (!op->type)
430     LOG (llevDebug, " WARNING: Archetype %s has no type info!\n", op->arch->name);
431 elmex 1.1 #endif
432 root 1.15 at->tail_x = 0;
433     at->tail_y = 0;
434     break;
435    
436     case LL_MORE: /* Another part of the previous archetype, link it correctly */
437    
438     at->head = head;
439     at->clone.head = &head->clone;
440     if (last_more != NULL)
441     {
442     last_more->more = at;
443     last_more->clone.more = &at->clone;
444     }
445     last_more = at;
446    
447     /* If this multipart image is still composed of individual small
448     * images, don't set the tail_.. values. We can't use them anyways,
449     * and setting these to zero makes the map sending to the client much
450     * easier as just looking at the head, we know what to do.
451     */
452     if (at->clone.face != head->clone.face)
453     {
454     head->tail_x = 0;
455     head->tail_y = 0;
456     }
457     else
458     {
459     if (at->clone.x > head->tail_x)
460     head->tail_x = at->clone.x;
461     if (at->clone.y > head->tail_y)
462     head->tail_y = at->clone.y;
463     }
464     break;
465 root 1.7
466     }
467    
468 root 1.14 at = new archetype;
469 root 1.15
470 root 1.14 at->clone.arch = at;
471 elmex 1.1 }
472 root 1.10
473 root 1.16 delete at;
474 elmex 1.1 }
475    
476     /*
477     * Reads the archetype file once more, and links all pointers between
478     * archetypes.
479     */
480    
481 root 1.12 void
482     second_arch_pass (object_thawer & thawer)
483     {
484 root 1.22 char buf[MAX_BUF], *variable = buf, *argument, *cp;
485     archetype *at = NULL, *other;
486 root 1.12
487     while (fgets (buf, MAX_BUF, thawer) != NULL)
488     {
489     if (*buf == '#')
490     continue;
491     if ((argument = strchr (buf, ' ')) != NULL)
492     {
493     *argument = '\0', argument++;
494     cp = argument + strlen (argument) - 1;
495     while (isspace (*cp))
496     {
497     *cp = '\0';
498     cp--;
499     }
500     }
501     if (!strcmp ("Object", variable))
502     {
503 root 1.20 if ((at = archetype::find (argument)) == NULL)
504 root 1.12 LOG (llevError, "Warning: failed to find arch %s\n", argument);
505     }
506     else if (!strcmp ("other_arch", variable))
507     {
508     if (at != NULL && at->clone.other_arch == NULL)
509     {
510 root 1.20 if ((other = archetype::find (argument)) == NULL)
511 root 1.12 LOG (llevError, "Warning: failed to find other_arch %s\n", argument);
512     else if (at != NULL)
513     at->clone.other_arch = other;
514     }
515     }
516     else if (!strcmp ("randomitems", variable))
517     {
518     if (at != NULL)
519     {
520 root 1.24 treasurelist *tl = find_treasurelist (argument);
521 root 1.15
522 root 1.12 if (tl == NULL)
523     LOG (llevError, "Failed to link treasure to arch (%s): %s\n", &at->name, argument);
524     else
525     at->clone.randomitems = tl;
526     }
527     }
528 elmex 1.1 }
529     }
530    
531     #ifdef DEBUG
532 root 1.12 void
533     check_generators (void)
534     {
535 root 1.22 archetype *at;
536 root 1.15
537 root 1.12 for (at = first_archetype; at != NULL; at = at->next)
538     if (QUERY_FLAG (&at->clone, FLAG_GENERATOR) && at->clone.other_arch == NULL)
539     LOG (llevError, "Warning: %s is generator but lacks other_arch.\n", &at->name);
540 elmex 1.1 }
541     #endif
542    
543     /*
544     * First initialises the archtype hash-table (init_archetable()).
545     * Reads and parses the archetype file (with the first and second-pass
546     * functions).
547     * Then initialises treasures by calling load_treasures().
548     */
549    
550 root 1.8 void
551     load_archetypes (void)
552     {
553 root 1.22 char filename[MAX_BUF];
554 root 1.15
555 root 1.8 sprintf (filename, "%s/%s", settings.datadir, settings.archetypes);
556     LOG (llevDebug, "Reading archetypes from %s:\n", filename);
557    
558     {
559 root 1.16 object_thawer
560     thawer (filename);
561 root 1.8
562     clear_archetable ();
563     LOG (llevDebug, " arch-pass 1...\n");
564     first_arch_pass (thawer);
565     LOG (llevDebug, " done\n");
566 root 1.12 }
567 root 1.8
568 root 1.12 init_archetable ();
569     warn_archetypes = 1;
570 root 1.8
571     {
572 root 1.16 object_thawer
573     thawer (filename);
574 elmex 1.1
575 root 1.8 LOG (llevDebug, " loading treasure...\n");
576     load_treasures ();
577 pippijn 1.34 LOG (llevDebug, " done\n");
578     LOG (llevDebug, " arch-pass 2...\n");
579 root 1.8 second_arch_pass (thawer);
580     LOG (llevDebug, " done\n");
581 elmex 1.1 #ifdef DEBUG
582 root 1.8 check_generators ();
583 elmex 1.1 #endif
584 root 1.8 }
585     LOG (llevDebug, " done\n");
586 elmex 1.1 }
587    
588     /*
589     * Creates and returns a new object which is a copy of the given archetype.
590     * This function returns NULL on failure.
591     */
592 root 1.12 object *
593 root 1.15 arch_to_object (archetype *at)
594 root 1.12 {
595 root 1.22 object *op;
596 root 1.15
597 root 1.12 if (at == NULL)
598     {
599     if (warn_archetypes)
600     LOG (llevError, "Couldn't find archetype.\n");
601 root 1.15
602 root 1.12 return NULL;
603     }
604 root 1.15
605 root 1.30 op = at->clone.clone ();
606 root 1.15 op->arch = at;
607 root 1.2 op->instantiate ();
608 elmex 1.1 return op;
609     }
610    
611     /*
612     * Creates an object. This function is called by get_archetype()
613     * if it fails to find the appropriate archetype.
614     * Thus get_archetype() will be guaranteed to always return
615     * an object, and never NULL.
616     */
617 root 1.12 object *
618     create_singularity (const char *name)
619     {
620 root 1.22 object *op;
621 root 1.20 char buf[MAX_BUF];
622 root 1.15
623 root 1.12 sprintf (buf, "%s (%s)", ARCH_SINGULARITY, name);
624 root 1.29 op = object::create ();
625 root 1.10 op->name = op->name_pl = buf;
626 root 1.12 SET_FLAG (op, FLAG_NO_PICK);
627 elmex 1.1 return op;
628     }
629    
630     /*
631     * Finds which archetype matches the given name, and returns a new
632     * object containing a copy of the archetype.
633     */
634 root 1.12 object *
635     get_archetype (const char *name)
636     {
637 root 1.20 archetype *at = archetype::find (name);
638 root 1.15
639 root 1.20 if (!at)
640 root 1.12 return create_singularity (name);
641 root 1.15
642 root 1.12 return arch_to_object (at);
643 elmex 1.1 }
644    
645     /*
646     * Hash-function used by the arch-hashtable.
647     */
648    
649     unsigned long
650 root 1.12 hasharch (const char *str, int tablesize)
651 root 1.10 {
652 root 1.20 unsigned long hash = 0;
653     unsigned int i = 0;
654     const char *p;
655 root 1.10
656     /* use the one-at-a-time hash function, which supposedly is
657     * better than the djb2-like one used by perl5.005, but
658     * certainly is better then the bug used here before.
659     * see http://burtleburtle.net/bob/hash/doobs.html
660     */
661     for (p = str; i < MAXSTRING && *p; p++, i++)
662     {
663     hash += *p;
664     hash += hash << 10;
665 root 1.12 hash ^= hash >> 6;
666 root 1.10 }
667    
668 root 1.12 hash += hash << 3;
669 root 1.10 hash ^= hash >> 11;
670     hash += hash << 15;
671    
672     return hash % tablesize;
673 elmex 1.1 }
674    
675     /*
676     * Finds, using the hashtable, which archetype matches the given name.
677     * returns a pointer to the found archetype, otherwise NULL.
678     */
679    
680 root 1.12 archetype *
681 root 1.20 archetype::find (const char *name)
682 root 1.12 {
683     if (!name)
684     return 0;
685    
686 root 1.20 #if USE_UNORDERED_MAP
687 root 1.19 AUTODECL (i, ht.find ((size_t) name));
688 root 1.12
689     if (i == ht.end ())
690     return 0;
691     else
692     return i->second;
693     #endif
694    
695 root 1.20 archetype *at;
696     unsigned long index;
697 elmex 1.1
698 root 1.12 index = hasharch (name, ARCHTABLE);
699 elmex 1.1 arch_search++;
700 root 1.12 for (;;)
701     {
702     at = arch_table[index];
703 root 1.20
704 root 1.12 if (at == NULL)
705     {
706     if (warn_archetypes)
707     LOG (llevError, "Couldn't find archetype %s\n", name);
708 root 1.20
709 root 1.12 return NULL;
710     }
711 root 1.20
712 root 1.12 arch_cmp++;
713 root 1.20
714 root 1.12 if (!strcmp ((const char *) at->name, name))
715     return at;
716 root 1.20
717 root 1.12 if (++index >= ARCHTABLE)
718     index = 0;
719 elmex 1.1 }
720     }
721    
722     /*
723     * Adds an archetype to the hashtable.
724     */
725 root 1.26 void
726     archetype::hash_add ()
727     {
728     #if USE_UNORDERED_MAP
729     ht.insert (std::make_pair ((size_t) (const char *) name, this));
730     #else
731    
732     int index = hasharch ((const char *) name, ARCHTABLE), org_index = index;
733    
734     for (;;)
735     {
736     if (!arch_table[index])
737     {
738     arch_table[index] = this;
739     break;
740     }
741    
742     if (++index == ARCHTABLE)
743     index = 0;
744    
745     if (index == org_index)
746     fatal (ARCHTABLE_TOO_SMALL);
747     }
748     #endif
749     }
750 elmex 1.1
751 root 1.26 void
752     archetype::hash_del ()
753 root 1.12 {
754     #if USE_UNORDERED_MAP
755 root 1.26 # error remove this from HT
756     #else
757 root 1.12
758 root 1.26 int index = hasharch ((const char *) name, ARCHTABLE), org_index = index;
759 root 1.12
760     for (;;)
761     {
762 root 1.26 if (arch_table[index] == this)
763 root 1.12 {
764 root 1.26 arch_table[index] = 0;
765     break;
766 root 1.12 }
767    
768     if (++index == ARCHTABLE)
769     index = 0;
770    
771     if (index == org_index)
772 root 1.26 break;
773 root 1.12 }
774 root 1.26 #endif
775 elmex 1.1 }
776    
777     /*
778     * Returns the first archetype using the given type.
779     * Used in treasure-generation.
780     */
781    
782 root 1.12 archetype *
783     type_to_archetype (int type)
784     {
785 root 1.20 archetype *at;
786 elmex 1.1
787 root 1.20 for (at = first_archetype; at; at = at->more == 0 ? at->next : at->more)
788 root 1.12 if (at->clone.type == type)
789 elmex 1.1 return at;
790 root 1.20
791     return 0;
792 elmex 1.1 }
793    
794     /*
795     * Returns a new object copied from the first archetype matching
796     * the given type.
797     * Used in treasure-generation.
798     */
799    
800 root 1.12 object *
801     clone_arch (int type)
802     {
803 root 1.20 archetype *at;
804 elmex 1.1
805 root 1.12 if ((at = type_to_archetype (type)) == NULL)
806     {
807     LOG (llevError, "Can't clone archetype %d\n", type);
808 root 1.30 return 0;
809 root 1.12 }
810 root 1.20
811 root 1.30 object *op = at->clone.clone ();
812 root 1.3 op->instantiate ();
813 elmex 1.1 return op;
814     }
815    
816     /*
817     * member: make instance from class
818     */
819    
820 root 1.12 object *
821 root 1.15 object_create_arch (archetype *at)
822 elmex 1.1 {
823 root 1.20 object *op, *prev = 0, *head = 0;
824 elmex 1.1
825 root 1.12 while (at)
826     {
827     op = arch_to_object (at);
828     op->x = at->clone.x;
829     op->y = at->clone.y;
830 root 1.20
831 root 1.12 if (head)
832     op->head = head, prev->more = op;
833 root 1.20
834 root 1.12 if (!head)
835     head = op;
836 root 1.20
837 root 1.12 prev = op;
838     at = at->more;
839 elmex 1.1 }
840 root 1.20
841 root 1.12 return (head);
842 elmex 1.1 }
843