1 /*
2  * items.h
3  * Copyright (C) 2009-2018 Joachim de Groot <jdegroot@web.de>
4  *
5  * NLarn is free software: you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * NLarn is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef __ITEM_H_
20 #define __ITEM_H_
21 
22 #include <glib.h>
23 
24 #include "effects.h"
25 
26 typedef enum item_types {
27     IT_NONE,
28     IT_AMULET,          /* amulet, defined in amulets.h */
29     IT_AMMO,            /* ammunition, defined in weapons.h */
30     IT_ARMOUR,          /* armour, defined in armour.h */
31     IT_BOOK,            /* book, defined in spells.h */
32     IT_CONTAINER,       /* container, defined in container.h */
33     IT_GEM,             /* gem, defined in gems.h */
34     IT_GOLD,            /* just gold. defined nowhere as type and count are sufficient. */
35     IT_POTION,          /* potion, defined in potions.h */
36     IT_RING,            /* ring, defined in rings.h */
37     IT_SCROLL,          /* magic_scroll, defined in scrolls.h */
38     IT_WEAPON,          /* weapon, defined in weapons.h */
39     IT_MAX,             /* ~ item type count */
40     IT_ALL             /* for special uses: all item types */
41 } item_t;
42 
43 /* inspired by Nethack's objclass.h */
44 typedef enum item_material_t {
45     IM_PAPER,
46     IM_CLOTH,
47     IM_LEATHER,
48     IM_WOOD,
49     IM_BONE,
50     /* materials up to here can burn */
51     IM_DRAGON_HIDE,     /* not leather! */
52     IM_LEAD,
53     IM_IRON,            /* Fe, can rust/corrode */
54     IM_STEEL,           /* stainless steel */
55     IM_COPPER,          /* Cu - includes brass */
56     IM_SILVER,
57     IM_GOLD,            /* Au */
58     IM_PLATINUM,        /* Pt */
59     IM_MITHRIL,
60     IM_GLASS,
61     IM_STONE,
62     IM_GEMSTONE,
63     IM_MAX              /* ~ item material count */
64 } item_material_t;
65 
66 typedef struct item_material_data {
67     item_material_t type;
68     const char *name;
69     const char *adjective;
70     int colour;
71     guint fragility;
72 } item_material_data;
73 
74 typedef struct item_usage_result
75 {
76     int identified;
77     int used_up;
78 } item_usage_result;
79 
80 typedef enum item_erosion_t {
81     IET_NONE,
82     IET_BURN,
83     IET_CORRODE,
84     IET_RUST,
85     IET_MAX
86 } item_erosion_type;
87 
88 struct game;
89 struct _inventory;
90 
91 typedef struct _item {
92     gpointer oid;           /* item's game object id */
93     item_t type;            /* element type */
94     guint32 id;             /* item id, type specific */
95     gint32 bonus;
96     guint32 count;          /* for stackable items */
97     GPtrArray *effects;     /* storage for effects */
98     struct _inventory *content;     /* for containers */
99     char *notes;            /* storage for player's notes about the item */
100     guint32
101         blessed: 1,
102         cursed: 1,
103         corroded: 2,        /* 0: no; 1: yes; 2: very */
104         burnt: 2,           /* 0: no; 1: yes; 2: very */
105         rusty: 2,           /* 0: no; 1: yes; 2: very */
106         blessed_known: 1,   /* player known if item is cursed / blessed */
107         bonus_known: 1,     /* player knows the bonus */
108         fired: 1;           /* player has fired the item */
109 } item;
110 
111 typedef struct item_type_data {
112     item_t id;
113     const char *name_sg;
114     const char *name_pl;
115     const char glyph;
116     guint max_id;
117     unsigned
118         optimizable: 1,     /* item type can have a bonus */
119         blessable: 1,       /* item type can be blessed / cursed */
120         corrodible: 1,      /* item type can corrode */
121         equippable: 1,
122         usable: 1,
123         stackable: 1,
124         identifyable: 1;
125 } item_type_data;
126 
127 /* function definitions */
128 
129 item *item_new(item_t item_type, int item_id);
130 item *item_new_random(item_t item_type, gboolean finetouch);
131 item *item_new_by_level(item_t item_type, int num_level);
132 item *item_new_finetouch(item *it);
133 item *item_copy(item *original);
134 item *item_split(item *original, guint32 count);
135 void item_destroy(item *it);
136 
137 void item_serialize(gpointer oid, gpointer it, gpointer root);
138 item *item_deserialize(cJSON *iser, struct game *g);
139 
140 /**
141  * Compare two items.
142  *
143  * @param a item1
144  * @param b item2
145  * @return TRUE if items are identical
146  */
147 int item_compare(item *a, item *b);
148 
149 int item_sort(gconstpointer a, gconstpointer b, gpointer data, gboolean force_id);
150 
151 /**
152  * Describe an item.
153  *
154  * @param the item
155  * @param TRUE if the item is known to the player.
156  * @param TRUE if the item count shall be ignored and the description for
157  *       a single item of a stack shall be returned.
158  * @param TRUE if the description shall be prepend by the definite article.
159  * @return a newly allocated string that should be disposed with g_free().
160  */
161 gchar *item_describe(item *it, gboolean known, gboolean singular, gboolean definite);
162 
163 item_material_t item_material(item *it);
164 guint item_base_price(item *it);
165 guint item_price(item *it);
166 
167 /**
168  * Calculate the weight of the given item.
169  *
170  * @param an item
171  * @return weight in grams
172  */
173 int item_weight(item *it);
174 
175 /**
176  * Determine the colour of the given object.
177  *
178  * @param an item
179  * @return the coulour
180  */
181 int item_colour(item *it);
182 
183 
184 /*
185  * @brief Determine the chance if an item breaks when exposed to force.
186  *
187  * @param a item
188  * @return an integer between 0 and 100.
189  */
190 guint item_fragility(item *it);
191 
192 void item_effect_add(item *it, effect *e);
193 
194 int item_bless(item *it);
195 int item_curse(item *it);
196 int item_remove_curse(item *it);
197 
198 item *item_enchant(item *it);
199 item *item_disenchant(item *it);
200 
201 /**
202  * Erode an item.
203  *
204  * @param  the inventory the item is in (may be null for new items)
205  * @param  the item to erode
206  * @param  the type of erosion which affects the item
207  * @param  TRUE if the player can see the item
208  * @return the item, NULL it the item has been destroyed
209  *
210  */
211 item *item_erode(struct _inventory **inv, item *it, item_erosion_type iet, gboolean visible);
212 
213 int item_obtainable(item_t type, int id);
214 
215 /**
216  * @brief Describe an item thoroughly.
217  *
218  * @param An item.
219  * @param (Y/N) if the item is known
220  * @param (Y/N) show the item price
221  * @return A newly allocated string that must be freed in the calling function.
222  */
223 char *item_detailed_description(item *it, gboolean known, gboolean shop);
224 
225 /* external vars */
226 extern const item_type_data item_data[IT_MAX];
227 extern const item_material_data item_materials[IM_MAX];
228 
item_condition_bonus(item * it)229 static inline int item_condition_bonus(item *it)
230 {
231     g_assert(it->type < IT_MAX);
232 
233     /* sum item bonus or malus and the general condition */
234     int bonus = it->bonus;
235     bonus -= it->rusty;
236     bonus -= it->burnt;
237     bonus -= it->corroded;
238 
239     return bonus;
240 }
241 
242 /* item macros */
243 #define item_glyph(type)          item_data[(type)].glyph
244 #define item_name_sg(type)        item_data[(type)].name_sg
245 #define item_name_pl(type)        item_data[(type)].name_pl
246 #define item_max_id(type)         item_data[(type)].max_id
247 #define item_is_optimizable(type)     item_data[(type)].optimizable
248 #define item_is_blessable(type)       item_data[(type)].blessable
249 #define item_is_corrodible(type)      item_data[(type)].corrodible
250 #define item_is_equippable(type)      item_data[(type)].equippable
251 #define item_is_usable(type)          item_data[(type)].usable
252 #define item_is_stackable(type)       item_data[(type)].stackable
253 #define item_is_identifyable(type)    item_data[(type)].identifyable
254 #define item_material_name(type)      item_materials[(type)].name
255 #define item_material_adjective(type) item_materials[(type)].adjective
256 
257 /* item filters */
258 
259 int item_filter_container(item *it);
260 int item_filter_gems(item *it);
261 int item_filter_gold(item *it);
262 int item_filter_not_gold(item *it);
263 int item_filter_potions(item *it);
264 int item_filter_legible(item *it);
265 int item_filter_unid(item *it);
266 int item_filter_cursed(item *it);
267 int item_filter_cursed_or_unknown(item *it);
268 int item_filter_nonblessed(item *it);
269 
270 /**
271  * @brief Item filter function for the potion of cure dianthroritis.
272  * @param a pointer to an item
273  * @return TRUE if the supplied item is the potion of cure dianthroritis
274  */
275 int item_filter_pcd(item *it);
276 
277 /**
278  * @brief Item filter function for blank scrolls.
279  * @param a pointer to an item
280  * @return TRUE if the supplied item is a blank scroll
281  */
282 int item_filter_blank_scroll(item *it);
283 
284 /**
285  * @brief Check if an item is unique.
286  *
287  * @param A pointer to an item.
288  * @return TRUE if the item is unique.
289  */
290 gboolean item_is_unique(item *it);
291 
292 #endif
293