-
Notifications
You must be signed in to change notification settings - Fork 0
/
skills.cpp
293 lines (220 loc) · 8.62 KB
/
skills.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
#include "skills.h"
#include <memory>
#include <iostream>
#include <unistd.h>
#include "player.h"
//============================
// Skill & subclasses
//============================
bool Skill::checkCost(Creature &caster) {
CreaturePoints points = caster.getPointValues();
if (points.HP < cost.HP) { return false; }
else if (points.SP < cost.SP) { return false; }
else if (points.MP < cost.MP) { return false; }
else {return true;}
}
skillReturnType Skill::canCast(Creature &caster) {
if (checkCost(caster) == false) {
return SKILL_FAIL_COST;
}
else if (isUnlocked() == false) {
return SKILL_NOT_UNLOCKED;
}
else {
return SKILL_SUCCESS;
}
}
std::string Skill::getName() {
return name;
}
std::string Skill::getDesc() {
return description;
}
// Skill::getNameC() {
// return name.c_str();
//}
bool Skill::isUnlocked() const {
return unlocked;
}
bool Skill::canUnlock() {
return parent->isUnlocked();
}
void Skill::unlock() {
unlocked = true;
}
skillTargetType Skill::getTargetType() {
return targetType;
};
//
//Skill::Skill() {
//
//}
Skill::Skill(skillTargetType type, skillDamageType damageType, bool startsUnlocked, bool isPassive, Skill *parentNode, char key, std::string skillName, std::string skillDescription, Points costPoints) : shortcut(key) {
targetType = type;
this->damageType = damageType;
unlocked = startsUnlocked;
passive = isPassive;
parent = parentNode;
//shortcut = key;
name = skillName;
description = skillDescription;
cost = costPoints;
}
skillReturnType Skill::Use(Creature &caster) {
std::cerr << "Error: Skill::Use(Creature &caster) called!" << std::endl;
return SKILL_BASE_CLASS_ERROR;
}
skillReturnType Skill::Use(Creature &caster, Creature &target) {
std::cerr << "Error: Skill::Use(Creature &caster, Creature &target) called!" << std::endl;
return SKILL_BASE_CLASS_ERROR;
}
Points Skill::getCost() {
return cost;
}
skillDamageType Skill::getDamageType() {
return damageType;
}
//Heal
Heal::Heal() {
}
Heal::Heal(bool startsUnlocked, Skill *parentNode, char key, std::string name, std::string skillDescription, Points costPoints, Points pointsToHeal)
: Skill(TYPE_SELF, DMGTYPE_NONE, startsUnlocked, false, parentNode, key, name, skillDescription, costPoints) { //Pass through to Skill constructor
baseHealPoints = pointsToHeal;
}
skillReturnType Heal::Use(Creature &caster) {
skillReturnType r = canCast(caster);
if (r == SKILL_SUCCESS) {
caster.takeCost(getCost());
caster.heal(baseHealPoints);
}
return r;
}
//Melee
Melee::Melee() {
}
Melee::Melee(bool startsUnlocked, Skill *parentNode, char key, std::string skillName, std::string skillDescription, Points costPoints, int baseDmg, Stats damageFactors )
: Skill(TYPE_ENEMY, DMGTYPE_PHYSICAL, startsUnlocked, false, parentNode, key, skillName, skillDescription, costPoints) {
baseDamage = baseDmg;
statDamageFactors = damageFactors;
}
skillReturnType Melee::Use(Creature &caster, Creature &target) {
skillReturnType r = canCast(caster);
if (r == SKILL_SUCCESS) {
caster.takeCost(getCost());
Points dmg = {0,0,0};
dmg.HP = baseDamage + runStatMultipliers(caster.getStats(), statDamageFactors);
dmg = caster.runDamageMultipliers(dmg, getDamageType());
target.damage(dmg, getDamageType());
}
return r;
}
//MagicTouch
skillReturnType MagicTouch::Use(Creature &caster, Creature &target) {
skillReturnType r = canCast(caster);
if (r == SKILL_SUCCESS) {
caster.takeCost(getCost());
Points dmg = {0,0,0};
dmg.HP = baseDamage + runStatMultipliers(caster.getStats(), statDamageFactors);
dmg = caster.runDamageMultipliers(dmg, getDamageType());
target.damage(dmg, getDamageType());
//Clone the "master copy" of the buff
Buff *newBuff = debuff->Clone();
//set buff duration based on stats
newBuff->turnsLeft = debuff->getBaseDuration() + runStatMultipliers(caster.getStats(), debuff->getDurationMultipliers());
newBuff->apply(target);
}
return r;
}
MagicTouch::MagicTouch() {}
MagicTouch::MagicTouch(bool startsUnlocked, Skill *parentNode, char key, std::string name, std::string skillDescription, Points costPoints, int baseDmg, Stats damageFactors, Buff *buff)
: Skill(TYPE_ENEMY, DMGTYPE_MAGICAL, startsUnlocked, false, parentNode, key, name, skillDescription, costPoints) {
baseDamage = baseDmg;
statDamageFactors = damageFactors;
debuff = buff;
}
//=============================
// Provide Skill Tree
//=============================
Skill * getSkill_RootSkill() { //Empty parent node of everything, only time using Skill directly
Skill *RootSkill;
RootSkill = new Skill {TYPE_SELF, DMGTYPE_NONE, true, true, nullptr, '#', "RootSkill", "RootSkill", {0,0,0}};
//RootSkill->unlock();
return RootSkill;
}
skillPtrList createSkillPtrList() {
skillPtrList skillPtrs;
Points cost_none {0,0,0};
Stats multipliers_none = allStats(0);
Skill RootSkill = *getSkill_RootSkill();
//Not added to skill list
//Tier 0: Unlocked by default
Skill *skill_Rest;
skill_Rest = new Heal (true, &RootSkill, 'r', "Rest", "Rest a turn", cost_none, {1,1,1}); //Root of Mage tree
skillPtrs.push_back(skill_Rest);
Stats multipliers_Hit = allStats(0);
multipliers_Hit["strength"] = 1; // 1 + 1*STR damage
Skill *skill_Hit;
skill_Hit = new Melee (true, &RootSkill, 'h', "Hit", "Hit an enemy", cost_none, 1, multipliers_Hit); //Root of Warrior tree
skillPtrs.push_back(skill_Hit);
//Tier 1: First unlockables
//Flame Touch
// name dispel, stacks, duration, duration mults, damage
Buff * buff_FlameTouch;
buff_FlameTouch = new DoT ("Flame Touch burn", true, false, 4, multipliers_none, {1,0,0});
Points cost_FlameTouch {0,0,2};
Stats multipliers_FlameTouch_damage = allStats(0); //Inits with 0's
multipliers_FlameTouch_damage["power"] = 1;
Skill *skill_FlameTouch;
skill_FlameTouch = new MagicTouch (false, skill_Rest, 'f', "Flame Touch", "Scorch your enemy with your burning hand", cost_FlameTouch, 1, multipliers_FlameTouch_damage, buff_FlameTouch);
skillPtrs.push_back(skill_FlameTouch);
//skill_FlameTouch->unlock(); //Debug
//Frost Touch
BuffTurnMultipliers effects_IceTouch; //Inits to 1's
effects_IceTouch.physicalDamageOutput = 0.5; //Debug, deals no physical dmg
Buff * buff_IceTouch;
// name dispel, stacks, duration, duration mults, damage
buff_IceTouch = new DamageMod ("Ice Touch slow", true, false, 4, multipliers_none, effects_IceTouch);
Points cost_IceTouch = {0,0,2};
Stats multipliers_IceTouch_damage = allStats(0);
multipliers_IceTouch_damage["power"] = 1;
Skill *skill_IceTouch;
skill_IceTouch = new MagicTouch (false, skill_Rest, 'i', "Ice Touch", "Impair your enemy with a freezing touch", cost_IceTouch, 1, multipliers_IceTouch_damage, buff_IceTouch);
skillPtrs.push_back(skill_IceTouch);
//skill_IceTouch->unlock(); //Debug
//Smash
Stats multipliers_Smash = allStats(0);
multipliers_Smash["strength"] = 2; // 1 + 2 * STR damage
Skill *skill_Smash;
skill_Smash = new Melee (false, skill_Hit, 's', "Smash", "A strike depending on sheer strength", {0,2,0}, 1, multipliers_Smash); //Root of Warrior tree
skillPtrs.push_back(skill_Smash);
//skill_Smash->unlock();
return skillPtrs;
}
Skill * getSkill_Strike() {
Stats multipliers_Strike = allStats(0);
multipliers_Strike["strength"] = 1;
Skill *Strike;
// 1 + 1*STR damage
Strike = new Melee (true, getSkill_RootSkill(), '.', "Strike", "Strike", {0,0,0}, 1, multipliers_Strike); //Root of Warrior tree
return Strike;
}
//Default Skill list for monsters
skillPtrList createMonsterSkillList() {
skillPtrList skillPtrs;
//Default Monster attack - '.' for Monster hotkeys, never used
skillPtrs.push_back(getSkill_Strike());
return skillPtrs;
}
//Returns nullptr if not a valid skill. Caller must handle this.
Skill * getSkillByHotkey(skillPtrList &skillPtrs, char key) {
Skill *chosenSkill = nullptr;
std::list<Skill*>::const_iterator it;
for (it = skillPtrs.begin(); it != skillPtrs.end(); it++) {
//First deref for iterator -> content, second for pointer -> Skill
if ( ((**it).shortcut) == key ) {
chosenSkill = *(it);
break;
}
}
return chosenSkill;
}