1 /*
2  *
3  *  Iter Vehemens ad Necem (IVAN)
4  *  Copyright (C) Timo Kiviluoto
5  *  Released under the GNU General
6  *  Public License
7  *
8  *  See LICENSING which should be included
9  *  along with this file for more details
10  *
11  */
12 
13 #include "wskill.h"
14 #include "message.h"
15 #include "save.h"
16 #include "item.h"
17 
18 int CWeaponSkillLevelMap[]
19 = { 0, 1500, 2000, 3000, 5000, 7500, 10000, 15000,
20     20000, 30000, 50000, 75000, 100000, 150000,
21     200000, 300000, 500000, 750000, 1000000,
22     1500000, 2000000 };
23 
24 ulong CWeaponSkillUnuseTickMap[]
25 = { 500000, 400000, 300000, 250000, 200000,
26     150000, 125000, 100000, 80000, 62500,
27     50000, 40000, 30000, 25000, 20000,
28     15000, 12500, 10000, 8000, 6250, 5000 };
29 
30 int CWeaponSkillUnusePenaltyMap[]
31 = { 100, 125, 150, 200, 250, 300, 400, 500,
32     625, 800, 1000, 1250, 1500, 2000, 2500,
33     3000, 4000, 5000, 6250, 8000, 10000 };
34 
35 cchar* CWeaponSkillName[WEAPON_SKILL_CATEGORIES]
36 = { "unarmed combat",
37     "kicking",
38     "biting",
39     "uncategorized",
40     "small swords",
41     "large swords",
42     "blunt weapons",
43     "axes",
44     "polearms",
45     "whips",
46     "shields",
47     "crafting"
48 };
49 
50 int SWeaponSkillLevelMap[]
51 = { 0, 500, 750, 1000, 1500, 2000, 3000, 5000,
52     7500, 10000, 15000, 20000, 30000, 50000,
53     75000, 100000, 150000, 200000, 300000,
54     500000, 750000 };
55 
56 ulong SWeaponSkillUnuseTickMap[]
57 = { 250000, 200000, 150000, 125000, 100000,
58     80000, 62500, 50000, 40000, 30000,
59     25000, 20000, 15000, 12500, 10000,
60     8000, 6250, 5000, 4000, 3000, 2500 };
61 
62 int SWeaponSkillUnusePenaltyMap[]
63 = { 250, 300, 400, 500, 625, 800, 1000,
64     1250, 1500, 2000, 2500, 3000, 4000,
65     5000, 6250, 8000, 10000, 12500, 15000,
66     20000, 25000 };
67 
GetLevelMap(int I) const68 int cweaponskill::GetLevelMap(int I) const
69 { return CWeaponSkillLevelMap[I]; }
GetUnuseTickMap(int I) const70 ulong cweaponskill::GetUnuseTickMap(int I) const
71 { return CWeaponSkillUnuseTickMap[I]; }
GetUnusePenaltyMap(int I) const72 int cweaponskill::GetUnusePenaltyMap(int I) const
73 { return CWeaponSkillUnusePenaltyMap[I]; }
GetName(int Category) const74 cchar* cweaponskill::GetName(int Category) const
75 { return CWeaponSkillName[Category]; }
76 
sweaponskill(citem * Item)77 sweaponskill::sweaponskill(citem* Item)
78 : ID(Item->GetID()), Weight(Item->GetWeight()), Config(Item->GetConfig()) { }
GetLevelMap(int I) const79 int sweaponskill::GetLevelMap(int I) const
80 { return SWeaponSkillLevelMap[I]; }
GetUnuseTickMap(int I) const81 ulong sweaponskill::GetUnuseTickMap(int I) const
82 { return SWeaponSkillUnuseTickMap[I]; }
GetUnusePenaltyMap(int I) const83 int sweaponskill::GetUnusePenaltyMap(int I) const
84 { return SWeaponSkillUnusePenaltyMap[I]; }
85 
Save(outputfile & SaveFile) const86 void weaponskill::Save(outputfile& SaveFile) const
87 {
88   SaveFile << Level << Hits << static_cast<int>(HitCounter);
89 }
90 
Load(inputfile & SaveFile)91 void weaponskill::Load(inputfile& SaveFile)
92 {
93   SaveFile >> Level >> Hits >> reinterpret_cast<int&>(HitCounter);
94 }
95 
AddHit(int AddHits)96 truth weaponskill::AddHit(int AddHits)
97 {
98   if(!AddHits)
99     return false;
100 
101   HitCounter = 0;
102 
103   if(Hits <= 5000000 - AddHits)
104     Hits += AddHits;
105   else
106     Hits = 5000000;
107 
108   int OldLevel = Level;
109 
110   while(Level < 20 && Hits >= GetLevelMap(Level + 1))
111     ++Level;
112 
113   return Level != OldLevel;
114 }
115 
SubHit(int SubHits)116 truth weaponskill::SubHit(int SubHits)
117 {
118   if(!SubHits)
119     return false;
120 
121   if(Hits >= SubHits)
122     Hits -= SubHits;
123   else
124     Hits = 0;
125 
126   int OldLevel = Level;
127 
128   while(Level && Hits < GetLevelMap(Level))
129     --Level;
130 
131   return Level != OldLevel;
132 }
133 
AddLevelUpMessage(int Category) const134 void cweaponskill::AddLevelUpMessage(int Category) const
135 {
136   ADD_MESSAGE("You advance to skill level %d with %s!",
137               Level, CWeaponSkillName[Category]);
138 }
139 
AddLevelDownMessage(int Category) const140 void cweaponskill::AddLevelDownMessage(int Category) const
141 {
142   ADD_MESSAGE("You have not practised enough with %s lately. "
143               "Your skill level is reduced to %d!",
144               CWeaponSkillName[Category], Level);
145 }
146 
AddLevelUpMessage(cchar * WeaponName) const147 void sweaponskill::AddLevelUpMessage(cchar* WeaponName) const
148 {
149   ADD_MESSAGE("You advance to skill level %d with your %s!",
150               Level, WeaponName);
151 }
152 
AddLevelDownMessage(cchar * WeaponName) const153 void sweaponskill::AddLevelDownMessage(cchar* WeaponName) const
154 {
155   ADD_MESSAGE("You have not practised enough with your %s lately. "
156               "Your skill level is reduced to %d!", WeaponName, Level);
157 }
158 
Save(outputfile & SaveFile) const159 void sweaponskill::Save(outputfile& SaveFile) const
160 {
161   weaponskill::Save(SaveFile);
162   SaveFile << ID << Weight << Config;
163 }
164 
Load(inputfile & SaveFile)165 void sweaponskill::Load(inputfile& SaveFile)
166 {
167   weaponskill::Load(SaveFile);
168   SaveFile >> ID >> Weight >> Config;
169 }
170 
Tick()171 truth weaponskill::Tick()
172 {
173   if(Hits && HitCounter++ >= GetUnuseTickMap(Level))
174   {
175     HitCounter -= GetUnuseTickMap(Level);
176 
177     if(SubHit(GetUnusePenaltyMap(Level)))
178       return true;
179   }
180 
181   return false;
182 }
183 
IsSkillOf(citem * Item) const184 truth sweaponskill::IsSkillOf(citem* Item) const
185 {
186   return (ID == Item->GetID()
187           && Weight == Item->GetWeight()
188           && Config == Item->GetConfig());
189 }
190 
IsSkillOfCloneMother(citem * Item,ulong CMID) const191 truth sweaponskill::IsSkillOfCloneMother(citem* Item, ulong CMID) const
192 {
193   return (ID == CMID
194           && Weight == Item->GetWeight()
195           && Config == Item->GetConfig());
196 }
197