1 /*
2 * Copyright 2011-2012 Arx Libertatis Team (see the AUTHORS file)
3 *
4 * This file is part of Arx Libertatis.
5 *
6 * Arx Libertatis 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 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Arx Libertatis 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 Arx Libertatis. If not, see <http://www.gnu.org/licenses/>.
18 */
19 /* Based on:
20 ===========================================================================
21 ARX FATALIS GPL Source Code
22 Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company.
23
24 This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code').
25
26 Arx Fatalis Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
27 License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
28
29 Arx Fatalis Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
30 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
31
32 You should have received a copy of the GNU General Public License along with Arx Fatalis Source Code. If not, see
33 <http://www.gnu.org/licenses/>.
34
35 In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these
36 additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx
37 Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below.
38
39 If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o
40 ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
41 ===========================================================================
42 */
43 // Copyright (c) 1999-2001 ARKANE Studios SA. All rights reserved
44
45 #include "graphics/spells/Spells10.h"
46
47 #include <algorithm>
48
49 #include "core/GameTime.h"
50
51 #include "game/EntityManager.h"
52
53 #include "graphics/Math.h"
54 #include "graphics/data/TextureContainer.h"
55 #include "graphics/effects/SpellEffects.h"
56 #include "graphics/spells/Spells07.h"
57 #include "graphics/spells/Spells09.h"
58 #include "graphics/particle/ParticleEffects.h"
59
60 #include "scene/Interactive.h"
61
62 //-----------------------------------------------------------------------------
63 //-----------------------------------------------------------------------------
CMassLightning(long nbmissiles)64 CMassLightning::CMassLightning(long nbmissiles)
65 {
66 SetDuration(2000);
67 pTab = new CLightning*[10];
68 number = std::min(10L, nbmissiles);
69
70 for (int i = 0; i < number; i++)
71 {
72 pTab[i] = new CLightning();
73 pTab[i]->fDamage = 2;
74 }
75 }
76
77 //-----------------------------------------------------------------------------
Create(Vec3f aePos,float afBeta=0)78 void CMassLightning::Create(Vec3f aePos, float afBeta = 0) {
79
80 (void)afBeta;
81
82 long lMax = 0;
83 Vec3f eTarget;
84 float ft = 360.0f / (float)number;
85
86 for (int i = 0; i < number; i++)
87 {
88 eTarget.x = aePos.x - EEsin(radians(i * ft)) * 500.0f;
89 eTarget.y = aePos.y;
90 eTarget.z = aePos.z + EEcos(radians(i * ft)) * 500.0f;
91 pTab[i]->Create(aePos, eTarget, 0);
92 long lTime = ulDuration + Random::get(0, 5000);
93 pTab[i]->SetDuration(lTime);
94 lMax = std::max(lMax, lTime);
95 pTab[i]->spellinstance = this->spellinstance;
96 pTab[i]->SetColor1(1.f, 0.75f, 0.75f); // middle
97 pTab[i]->SetColor2(0.3f, 0.f, 0.f); // extremities
98 }
99
100 SetDuration(lMax + 1000);
101 }
102
103 //-----------------------------------------------------------------------------
Update(unsigned long _ulTime)104 void CMassLightning::Update(unsigned long _ulTime)
105 {
106 for (int i = 0; i < number; i++)
107 {
108 pTab[i]->Update(_ulTime);
109 }
110 }
111
112 //-----------------------------------------------------------------------------
Render()113 float CMassLightning::Render()
114 {
115 for (int i = 0; i < number; i++)
116 {
117 pTab[i]->Render();
118 }
119
120 return 1;
121 }
122
CControlTarget()123 CControlTarget::CControlTarget() {
124
125 eSrc = Vec3f::ZERO;
126 eTarget = Vec3f::ZERO;
127
128 SetDuration(8000);
129 ulCurrentTime = ulDuration + 1;
130
131 tex_mm = TextureContainer::Load("graph/obj3d/textures/(fx)_ctrl_target");
132
133 fColor[0] = 1;
134 fColor[1] = 1;
135 fColor[2] = 0;
136
137 fColor1[0] = 0.8f;
138 fColor1[1] = 0.6f;
139 fColor1[2] = 0.2f;
140 }
141
Create(Vec3f aeSrc,float afBeta)142 void CControlTarget::Create(Vec3f aeSrc, float afBeta) {
143
144 SetDuration(ulDuration);
145
146 eSrc = aeSrc;
147
148 fBeta = afBeta;
149 fBetaRad = radians(fBeta);
150 fBetaRadCos = (float) cos(fBetaRad);
151 fBetaRadSin = (float) sin(fBetaRad);
152
153 fSize = 1;
154 bDone = true;
155 eTarget = eSrc + Vec3f(-fBetaRadSin * 1000.f, 100.f, fBetaRadCos * 1000.f);
156
157 for(size_t i = 1; i < entities.size(); i++) {
158 if(entities[i]) {
159 eTarget = entities[i]->pos;
160 }
161 }
162
163 end = 20 - 1;
164 v1a[0].p = eSrc + Vec3f(0.f, 100.f, 0.f);
165 v1a[end].p = eTarget;
166
167 Vec3f h;
168 Vec3f s = eSrc;
169 Vec3f e = eSrc;
170 int i = 0;
171 while(Visible(&s, &e, NULL, &h) && i < 20) {
172 e.x -= fBetaRadSin * 50;
173 e.z += fBetaRadCos * 50;
174 i++;
175 }
176
177 pathways[0].p = eSrc + Vec3f(0.f, 100.f, 0.f);
178 pathways[9].p = eTarget;
179 Split(pathways, 0, 9, 150);
180
181 for(int i = 0; i < 9; i++) {
182 if(pathways[i].p.y >= eSrc.y + 150) {
183 pathways[i].p.y = eSrc.y + 150;
184 }
185 }
186
187 fTrail = 0;
188 }
189
Update(unsigned long _ulTime)190 void CControlTarget::Update(unsigned long _ulTime) {
191 ulCurrentTime += _ulTime;
192 }
193
194 //---------------------------------------------------------------------
Render()195 float CControlTarget::Render()
196 {
197 int i = 0;
198
199 GRenderer->SetCulling(Renderer::CullNone);
200 GRenderer->SetRenderState(Renderer::DepthWrite, false);
201 GRenderer->SetRenderState(Renderer::AlphaBlending, true);
202 GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
203 GRenderer->SetTexture(0, tex_mm);
204
205 // -------------------
206 fTrail += 1;
207
208 if (fTrail >= 300) fTrail = 0;
209
210 int n = BEZIERPrecision;
211 float delta = 1.0f / n;
212
213 fTrail = (ulCurrentTime * fOneOnDuration) * 9 * (n + 2);
214
215 Vec3f v;
216
217 int arx_check_init = -1;
218 Vec3f newpos = Vec3f::ZERO;
219 Vec3f lastpos = pathways[0].p;
220
221 for (i = 0; i < 9; i++)
222 {
223 int kp = i;
224 int kpprec = (i > 0) ? kp - 1 : kp ;
225 int kpsuiv = kp + 1 ;
226 int kpsuivsuiv = (i < (9 - 2)) ? kpsuiv + 1 : kpsuiv;
227
228 for (int toto = 1; toto < n; toto++)
229 {
230 if (fTrail < i * n + toto) break;
231
232 float t = toto * delta;
233
234 float t1 = t;
235 float t2 = t1 * t1 ;
236 float t3 = t2 * t1 ;
237 float f0 = 2.f * t3 - 3.f * t2 + 1.f ;
238 float f1 = -2.f * t3 + 3.f * t2 ;
239 float f2 = t3 - 2.f * t2 + t1 ;
240 float f3 = t3 - t2 ;
241
242 float val = pathways[kpsuiv].p.x;
243 float p0 = 0.5f * (val - pathways[kpprec].p.x) ;
244 float p1 = 0.5f * (pathways[kpsuivsuiv].p.x - pathways[kp].p.x) ;
245 v.x = f0 * pathways[kp].p.x + f1 * val + f2 * p0 + f3 * p1 ;
246
247 val = pathways[kpsuiv].p.y ;
248 p0 = 0.5f * (val - pathways[kpprec].p.y) ;
249 p1 = 0.5f * (pathways[kpsuivsuiv].p.y - pathways[kp].p.y) ;
250 v.y = f0 * pathways[kp].p.y + f1 * val + f2 * p0 + f3 * p1 ;
251
252 val = pathways[kpsuiv].p.z ;
253 p0 = 0.5f * (val - pathways[kpprec].p.z) ;
254 p1 = 0.5f * (pathways[kpsuivsuiv].p.z - pathways[kp].p.z) ;
255 v.z = f0 * pathways[kp].p.z + f1 * val + f2 * p0 + f3 * p1 ;
256
257 newpos = v;
258
259 if(fTrail - (i * n + toto) <= 70) {
260 float c = 1.0f - (fTrail - (i * n + toto)) / 70.0f;
261 PARTICLE_DEF * pd = createParticle();
262 if(pd) {
263 pd->ov = lastpos;
264 pd->siz = 5 * c;
265 pd->tolive = Random::get(10, 110);
266 pd->tc = tex_mm;
267 pd->special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING;
268 pd->fparam = 0.0000001f;
269 pd->rgb = Color3f::gray(c);
270 }
271 }
272
273 std::swap(lastpos, newpos);
274 ++arx_check_init;
275
276 PARTICLE_DEF * pd = createParticle();
277 if(pd) {
278 pd->ov = lastpos;
279 pd->siz = 5;
280 pd->tolive = Random::get(10, 110);
281 pd->tc = tex_mm;
282 pd->special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING;
283 pd->fparam = 0.0000001f;
284 pd->rgb = Color3f::gray(0.1f);
285 }
286 }
287 }
288
289 arx_assert(arx_check_init >= 0);
290
291 eCurPos = lastpos;
292
293 return 1;
294 }
295
296 //---------------------------------------------------------------------
~CMassIncinerate()297 CMassIncinerate::~CMassIncinerate()
298 {
299 }
300
301 //---------------------------------------------------------------------
Create(Vec3f aePos,float afBeta=0)302 void CMassIncinerate::Create(Vec3f aePos, float afBeta = 0) {
303
304 (void)afBeta;
305
306 aePos.y += 150.0f;
307
308 for (int i = 0; i < 10; i++)
309 {
310 pTabIncinerate[i]->Create(aePos, i * 36.f);
311 }
312 }
313
314 //---------------------------------------------------------------------
Update(unsigned long _ulTime)315 void CMassIncinerate::Update(unsigned long _ulTime)
316 {
317 for (int i = 0; i < 10; i++)
318 {
319 pTabIncinerate[i]->Update(_ulTime);
320 }
321
322 }
323
324 //---------------------------------------------------------------------
Render()325 float CMassIncinerate::Render()
326 {
327 for (int i = 0; i < 10; i++)
328 {
329 pTabIncinerate[i]->Render();
330 }
331
332 return 0;
333 }
334
335