1 /*
2 This file is part of "Avanor, the Land of Mystery" roguelike game
3 Home page: http://www.avanor.com/
4 Copyright (C) 2000-2003 Vadim Gaidukevich
5 
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20 
21 #include "xhero.h"
22 #include "quest.h"
23 #include "hiscore.h"
24 #include "game.h"
25 
UseTool()26 int XHero::UseTool()
27 {
28 	XBodyPart * tbp = GetBodyPart(BP_TOOL);
29 	XItem * tool = NULL;
30 	if (tbp)
31 		tool = tbp->Item();
32 
33 	if (tool)
34 	{
35 		UseItem(tool);
36 		return 1;
37 	} else
38 	{
39 		msgwin.Add("You have no tool.");
40 		return 0;
41 	}
42 
43 	return 1;
44 }
45 
doSacrifice()46 void XHero::doSacrifice()
47 {
48 	while (1)
49 	{
50 		XItem * item = NULL;
51 
52 		XItemList * tmpquae = l->map->GetItemList(x, y);
53 		if (tmpquae->empty() || l->map->GetPlace(x, y))
54 			item = Inventory(&contain);
55 		else
56 			item = Inventory(tmpquae);
57 		XItem * drop_item = item;
58 		if (item)
59 		{
60 			if (item->quantity > 1)
61 			{
62 				XPoint pt(0, item->quantity);
63  				msgwin.Add("How much?");
64 				int res = GetTarget(TR_HOW_MUCH, &pt, item->quantity);
65 				if (res == 0)
66 				{
67 					contain.Add(item);
68 					break;
69 				}
70 				if (res != item->quantity)
71 				{
72 					drop_item = (XItem *)item->MakeCopy();
73 					drop_item->quantity = res;
74 					item->quantity -= res;
75 					contain.Add(item);
76 				}
77 			}
78 			if (drop_item)
79 				Sacrifice(drop_item);
80 		} else
81 			break;
82 	}
83 }
84 
SelectItem(ITEM_FILTR * filtr)85 XItem * XHero::SelectItem(ITEM_FILTR * filtr)
86 {
87 	return Inventory(&contain, IM_UNKNOWN, IF_NONE, 1, filtr);
88 }
89 
DumpVBuffer(FILE * f)90 void XHero::DumpVBuffer(FILE * f)
91 {
92 	for (int j = 0; j < size_y; j++)
93 	{
94 		for (int k = 0; k < size_x; k++)
95 		{
96 			fprintf(f, "%c", vTestCh(k, j));
97 		}
98 		fprintf(f, "\n");
99 	}
100 
101 }
102 
CreateScreenShot()103 void XHero::CreateScreenShot()
104 {
105 	for (int i = 0; i < 1000; i++)
106 	{
107 		char buf[256];
108 		sprintf(buf, "shot%3d.txt", i);
109 		for (unsigned int q = 0; q < strlen(buf); q++)
110 			if (buf[q] == ' ') buf[q] = '_';
111 		FILE * f = fopen(buf, "rb");
112 		if (!f)
113 		{
114 			f = fopen(buf, "wb");
115 			DumpVBuffer(f);
116 			fclose(f);
117 			char buf2[256];
118 			sprintf(buf2, "Screenshot '%s' created successfuly.", buf);
119 			msgwin.Add(buf2);
120 			return;
121 		} else
122 			fclose(f);
123 	}
124 }
125 
Pray()126 void XHero::Pray()
127 {
128 	XGuiList list;
129 	char buf[256];
130 	DEITY_HELP * pLifeHelp;
131 	DEITY_HELP * pDeathHelp;
132 
133 	DEITY_RELATION dr = religion.GetRelation(D_LIFE);
134 	sprintf(buf, MSG_YELLOW "%s " MSG_LIGHTGRAY "(%s" MSG_LIGHTGRAY ")", religion.GetDeityName(D_LIFE), religion.GetRelationName(dr));
135 	list.AddItem(new XGuiItem_Text(buf, 0));
136 	int life_count = religion.GetAvailHelp(D_LIFE, &pLifeHelp);
137 	if (life_count == 0)
138 		list.AddItem(new XGuiItem_Text("< No help available >", 0));
139 	else
140 	{
141 		for (int i = 0; i < life_count; i++)
142 		{
143 			list.AddItem(new XGuiItem_Text(pLifeHelp[i].help_name, 1));
144 		}
145 	}
146 	list.AddItem(new XGuiItem_Text("", 0));
147 
148 	dr = religion.GetRelation(D_DEATH);
149 	sprintf(buf, MSG_YELLOW "%s " MSG_LIGHTGRAY "(%s" MSG_LIGHTGRAY ")", religion.GetDeityName(D_DEATH), religion.GetRelationName(dr));
150 	list.AddItem(new XGuiItem_Text(buf, 0));
151 	int death_count = religion.GetAvailHelp(D_DEATH, &pDeathHelp);
152 	if (death_count == 0)
153 		list.AddItem(new XGuiItem_Text("< No help available >", 0));
154 	else
155 	{
156 		for (int i = 0; i < death_count; i++)
157 		{
158 			list.AddItem(new XGuiItem_Text(pDeathHelp[i].help_name, 1));
159 		}
160 	}
161 
162 	int res = list.Run();
163 	if (res == -1)
164 		return;
165 	if (res < life_count)
166 	{
167 		religion.Pray(D_LIFE, &pLifeHelp[res], this);
168 	} else
169 		if (res < life_count + death_count)
170 		{
171 			religion.Pray(D_DEATH, &pDeathHelp[res - life_count], this);
172 		}
173 
174 }
175 
176 
177 
EndGame(char * end_msg)178 void XHero::EndGame(char * end_msg)
179 {
180 	int score = ((XHero *)main_creature)->_EXP + ((XHero *)main_creature)->MoneyOp(0);
181 
182 	XGuiList list;
183 
184 	char buf2[256];
185 	char tbuf[256];
186 	sprintf(buf2, "%s, %s %s %s (L%d).", ((XHero *)main_creature)->name, ((XHero *)main_creature)->GetGenderStr(), ((XHero *)main_creature)->GetRaceStr(), ((XHero *)main_creature)->GetProfessionStr(), ((XHero *)main_creature)->level);
187 	list.AddItem(new XGuiItem_Text(buf2));
188 
189 	sprintf(tbuf, "You survived %d turns.", ((XHero *)main_creature)->turn_count);
190 	list.AddItem(new XGuiItem_Text(tbuf));
191 
192 	if (XQuest::quest.hero_win)
193 	{
194 		if (XQuest::quest.ahk_ulan_killed && XQuest::quest.roderick_killed)
195 		{
196 			if(main_creature->GetGender() == GEN_MALE)
197 			{
198 				list.AddItem(new XGuiItem_Text("You killed Ahk-Ulan and the King of Avanor and became the new King of Avanor."));
199 			} else if(main_creature->GetGender() == GEN_FEMALE)
200 			{
201 				list.AddItem(new XGuiItem_Text("You killed Ahk-Ulan and the King of Avanor and became the new Queen of Avanor."));
202 			}
203 			score += 30000;
204 		} else if(XQuest::quest.ahk_ulan_killed)
205 		{
206 			list.AddItem(new XGuiItem_Text("You killed evil Ahk-Ulan and saved Kingdom of Avanor from Ahk-Ulans deadly plans."));
207 			score += 10000;
208 		} else
209 		{
210 			list.AddItem(new XGuiItem_Text("You killed the King of Avanor and helped Ahk-Ulan to become Usurper of Avanor."));
211 			score += 20000;
212 		}
213 	} else
214 	{
215 		list.AddItem(new XGuiItem_Text(end_msg));
216 	}
217 
218 	int place_count = 0;
219 	for (int i = 0; i < L_EOF; i++)
220 	{
221 		if (Game.locations[i] && Game.locations[i]->visited_by_hero)
222 		{
223 			place_count++;
224 		}
225 	}
226 
227 	score += place_count * 200;
228 	sprintf(tbuf, "You visited %d places.", place_count);
229 	list.AddItem(new XGuiItem_Text(tbuf));
230 
231 	DEITY_RELATION dr1 = ((XHero *)main_creature)->religion.GetRelation(D_LIFE);
232 	DEITY_RELATION dr2 = ((XHero *)main_creature)->religion.GetRelation(D_DEATH);
233 	int flag = 1;
234 	if (dr1 >= DR_ADEPT)
235 	{
236 		sprintf(tbuf, "You were a %s of %s", XReligion::GetRelationName(dr1), XReligion::GetDeityName(D_LIFE));
237 		list.AddItem(new XGuiItem_Text(tbuf));
238 		flag = 0;
239 		score += dr1 * 300;
240 	}
241 	if (dr2 >= DR_ADEPT)
242 	{
243 		sprintf(tbuf, "You were a %s of %s", XReligion::GetRelationName(dr2), XReligion::GetDeityName(D_DEATH));
244 		list.AddItem(new XGuiItem_Text(tbuf));
245 		score += dr2 * 300;
246 		flag = 0;
247 	}
248 	if (flag)
249 	{
250 		list.AddItem(new XGuiItem_Text("You were not very religious."));
251 	}
252 
253 	if (XQuest::quest.beelzvile_killed)
254 	{
255 		list.AddItem(new XGuiItem_Text("You killed an ancient demon."));
256 	}
257 
258 	if (XQuest::quest.torin_quest == 2)
259 	{
260 		list.AddItem(new XGuiItem_Text("You helped to pump out gas from the dwarven golden mine."));
261 		score += 5000;
262 	}
263 
264 	if (XQuest::quest.guards_get_orc_slay)
265 	{
266 		list.AddItem(new XGuiItem_Text("You brought a useful thing to Ozorik."));
267 	}
268 
269 	if (XQuest::quest.roderick_quest == 2)
270 	{
271 		list.AddItem(new XGuiItem_Text("You returned 'Eye of Raa' to Roderick."));
272 		score += 10000;
273 	}
274 	if (XQuest::quest.roderick_quest2 == 2)
275 	{
276 		list.AddItem(new XGuiItem_Text("You cleansed the tomb of Roderick's ancestors."));
277 		score += 5000;
278 	}
279 
280 
281 
282 	if (XQuest::quest.orcs_killed > 0 && XQuest::quest.total_orcs_killed == 30)
283 	{
284 		list.AddItem(new XGuiItem_Text("You helped to repulse an attack of orcs."));
285 	} else if (XQuest::quest.orcs_killed > 0)
286 	{
287 		list.AddItem(new XGuiItem_Text("You tried to help to repulse an attack of orcs."));
288 	}
289 
290 	sprintf(tbuf, "You scored %d.", score);
291 	list.AddItem(new XGuiItem_Text(tbuf));
292 	list.SetCaption(MSG_BROWN "###" MSG_LIGHTGRAY " Achievements " MSG_BROWN "###");
293 	list.Run();
294 
295 	vGotoXY(0, 0);
296 	msgwin.ClrMsg();
297 	msgwin.Add("Create Memory File? (Y/" MSG_CYAN "N" MSG_LIGHTGRAY ")");
298 	msgwin.Put();
299 	vRefresh();
300 	int tch = vGetch();
301 	if (tch == 'y' || tch == 'Y')
302 	{
303 		msgwin.ClrMsg();
304 		msgwin.Add("### Screenshot ###");
305 		msgwin.Put();
306 		char tname[256];
307 		strcpy(tname, ((XHero *)main_creature)->name);
308 		strcat(tname, ".mem");
309 		FILE * f = fopen(vMakePath(HOME_DIR, tname), "w");
310 		((XHero *)main_creature)->DumpVBuffer(f);
311 		list.Put(f);
312 		fprintf(f, "\n");
313 		((XHero *)main_creature)->Equipment(f);
314 		fprintf(f, "\n");
315 		((XHero *)main_creature)->WarSkillsList(f);
316 		fprintf(f, "\n");
317 		((XHero *)main_creature)->SkillsList(SKF_LIST_SKILL, 0, f);
318 		fprintf(f, "\n");
319 		((XHero *)main_creature)->XCast(f);
320 		fprintf(f, "\n");
321 		((XHero *)main_creature)->ShowResistance(f);
322 		fprintf(f, "\n");
323 		it_iterator i;
324 		for (i = ((XHero *)main_creature)->contain.begin(); i != ((XHero *)main_creature)->contain.end(); i++)
325 		{
326 			i->Identify(1);
327 		}
328 		((XHero *)main_creature)->Inventory(&((XHero *)main_creature)->contain, IM_ALL, IF_NONE, 0, NULL, f);
329 		fclose(f);
330 		vClrScr();
331 	}
332 
333 	XHiScoreItem * hii;
334 	if (XQuest::quest.hero_win)
335 		hii = new XHiScoreItem(0, score, buf2, end_msg, 1, 1);
336 	else
337 		hii = new XHiScoreItem(0, score, buf2, end_msg, 0, 1);
338 	XHiScore hiscore;
339 	hiscore.AddRecord(hii);
340 	hiscore.Show();
341 }
342 
ShowResistance(FILE * f)343 void XHero::ShowResistance(FILE * f)
344 {
345 	XGuiList list;
346 	list.SetCaption(MSG_BROWN "###" MSG_LIGHTGRAY " Resistances and Intrinsics " MSG_BROWN "###");
347 	list.SetFooter("Press any key to exit");
348 
349 	int flag = 0;
350 	char buf[256];
351 	XResistance tr;
352 	for (int i = 0; i < R_EOF; i++)
353 	{
354 		tr.SetResistance((RESISTANCE)i, GetResistance((RESISTANCE)i));
355 		if (tr.GetResistance((RESISTANCE)i) != 0)
356 		{
357 			sprintf(buf, MSG_LIGHTGRAY "%-15s%s", tr.GetResistanceName((RESISTANCE)i), tr.GetResistanceLevel((RESISTANCE)i));
358 			list.AddItem(new XGuiItem_Text(buf, 0), 0);
359 			flag = 1;
360 		}
361 	}
362 
363 	if (flag == 0)
364 	{
365 		list.AddItem(new XGuiItem_Text("You have no Resistances and Intrinsics.", 0), 0);
366 	}
367 
368 	if (f)
369 	{
370 		list.Put(f);
371 	} else
372 	{
373 		int ch = list.Run(1);
374 	}
375 }
376 
377 
LearnReception(POTION_NAME pn1,POTION_NAME pn2,POTION_NAME pn3)378 int XHero::LearnReception(POTION_NAME pn1, POTION_NAME pn2, POTION_NAME pn3)
379 {
380 	XList<XAlchemyRec *>::iterator it;
381 	for (it = reception_list.begin(); it != reception_list.end(); it++)
382 		if (it->pn1 == pn1 && it->pn2 == pn2)
383 			return 0;
384 
385 	if (XAlchemy::isValidReception(pn1, pn2, pn3))
386 	{
387 		reception_list.push_back(new XAlchemyRec(pn1, pn2, pn3));
388 		msgwin.Add("You have learned a new alchemy recipe.");
389 	}
390 	return 1;
391 }
392 
ShowReception()393 void XHero::ShowReception()
394 {
395 	XGuiList list;
396 	list.SetCaption(MSG_BROWN "###" MSG_LIGHTGRAY " Recipes " MSG_BROWN "###");
397 	if (reception_list.empty())
398 	{
399 		list.AddItem(new XGuiItem_Text("You don't know any recipes yet.", 0), 0);
400 	} else
401 	{
402 		XList<XAlchemyRec *>::iterator it;
403 		for (it = reception_list.begin(); it != reception_list.end(); it++)
404 		{
405 			char buf[256];
406 			XAlchemy::GetReceptionName(buf, it->pn1, it->pn2, it->result);
407 			list.AddItem(new XGuiItem_Text(buf, 0), 0);
408 		}
409 	}
410 	list.Run();
411 }
412 
MixPotions()413 void XHero::MixPotions()
414 {
415     XPotion * pot1 = (XPotion *)Inventory(&contain, IM_POTION, IF_FIXED_MASK, 1);
416     if (pot1)
417     {
418 		XPotion * pot2 = (XPotion *)Inventory(&contain, IM_POTION, IF_FIXED_MASK, 1);
419 		if (pot2)
420 		{
421 			POTION_NAME pn = XAlchemy::GetPotionName(pot1->pn, pot2->pn);
422 			POTION_REC * pr = POTION_REC::GetRec(pot1->pn);
423 			int val = sk->GetLevel(SKT_ALCHEMY) * 8 + 30 - pr->alchemy_power * 10;
424 			if (pn != PN_UNKNOWN && vRand(100) < val)
425 			{
426 				XPotion * pot = new XPotion(pn);
427 				sk->UseSkill(SKT_ALCHEMY, 3);
428 				char buf[256];
429 				char buf1[256];
430 				pot->toString(buf);
431 				sprintf(buf1, "You have mixed %s.", buf);
432 				msgwin.Add(buf1);
433 				CarryItem(pot);
434 				contain.Add(pot);
435 			} else
436 			{
437 				msgwin.Add("You failed to mix a new potion.");
438 			}
439 			pot1->Invalidate();
440 			pot2->Invalidate();
441 		}
442     }
443 }
444 
445 
446 
447