1 /*-------------------------------------------------------------------------------
2 
3 BARONY
4 File: items.cpp
5 Desc: contains helper functions for item stuff
6 
7 Copyright 2013-2016 (c) Turning Wheel LLC, all rights reserved.
8 See LICENSE for details.
9 
10 -------------------------------------------------------------------------------*/
11 
12 #include "main.hpp"
13 #include "game.hpp"
14 #include "items.hpp"
15 #include "files.hpp"
16 
17 Uint32 itemuids = 1;
18 ItemGeneric items[NUMITEMS];
19 
20 /*-------------------------------------------------------------------------------
21 
22 newItem
23 
24 Creates a new item and places it in an inventory
25 
26 -------------------------------------------------------------------------------*/
27 
newItem(const ItemType type,const Status status,const Sint16 beatitude,const Sint16 count,const Uint32 appearance,const bool identified,list_t * const inventory)28 Item* newItem(const ItemType type, const Status status, const Sint16 beatitude, const Sint16 count, const Uint32 appearance, const bool identified, list_t* const inventory)
29 {
30 	Item* item;
31 
32 	// allocate memory for the item
33 	if ( (item = static_cast<Item*>(malloc(sizeof(Item)))) == nullptr )
34 	{
35 		printlog("failed to allocate memory for new item!\n");
36 		exit(1);
37 	}
38 
39 	//item->captured_monster = nullptr;
40 
41 	// add the item to the inventory
42 	if ( inventory != nullptr )
43 	{
44 		item->node = list_AddNodeLast(inventory);
45 		item->node->element = item;
46 		item->node->deconstructor = &defaultDeconstructor;
47 		item->node->size = sizeof(Item);
48 	}
49 	else
50 	{
51 		item->node = nullptr;
52 	}
53 
54 	// now set all of my data elements
55 	item->type = type;
56 	item->status = status;
57 	item->beatitude = beatitude;
58 	item->count = count;
59 	item->appearance = appearance;
60 	item->identified = identified;
61 	item->uid = itemuids;
62 	if ( inventory )
63 	{
64 		/*int x, y;
65 		bool notfree = false, foundaspot = false;
66 
67 		bool is_spell = false;
68 		if ( itemCategory(item) == SPELL_CAT )
69 		{
70 			is_spell = true;
71 		}
72 
73 		x = 0;*/
74 	}
75 	else
76 	{
77 		item->x = 0;
78 		item->y = 0;
79 	}
80 
81 	itemuids++;
82 	return item;
83 }
84 
85 /*-------------------------------------------------------------------------------
86 
87 itemCategory
88 
89 Returns the category that a specified item belongs to
90 
91 -------------------------------------------------------------------------------*/
92 
itemCategory(const Item * const item)93 Category itemCategory(const Item* const item)
94 {
95 	if ( !item )
96 	{
97 		return GEM;
98 	}
99 	return items[item->type].category;
100 }
101 
102 /*-------------------------------------------------------------------------------
103 
104 itemModel
105 
106 returns a model index number based on the properties of the given item
107 
108 -------------------------------------------------------------------------------*/
109 
itemModel(const Item * const item)110 Sint32 itemModel(const Item* const item)
111 {
112 	if ( !item )
113 	{
114 		return 0;
115 	}
116 	return items[item->type].index + item->appearance % items[item->type].variations;
117 }
118 
119 /*-------------------------------------------------------------------------------
120 
121 itemModelFirstperson
122 
123 returns the first person model of the given item
124 
125 -------------------------------------------------------------------------------*/
126 
itemModelFirstperson(const Item * const item)127 Sint32 itemModelFirstperson(const Item* const item)
128 {
129 	if ( !item )
130 	{
131 		return 0;
132 	}
133 	return items[item->type].fpindex + item->appearance % items[item->type].variations;
134 }
135 
136 /*-------------------------------------------------------------------------------
137 
138 itemSprite
139 
140 returns a pointer to the SDL_Surface used to represent the item
141 
142 -------------------------------------------------------------------------------*/
143 
itemSprite(Item * const item)144 SDL_Surface* itemSprite(Item* const item)
145 {
146 	if ( !item )
147 	{
148 		return nullptr;
149 	}
150 	node_t* node = list_Node(&items[item->type].surfaces, item->appearance % items[item->type].variations);
151 	if ( !node )
152 	{
153 		return nullptr;
154 	}
155 
156 	auto** surface = static_cast<SDL_Surface**>(node->element);
157 	return *surface;
158 }
159 
160 /*-------------------------------------------------------------------------------
161 
162 newItemFromEntity
163 
164 returns a pointer to an item struct from the given entity if it's an
165 "item" entity, and returns NULL if the entity is anything else
166 
167 -------------------------------------------------------------------------------*/
168 
newItemFromEntity(const Entity * const entity)169 Item* newItemFromEntity(const Entity* const entity)
170 {
171 	if ( entity == nullptr )
172 	{
173 		return nullptr;
174 	}
175 	return newItem(static_cast<ItemType>(entity->skill[10]), static_cast<Status>(entity->skill[11]), entity->skill[12], entity->skill[13], entity->skill[14], entity->skill[15], nullptr);
176 }
177 
loadItems()178 int loadItems()
179 {
180 	int c, x;
181 	char name[32];
182 	// load item types
183 	printlog("loading items...\n");
184 	FILE* const fp = openDataFile("items/items.txt", "r");
185 	for ( c = 0; !feof(fp); c++ )
186 	{
187 		items[c].name_identified = language[1545 + c * 2];
188 		items[c].name_unidentified = language[1546 + c * 2];
189 		fscanf(fp, "%d", &items[c].index);
190 		while ( fgetc(fp) != '\n' ) if ( feof(fp) )
191 		{
192 			break;
193 		}
194 		fscanf(fp, "%d", &items[c].fpindex);
195 		while ( fgetc(fp) != '\n' ) if ( feof(fp) )
196 		{
197 			break;
198 		}
199 		fscanf(fp, "%d", &items[c].variations);
200 		while ( fgetc(fp) != '\n' ) if ( feof(fp) )
201 		{
202 			break;
203 		}
204 		fscanf(fp, "%s", name);
205 		while ( fgetc(fp) != '\n' ) if ( feof(fp) )
206 		{
207 			break;
208 		}
209 		if ( !strcmp(name, "WEAPON") )
210 		{
211 			items[c].category = WEAPON;
212 		}
213 		else if ( !strcmp(name, "ARMOR") )
214 		{
215 			items[c].category = ARMOR;
216 		}
217 		else if ( !strcmp(name, "AMULET") )
218 		{
219 			items[c].category = AMULET;
220 		}
221 		else if ( !strcmp(name, "POTION") )
222 		{
223 			items[c].category = POTION;
224 		}
225 		else if ( !strcmp(name, "SCROLL") )
226 		{
227 			items[c].category = SCROLL;
228 		}
229 		else if ( !strcmp(name, "MAGICSTAFF") )
230 		{
231 			items[c].category = MAGICSTAFF;
232 		}
233 		else if ( !strcmp(name, "RING") )
234 		{
235 			items[c].category = RING;
236 		}
237 		else if ( !strcmp(name, "SPELLBOOK") )
238 		{
239 			items[c].category = SPELLBOOK;
240 		}
241 		else if ( !strcmp(name, "TOOL") )
242 		{
243 			items[c].category = TOOL;
244 		}
245 		else if ( !strcmp(name, "FOOD") )
246 		{
247 			items[c].category = FOOD;
248 		}
249 		else if ( !strcmp(name, "BOOK") )
250 		{
251 			items[c].category = BOOK;
252 		}
253 		else if ( !strcmp(name, "SPELL_CAT") )
254 		{
255 			items[c].category = SPELL_CAT;
256 		}
257 		else
258 		{
259 			items[c].category = GEM;
260 		}
261 		fscanf(fp, "%d", &items[c].weight);
262 		while ( fgetc(fp) != '\n' ) if ( feof(fp) )
263 		{
264 			break;
265 		}
266 		fscanf(fp, "%d", &items[c].value);
267 		while ( fgetc(fp) != '\n' ) if ( feof(fp) )
268 		{
269 			break;
270 		}
271 		items[c].images.first = nullptr;
272 		items[c].images.last = nullptr;
273 		while ( true )
274 		{
275 			auto* string = static_cast<string_t*>(malloc(sizeof(string_t)));
276 			string->data = static_cast<char*>(malloc(sizeof(char) * 64));
277 			string->lines = 1;
278 
279 			node_t* node = list_AddNodeLast(&items[c].images);
280 			node->element = string;
281 			node->deconstructor = &stringDeconstructor;
282 			node->size = sizeof(string_t);
283 			string->node = node;
284 
285 			x = 0;
286 			bool fileend = false;
287 			while ( (string->data[x] = fgetc(fp)) != '\n' )
288 			{
289 				if ( feof(fp) )
290 				{
291 					fileend = true;
292 					break;
293 				}
294 				x++;
295 			}
296 			if ( x == 0 || fileend )
297 			{
298 				list_RemoveNode(node);
299 				break;
300 			}
301 			string->data[x] = 0;
302 		}
303 	}
304 	for ( c = 0; c < NUMITEMS; c++ )
305 	{
306 		items[c].surfaces.first = nullptr;
307 		items[c].surfaces.last = nullptr;
308 		for ( x = 0; x < list_Size(&items[c].images); x++ )
309 		{
310 			auto** surface = static_cast<SDL_Surface**>(malloc(sizeof(SDL_Surface*)));
311 			node_t* node = list_AddNodeLast(&items[c].surfaces);
312 			node->element = surface;
313 			node->deconstructor = &defaultDeconstructor;
314 			node->size = sizeof(SDL_Surface*);
315 
316 			node_t* node2 = list_Node(&items[c].images, x);
317 			auto* string = static_cast<string_t*>(node2->element);
318 			*surface = loadImage(string->data);
319 		}
320 	}
321 	fclose(fp);
322 	return 1;
323 }
324