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 "xbook.h"
22 #include "effect.h"
23 #include "creature.h"
24
25 REGISTER_CLASS(XBook);
26
27 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
28
29 char * books_descr[] =
30 {
31 "old tome", "small tome", "ancient tome", "dirty tome", "heavy tome",
32 "old book", "small book", "ancient book", "dirty book", "heavy book",
33 "wrapped tome", "pocket book", "leather-bound tome", "parchment book",
34 "thin book", "gold decorated", "silver decorated"
35 };
36
37 #define BOOKS_DESCR_SZ ARRAY_SIZE(books_descr)
38
39 int BOOK_REC::current_descr = 0;
40 int BOOK_REC::total_value = 0;
41
BOOK_REC(int _rarity,BOOK_NAME bn,SPELL_NAME sn)42 BOOK_REC::BOOK_REC(int _rarity, BOOK_NAME bn, SPELL_NAME sn)
43 : book_name(bn), spell_name(sn), identify(0), name_index(current_descr), rarity(_rarity)
44 {
45 current_descr++;
46 assert(current_descr <= BOOKS_DESCR_SZ);
47 total_value += rarity;
48 }
49
50
51 BOOK_REC book_descr[] = {
52 BOOK_REC(100, BOOK_BURNING_HANDS, SPELL_BURNING_HANDS),
53 BOOK_REC(100, BOOK_ICE_TOUCH, SPELL_ICE_TOUCH),
54 BOOK_REC(150, BOOK_CURE_LIGHT_WOUNDS, SPELL_CURE_LIGHT_WOUNDS),
55 BOOK_REC(70, BOOK_DRAIN_LIFE, SPELL_DRAIN_LIFE),
56 BOOK_REC(20, BOOK_IDENTIFY, SPELL_IDENTIFY),
57 BOOK_REC(200, BOOK_MAGIC_ARROW, SPELL_MAGIC_ARROW),
58 BOOK_REC(50, BOOK_FIRE_BOLT, SPELL_FIRE_BOLT),
59 BOOK_REC(50, BOOK_ICE_BOLT, SPELL_ICE_BOLT),
60 BOOK_REC(20, BOOK_LIGHTNING_BOLT, SPELL_LIGHTNING_BOLT),
61 BOOK_REC(10, BOOK_ACID_BOLT, SPELL_ACID_BOLT),
62 BOOK_REC(60, BOOK_CURE_DISEASE, SPELL_CURE_DISEASE),
63 BOOK_REC(80, BOOK_CURE_POISON, SPELL_CURE_POISON),
64 BOOK_REC(15, BOOK_BLINK, SPELL_BLINK),
65 BOOK_REC(5, BOOK_SELF_KNOWLEDGE, SPELL_SELF_KNOWLEDGE),
66 };
67
Store(XFile * f)68 void BOOK_REC::Store(XFile * f)
69 {
70 f->Write(&identify, sizeof(identify));
71 f->Write(&name_index, sizeof(name_index));
72 f->Write(&spell_name, sizeof(spell_name));
73 f->Write(&book_name, sizeof(book_name));
74 }
75
Restore(XFile * f)76 void BOOK_REC::Restore(XFile * f)
77 {
78 f->Read(&identify, sizeof(identify));
79 f->Read(&name_index, sizeof(name_index));
80 f->Read(&spell_name, sizeof(spell_name));
81 f->Read(&book_name, sizeof(book_name));
82 }
83
GetBook(BOOK_NAME bn)84 int BOOK_REC::GetBook(BOOK_NAME bn)
85 {
86 if (bn != BOOK_RANDOM)
87 {
88 for (int i = 0; i < BOOK_RANDOM; i++)
89 if (book_descr[i].book_name == bn)
90 return i;
91 } else
92 {
93 int val = vRand(total_value);
94 int pos = -1;
95 do
96 {
97 pos++;
98 val -= book_descr[pos].rarity;
99 } while (val >= 0);
100
101 assert(pos < BOOK_RANDOM);
102 return pos;
103 }
104 assert(0);
105 return -1;
106 }
107
108
StoreTable(XFile * f)109 void XBook::StoreTable(XFile * f)
110 {
111 for (int i = 0; i < ARRAY_SIZE(book_descr); i++)
112 {
113 book_descr[i].Store(f);
114 }
115 }
116
RestoreTable(XFile * f)117 void XBook::RestoreTable(XFile * f)
118 {
119 for (int i = 0; i < ARRAY_SIZE(book_descr); i++)
120 {
121 book_descr[i].Restore(f);
122 }
123 }
124
125
XBook(BOOK_NAME bn)126 XBook::XBook(BOOK_NAME bn)
127 {
128 descr = BOOK_REC::GetBook(bn);
129 assert(descr > -1 && descr < BOOK_RANDOM);
130
131 value = 20000 / book_descr[descr].rarity;
132 strcpy(name, XSpell::GetName(book_descr[descr].spell_name));
133
134 im = IM_BOOK;
135 bp = BP_OTHER;
136 it = IT_BOOK;
137
138 view = '"';
139 color = xBROWN;
140 weight = 100;
141 dice.Setup("1d3");
142 left_to_read = value * 10;
143 reader_guid = 0;
144 }
145
146
isIdentifed()147 int XBook::isIdentifed()
148 {
149 return book_descr[descr].identify;
150 }
151
Identify(int level)152 void XBook::Identify(int level)
153 {
154 book_descr[descr].identify = level;
155 }
156
Compare(XObject * o)157 int XBook::Compare(XObject * o)
158 {
159 assert(dynamic_cast<XBook *>(o));
160 XBook * tit = (XBook *)o;
161
162 if (descr == tit->descr && x == tit->x && y == tit->y)
163 return 0;
164 else
165 {
166 if (quantity > tit->quantity)
167 return -1;
168 else
169 return 1;
170 }
171 }
172
toString(char * buf)173 void XBook::toString(char * buf)
174 {
175 if (!isIdentifed())
176 {
177 if (quantity == 1)
178 sprintf(buf, "%s", books_descr[book_descr[descr].name_index]);
179 else
180 sprintf(buf, "heap of (%d) %ss", quantity, books_descr[book_descr[descr].name_index]);
181 } else
182 {
183 if (quantity == 1)
184 sprintf(buf, "book of %s", name);
185 else
186 sprintf(buf, "heap of (%d) books of %s", quantity, name);
187 }
188 }
189
onRead(XCreature * reader)190 int XBook::onRead(XCreature * reader)
191 {
192 if (reader->xguid != reader_guid)
193 {
194 left_to_read = value * 20;
195 reader_guid = reader->xguid;
196 }
197
198
199 XSkill * skill = reader->sk->GetSkill(SKT_LITERACY);
200 left_to_read -= (skill->GetLevel() + reader->GetStats(S_LEN));
201
202 if (left_to_read <= 0)
203 {
204 reader->m->Learn(book_descr[descr].spell_name);
205 skill->UseSkill(10);
206 if (reader->isHero())
207 {
208 char buf[256];
209 toString(buf);
210 msgwin.Add("You read the");
211 msgwin.AddLast(buf);
212 if (!isIdentifed())
213 {
214 Identify(1);
215 msgwin.Add("It was");
216 toString(buf);
217 msgwin.AddLast(buf);
218 }
219 }
220 else if (reader->isVisible())
221 {
222 char buf[256];
223 toString(buf);
224 msgwin.Add(reader->GetNameEx(CRN_T1));
225 msgwin.Add(reader->GetVerb("read"));
226 msgwin.AddLast(buf);
227 if (!isIdentifed())
228 {
229 Identify(1);
230 msgwin.Add("It was");
231 toString(buf);
232 msgwin.AddLast(buf);
233 }
234 }
235 }
236 return 1;
237 }
238
Store(XFile * f)239 void XBook::Store(XFile * f)
240 {
241 XItem::Store(f);
242 f->Write(&descr, sizeof(int));
243 f->Write(&left_to_read, sizeof(int));
244 f->Write(&reader_guid, sizeof(XGUID));
245 }
246
Restore(XFile * f)247 void XBook::Restore(XFile * f)
248 {
249 XItem::Restore(f);
250 f->Read(&descr, sizeof(int));
251 f->Read(&left_to_read, sizeof(int));
252 f->Read(&reader_guid, sizeof(XGUID));
253 }
254