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