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)
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 ***********************************************************************/
15 #include <fc_config.h>
21 #include "string_vector.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)
40 for (i
= 0; i
< ARRAY_SIZE(specialists
); i
++) {
41 struct specialist
*p
= &specialists
[i
];
45 requirement_vector_init(&p
->reqs
);
49 /****************************************************************************
50 Free data for specialists.
51 ****************************************************************************/
52 void specialists_free(void)
56 for (i
= 0; i
< ARRAY_SIZE(specialists
); i
++) {
57 struct specialist
*p
= &specialists
[i
];
59 requirement_vector_free(&p
->reqs
);
60 if (NULL
!= p
->helptext
) {
61 strvec_destroy(p
->helptext
);
67 /**************************************************************************
68 Return the number of specialist_types.
69 **************************************************************************/
70 Specialist_type_id
specialist_count(void)
72 return game
.control
.num_specialist_types
;
75 /****************************************************************************
76 Return the specialist index.
78 Currently same as specialist_number(), paired with specialist_count()
79 indicates use as an array index.
80 ****************************************************************************/
81 Specialist_type_id
specialist_index(const struct specialist
*sp
)
83 fc_assert_ret_val(NULL
!= sp
, -1);
84 return sp
- specialists
;
87 /****************************************************************************
88 Return the specialist item_number.
89 ****************************************************************************/
90 Specialist_type_id
specialist_number(const struct specialist
*sp
)
92 fc_assert_ret_val(NULL
!= sp
, -1);
93 return sp
->item_number
;
96 /****************************************************************************
97 Return the specialist pointer for the given number.
98 ****************************************************************************/
99 struct specialist
*specialist_by_number(const Specialist_type_id id
)
101 if (id
< 0 || id
>= game
.control
.num_specialist_types
) {
104 return &specialists
[id
];
107 /****************************************************************************
108 Return the specialist type with the given (untranslated!) rule name.
109 Returns NULL if none match.
110 ****************************************************************************/
111 struct specialist
*specialist_by_rule_name(const char *name
)
113 const char *qname
= Qn_(name
);
115 specialist_type_iterate(i
) {
116 struct specialist
*sp
= specialist_by_number(i
);
117 if (0 == fc_strcasecmp(specialist_rule_name(sp
), qname
)) {
120 } specialist_type_iterate_end
;
125 /****************************************************************************
126 Return the specialist type with the given (translated, plural) name.
127 Returns NULL if none match.
128 ****************************************************************************/
129 struct specialist
*specialist_by_translated_name(const char *name
)
131 specialist_type_iterate(i
) {
132 struct specialist
*sp
= specialist_by_number(i
);
133 if (0 == strcmp(specialist_plural_translation(sp
), name
)) {
136 } specialist_type_iterate_end
;
141 /**************************************************************************
142 Return the (untranslated) rule name of the specialist type.
143 You don't have to free the return pointer.
144 **************************************************************************/
145 const char *specialist_rule_name(const struct specialist
*sp
)
147 return rule_name(&sp
->name
);
150 /**************************************************************************
151 Return the (translated, plural) name of the specialist type.
152 You don't have to free the return pointer.
153 **************************************************************************/
154 const char *specialist_plural_translation(const struct specialist
*sp
)
156 return name_translation(&sp
->name
);
159 /**************************************************************************
160 Return the (translated) abbreviation of the specialist type.
161 You don't have to free the return pointer.
162 **************************************************************************/
163 const char *specialist_abbreviation_translation(const struct specialist
*sp
)
165 return name_translation(&sp
->abbreviation
);
168 /****************************************************************************
169 Return a string containing all the specialist abbreviations, for instance
171 You don't have to free the return pointer.
172 ****************************************************************************/
173 const char *specialists_abbreviation_string(void)
175 static char buf
[5 * SP_MAX
];
179 specialist_type_iterate(sp
) {
180 char *separator
= (buf
[0] == '\0') ? "" : "/";
182 cat_snprintf(buf
, sizeof(buf
), "%s%s", separator
,
183 specialist_abbreviation_translation(specialist_by_number(sp
)));
184 } specialist_type_iterate_end
;
189 /****************************************************************************
190 Return a string showing the number of specialists in the array.
192 For instance with a city with (0,3,1) specialists call
194 specialists_string(pcity->specialists);
196 and you'll get "0/3/1".
197 ****************************************************************************/
198 const char *specialists_string(const citizens
*specialists
)
200 static char buf
[5 * SP_MAX
];
204 specialist_type_iterate(sp
) {
205 char *separator
= (buf
[0] == '\0') ? "" : "/";
207 cat_snprintf(buf
, sizeof(buf
), "%s%d", separator
, specialists
[sp
]);
208 } specialist_type_iterate_end
;
213 /****************************************************************************
214 Return the output for the specialist type with this output type.
215 ****************************************************************************/
216 int get_specialist_output(const struct city
*pcity
,
217 Specialist_type_id sp
, Output_type_id otype
)
219 struct specialist
*pspecialist
= &specialists
[sp
];
220 struct output_type
*poutput
= get_output_type(otype
);
222 return get_city_specialist_output_bonus(pcity
, pspecialist
, poutput
,
223 EFT_SPECIALIST_OUTPUT
);