Atrinik Server  4.0
race.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
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 author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
30 #include <global.h>
31 #include <arch.h>
32 
37 const char *item_races[NROF_ITEM_RACES] = {
38  "", "dwarven ", "elven ", "gnomish ", "drow ", "orcish ", "goblin ",
39  "kobold ", "giant ", "tiny ", "demonish ", "draconish ", "ogre "
40 };
41 
45 static ob_race *races = NULL;
49 static size_t num_races = 0;
50 
58 static void race_add_corpse(shstr *race_name, archetype_t *at)
59 {
60  ob_race *race;
61 
62  if (!at || !race_name) {
63  return;
64  }
65 
66  race = race_find(race_name);
67 
68  if (!race) {
69  return;
70  }
71 
72  race->corpse = at;
73 }
74 
82 static void race_add(shstr *race_name, object *ob)
83 {
84  ob_race *race;
85  objectlink *ol;
86 
87  if (!ob || !race_name) {
88  return;
89  }
90 
91  race = race_find(race_name);
92 
93  /* No such race yet? Initialize it then. */
94  if (!race) {
95  size_t i, ii;
96 
97  races = erealloc(races, sizeof(ob_race) * (num_races + 1));
98 
99  /* Now, insert the race into the correct spot in the array. */
100  for (i = 0; i < num_races; i++) {
101  if (races[i].name > race_name) {
102  break;
103  }
104  }
105 
106  /* If this is not the special case of insertion at the last point, then
107  * shift everything. */
108  for (ii = num_races; ii > i; ii--) {
109  races[ii] = races[ii - 1];
110  }
111 
112  memset(&races[i], 0, sizeof(ob_race));
113  FREE_AND_COPY_HASH(races[i].name, race_name);
114  race = &races[i];
115  num_races++;
116  }
117 
118  ol = get_objectlink();
119  ol->objlink.ob = ob;
120  ol->id = ob->count;
121  /* Link the new object link to the race's list. */
122  objectlink_link(&race->members, NULL, NULL, race->members, ol);
123  /* Increase the number of race's members. */
124  race->num_members++;
125 }
126 
130 static int race_compare(const void *one, const void *two)
131 {
132  const ob_race *one_race = one;
133  const ob_race *two_race = two;
134 
135  if (one == NULL) {
136  return -1;
137  } else if (two == NULL) {
138  return 1;
139  }
140 
141  if (one_race->name < two_race->name) {
142  return -1;
143  } else if (one_race->name > two_race->name) {
144  return 1;
145  } else {
146  return 0;
147  }
148 }
149 
157 ob_race *race_find(shstr *name)
158 {
159  ob_race key;
160 
161  if (!races || !name) {
162  return NULL;
163  }
164 
165  key.name = name;
166 
167  return bsearch(&key, races, num_races, sizeof(ob_race), race_compare);
168 }
169 
176 {
177  if (!races || !num_races) {
178  return NULL;
179  }
180 
181  return &races[rndm(1, num_races) - 1];
182 }
183 
188 void race_init(void)
189 {
190  size_t i;
191 
192  races = NULL;
193  num_races = 0;
194 
195  archetype_t *at, *tmp;
196  HASH_ITER(hh, arch_table, at, tmp) {
197  if (at->clone.type == MONSTER || at->clone.type == PLAYER) {
198  race_add(at->clone.race, &at->clone);
199  } else if (at->clone.type == CONTAINER &&
201  race_add_corpse(at->clone.race, at);
202  }
203  }
204 
205  /* Try to find the default corpse archetype. */
207 
208  if (!tmp) {
209  LOG(ERROR, "Can't find required archetype: '%s'.", RACE_CORPSE_DEFAULT);
210  exit(1);
211  }
212 
213  /* Look through the races, and assign the default corpse archetype
214  * to those which do not have any yet. */
215  for (i = 0; i < num_races; i++) {
216  if (!races[i].corpse) {
217  races[i].corpse = tmp;
218  }
219  }
220 }
221 
225 void race_free(void)
226 {
227  size_t i;
228  objectlink *ol, *ol_next;
229 
230  for (i = 0; i < num_races; i++) {
231  FREE_ONLY_HASH(races[i].name);
232 
233  for (ol = races[i].members; ol; ol = ol_next) {
234  ol_next = ol->next;
235  free_objectlink_simple(ol);
236  }
237  }
238 
239  efree(races);
240 }
struct archetype * corpse
Definition: race.h:45
#define FREE_AND_COPY_HASH(_sv_, _nv_)
Definition: global.h:100
archetype_t * arch_table
Definition: arch.c:41
#define MONSTER
Definition: define.h:353
struct oblnk * members
Definition: race.h:50
ob_race * race_find(shstr *name)
Definition: race.c:157
Definition: object.h:488
const char * race
Definition: object.h:174
static size_t num_races
Definition: race.c:49
void race_init(void)
Definition: race.c:188
#define NROF_ITEM_RACES
Definition: race.h:72
static void race_add(shstr *race_name, object *ob)
Definition: race.c:82
#define ST1_CONTAINER_CORPSE
Definition: define.h:568
#define PLAYER
Definition: define.h:122
int num_members
Definition: race.h:55
tag_t id
Definition: object.h:506
object * ob
Definition: object.h:496
#define RACE_CORPSE_DEFAULT
Definition: race.h:62
Definition: arch.h:40
#define CONTAINER
Definition: define.h:493
union oblnk::@3 objlink
shstr * name
Definition: race.h:40
static void race_add_corpse(shstr *race_name, archetype_t *at)
Definition: race.c:58
Definition: race.h:36
static int race_compare(const void *one, const void *two)
Definition: race.c:130
static ob_race * races
Definition: race.c:45
void race_free(void)
Definition: race.c:225
tag_t count
Definition: object.h:142
struct oblnk * next
Definition: object.h:500
uint8_t type
Definition: object.h:360
ob_race * race_get_random(void)
Definition: race.c:175
#define FREE_ONLY_HASH(_nv_)
Definition: global.h:143
const char * item_races[NROF_ITEM_RACES]
Definition: race.c:37
object clone
An object from which to do object_copy().
Definition: arch.h:47
archetype_t * arch_find(const char *name)
Definition: arch.c:407
uint8_t sub_type
Definition: object.h:363