1 /**
2  * \file obj-tval.c
3  * \brief Wrapper functions for tvals.
4  *
5  * Copyright (c) 2014 Ben Semmler
6  *
7  * This work is free software; you can redistribute it and/or modify it
8  * under the terms of either:
9  *
10  * a) the GNU General Public License as published by the Free Software
11  *    Foundation, version 2, or
12  *
13  * b) the "Angband licence":
14  *    This software may be copied and distributed for educational, research,
15  *    and not for profit purposes provided that this copyright and statement
16  *    are included in all such copies.  Other copyrights may also apply.
17  */
18 
19 #include "init.h"
20 #include "obj-tval.h"
21 #include "z-type.h"
22 #include "z-util.h"
23 
tval_is_staff(const struct object * obj)24 bool tval_is_staff(const struct object *obj)
25 {
26 	return obj->tval == TV_STAFF;
27 }
28 
tval_is_wand(const struct object * obj)29 bool tval_is_wand(const struct object *obj)
30 {
31 	return obj->tval == TV_WAND;
32 }
33 
tval_is_rod(const struct object * obj)34 bool tval_is_rod(const struct object *obj)
35 {
36 	return obj->tval == TV_ROD;
37 }
38 
tval_is_potion(const struct object * obj)39 bool tval_is_potion(const struct object *obj)
40 {
41 	return obj->tval == TV_POTION;
42 }
43 
tval_is_scroll(const struct object * obj)44 bool tval_is_scroll(const struct object *obj)
45 {
46 	return obj->tval == TV_SCROLL;
47 }
48 
tval_is_food(const struct object * obj)49 bool tval_is_food(const struct object *obj)
50 {
51 	return obj->tval == TV_FOOD;
52 }
53 
tval_is_food_k(const struct object_kind * kind)54 bool tval_is_food_k(const struct object_kind *kind)
55 {
56 	return kind->tval == TV_FOOD;
57 }
58 
tval_is_mushroom(const struct object * obj)59 bool tval_is_mushroom(const struct object *obj)
60 {
61 	return obj->tval == TV_MUSHROOM;
62 }
63 
tval_is_mushroom_k(const struct object_kind * kind)64 bool tval_is_mushroom_k(const struct object_kind *kind)
65 {
66 	return kind->tval == TV_MUSHROOM;
67 }
68 
tval_is_light(const struct object * obj)69 bool tval_is_light(const struct object *obj)
70 {
71 	return obj->tval == TV_LIGHT;
72 }
73 
tval_is_light_k(const struct object_kind * kind)74 bool tval_is_light_k(const struct object_kind *kind)
75 {
76 	return kind->tval == TV_LIGHT;
77 }
78 
tval_is_ring(const struct object * obj)79 bool tval_is_ring(const struct object *obj)
80 {
81 	return obj->tval == TV_RING;
82 }
83 
tval_is_chest(const struct object * obj)84 bool tval_is_chest(const struct object *obj)
85 {
86 	return obj->tval == TV_CHEST;
87 }
88 
tval_is_fuel(const struct object * obj)89 bool tval_is_fuel(const struct object *obj)
90 {
91 	return obj->tval == TV_FLASK;
92 }
93 
tval_is_money(const struct object * obj)94 bool tval_is_money(const struct object *obj)
95 {
96 	return obj->tval == TV_GOLD;
97 }
98 
tval_is_money_k(const struct object_kind * kind)99 bool tval_is_money_k(const struct object_kind *kind)
100 {
101 	return kind->tval == TV_GOLD;
102 }
103 
tval_is_digger(const struct object * obj)104 bool tval_is_digger(const struct object *obj)
105 {
106 	return obj->tval == TV_DIGGING;
107 }
108 
tval_can_have_nourishment(const struct object * obj)109 bool tval_can_have_nourishment(const struct object *obj)
110 {
111 	return obj->tval == TV_FOOD || obj->tval == TV_POTION ||
112 			obj->tval == TV_MUSHROOM;
113 }
114 
tval_can_have_charges(const struct object * obj)115 bool tval_can_have_charges(const struct object *obj)
116 {
117 	return obj->tval == TV_STAFF || obj->tval == TV_WAND;
118 }
119 
tval_can_have_timeout(const struct object * obj)120 bool tval_can_have_timeout(const struct object *obj)
121 {
122 	return obj->tval == TV_ROD;
123 }
124 
tval_is_body_armor(const struct object * obj)125 bool tval_is_body_armor(const struct object *obj)
126 {
127 	switch (obj->tval) {
128 		case TV_SOFT_ARMOR:
129 		case TV_HARD_ARMOR:
130 		case TV_DRAG_ARMOR:
131 			return true;
132 		default:
133 			return false;
134 	}
135 }
136 
tval_is_head_armor(const struct object * obj)137 bool tval_is_head_armor(const struct object *obj)
138 {
139 	return obj->tval == TV_HELM || obj->tval == TV_CROWN;
140 }
141 
tval_is_ammo(const struct object * obj)142 bool tval_is_ammo(const struct object *obj)
143 {
144 	switch (obj->tval) {
145 		case TV_SHOT:
146 		case TV_ARROW:
147 		case TV_BOLT:
148 			return true;
149 		default:
150 			return false;
151 	}
152 }
153 
tval_is_sharp_missile(const struct object * obj)154 bool tval_is_sharp_missile(const struct object *obj)
155 {
156 	switch (obj->tval) {
157 		case TV_ARROW:
158 		case TV_BOLT:
159 			return true;
160 		default:
161 			return false;
162 	}
163 }
164 
tval_is_launcher(const struct object * obj)165 bool tval_is_launcher(const struct object *obj)
166 {
167 	return obj->tval == TV_BOW;
168 }
169 
tval_is_useable(const struct object * obj)170 bool tval_is_useable(const struct object *obj)
171 {
172 	switch (obj->tval) {
173 		case TV_ROD:
174 		case TV_WAND:
175 		case TV_STAFF:
176 		case TV_SCROLL:
177 		case TV_POTION:
178 		case TV_FOOD:
179 		case TV_MUSHROOM:
180 			return true;
181 		default:
182 			return false;
183 	}
184 }
185 
tval_can_have_failure(const struct object * obj)186 bool tval_can_have_failure(const struct object *obj)
187 {
188 	switch (obj->tval) {
189 		case TV_STAFF:
190 		case TV_WAND:
191 		case TV_ROD:
192 			return true;
193 		default:
194 			return false;
195 	}
196 }
197 
tval_is_jewelry(const struct object * obj)198 bool tval_is_jewelry(const struct object *obj)
199 {
200 	return obj->tval == TV_RING || obj->tval == TV_AMULET;
201 }
202 
tval_is_weapon(const struct object * obj)203 bool tval_is_weapon(const struct object *obj)
204 {
205 	switch (obj->tval) {
206 		case TV_SWORD:
207 		case TV_HAFTED:
208 		case TV_POLEARM:
209 		case TV_DIGGING:
210 		case TV_BOW:
211 		case TV_BOLT:
212 		case TV_ARROW:
213 		case TV_SHOT:
214 			return true;
215 		default:
216 			return false;
217 	}
218 }
219 
tval_is_armor(const struct object * obj)220 bool tval_is_armor(const struct object *obj)
221 {
222 	switch (obj->tval) {
223 		case TV_DRAG_ARMOR:
224 		case TV_HARD_ARMOR:
225 		case TV_SOFT_ARMOR:
226 		case TV_SHIELD:
227 		case TV_CLOAK:
228 		case TV_CROWN:
229 		case TV_HELM:
230 		case TV_BOOTS:
231 		case TV_GLOVES:
232 			return true;
233 		default:
234 			return false;
235 	}
236 }
237 
tval_is_melee_weapon(const struct object * obj)238 bool tval_is_melee_weapon(const struct object *obj)
239 {
240 	switch (obj->tval) {
241 		case TV_SWORD:
242 		case TV_HAFTED:
243 		case TV_POLEARM:
244 		case TV_DIGGING:
245 			return true;
246 		default:
247 			return false;
248 	}
249 }
250 
tval_has_variable_power(const struct object * obj)251 bool tval_has_variable_power(const struct object *obj)
252 {
253 	switch (obj->tval) {
254 		case TV_SHOT:
255 		case TV_ARROW:
256 		case TV_BOLT:
257 		case TV_BOW:
258 		case TV_DIGGING:
259 		case TV_HAFTED:
260 		case TV_POLEARM:
261 		case TV_SWORD:
262 		case TV_BOOTS:
263 		case TV_GLOVES:
264 		case TV_HELM:
265 		case TV_CROWN:
266 		case TV_SHIELD:
267 		case TV_CLOAK:
268 		case TV_SOFT_ARMOR:
269 		case TV_HARD_ARMOR:
270 		case TV_DRAG_ARMOR:
271 		case TV_LIGHT:
272 		case TV_AMULET:
273 		case TV_RING:
274 			return true;
275 		default:
276 			return false;
277 	}
278 }
279 
tval_is_wearable(const struct object * obj)280 bool tval_is_wearable(const struct object *obj)
281 {
282 	switch (obj->tval) {
283 		case TV_BOW:
284 		case TV_DIGGING:
285 		case TV_HAFTED:
286 		case TV_POLEARM:
287 		case TV_SWORD:
288 		case TV_BOOTS:
289 		case TV_GLOVES:
290 		case TV_HELM:
291 		case TV_CROWN:
292 		case TV_SHIELD:
293 		case TV_CLOAK:
294 		case TV_SOFT_ARMOR:
295 		case TV_HARD_ARMOR:
296 		case TV_DRAG_ARMOR:
297 		case TV_LIGHT:
298 		case TV_AMULET:
299 		case TV_RING:
300 			return true;
301 		default:
302 			return false;
303 	}
304 }
305 
tval_is_edible(const struct object * obj)306 bool tval_is_edible(const struct object *obj)
307 {
308 	switch (obj->tval) {
309 		case TV_FOOD:
310 		case TV_MUSHROOM:
311 			return true;
312 		default:
313 			return false;
314 	}
315 }
316 
tval_can_have_flavor_k(const struct object_kind * kind)317 bool tval_can_have_flavor_k(const struct object_kind *kind)
318 {
319 	switch (kind->tval) {
320 		case TV_AMULET:
321 		case TV_RING:
322 		case TV_STAFF:
323 		case TV_WAND:
324 		case TV_ROD:
325 		case TV_POTION:
326 		case TV_MUSHROOM:
327 		case TV_SCROLL:
328 			return true;
329 		default:
330 			return false;
331 	}
332 }
333 
tval_is_book_k(const struct object_kind * kind)334 bool tval_is_book_k(const struct object_kind *kind)
335 {
336 	switch (kind->tval) {
337 		case TV_MAGIC_BOOK:
338 		case TV_PRAYER_BOOK:
339 		case TV_NATURE_BOOK:
340 		case TV_SHADOW_BOOK:
341 		case TV_OTHER_BOOK:
342 			return true;
343 		default:
344 			return false;
345 	}
346 }
347 
tval_is_zapper(const struct object * obj)348 bool tval_is_zapper(const struct object *obj)
349 {
350 	return obj->tval == TV_WAND || obj->tval == TV_STAFF;
351 }
352 
353 /**
354  * List of { tval, name } pairs.
355  */
356 static const grouper tval_names[] =
357 {
358 	#define TV(a, b, c) { TV_##a, b },
359 	#include "list-tvals.h"
360 	#undef TV
361 };
362 
363 /**
364  * Small hack to allow both spellings of armer
365  */
de_armour(const char * name)366 char *de_armour(const char *name)
367 {
368 	char newname[40];
369 	char *armour;
370 
371 	my_strcpy(newname, name, sizeof(newname));
372 	armour = strstr(newname, "armour");
373 	if (armour)
374 		my_strcpy(armour + 4, "r", 2);
375 
376 	return string_make(newname);
377 }
378 
379 /**
380  * Returns the numeric equivalent tval of the textual tval `name`.
381  */
tval_find_idx(const char * name)382 int tval_find_idx(const char *name)
383 {
384 	size_t i = 0;
385 	unsigned int r;
386 	char *mod_name;
387 
388 	if (sscanf(name, "%u", &r) == 1)
389 		return r;
390 
391 	mod_name = de_armour(name);
392 
393 	for (i = 0; i < N_ELEMENTS(tval_names); i++) {
394 		if (!my_stricmp(mod_name, tval_names[i].name)) {
395 			string_free(mod_name);
396 			return tval_names[i].tval;
397 		}
398 	}
399 
400 	string_free(mod_name);
401 	return -1;
402 }
403 
404 /**
405  * Returns the textual equivalent tval of the numeric tval `name`.
406  */
tval_find_name(int tval)407 const char *tval_find_name(int tval)
408 {
409 	size_t i = 0;
410 
411 	for (i = 0; i < N_ELEMENTS(tval_names); i++)
412 	{
413 		if (tval == tval_names[i].tval)
414 			return tval_names[i].name;
415 	}
416 
417 	return "unknown";
418 }
419 
420 /**
421  * Counts the svals (from object.txt) of a given non-null tval
422  */
tval_sval_count(const char * name)423 int tval_sval_count(const char *name)
424 {
425 	size_t i, num = 0;
426 	int tval = tval_find_idx(name);
427 
428 	if (tval < 0) return 0;
429 
430 	for (i = 0; i < z_info->k_max; i++) {
431 		struct object_kind *kind = &k_info[i];
432 
433 		if (!kind->tval) continue;
434 		if (kind->tval != tval) continue;
435 		num++;
436 	}
437 
438 	return num;
439 }
440 
441 /**
442  * Lists up to max_size svals (from object.txt) of a given non-null tval
443  * Assumes list has allocated space for at least max_size elements
444  */
tval_sval_list(const char * name,int * list,int max_size)445 int tval_sval_list(const char *name, int *list, int max_size)
446 {
447 	size_t i;
448 	int num = 0;
449 	int tval = tval_find_idx(name);
450 
451 	if (tval < 0) return 0;
452 
453 	for (i = 0; i < z_info->k_max; i++) {
454 		struct object_kind *kind = &k_info[i];
455 
456 		if (!kind->tval) continue;
457 		if (kind->tval != tval) continue;
458 		if (num >= max_size) break;
459 		list[num++] = kind->sval;
460 	}
461 
462 	return num;
463 }
464