comparison Engine/Spells/Spells.cpp @ 2499:68cdef6879a0

engine folder
author Ritor1
date Fri, 19 Sep 2014 02:57:42 +0600
parents
children a77c34acdbc9
comparison
equal deleted inserted replaced
2498:92eeeb5200f2 2499:68cdef6879a0
1 #define _CRTDBG_MAP_ALLOC
2 #include <stdlib.h>
3 #include <crtdbg.h>
4
5 #define _CRT_SECURE_NO_WARNINGS
6 #include <stdlib.h>
7 #include "../ErrorHandling.h"
8
9 #include "Spells.h"
10 #include "Engine/Graphics/Overlays.h"
11 #include "../LOD.h"
12 #include "../texts.h"
13
14 #include "../Party.h"
15 #include "../OurMath.h"
16 #include "Engine/Objects/SpriteObject.h"
17 #include "Engine/Objects/ObjectList.h"
18 #include "Engine/Graphics/Indoor.h"
19 #include "AudioPlayer.h"
20 #include "Engine/Objects/Actor.h"
21 #include "../Game.h"
22 #include "stru6.h"
23
24
25 std::array<TownPortalData, 6> TownPortalList = //4ECBB8
26 {{
27 {Vec3_int_(-5121, 2107, 1), 1536, 0, 21, 0},
28 {Vec3_int_(-15148, -10240, 1473), 0, 0, 4, 0},
29 {Vec3_int_(-10519, 5375, 753), 512, 0, 3, 0},
30 {Vec3_int_(3114, -11055, 513), 0, 0, 10, 0},
31 {Vec3_int_(-158, 7624, 1), 512, 0, 7, 0},
32 {Vec3_int_(-1837, -4247, 65), 65, 0, 8, 0}
33 }} ;
34
35 struct SpellStats *pSpellStats;
36
37
38 std::array<stru324_spell, 103> stru_4E3ACC =
39 {{
40 {10, 0},
41 {1000, 0}, {1010, 0}, {1020, 0}, {1030, 0}, {1040, 0}, {1050, 0}, {1060, 0}, {1070, 0}, {1080, 0}, {1090, 0}, {1100, 0},
42 {2000, 0}, {2010, 0}, {2020, 0}, {2030, 0}, {2040, 0}, {2050, 0}, {2060, 0}, {2070, 0}, {2080, 0}, {2090, 0}, {2100, 0},
43 {3000, 0}, {3010, 0}, {3020, 0}, {3030, 0}, {3040, 0}, {3050, 0}, {3060, 0}, {3070, 0}, {3080, 0}, {3090, 0}, {3100, 0},
44 {4000, 0}, {4010, 0}, {4020, 0}, {4030, 0}, {4040, 0}, {4050, 0}, {4060, 0}, {4070, 0}, {4080, 0}, {4090, 0}, {4100, 0},
45 {5000, 0}, {5010, 0}, {5020, 0}, {5030, 0}, {5040, 0}, {5050, 0}, {5060, 0}, {5070, 0}, {5080, 0}, {5090, 0}, {5100, 0},
46 {6000, 0}, {6010, 0}, {6020, 0}, {6030, 0}, {6040, 0}, {6050, 0}, {6060, 0}, {6070, 0}, {6080, 0}, {6090, 0}, {6100, 0},
47 {7000, 0}, {7010, 0}, {7020, 0}, {7030, 0}, {7040, 0}, {7050, 0}, {7060, 0}, {7070, 0}, {7080, 0}, {7090, 0}, {7100, 0},
48 {8000, 0}, {8010, 0}, {8020, 0}, {8030, 0}, {8040, 0}, {8050, 0}, {8060, 0}, {8070, 0}, {8080, 0}, {8090, 0}, {8100, 0},
49 {9000, 0}, {9010, 0}, {9020, 0}, {9030, 0}, {9040, 0}, {9050, 0}, {9060, 0}, {9070, 0}, {9080, 0}, {9090, 0}, {9100, 0},
50 {545, 0},
51 {545, 0},
52 {555, 0}
53 }};
54
55
56
57 SpellData::SpellData( __int16 innormalMana, __int16 inExpertLevelMana, __int16 inMasterLevelMana, __int16 inMagisterLevelMana,
58 __int16 inNormalLevelRecovery, __int16 inExpertLevelRecovery, __int16 inMasterLevelRecovery, __int16 inMagisterLevelRecovery,
59 __int8 inbaseDamage, __int8 inbonusSkillDamage, __int16 instats ):
60 uNormalLevelMana(innormalMana),
61 uExpertLevelMana(inExpertLevelMana),
62 uMasterLevelMana(inMasterLevelMana),
63 uMagisterLevelMana(inMagisterLevelMana),
64 uNormalLevelRecovery(inNormalLevelRecovery),
65 uExpertLevelRecovery(inExpertLevelRecovery),
66 uMasterLevelRecovery(inMasterLevelRecovery),
67 uMagisterLevelRecovery(inMagisterLevelRecovery),
68 baseDamage(inbaseDamage),
69 bonusSkillDamage(inbonusSkillDamage),
70 stats(instats)
71 {
72
73 }
74
75 //9 spellbook pages 11 spells per page 9*11 =99 +1 zero struct at 0. It counted from 1!
76 std::array<SpellData, 100> pSpellDatas={{
77 SpellData(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
78
79 SpellData(1, 1, 1, 1, 60, 60, 60, 40, 0, 0, 0),//0 fire
80 SpellData(2, 2, 2, 2, 110, 110, 100, 90, 3, 3, 0),
81 SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0),
82 SpellData(4, 4, 4, 4, 120, 120, 120, 120, 0, 0, 0),
83 SpellData(5, 5, 5, 5, 120, 120, 120, 120, 0, 0, 0),
84 SpellData(8, 8, 8, 8, 100, 100, 90, 80, 0, 6, 0),
85 SpellData(10, 10, 10, 10, 150, 150, 150, 150, 0, 6, 0),
86 SpellData(15, 15, 15, 15, 120, 120, 120, 120, 0, 6, 0),
87 SpellData(20, 20, 20, 20, 100, 100, 100, 90, 8, 1, 0),
88 SpellData(25, 25, 25, 25, 100, 100, 100, 90, 12, 1, 0),
89 SpellData(30, 30, 30, 30, 90, 90, 90, 90, 15, 15, 0),
90
91 SpellData(1, 1, 1, 0, 60, 60, 60, 60, 0, 0, 0), //1 air
92 SpellData(2, 2, 2, 2, 120, 120, 120, 100, 0, 0, 0),
93 SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0),
94 SpellData(4, 4, 4, 4, 110, 100, 90, 80, 2, 1, 0),
95 SpellData(5, 5, 5, 5, 90, 90, 70, 50, 0, 0, 0),
96 SpellData(8, 8, 8, 8, 120, 120, 120, 120, 0, 0, 0),
97 SpellData(10, 10, 10, 10, 100, 100, 90, 70, 0, 8, 0),
98 SpellData(15, 15, 15, 15, 200, 200, 200, 200, 0, 0, 0),
99 SpellData(20, 20, 20, 20, 100, 100, 100, 90, 10, 10, 0),
100 SpellData(25, 25, 25, 25, 250, 250, 250, 250, 0, 0, 0),
101 SpellData(30, 30, 30, 30, 90, 90, 90, 90, 20, 1, 0),
102
103 SpellData(1, 1, 1, 1, 60, 60, 60, 20, 0, 0, 0), //2 water
104 SpellData(2, 2, 2, 2, 110, 100, 90, 70, 2, 2, 0),
105 SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0),
106 SpellData(4, 4, 4, 4, 110, 100, 90, 80, 0, 4, 0),
107 SpellData(5, 5, 5, 5, 150, 150, 150, 150, 0, 0, 0),
108 SpellData(8, 8, 8, 8, 200, 200, 200, 200, 0, 0, 0),
109 SpellData(10, 10, 10, 10, 100, 100, 90, 80, 9, 9, 0),
110 SpellData(15, 15, 15, 15, 140, 140, 140, 140, 0, 0, 0),
111 SpellData(20, 20, 20, 20, 200, 200, 200, 200, 0, 0, 0),
112 SpellData(25, 25, 25, 25, 80, 80, 80, 80, 12, 3, 0),
113 SpellData(30, 30, 30, 30, 250, 250, 250, 250, 0, 0, 0),
114
115 SpellData(1, 1, 1, 1, 80, 80, 80, 80, 0, 0, 0), //3 earth
116 SpellData(2, 2, 2, 2, 100, 100, 100, 100, 0, 0, 0),
117 SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0),
118 SpellData(4, 4, 4, 4, 110, 100, 90, 80, 5, 3, 0),
119 SpellData(5, 5, 5, 5, 120, 120, 120, 120, 0, 0, 0),
120 SpellData(8, 8, 8, 8, 100, 100, 90, 80, 0, 9, 0),
121 SpellData(10, 10, 10, 10, 140, 140, 140, 140, 0, 0, 0),
122 SpellData(15, 15, 15, 15, 90, 90, 90, 80, 0, 8, 0),
123 SpellData(20, 20, 20, 20, 150, 150, 150, 150, 0, 0, 0),
124 SpellData(25, 25, 25, 25, 100, 100, 100, 90, 20, 1, 0),
125 SpellData(30, 30, 30, 30, 90, 90, 90, 90, 25, 0, 0),
126
127 SpellData(1, 1, 1, 1, 100, 100, 100, 100, 0, 0, 0), //4 spirit
128 SpellData(2, 2, 2, 2, 100, 100, 100, 100, 0, 0, 0),
129 SpellData(3, 3, 3, 3, 90, 90, 90, 90, 0, 0, 0),
130 SpellData(4, 4, 4, 4, 120, 120, 120, 120, 0, 0, 0),
131 SpellData(5, 5, 5, 5, 120, 120, 120, 120, 0, 0, 0),
132 SpellData(8, 8, 8, 8, 120, 120, 120, 120, 0, 0, 0),
133 SpellData(10, 10, 10, 10, 120, 120, 120, 120, 0, 0, 0),
134 SpellData(15, 15, 15, 15, 100, 100, 100, 100, 10, 8, 0),
135 SpellData(20, 20, 20, 20, 240, 240, 240, 240, 0, 0, 0),
136 SpellData(25, 25, 25, 25, 150, 150, 150, 150, 0, 0, 0),
137 SpellData(30, 30, 30, 30, 1000, 1000, 1000, 1000, 0, 0, 0),
138
139 SpellData(1, 1, 1, 1, 120, 120, 120, 120, 0, 0, 0), //5 mind
140 SpellData(2, 2, 2, 2, 110, 110, 110, 110, 3, 3, 0),
141 SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0),
142 SpellData(4, 4, 4, 4, 110, 100, 90, 80, 0, 0, 0),
143 SpellData(5, 5, 5, 5, 100, 100, 100, 100, 0, 0, 0),
144 SpellData(8, 8, 8, 8, 120, 120, 120, 120, 0, 0, 0),
145 SpellData(10, 10, 10, 10, 120, 120, 120, 120, 0, 0, 0),
146 SpellData(15, 15, 15, 15, 80, 80, 80, 80, 0, 0, 0),
147 SpellData(20, 20, 20, 20, 120, 120, 120, 120, 0, 0, 0),
148 SpellData(25, 25, 25, 25, 110, 110, 110, 100, 12, 12, 0),
149 SpellData(30, 30, 30, 30, 120, 120, 120, 120, 0, 0, 0),
150
151 SpellData(1, 1, 1, 1, 120, 120, 120, 120, 0, 0, 0), //6 body
152 SpellData(2, 2, 2, 2, 100, 100, 100, 100, 0, 0, 0),
153 SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0),
154 SpellData(4, 4, 4, 4, 110, 100, 90, 80, 8, 2, 0),
155 SpellData(5, 5, 5, 5, 110, 110, 110, 110, 0, 0, 0),
156 SpellData(8, 8, 8, 8, 120, 120, 120, 120, 0, 0, 0),
157 SpellData(10, 10, 10, 10, 120, 120, 120, 120, 0, 0, 0),
158 SpellData(15, 15, 15, 15, 120, 120, 120, 120, 0, 0, 0),
159 SpellData(20, 20, 20, 20, 120, 120, 120, 120, 0, 0, 0),
160 SpellData(25, 25, 25, 25, 110, 110, 110, 100, 30, 5, 0),
161 SpellData(30, 30, 30, 30, 100, 100, 100, 100, 0, 0, 0),
162
163 SpellData(5, 5, 5, 5, 110, 100, 90, 80, 0, 4, 0), //7 light
164 SpellData(10, 10, 10, 10, 120, 110, 100, 90, 16, 16, 0),
165 SpellData(15, 15, 15, 15, 120, 110, 100, 90, 0, 0, 0),
166 SpellData(20, 20, 20, 20, 160, 140, 120, 100, 0, 0, 0),
167 SpellData(25, 25, 25, 25, 140, 140, 140, 140, 0, 0, 0),
168 SpellData(30, 30, 30, 30, 500, 500, 500, 500, 0, 0, 0),
169 SpellData(35, 35, 35, 35, 135, 135, 120, 100, 25, 1, 0),
170 SpellData(40, 40, 40, 40, 500, 500, 500, 500, 0, 0, 0),
171 SpellData(45, 45, 45, 45, 250, 250, 250, 250, 0, 0, 0),
172 SpellData(50, 50, 50, 50, 150, 150, 150, 135, 20, 20, 0),
173 SpellData(55, 55, 55, 55, 300, 300, 300, 300, 0, 0, 0),
174
175 SpellData(10, 10, 10, 10, 140, 140, 140, 140, 0, 0, 0), //8 dark
176 SpellData(15, 15, 15, 15, 120, 110, 100, 90, 25, 10, 0),
177 SpellData(20, 20, 20, 20, 120, 100, 90, 120, 0, 0, 0),
178 SpellData(25, 25, 25, 25, 120, 120, 120, 120, 0, 0, 0),
179 SpellData(30, 30, 30, 30, 90, 90, 80, 70, 6, 6, 0),
180 SpellData(35, 35, 35, 35, 120, 120, 100, 80, 0, 0, 0),
181 SpellData(40, 40, 40, 40, 110, 110, 110, 110, 0, 0, 0),
182 SpellData(45, 45, 45, 45, 200, 200, 200, 150, 0, 0, 0),
183 SpellData(50, 50, 50, 50, 120, 120, 120, 100, 0, 25, 0),
184 SpellData(55, 55, 55, 55, 250, 250, 250, 250, 50, 1, 0),
185 SpellData(60, 60, 60, 60, 300, 300, 300, 300, 25, 8, 0)
186 }};
187
188 std::array<unsigned int, 25> wand_spell_ids =
189 {
190 // 135 Wand of Fire 136 Wand of Sparks 137 Wand of Poison 138 Wand of Stunning 139 Wand of Harm
191 SPELL_FIRE_FIRE_BOLT, SPELL_AIR_SPARKS, SPELL_WATER_POISON_SPRAY, SPELL_EARTH_STUN, SPELL_BODY_HARM,
192 // 140 Fairy Wand of Light 141 Fairy Wand of Ice 142 Fairy Wand of Lashing 143 Fairy Wand of Mind 144 Fairy Wand of Swarms
193 SPELL_LIGHT_LIGHT_BOLT, SPELL_WATER_ICE_BOLT, SPELL_SPIRIT_SPIRIT_LASH, SPELL_MIND_MIND_BLAST, SPELL_EARTH_DEADLY_SWARM,
194 // 145 Alacorn Wand of Fireballs 146 Alacorn Wand of Acid 147 Alacorn Wand of Lightning 148 Alacorn Wand of Blades 149 Alacorn Wand of Charms
195 SPELL_FIRE_FIREBALL, SPELL_WATER_ACID_BURST, SPELL_AIR_LIGHNING_BOLT, SPELL_EARTH_BLADES, SPELL_MIND_CHARM,
196 // 150 Arcane Wand of Blasting 151 Arcane Wand of The Fist 152 Arcane Wand of Rocks 153 Arcane Wand of Paralyzing 154 Arcane Wand of Clouds
197 SPELL_WATER_ICE_BLAST, SPELL_BODY_FLYING_FIST, SPELL_EARTH_ROCK_BLAST, SPELL_LIGHT_PARALYZE, SPELL_DARK_TOXIC_CLOUD,
198 // 155 Mystic Wand of Implosion 156 Mystic Wand of Distortion 157 Mystic Wand of Sharpmetal 158 Mystic Wand of Shrinking 159 Mystic Wand of Incineration
199 SPELL_AIR_IMPLOSION, SPELL_EARTH_MASS_DISTORTION, SPELL_DARK_SHARPMETAL, SPELL_DARK_SHRINKING_RAY, SPELL_FIRE_INCINERATE
200 };
201
202
203 std::array<std::array<unsigned char, 12>, 9> pSpellbookSpellIndices = // 4E2430
204 {{ //0 1 2 3 4 5 6 7 8 9 10 11
205 {0, 3, 1, 8, 11, 7, 4, 10, 6, 2, 5, 9},
206 {0, 11, 2, 9, 6, 8, 5, 10, 3, 7, 1, 4},
207 {0, 4, 8, 9, 1, 10, 3, 11, 7, 6, 2, 5},
208 {0, 7, 10, 8, 2, 11, 1, 5, 3, 6, 4, 9},
209 {0, 5, 10, 11, 7, 2, 8, 1, 4, 9, 3, 6},
210 {0, 5, 9, 8, 3, 7, 6, 4, 1, 11, 2, 10},
211 {0, 1, 6, 9, 3, 5, 8, 11, 7, 10, 4, 2},
212 {0, 1, 10, 11, 9, 4, 3, 6, 5, 7, 8, 2},
213 {0, 9, 3, 7, 1, 5, 2, 10, 11, 8, 6, 4}
214 }};
215
216 std::array<std::array<struct SpellBookIconPos, 12>, 9> pIconPos={{
217
218 { 0, 0, 17, 13, 115, 2, 217, 15,
219 299, 6, 28, 125, 130, 133, 294, 114,
220 11, 232, 134, 233, 237, 171, 296, 231},
221
222 { 0, 0, 19, 9, 117, 3, 206, 13,
223 285, 7, 16, 123, 113, 101, 201, 118,
224 317, 110, 11, 230, 149, 236, 296, 234},
225
226 { 0, 0, 17, 9, 140, 0, 210, 34,
227 293, 5, 15, 98, 78, 121, 175, 136,
228 301, 115, 15, 226, 154, 225, 272, 220},
229
230 { 0, 0, 7, 9, 156, 2, 277, 9,
231 11, 117, 111, 82, 180, 102, 303, 108,
232 10, 229, 120, 221, 201, 217, 296, 225},
233
234 { 0, 0, 18, 8, 89, 15, 192, 14,
235 292, 7, 22, 129, 125, 146, 217, 136,
236 305, 115, 22, 226, 174, 237, 290, 231},
237
238 { 0, 0, 18, 12, 148, 9, 292, 7,
239 17, 122, 121, 99, 220, 87, 293, 112,
240 13, 236, 128, 213, 220, 223, 315, 223},
241
242 { 0, 0, 23, 14, 127, 8, 204, 0,
243 306, 8, 14, 115, 122, 132, 200, 116,
244 293, 122, 20, 228, 154, 228, 294, 239},
245
246 { 0, 0, 19, 14, 124, 10, 283, 12,
247 8, 105, 113, 89, 190, 82, 298, 108,
248 18, 181, 101, 204, 204, 203, 285, 218},
249
250 { 0, 0, 18, 17, 110, 16, 201, 15,
251 307, 15, 18, 148, 125, 166, 201, 123,
252 275, 120, 28, 235, 217, 222, 324, 216}}};
253
254
255 //----- (0042EB31) --------------------------------------------------------
256 bool SpellBuff::NotExpired()
257 {
258 return (signed __int64)this->uExpireTime > 0 ? true:false;
259 }
260
261
262 //----- (00458585) --------------------------------------------------------
263 void SpellBuff::Reset()
264 {
265 uSkill = 0;
266 uPower = 0;
267 uExpireTime = 0i64;
268 uCaster = 0;
269 uFlags = 0;
270 if (uOverlayID)
271 {
272 pOtherOverlayList->pOverlays[uOverlayID - 1].Reset();
273 pOtherOverlayList->bRedraw = true;
274 uOverlayID = 0;
275 }
276 }
277
278 //----- (004585CA) --------------------------------------------------------
279 bool SpellBuff::IsBuffExpiredToTime( __int64 time_end )
280 {
281 if (uExpireTime && (uExpireTime < time_end))
282 {
283 uExpireTime = 0;
284 uPower = 0;
285 uSkill = 0;
286 uOverlayID = 0;
287 return true;
288 }
289 return false;
290 }
291
292 //----- (004584E0) --------------------------------------------------------
293 bool SpellBuff::Apply( signed __int64 uExpireTime, unsigned __int16 uSkillLevel, unsigned __int16 uPower, int uOverlayID, unsigned __int8 caster )
294 {
295 if (this->uExpireTime && (uExpireTime < this->uExpireTime))
296 return false;
297
298 this->uSkill = uSkillLevel;
299 this->uPower = uPower;
300 this->uExpireTime = uExpireTime;
301 if (this->uOverlayID && this->uOverlayID != uOverlayID)
302 {
303 pOtherOverlayList->pOverlays[this->uOverlayID - 1].Reset();
304 pOtherOverlayList->bRedraw = true;
305 this->uOverlayID = 0;
306 }
307 this->uOverlayID = uOverlayID;
308 this->uCaster = caster;
309
310 return true;
311 }
312
313 //----- (0045384A) --------------------------------------------------------
314 void SpellStats::Initialize()
315 {
316 std::map<std::string, SPELL_SCHOOL, ci_less> spellSchoolMaps;
317 spellSchoolMaps["fire"] = SPELL_SCHOOL_FIRE;
318 spellSchoolMaps["air"] = SPELL_SCHOOL_AIR;
319 spellSchoolMaps["water"] = SPELL_SCHOOL_WATER;
320 spellSchoolMaps["earth"] = SPELL_SCHOOL_EARTH;
321 spellSchoolMaps["spirit"] = SPELL_SCHOOL_SPIRIT;
322 spellSchoolMaps["mind"] = SPELL_SCHOOL_MIND;
323 spellSchoolMaps["body"] = SPELL_SCHOOL_BODY;
324 spellSchoolMaps["light"] = SPELL_SCHOOL_LIGHT;
325 spellSchoolMaps["dark"] = SPELL_SCHOOL_DARK;
326 spellSchoolMaps["magic"] = SPELL_SCHOOL_MAGIC;
327
328 char* test_string;
329
330 free(pSpellsTXT_Raw);
331 pSpellsTXT_Raw = (char *)pEvents_LOD->LoadRaw("spells.txt", 0);
332
333 strtok(pSpellsTXT_Raw, "\r");
334 for(int i=1; i<100; ++i)
335 {
336 if (((i % 11) - 1 )==0)
337 strtok(NULL, "\r");
338 test_string=strtok(NULL, "\r")+1;
339 auto tokens = Tokenize(test_string, '\t');
340 pInfos[i].pName=RemoveQuotes(tokens[2]);
341 auto findResult = spellSchoolMaps.find(tokens[3]);
342 pInfos[i].uSchool = findResult == spellSchoolMaps.end() ? SPELL_SCHOOL_NONE : findResult->second;
343 pInfos[i].pShortName=RemoveQuotes(tokens[4]);
344 pInfos[i].pDescription=RemoveQuotes(tokens[5]);
345 pInfos[i].pBasicSkillDesc=RemoveQuotes(tokens[6]);
346 pInfos[i].pExpertSkillDesc=RemoveQuotes(tokens[7]);
347 pInfos[i].pMasterSkillDesc=RemoveQuotes(tokens[8]);
348 pInfos[i].pGrandmasterSkillDesc=RemoveQuotes(tokens[9]);
349 pSpellDatas[i].stats |= strchr(tokens[10], 'm') || strchr(tokens[10], 'M') ? 1 : 0;
350 pSpellDatas[i].stats |= strchr(tokens[10], 'e') || strchr(tokens[10], 'E') ? 2 : 0;
351 pSpellDatas[i].stats |= strchr(tokens[10], 'c') || strchr(tokens[10], 'C') ? 4 : 0;
352 pSpellDatas[i].stats |= strchr(tokens[10], 'x') || strchr(tokens[10], 'X') ? 8 : 0;
353 }
354 }
355 //----- (00448DF8) --------------------------------------------------------
356 void __fastcall EventCastSpell(int uSpellID, int uSkillLevel, int uSkill, int fromx, int fromy, int fromz, int tox, int toy, int toz)//sub_448DF8
357 {
358 int v9; // esi@1
359 signed __int64 v10; // st7@4
360 signed __int64 v11; // st6@4
361 signed __int64 v12; // st5@4
362 double v13; // st7@6
363 int v14; // ST44_4@7
364 uint skillMasteryPlusOne; // ebx@9
365 uint v16; // edx@15
366 int i; // esi@42
367 int j; // esi@60
368 unsigned __int64 v36; // qax@99
369 // SpellBuff *v37; // ecx@99
370 int v38; // esi@103
371 signed __int64 v39; // qax@105
372 int v42; // esi@111
373 int v43; // ebx@111
374 int v47; // [sp-4h] [bp-B8h]@35
375 int v49; // [sp+0h] [bp-B4h]@35
376 int v55; // [sp+28h] [bp-8Ch]@7
377 unsigned int yaw; // [sp+30h] [bp-84h]@7
378 int pitch; // [sp+34h] [bp-80h]@7
379 int v60; // [sp+ACh] [bp-8h]@1
380 int a6_4; // [sp+C8h] [bp+14h]@117
381 int a7c; // [sp+CCh] [bp+18h]@29
382 int a7d; // [sp+CCh] [bp+18h]@55
383 signed __int64 xSquared; // [sp+D0h] [bp+1Ch]@6
384 int a8b; // [sp+D0h] [bp+1Ch]@37
385 int a8c; // [sp+D0h] [bp+1Ch]@55
386 signed __int64 ySquared; // [sp+D4h] [bp+20h]@6
387
388 v9 = 0;
389 skillMasteryPlusOne = uSkillLevel + 1;
390 //spellnum_ = uSpellID;
391 v60 = 0;
392 if ( tox || toy || toz )
393 {
394 v10 = tox - fromx;
395 v11 = toy - fromy;
396 v12 = toz - fromz;
397 }
398 else
399 {
400 v10 = pParty->vPosition.x - fromx;
401 v11 = pParty->vPosition.y - fromy;
402 v12 = (pParty->vPosition.z + pParty->sEyelevel) - fromz;
403 }
404 v13 = sqrt(long double(v10 * v10 + v11 * v11 + v12 * v12));
405 if ( v13 <= 1.0 )
406 {
407 v55 = 1;
408 yaw = 0;
409 pitch = 0;
410 }
411 else
412 {
413 v55 = (int)v13;
414 ySquared = v11 * v11;
415 xSquared = v10 * v10;
416 v14 = (int)sqrt(long double(xSquared + ySquared));
417 yaw = stru_5C6E00->Atan2((int)v10, (int)v11);
418 pitch = stru_5C6E00->Atan2(v14, (int)v12);
419 }
420 Assert(skillMasteryPlusOne > 0 && skillMasteryPlusOne <= 4, "Invalid mastery level");
421
422 SpriteObject a1; // [sp+38h] [bp-7Ch]@12
423 //SpriteObject::SpriteObject(&a1);
424
425 switch ( uSpellID )
426 {
427 case SPELL_FIRE_FIRE_BOLT:
428 case SPELL_FIRE_FIREBALL:
429 case SPELL_AIR_LIGHNING_BOLT:
430 case SPELL_WATER_ICE_BOLT:
431 case SPELL_WATER_ACID_BURST:
432 case SPELL_WATER_ICE_BLAST:
433 case SPELL_EARTH_BLADES:
434 case SPELL_EARTH_ROCK_BLAST:
435 case SPELL_WATER_POISON_SPRAY:
436 case SPELL_AIR_SPARKS:
437 case SPELL_EARTH_DEATH_BLOSSOM:
438 a1.uType = stru_4E3ACC[uSpellID].uType;
439 a1.stru_24.Reset();
440 a1.spell_id = uSpellID;
441 a1.spell_level = uSkill;
442 a1.spell_skill = skillMasteryPlusOne;
443 v16 = 0;
444 while (v16 < pObjectList->uNumObjects)
445 {
446 if ( a1.uType == pObjectList->pObjects[v16].uObjectID)
447 {
448 break;
449 }
450 v16++;
451 }
452 a1.uObjectDescID = v16;
453 a1.vPosition.x = fromx;
454 a1.vPosition.y = fromy;
455 a1.vPosition.z = fromz;
456 a1.uAttributes = 16;
457 a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
458 a1.field_60_distance_related_prolly_lod = v55;
459 a1.uSpriteFrameID = 0;
460 a1.spell_caster_pid = 8000 | OBJECT_Item;
461 a1.uSoundID = 0;
462 break;
463 }
464
465 switch ( uSpellID )
466 {
467 case SPELL_FIRE_FIRE_BOLT:
468 case SPELL_FIRE_FIREBALL:
469 case SPELL_AIR_LIGHNING_BOLT:
470 case SPELL_WATER_ICE_BOLT:
471 case SPELL_WATER_ACID_BURST:
472 case SPELL_WATER_ICE_BLAST:
473 case SPELL_EARTH_BLADES:
474 case SPELL_EARTH_ROCK_BLAST:
475 //v20 = yaw;
476 a1.spell_target_pid = 0;
477 a1.uFacing = yaw;
478 a1.uSoundID = 0;
479 v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
480 a1.Create(yaw, pitch, v49, 0);
481 pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
482 return;
483 case SPELL_WATER_POISON_SPRAY:
484 switch ( skillMasteryPlusOne )
485 {
486 case 1:
487 v60 = 1;
488 break;
489 case 2:
490 v60 = 3;
491 break;
492 case 3:
493 v60 = 5;
494 break;
495 case 4:
496 v60 = 7;
497 break;
498 }
499 a1.spell_target_pid = 0;
500 a1.uFacing = yaw;
501 if ( v60 == 1 )
502 {
503 v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
504 a1.Create(yaw, pitch, v49, 0);
505 }
506 else
507 {
508 a7c = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
509 a8b = a7c / (v60 - 1);
510 for ( i = a7c / -2; i <= a7c / 2; i += a8b )
511 {
512 a1.uFacing = i + yaw;
513 a1.Create((signed __int16)(i + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
514 }
515 }
516 pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
517 return;
518 case SPELL_AIR_SPARKS:
519 switch ( skillMasteryPlusOne )
520 {
521 case 1:
522 v60 = 3;
523 break;
524 case 2:
525 v60 = 5;
526 break;
527 case 3:
528 v60 = 7;
529 break;
530 case 4:
531 v60 = 9;
532 break;
533 }
534 a7d = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
535 a8c = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v60 - 1);
536 a1.spell_target_pid = 4;
537 for ( j = a7d / -2; j <= a7d / 2; j += a8c )
538 {
539 a1.uFacing = j + yaw;
540 a1.Create((signed __int16)(j + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
541 }
542 pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
543 return;
544 case SPELL_EARTH_DEATH_BLOSSOM:
545 if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
546 return;
547 a1.spell_target_pid = 4;
548 v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
549 v47 = (signed int)stru_5C6E00->uIntegerHalfPi / 2;
550 a1.Create(yaw, v47, v49, 0);
551 pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
552 return;
553
554 case SPELL_FIRE_HASTE:
555 if ( skillMasteryPlusOne > 0 )
556 {
557 if ( skillMasteryPlusOne <= 2 )
558 v9 = 60 * (uSkill + 60);
559 else if ( skillMasteryPlusOne == 3 )
560 v9 = 180 * (uSkill + 20);
561 else if ( skillMasteryPlusOne == 4 )
562 v9 = 240 * (uSkill + 15);
563 }
564 for (uint i = 0; i < 4; ++i)
565 if (pParty->pPlayers[i].IsWeak())
566 return;
567 pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(v9 * 128) * 0.033333335), skillMasteryPlusOne, 0, 0, 0);
568 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
569 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
570 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
571 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
572 pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);//звук алтаря
573 return;
574 case SPELL_AIR_SHIELD:
575 case SPELL_EARTH_STONESKIN:
576 case SPELL_SPIRIT_HEROISM:
577 switch ( skillMasteryPlusOne )
578 {
579 case 1:
580 case 2:
581 v9 = 300 * (uSkill + 12);
582 break;
583 case 3:
584 v9 = 900 * (uSkill + 4);
585 break;
586 case 4:
587 v9 = 3600 * (uSkill + 1);
588 break;
589 }
590 switch ( uSpellID )
591 {
592 case SPELL_AIR_SHIELD:
593 v60 = 0;
594 uSkill = 14;
595 break;
596 case SPELL_EARTH_STONESKIN:
597 v60 = uSkill + 5;
598 uSkill = 15;
599 break;
600 case SPELL_SPIRIT_HEROISM:
601 v60 = uSkill + 5;
602 uSkill = 9;
603 break;
604 }
605 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
606 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
607 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
608 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
609 v36 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(v9 << 7) * 0.033333335);
610 pParty->pPartyBuffs[uSkill].Apply(v36, skillMasteryPlusOne, v60, 0, 0);
611 pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
612 return;
613 case SPELL_FIRE_IMMOLATION:
614 if (skillMasteryPlusOne == 4)
615 v38 = 600 * uSkill;
616 else
617 v38 = 60 * uSkill;
618 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
619 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
620 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
621 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
622 v39 = (signed __int64)((double)(v38 << 7) * 0.033333335);
623 v36 = pParty->uTimePlayed + v39;
624 pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].Apply(v36, skillMasteryPlusOne, uSkill, 0, 0);
625 pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
626 return;
627 case SPELL_FIRE_PROTECTION_FROM_FIRE:
628 case SPELL_AIR_PROTECTION_FROM_AIR:
629 case SPELL_WATER_PROTECTION_FROM_WATER:
630 case SPELL_EARTH_PROTECTION_FROM_EARTH:
631 case SPELL_MIND_PROTECTION_FROM_MIND:
632 case SPELL_BODY_PROTECTION_FROM_BODY:
633 a6_4 = 3600 * uSkill;
634 switch (skillMasteryPlusOne)
635 {
636 case 1:
637 v60 = uSkill;
638 break;
639 case 2:
640 v60 = 2 * uSkill;
641 break;
642 case 3:
643 v60 = 3 * uSkill;
644 break;
645 case 4:
646 v60 = 4 * uSkill;
647 break;
648 }
649 switch ( uSpellID )
650 {
651 case SPELL_FIRE_PROTECTION_FROM_FIRE:
652 uSkill = PARTY_BUFF_RESIST_FIRE;
653 break;
654 case SPELL_AIR_PROTECTION_FROM_AIR:
655 uSkill = PARTY_BUFF_RESIST_AIR;
656 break;
657 case SPELL_WATER_PROTECTION_FROM_WATER:
658 uSkill = PARTY_BUFF_RESIST_WATER;
659 break;
660 case SPELL_EARTH_PROTECTION_FROM_EARTH:
661 uSkill = PARTY_BUFF_RESIST_EARTH;
662 break;
663 case SPELL_MIND_PROTECTION_FROM_MIND:
664 uSkill = PARTY_BUFF_RESIST_MIND;
665 break;
666 case SPELL_BODY_PROTECTION_FROM_BODY:
667 uSkill = PARTY_BUFF_RESIST_BODY;
668 break;
669 }
670 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
671 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
672 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
673 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
674 pParty->pPartyBuffs[uSkill].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)a6_4 * 4.2666669), skillMasteryPlusOne, v60, 0, 0);
675 pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
676 return;
677 case SPELL_LIGHT_DAY_OF_THE_GODS :
678 switch (skillMasteryPlusOne)
679 {
680 case 2:
681 v42 = 10800 * uSkill;
682 v43 = 3 * uSkill + 10;
683 break;
684 case 3:
685 v42 = 18000 * uSkill;
686 v43 = 5 * uSkill + 10;
687 break;
688 case 4:
689 v42 = 14400 * uSkill;
690 v43 = 4 * uSkill + 10;
691 break;
692 }
693 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
694 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
695 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
696 pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
697 v39 = (signed __int64)((double)(v42 << 7) * 0.033333335);
698 v36 = pParty->uTimePlayed + v39;
699 pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].Apply(v36, skillMasteryPlusOne, v43, 0, 0);
700 pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
701 return;
702 default:
703 return;
704 }
705 }
706 //----- (00427769) --------------------------------------------------------
707 bool sub_427769_isSpellQuickCastableOnShiftClick(unsigned int uSpellID)
708 {
709 return ( pSpellDatas[uSpellID].stats & 0xC ) != 0;
710 }
711 //----- (0043AFE3) --------------------------------------------------------
712 int _43AFE3_calc_spell_damage(int spellId, int spellLevel, signed int skillMastery, int currentHp)
713 {
714 int result; // eax@1
715 unsigned int v5; // [sp-4h] [bp-8h]@9
716
717 result = 0;
718 if ( spellId == SPELL_FIRE_FIRE_SPIKE )
719 {
720 switch (skillMastery)
721 {
722 case 1:
723 case 2:
724 v5 = 6;
725 case 3:
726 v5 = 8;
727 case 4:
728 v5 = 10;
729 default:
730 return 0;
731 }
732 result = GetDiceResult(spellLevel, v5);
733 }
734 else if ( spellId == SPELL_EARTH_MASS_DISTORTION )
735 result = currentHp * (pSpellDatas[SPELL_EARTH_MASS_DISTORTION].baseDamage + 2 * spellLevel) / 100;
736 else
737 result = pSpellDatas[spellId].baseDamage
738 + GetDiceResult(spellLevel, pSpellDatas[spellId].bonusSkillDamage);
739
740 return result;
741 }