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 "skill.h"
22 #include "creature.h"
23 #include "other_misc.h"
24
25 REGISTER_CLASS(XSkill);
26
27 SKILL_DB skill_db[] = {
28 {"Archery", 1},
29 {"Find Weakness", 1},
30 {"Healing", 2},
31 {"Concentration", 3},
32 {"Dodge", 1},
33 {"Trading", 1},
34 {"Stealing", 1},
35 {"Literacy", 1},
36 {"Detect trap", 1},
37 {"Disarm trap", 1},
38 {"Cooking", 1},
39 {"Mining", 5},
40 {"Herbalism", 1},
41 {"Religion", 1},
42 {"Backstabbing", 1},
43 {"First aid", 2},
44 {"Tactics", 1},
45 {"Alchemy", 1},
46 {"Woodcraft", 1},
47 {"Create trap", 1},
48 {"Necromancy", 1},
49 {"Athletics", 1},
50 };
51
52 char * skill_level_name[16] = {
53 MSG_LIGHTGRAY "NONE",
54 MSG_LIGHTGREEN "Basic",
55 MSG_LIGHTGREEN "Basic",
56 MSG_LIGHTGREEN "Basic",
57 MSG_GREEN "Skilled",
58 MSG_GREEN "Skilled",
59 MSG_GREEN "Skilled",
60 MSG_GREEN "Skilled",
61 MSG_YELLOW "Expert",
62 MSG_YELLOW "Expert",
63 MSG_YELLOW "Expert",
64 MSG_YELLOW "Expert",
65 MSG_LIGHTRED "Master",
66 MSG_LIGHTRED "Master",
67 MSG_LIGHTRED "Master",
68 MSG_DARKGRAY "Grand Master"
69 };
70
71
XSkill(SKILL_TYPE _skt,int _level)72 XSkill::XSkill(SKILL_TYPE _skt, int _level)
73 {
74 skt = _skt;
75 level = _level;
76 im = IM_OTHER;
77 if (_level < 4)
78 {
79 used_time = skill_db[skt].use_per_level * (4 * 4 - 1) * 2;
80 } else
81 {
82 used_time = skill_db[skt].use_per_level * (level * level - 1) * 2;
83 }
84 }
85
GetName()86 char * XSkill::GetName()
87 {
88 return skill_db[skt].name;
89 }
90
GetSkillLevel()91 char * XSkill::GetSkillLevel()
92 {
93 assert(level <= SKILL_MAX_LEVEL);
94 return skill_level_name[level];
95 }
96
GetMaxLevel()97 int XSkill::GetMaxLevel()
98 {
99 int xlevel = (int)(sqrt(used_time / (2 * skill_db[skt].use_per_level) + 1));
100 return xlevel < 15 ? xlevel : 15;
101 }
102
IncLevel()103 int XSkill::IncLevel()
104 {
105 if (level < GetMaxLevel())
106 {
107 level++;
108 return 1;
109 } else
110 {
111 return 0;
112 }
113 }
114
GetMastery()115 SKILL_MASTERY XSkill::GetMastery()
116 {
117 switch (level)
118 {
119 case 1 :
120 case 2 :
121 case 3 : return SM_BASIC; break;
122 case 4 :
123 case 5 :
124 case 6 :
125 case 7 : return SM_SKILLED; break;
126 case 8 :
127 case 9 :
128 case 10:
129 case 11: return SM_EXPERT; break;
130 case 12:
131 case 13:
132 case 14: return SM_MASTER; break;
133 case 15: return SM_GRANDMASTER; break;
134 }
135 return SM_BASIC;
136 }
137
Use(XCreature * user)138 int XSkill::Use(XCreature * user)
139 {
140 switch (skt)
141 {
142 case SKT_STEALING : return UseSteal(user);
143 case SKT_DISARMTRAP : return UseDisarm(user);
144 case SKT_CREATETRAP: return UseCreate(user);
145
146 };
147 return 1;
148 }
149
isUseable()150 int XSkill::isUseable()
151 {
152 if (skt == SKT_STEALING || skt == SKT_DISARMTRAP || skt == SKT_CREATETRAP)
153 return 1;
154 else
155 return 0;
156 }
157
158
UseSkill(int n)159 void XSkill::UseSkill(int n)
160 {
161 used_time += n;
162 }
163
Store(XFile * f)164 void XSkill::Store(XFile * f)
165 {
166 XObject::Store(f);
167
168 f->Write(&level, sizeof(int));
169 f->Write(&skt, sizeof(SKILL_TYPE));
170 f->Write(&used_time, sizeof(int));
171 }
172
Restore(XFile * f)173 void XSkill::Restore(XFile * f)
174 {
175 XObject::Restore(f);
176
177 f->Read(&level, sizeof(int));
178 f->Read(&skt, sizeof(SKILL_TYPE));
179 f->Read(&used_time, sizeof(int));
180 }
181
182
Compare(XObject * o)183 int XSkill::Compare(XObject * o)
184 {
185 return strcmp(GetName(), ((XSkill *)o)->GetName());
186 }
187
188
UseSteal(XCreature * user)189 int XSkill::UseSteal(XCreature * user)
190 {
191 XPoint pt;
192 XItem * object;
193 if (user->GetTarget(TR_STEAL_ITEM, &pt, 0, (XObject **)&object))
194 {
195 if (pt.x == 0 && pt.y == 0)
196 {
197 msgwin.Add("Stealing from yourself? You are successful!");
198 user->contain.Add(object);
199 } else
200 {
201 XCreature * cr = user->l->map->GetMonster(user->x + pt.x, user->y + pt.y);
202 int flag = 0;
203 if (cr == NULL)
204 {
205 XAnyPlace * pl = user->l->map->GetPlace(user->x + pt.x, user->y + pt.y);
206 if (pl)
207 {
208 cr = pl->GetOwner().get();
209 flag = 1;
210 }
211 }
212 assert(cr);
213 double perception = 1 + cr->s->Get(S_PER);
214 double stealing = 1 + user->sk->GetLevel(SKT_STEALING);
215 int p = (int)((stealing * 300) / perception);
216 if (vRand() % 100 < p || !user->isVisible())
217 {
218 if (user->isVisible())
219 {
220 char buf[256];
221 XItem * it = (XItem *)object;
222 it->toString(buf);
223 char buf2[256];
224 sprintf(buf2, "You steal %s.", buf);
225 msgwin.Add(buf2);
226 }
227 cr->UnCarryItem((XItem *)object);
228 user->CarryItem((XItem *)object);
229 user->contain.Add(object);
230 UseSkill(6);
231 } else
232 {
233 if (user->isVisible())
234 {
235 msgwin.Add(cr->name);
236 msgwin.Add("notices your efforts and becomes angry.");
237 }
238 cr->xai->onSteal(user);
239 if (flag)
240 {
241 (user->l->map->GetItemList(user->x + pt.x, user->y + pt.y))->Add(object);
242 } else
243 {
244 cr->contain.Add(object);
245 }
246 }
247 }
248 }
249 return 1;
250 }
251
UseDisarm(XCreature * user)252 int XSkill::UseDisarm(XCreature * user)
253 {
254 XMapObject * obj = user->l->map->GetSpecial(user->x, user->y);
255 if (obj && obj->im & IM_TRAP)
256 {
257 if (((XTrap *)obj)->Disarm(user))
258 UseSkill(1);
259 } else
260 msgwin.Add("There is no trap here.");
261 return 1;
262 }
263
UseCreate(XCreature * user)264 int XSkill::UseCreate(XCreature * user)
265 {
266 return 1;
267 }
268
269
270