Stop sharing requirement_unit_state_ereq().
[freeciv.git] / common / specialist.c
blob603b5e7c4a6ac1d50ed0922c5b5259572a85e14a
1 /***********************************************************************
2 Freeciv - Copyright (C) 2005 - The Freeciv Project
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 /* utility */
19 #include "fcintl.h"
20 #include "log.h"
21 #include "string_vector.h"
23 /* common */
24 #include "city.h"
25 #include "effects.h"
26 #include "game.h"
28 #include "specialist.h"
30 struct specialist specialists[SP_MAX];
31 int default_specialist;
33 /****************************************************************************
34 Initialize data for specialists.
35 ****************************************************************************/
36 void specialists_init(void)
38 int i;
40 for (i = 0; i < ARRAY_SIZE(specialists); i++) {
41 struct specialist *p = &specialists[i];
43 p->item_number = i;
44 p->disabled = FALSE;
46 requirement_vector_init(&p->reqs);
50 /****************************************************************************
51 Free data for specialists.
52 ****************************************************************************/
53 void specialists_free(void)
55 int i;
57 for (i = 0; i < ARRAY_SIZE(specialists); i++) {
58 struct specialist *p = &specialists[i];
60 requirement_vector_free(&p->reqs);
61 if (NULL != p->helptext) {
62 strvec_destroy(p->helptext);
63 p->helptext = NULL;
68 /**************************************************************************
69 Return the number of specialist_types.
70 **************************************************************************/
71 Specialist_type_id specialist_count(void)
73 return game.control.num_specialist_types;
76 /****************************************************************************
77 Return the specialist index.
79 Currently same as specialist_number(), paired with specialist_count()
80 indicates use as an array index.
81 ****************************************************************************/
82 Specialist_type_id specialist_index(const struct specialist *sp)
84 fc_assert_ret_val(NULL != sp, -1);
85 return sp - specialists;
88 /****************************************************************************
89 Return the specialist item_number.
90 ****************************************************************************/
91 Specialist_type_id specialist_number(const struct specialist *sp)
93 fc_assert_ret_val(NULL != sp, -1);
94 return sp->item_number;
97 /****************************************************************************
98 Return the specialist pointer for the given number.
99 ****************************************************************************/
100 struct specialist *specialist_by_number(const Specialist_type_id id)
102 if (id < 0 || id >= game.control.num_specialist_types) {
103 return NULL;
105 return &specialists[id];
108 /****************************************************************************
109 Return the specialist type with the given (untranslated!) rule name.
110 Returns NULL if none match.
111 ****************************************************************************/
112 struct specialist *specialist_by_rule_name(const char *name)
114 const char *qname = Qn_(name);
116 specialist_type_iterate(i) {
117 struct specialist *sp = specialist_by_number(i);
118 if (0 == fc_strcasecmp(specialist_rule_name(sp), qname)) {
119 return sp;
121 } specialist_type_iterate_end;
123 return NULL;
126 /****************************************************************************
127 Return the specialist type with the given (translated, plural) name.
128 Returns NULL if none match.
129 ****************************************************************************/
130 struct specialist *specialist_by_translated_name(const char *name)
132 specialist_type_iterate(i) {
133 struct specialist *sp = specialist_by_number(i);
134 if (0 == strcmp(specialist_plural_translation(sp), name)) {
135 return sp;
137 } specialist_type_iterate_end;
139 return NULL;
142 /**************************************************************************
143 Return the (untranslated) rule name of the specialist type.
144 You don't have to free the return pointer.
145 **************************************************************************/
146 const char *specialist_rule_name(const struct specialist *sp)
148 return rule_name_get(&sp->name);
151 /**************************************************************************
152 Return the (translated, plural) name of the specialist type.
153 You don't have to free the return pointer.
154 **************************************************************************/
155 const char *specialist_plural_translation(const struct specialist *sp)
157 return name_translation_get(&sp->name);
160 /**************************************************************************
161 Return the (translated) abbreviation of the specialist type.
162 You don't have to free the return pointer.
163 **************************************************************************/
164 const char *specialist_abbreviation_translation(const struct specialist *sp)
166 return name_translation_get(&sp->abbreviation);
169 /****************************************************************************
170 Return a string containing all the specialist abbreviations, for instance
171 "E/S/T".
172 You don't have to free the return pointer.
173 ****************************************************************************/
174 const char *specialists_abbreviation_string(void)
176 static char buf[5 * SP_MAX];
178 buf[0] = '\0';
180 specialist_type_iterate(sp) {
181 char *separator = (buf[0] == '\0') ? "" : "/";
183 cat_snprintf(buf, sizeof(buf), "%s%s", separator,
184 specialist_abbreviation_translation(specialist_by_number(sp)));
185 } specialist_type_iterate_end;
187 return buf;
190 /****************************************************************************
191 Return a string showing the number of specialists in the array.
193 For instance with a city with (0,3,1) specialists call
195 specialists_string(pcity->specialists);
197 and you'll get "0/3/1".
198 ****************************************************************************/
199 const char *specialists_string(const citizens *specialist_list)
201 static char buf[5 * SP_MAX];
203 buf[0] = '\0';
205 specialist_type_iterate(sp) {
206 char *separator = (buf[0] == '\0') ? "" : "/";
208 cat_snprintf(buf, sizeof(buf), "%s%d", separator, specialist_list[sp]);
209 } specialist_type_iterate_end;
211 return buf;
214 /****************************************************************************
215 Return the output for the specialist type with this output type.
216 ****************************************************************************/
217 int get_specialist_output(const struct city *pcity,
218 Specialist_type_id sp, Output_type_id otype)
220 struct specialist *pspecialist = &specialists[sp];
221 struct output_type *poutput = get_output_type(otype);
223 return get_city_specialist_output_bonus(pcity, pspecialist, poutput,
224 EFT_SPECIALIST_OUTPUT);