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 "deity.h"
22 #include "creature.h"
23 #include "item.h"
24
25 XCreature * XDeity::death = NULL;
26 XCreature * XDeity::life = NULL;
27
28 /*int XSimpleAttack::AskHelp(XCreature * asker)
29 {
30 SPELL_NAME spn;
31 if (vRand(2) == 0)
32 spn = SPELL_MAGIC_ARROW;
33 else
34 spn = SPELL_DRAIN_LIFE;
35
36 XBasicSpell * spell = XSpellFactory::Get(spn);
37 return spell->onCast(asker, 50);
38 return 0;
39 }
40
41 int XMediumAttack::AskHelp(XCreature * asker)
42 {
43 SPELL_NAME spn;
44 if (vRand(2) == 0)
45 spn = SPELL_FIRE_BOLT;
46 else
47 spn = SPELL_ICE_BOLT;
48
49 XBasicSpell * spell = XSpellFactory::Get(spn);
50 return spell->onCast(asker, 50);
51 return 0;
52 }
53
54 int XHardAttack::AskHelp(XCreature * asker)
55 {
56 SPELL_NAME spn;
57 if (vRand(2) == 0)
58 spn = SPELL_LIGHTNING_BOLT;
59 else
60 spn = SPELL_ACID_BOLT;
61
62 XBasicSpell * spell = XSpellFactory::Get(spn);
63 return spell->onCast(asker, 50);
64 return 0;
65 }
66 */
67
68 DEITY_HELP life_help[] = {
69 {"cure light wounds", 3, PRAY_CURE_LIGHT_WOUNDS},
70 {"minor divine intervention", 5, PRAY_MINOR_INTERVENTION},
71
72 {"cure poison", 10, PRAY_CURE_POISON},
73 {"heroism", 10, PRAY_HEROISM},
74
75 {"cure critical wounds", 20, PRAY_CURE_CRITICAL_WOUNDS},
76
77 {"great knowledge", 30, PRAY_IDENTIFY},
78
79 {"divine restoration", 50, PRAY_RESTORATION}
80 };
81
82 DEITY_HELP death_help[] =
83 {
84 {"cure light wounds", 5, PRAY_CURE_LIGHT_WOUNDS},
85 {"minor divine intervention", 5, PRAY_MINOR_INTERVENTION},
86
87 {"divine intervention", 5, PRAY_INTERVENTION},
88 {"divine escape", 50, PRAY_TELEPORT},
89
90 {"cure critical wounds", 30, PRAY_CURE_CRITICAL_WOUNDS},
91
92 {"knowledge of insight", 50, PRAY_SELF_KNOWLEDGE},
93
94 {"major divine intervention", 5, PRAY_MAJOR_INTERVENTION},
95 };
96
97
98 struct DEITY_ACT
99 {
100 int good;
101 int bad;
102 };
103
104 DEITY_ACT life_deity_act[] = {
105 {5, -15}, {5, -14}, {5, -12}, {5, -10}, {10, -10},
106 {10, -9}, {10, -8}, {10, -7}, {10, -6}, {10, -5},
107 {10, -4}, {10, -3}, {10, -2}, {10, -1}, {10, 0}, {10, 0}
108 };
109
110
111
112
KillCreature(XCreature * killer,XCreature * victim)113 void XReligion::KillCreature(XCreature * killer, XCreature * victim)
114 {
115 int val = killer->sk->GetLevel(SKT_RELIGION);
116 int bad = life_deity_act[val].bad;
117 int good = life_deity_act[val].good;
118 if (victim->creature_class == CR_UNDEAD)
119 {
120 death_act += bad;
121 life_act += good;
122 } else
123 {
124 death_act += good;
125 life_act += bad;
126 }
127 }
128
SacrificeItem(XCreature * cr,XItem * item,DEITY deity)129 int XReligion::SacrificeItem(XCreature * cr, XItem * item, DEITY deity)
130 {
131 int val = cr->sk->GetLevel(SKT_RELIGION);
132 if (deity == D_UNKNOWN)
133 {
134 if (life_act > death_act)
135 deity = D_LIFE;
136 else
137 deity = D_DEATH;
138 }
139
140 XMapObject * tmo = cr->l->map->GetSpecial(cr->x, cr->y);
141 if (tmo && tmo->im & IM_ALTAR)
142 {
143 if (tmo->color == xWHITE)
144 deity = D_LIFE;
145 else
146 deity = D_DEATH;
147 }
148
149 if (cr->isVisible())
150 {
151 char buf[256];
152 sprintf(buf, "%s prays to %s.", cr->name, GetDeityName(deity));
153 msgwin.Add(buf);
154 item->toString(buf);
155 msgwin.Add(buf);
156 msgwin.Add("disappears in a bright light.");
157 }
158
159 int sacrifice_value;
160 if (item->im & IM_MONEY)
161 sacrifice_value = (int)(sqrt(item->quantity) + 1) * (val / 4 + 1);
162 else
163 sacrifice_value = (int)((sqrt(item->GetValue()) * item->quantity) + 1) * (val / 4 + 1);
164
165 cr->sk->UseSkill(SKT_RELIGION);
166
167 if (tmo && tmo->im & IM_ALTAR)
168 {
169 sacrifice_value *= 3;
170 cr->sk->UseSkill(SKT_RELIGION, 5);
171 }
172
173 item->UnCarry();
174 item->Invalidate();
175
176 if (deity == D_LIFE)
177 {
178 life_act += sacrifice_value;
179 } else
180 {
181 death_act += sacrifice_value;
182 }
183
184 if (!cr->isHero() && vRand(5) == 0)
185 {
186 cr->s->Modify(XStats::Random(), 1);
187 if (cr->isVisible())
188 {
189 msgwin.Add(cr->name);
190 msgwin.Add("looks more powerful!");
191 }
192 }
193
194 return 1;
195 }
196
GetRelation(DEITY deity)197 DEITY_RELATION XReligion::GetRelation(DEITY deity)
198 {
199 int val = 0;
200 switch (deity)
201 {
202 case D_LIFE: val = life_act; break;
203 case D_DEATH: val = death_act; break;
204 }
205 if (val < -10000000)
206 return DR_FALLEN_CHAMPION;
207 else if (val < -100)
208 return DR_VERY_BAD;
209 else if (val < 0)
210 return DR_BAD;
211 else if (val < 100)
212 return DR_NORMAL;
213 else if (val < 1000)
214 return DR_ADEPT;
215 else if (val < 3000)
216 return DR_FOLLOWER;
217 else if (val < 10000)
218 return DR_MESSIAH;
219 else
220 return DR_CHAMPION;
221 }
222
223 char * relation_name[] = {
224 MSG_RED "fallen champion", MSG_RED "very bad", MSG_RED "bad",
225 MSG_LIGHTGRAY "normal", MSG_LIGHTGRAY "adept", MSG_LIGHTGREEN "follower",
226 MSG_YELLOW "messiah", MSG_WHITE "champion"
227 };
228
GetRelationName(DEITY_RELATION dr)229 char * XReligion::GetRelationName(DEITY_RELATION dr)
230 {
231 return relation_name[dr];
232 }
233
GetDeityName(DEITY deity)234 char * XReligion::GetDeityName(DEITY deity)
235 {
236 if (deity == D_LIFE)
237 return "Tiamat";
238 else
239 return "Marduk";
240 }
241
GetAvailHelp(DEITY deity,DEITY_HELP ** help)242 int XReligion::GetAvailHelp(DEITY deity, DEITY_HELP ** help)
243 {
244 if (deity == D_LIFE)
245 {
246 *help = &life_help[0];
247
248 } else
249 {
250 *help = &death_help[0];
251 }
252
253 DEITY_RELATION rel = GetRelation(deity);
254 if (rel < DR_ADEPT)
255 return 0;
256 if (rel < DR_FOLLOWER)
257 return 2;
258 if (rel < DR_MESSIAH)
259 return 4;
260 if (rel < DR_CHAMPION)
261 return 6;
262 return 7;
263 }
264
Pray(DEITY deity,DEITY_HELP * pray,XCreature * prayer)265 int XReligion::Pray(DEITY deity, DEITY_HELP * pray, XCreature * prayer)
266 {
267 EFFECT effect = E_CURE_LIGHT_WOUNDS;
268 switch (pray->pray)
269 {
270 case PRAY_CURE_LIGHT_WOUNDS: effect = E_CURE_LIGHT_WOUNDS; break;
271 case PRAY_CURE_CRITICAL_WOUNDS: effect = E_CURE_CRITICAL_WOUNDS; break;
272 case PRAY_RESTORATION: effect = E_RESTORATION; break;
273 case PRAY_IDENTIFY: effect = E_IDENTIFY; break;
274 case PRAY_SELF_KNOWLEDGE: effect = E_SELF_KNOWLEDGE; break;
275 case PRAY_CURE_POISON: effect = E_CURE_POISON; break;
276 case PRAY_HEROISM: effect = E_HEROISM; break;
277 case PRAY_TELEPORT: effect = E_TELEPORT; break;
278
279 case PRAY_MINOR_PUNISHMENT: effect = E_MAGIC_ARROW; break;
280 case PRAY_MINOR_INTERVENTION: effect = E_MAGIC_ARROW; break;
281 case PRAY_INTERVENTION: effect = vRand(2) == 0 ? E_FIRE_BOLT : E_ICE_BOLT; break;
282 case PRAY_MAJOR_INTERVENTION: effect = vRand(2) == 0 ? E_LIGHTNING_BOLT : E_ACID_BOLT; break;
283 }
284
285 RESULT res = XEffect::Make(prayer, effect, 50);
286
287 if (res == SUCCESS)
288 {
289 if (deity == D_LIFE)
290 {
291 life_act -= pray->help_cost;
292 } else
293 {
294 death_act -= pray->help_cost;
295 }
296 prayer->sk->UseSkill(SKT_RELIGION, 3);
297 } if (res != ABORT)
298 {
299 msgwin.Add("Your prayer was unheard.");
300 }
301 return 1;
302 }
303
Store(XFile * f)304 void XReligion::Store(XFile * f)
305 {
306 f->Write(&life_act);
307 f->Write(&death_act);
308 }
309
Restore(XFile * f)310 void XReligion::Restore(XFile * f)
311 {
312 f->Read(&life_act);
313 f->Read(&death_act);
314 }
315