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/Spells05.h"
46
47 #include <climits>
48
49 #include "animation/AnimationRender.h"
50
51 #include "core/Core.h"
52 #include "core/GameTime.h"
53
54 #include "game/Damage.h"
55 #include "game/EntityManager.h"
56 #include "game/Player.h"
57 #include "game/Spells.h"
58
59 #include "graphics/Math.h"
60 #include "graphics/data/TextureContainer.h"
61 #include "graphics/effects/SpellEffects.h"
62 #include "graphics/effects/Fog.h"
63 #include "graphics/particle/ParticleEffects.h"
64 #include "graphics/particle/Particle.h"
65 #include "graphics/particle/ParticleManager.h"
66 #include "graphics/particle/ParticleParams.h"
67 #include "graphics/texture/TextureStage.h"
68
69 #include "scene/Interactive.h"
70 #include "scene/Light.h"
71 #include "scene/Object.h"
72
73 #include <list>
74
75 extern ParticleManager * pParticleManager;
76
77
78 EERIE_3DOBJ * ssol = NULL;
79 long ssol_count = 0;
80 EERIE_3DOBJ * slight = NULL;
81 long slight_count = 0;
82 EERIE_3DOBJ * srune = NULL;
83 long srune_count = 0;
84 EERIE_3DOBJ * smotte = NULL;
85 long smotte_count = 0;
86 EERIE_3DOBJ * stite = NULL;
87 long stite_count = 0;
88 EERIE_3DOBJ * smissile = NULL;
89 long smissile_count = 0;
90 EERIE_3DOBJ * spapi = NULL;
91 long spapi_count = 0;
92 EERIE_3DOBJ * svoodoo = NULL;
93 long svoodoo_count = 0;
94 //-----------------------------------------------------------------------------
CCurePoison()95 CCurePoison::CCurePoison()
96 {
97 SetDuration(1000);
98 ulCurrentTime = ulDuration + 1;
99
100 pPS = new ParticleSystem();
101 }
102
103 //-----------------------------------------------------------------------------
~CCurePoison()104 CCurePoison::~CCurePoison()
105 {
106
107 }
108
109 //-----------------------------------------------------------------------------
Create()110 void CCurePoison::Create()
111 {
112 SetAngle(0);
113
114 eSrc.x = entities[spells[spellinstance].target]->pos.x;
115 eSrc.y = entities[spells[spellinstance].target]->pos.y;
116
117 if (spells[spellinstance].target == 0)
118 eSrc.y += 200;
119
120 eSrc.z = entities[spells[spellinstance].target]->pos.z;
121
122 pPS->SetPos(eSrc);
123 ParticleParams cp;
124 memset(&cp, 0, sizeof(cp));
125 cp.iNbMax = 350;
126 cp.fLife = 800;
127 cp.fLifeRandom = 2000;
128 cp.p3Pos.x = 100;
129 cp.p3Pos.y = 0;
130 cp.p3Pos.z = 100;
131 cp.p3Direction.x = 0;
132 cp.p3Direction.y = -10;
133 cp.p3Direction.z = 0;
134 cp.fAngle = radians(5);
135 cp.fSpeed = 120;
136 cp.fSpeedRandom = 84;
137 cp.p3Gravity.x = 0;
138 cp.p3Gravity.y = -10;
139 cp.p3Gravity.z = 0;
140 cp.fFlash = 0;
141 cp.fRotation = 80;
142
143 cp.fStartSize = 8;//6;
144 cp.fStartSizeRandom = 8;
145 cp.fStartColor[0] = 20;
146 cp.fStartColor[1] = 205;
147 cp.fStartColor[2] = 20;
148 cp.fStartColor[3] = 245;
149 cp.fStartColorRandom[0] = 50;
150 cp.fStartColorRandom[1] = 50;
151 cp.fStartColorRandom[2] = 50;
152 cp.fStartColorRandom[3] = 10;
153
154 cp.fEndSize = 6;
155 cp.fEndSizeRandom = 4;
156 cp.fEndColor[0] = 5;
157 cp.fEndColor[1] = 20;
158 cp.fEndColor[2] = 5;
159 cp.fEndColor[3] = 0;
160 cp.fEndColorRandom[0] = 0;
161 cp.fEndColorRandom[1] = 40;
162 cp.fEndColorRandom[2] = 0;
163 cp.fEndColorRandom[3] = 0;
164 cp.bTexInfo = false;
165 pPS->SetParams(cp);
166 pPS->ulParticleSpawn = PARTICLE_CIRCULAR | PARTICLE_BORDER;
167 pPS->SetTexture("graph/particles/cure_poison", 0, 100); //5
168
169 pPS->lLightId = GetFreeDynLight();
170
171 if (pPS->lLightId != -1)
172 {
173 long id = pPS->lLightId;
174 DynLight[id].exist = 1;
175 DynLight[id].intensity = 1.5f;
176 DynLight[id].fallstart = 200.f;
177 DynLight[id].fallend = 350.f;
178 DynLight[id].rgb.r = 0.f;
179 DynLight[id].rgb.g = 1.f;
180 DynLight[id].rgb.b = 0.0f;
181 DynLight[id].pos.x = eSrc.x;
182 DynLight[id].pos.y = eSrc.y - 50.f;
183 DynLight[id].pos.z = eSrc.z;
184 DynLight[id].time_creation = (unsigned long)(arxtime);
185 DynLight[id].duration = 200;
186 DynLight[id].extras = 0;
187 }
188
189 fSize = 1;
190 }
191
192 //---------------------------------------------------------------------
Update(unsigned long aulTime)193 void CCurePoison::Update(unsigned long aulTime)
194 {
195 ulCurrentTime += aulTime;
196
197 if (ulCurrentTime >= ulDuration)
198 {
199 return;
200 }
201
202 eSrc.x = entities[spells[spellinstance].target]->pos.x;
203 eSrc.y = entities[spells[spellinstance].target]->pos.y;
204
205 if (spells[spellinstance].target == 0)
206 eSrc.y += 200;
207
208 eSrc.z = entities[spells[spellinstance].target]->pos.z;
209
210
211 unsigned long ulCalc = ulDuration - ulCurrentTime ;
212 arx_assert(ulCalc <= LONG_MAX);
213 long ff = static_cast<long>(ulCalc);
214
215
216
217 if (ff < 1500)
218 {
219 pPS->uMaxParticles = 0;
220 pPS->ulParticleSpawn = PARTICLE_CIRCULAR;
221 pPS->p3ParticleGravity = Vec3f::ZERO;
222
223 std::list<Particle *>::iterator i;
224
225 for (i = pPS->listParticle.begin(); i != pPS->listParticle.end(); ++i)
226 {
227 Particle * pP = *i;
228
229 if (pP->isAlive())
230 {
231 pP->fColorEnd[3] = 0;
232
233 if (pP->ulTime + ff < pP->ulTTL)
234 {
235 pP->ulTime = pP->ulTTL - ff;
236 }
237 }
238 }
239 }
240
241 pPS->SetPos(eSrc);
242 pPS->Update(aulTime);
243
244 if (pPS->lLightId == -1) pPS->lLightId = GetFreeDynLight();
245
246 if (pPS->lLightId != -1)
247 {
248 long id = pPS->lLightId;
249 DynLight[id].exist = 1;
250 DynLight[id].intensity = 2.3f;
251 DynLight[id].fallstart = 200.f;
252 DynLight[id].fallend = 350.f;
253 DynLight[id].rgb.r = 0.4f;
254 DynLight[id].rgb.g = 1.f;
255 DynLight[id].rgb.b = 0.4f;
256 DynLight[id].pos.x = eSrc.x;
257 DynLight[id].pos.y = eSrc.y - 50.f;
258 DynLight[id].pos.z = eSrc.z;
259 DynLight[id].duration = 200;
260 DynLight[id].time_creation = (unsigned long)(arxtime);
261 DynLight[id].extras = 0;
262 }
263
264 }
265
266 //---------------------------------------------------------------------
Render()267 float CCurePoison::Render()
268 {
269 if (ulCurrentTime >= ulDuration)
270 {
271 return 0.f;
272 }
273
274 pPS->Render();
275
276 return 1;
277 }
278
CRuneOfGuarding()279 CRuneOfGuarding::CRuneOfGuarding() {
280
281 eSrc = Vec3f::ZERO;
282 eTarget = Vec3f::ZERO;
283
284 SetDuration(1000);
285 ulCurrentTime = ulDuration + 1;
286
287 tex_p2 = TextureContainer::Load("graph/obj3d/textures/(fx)_tsu_blueting");
288
289 if(!ssol) {
290 ssol = LoadTheObj("graph/obj3d/interactive/fix_inter/fx_rune_guard/fx_rune_guard.teo");
291 }
292 ssol_count++;
293
294 if(!slight) {
295 slight = LoadTheObj("graph/obj3d/interactive/fix_inter/fx_rune_guard/fx_rune_guard02.teo");
296 }
297 slight_count++;
298
299 if(!srune) {
300 srune = LoadTheObj("graph/obj3d/interactive/fix_inter/fx_rune_guard/fx_rune_guard03.teo");
301 }
302 srune_count++;
303 }
304
~CRuneOfGuarding()305 CRuneOfGuarding::~CRuneOfGuarding()
306 {
307 ssol_count--;
308
309 if (ssol && (ssol_count <= 0))
310 {
311 ssol_count = 0;
312 delete ssol;
313 ssol = NULL;
314 }
315
316 slight_count--;
317
318 if (slight && (slight_count <= 0))
319 {
320 slight_count = 0;
321 delete slight;
322 slight = NULL;
323 }
324
325 srune_count--;
326
327 if (srune && (srune_count <= 0))
328 {
329 srune_count = 0;
330 delete srune;
331 srune = NULL;
332 }
333 }
334
Create(Vec3f _eSrc,float _fBeta)335 void CRuneOfGuarding::Create(Vec3f _eSrc, float _fBeta) {
336
337 SetDuration(ulDuration);
338 SetAngle(_fBeta);
339 eSrc = _eSrc;
340 eTarget = eSrc;
341 fSize = 1;
342 bDone = true;
343
344 lLightId = GetFreeDynLight();
345 if(lLightId != -1) {
346 long id = lLightId;
347 DynLight[id].exist = 1;
348 DynLight[id].intensity = 0.7f + 2.3f;
349 DynLight[id].fallend = 500.f;
350 DynLight[id].fallstart = 400.f;
351 DynLight[id].rgb.r = 1.0f;
352 DynLight[id].rgb.g = 0.2f;
353 DynLight[id].rgb.b = 0.2f;
354 DynLight[id].pos = eSrc - Vec3f(0.f, 50.f, 0.f);
355 DynLight[id].time_creation = (unsigned long)(arxtime);
356 DynLight[id].duration = 200;
357 }
358 }
359
Update(unsigned long _ulTime)360 void CRuneOfGuarding::Update(unsigned long _ulTime) {
361
362 ulCurrentTime += _ulTime;
363
364 float fa = 1.0f - rnd() * 0.15f;
365
366 if (lLightId != -1)
367 {
368 long id = lLightId;
369 DynLight[id].exist = 1;
370 DynLight[id].intensity = 0.7f + 2.3f * fa;
371 DynLight[id].fallend = 350.f;
372 DynLight[id].fallstart = 150.f;
373 DynLight[id].rgb.r = 1.0f;
374 DynLight[id].rgb.g = 0.2f;
375 DynLight[id].rgb.b = 0.2f;
376 DynLight[id].time_creation = (unsigned long)(arxtime);
377 DynLight[id].duration = 200;
378 }
379 }
380
381 //---------------------------------------------------------------------
Render()382 float CRuneOfGuarding::Render()
383 {
384
385
386 float x = eSrc.x;
387 float y = eSrc.y - 20;
388 float z = eSrc.z;
389
390 GRenderer->SetRenderState(Renderer::DepthWrite, false);
391 GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
392 GRenderer->SetRenderState(Renderer::AlphaBlending, true);
393
394 Anglef stiteangle;
395 Color3f stitecolor;
396
397 float stiteangleb = (float) ulCurrentTime * fOneOnDuration * 120;
398 stiteangle.a = 0;
399 stiteangle.g = 0;
400 Vec3f stitepos = Vec3f(x, y, z);
401
402 float gtc = arxtime.get_updated();
403 float v = EEsin(gtc * ( 1.0f / 1000 )) * ( 1.0f / 10 );
404 stiteangle.b = MAKEANGLE(gtc * ( 1.0f / 1000 ));
405 stitecolor.r = 0.4f - v;
406 stitecolor.g = 0.4f - v;
407 stitecolor.b = 0.6f - v;
408 Vec3f stitescale = Vec3f(1.f, -0.1f, 1.f);
409
410 if(slight) {
411 DrawEERIEObjEx(slight, &stiteangle, &stitepos, &stitescale, &stitecolor);
412 }
413
414 stiteangle.b = stiteangleb;
415 stitecolor.r = 0.6f;
416 stitecolor.g = 0.f;
417 stitecolor.b = 0.f;
418 stitescale = Vec3f::repeat(2.f);
419
420 if(ssol) {
421 DrawEERIEObjEx(ssol, &stiteangle, &stitepos, &stitescale, &stitecolor);
422 }
423
424 stitecolor.r = 0.6f;
425 stitecolor.g = 0.3f;
426 stitecolor.b = 0.45f;
427 stitescale = Vec3f::repeat(1.8f);
428
429 if(srune) {
430 DrawEERIEObjEx(srune, &stiteangle, &stitepos, &stitescale, &stitecolor);
431 }
432
433 for(int n = 0; n < 4; n++) {
434
435 PARTICLE_DEF * pd = createParticle();
436 if(!pd) {
437 break;
438 }
439
440 pd->ov = Vec3f(x + frand2() * 40.f, y, z + frand2() * 40.f);
441 pd->move = Vec3f(0.8f * frand2(), -4.f * rnd(), 0.8f * frand2());
442 pd->scale = Vec3f::repeat(-0.1f);
443 pd->tolive = Random::get(2600, 3200);
444 pd->tc = tex_p2;
445 pd->siz = 0.3f;
446 pd->rgb = Color3f(.4f, .4f, .6f);
447 }
448
449 return 1.0f - rnd() * 0.3f;
450 }
451
LaunchPoisonExplosion(Vec3f * aePos)452 void LaunchPoisonExplosion(Vec3f * aePos) {
453
454 // système de partoches pour l'explosion
455 ParticleSystem * pPS = new ParticleSystem();
456 ParticleParams cp;
457 cp.iNbMax = 80;
458 cp.fLife = 1500;
459 cp.fLifeRandom = 500;
460 cp.p3Pos = Vec3f::repeat(5);
461 cp.p3Direction.x = 0;
462 cp.p3Direction.y = 4;
463 cp.p3Direction.z = 0;
464 cp.fAngle = radians(360);
465 cp.fSpeed = 200;
466 cp.fSpeedRandom = 0;
467 cp.p3Gravity.x = 0;
468 cp.p3Gravity.y = 17;
469 cp.p3Gravity.z = 0;
470 cp.fFlash = 0;
471 cp.fRotation = 80;
472 cp.bRotationRandomDirection = true;
473 cp.bRotationRandomStart = true;
474
475 cp.fStartSize = 5;
476 cp.fStartSizeRandom = 3;
477 cp.fStartColor[0] = 0;
478 cp.fStartColor[1] = 76;
479 cp.fStartColor[2] = 0;
480 cp.fStartColor[3] = 0;
481 cp.fStartColorRandom[0] = 0;
482 cp.fStartColorRandom[1] = 0;
483 cp.fStartColorRandom[2] = 0;
484 cp.fStartColorRandom[3] = 150;
485 cp.bStartLock = false;
486
487 cp.fEndSize = 30;
488 cp.fEndSizeRandom = 5;
489 cp.fEndColor[0] = 0;
490 cp.fEndColor[1] = 0;
491 cp.fEndColor[2] = 0;
492 cp.fEndColor[3] = 0;
493 cp.fEndColorRandom[0] = 0;
494 cp.fEndColorRandom[1] = 25;
495 cp.fEndColorRandom[2] = 0;
496 cp.fEndColorRandom[3] = 20;
497 cp.bEndLock = false;
498
499 cp.iBlendMode = 3;
500 cp.iFreq = -1;
501 cp.bTexInfo = false;
502 pPS->SetParams(cp);
503 pPS->ulParticleSpawn = 0;
504 pPS->SetTexture("graph/particles/big_greypouf", 0, 200);
505
506 pPS->SetPos(*aePos);
507 pPS->Update(0);
508 pPS->iParticleNbMax = 0;
509
510 std::list<Particle *>::iterator i;
511
512 for (i = pPS->listParticle.begin(); i != pPS->listParticle.end(); ++i)
513 {
514 Particle * pP = *i;
515
516 if (pP->isAlive())
517 {
518 if (pP->p3Velocity.y >= 0.5f * 200)
519 pP->p3Velocity.y = 0.5f * 200;
520
521 if (pP->p3Velocity.y <= -0.5f * 200)
522 pP->p3Velocity.y = -0.5f * 200;
523 }
524 }
525
526 if (pParticleManager)
527 {
528 pParticleManager->AddSystem(pPS);
529 }
530 }
531
532
CPoisonProjectile()533 CPoisonProjectile::CPoisonProjectile() : eSrc(Vec3f::ZERO) {
534 SetDuration(2000);
535 ulCurrentTime = ulDuration + 1;
536 }
537
538 //-----------------------------------------------------------------------------
Create(Vec3f _eSrc,float _fBeta)539 void CPoisonProjectile::Create(Vec3f _eSrc, float _fBeta)
540 {
541 int i;
542
543 SetDuration(ulDuration);
544
545 SetAngle(_fBeta);
546
547 eSrc = _eSrc;
548
549 bOk = false;
550
551 eMove = Vec3f(-fBetaRadSin * 2, 0.f, fBetaRadCos * 2);
552
553 Vec3f s, e, h;
554 s = eSrc;
555 e = eSrc;
556
557 i = 0;
558
559 while (Visible(&s, &e, NULL, &h) && i < 20)
560 {
561 e.x -= fBetaRadSin * 50;
562 e.z += fBetaRadCos * 50;
563
564 i++;
565 }
566
567 e.y += 0.f;
568
569 pathways[0].p = eSrc;
570 pathways[9].p = e;
571 Split(pathways, 0, 9, 10 * fBetaRadCos, 10, 10, 10, 10 * fBetaRadSin, 10);
572
573 if (0)
574 for (i = 0; i < 10; i++)
575 {
576 if (pathways[i].p.y >= eSrc.y + 150)
577 {
578 pathways[i].p.y = eSrc.y + 150;
579 }
580
581 if (pathways[i].p.y <= eSrc.y + 50)
582 {
583 pathways[i].p.y = eSrc.y + 50;
584 }
585 }
586
587 fTrail = -1;
588
589 //-------------------------------------------------------------------------
590 // système de partoches
591 ParticleParams cp;
592 cp.iNbMax = 5;
593 cp.fLife = 2000;
594 cp.fLifeRandom = 1000;
595 cp.p3Pos = Vec3f::ZERO;
596 cp.p3Direction = -eMove;
597 cp.fAngle = 0;
598 cp.fSpeed = 10;
599 cp.fSpeedRandom = 10;
600 cp.p3Gravity = Vec3f::ZERO;
601 cp.fFlash = 21;
602 cp.fRotation = 80;
603 cp.bRotationRandomDirection = true;
604 cp.bRotationRandomStart = true;
605
606 cp.fStartSize = 5;
607 cp.fStartSizeRandom = 3;
608 cp.fStartColor[0] = 0;
609 cp.fStartColor[1] = 50;
610 cp.fStartColor[2] = 0;
611 cp.fStartColor[3] = 40;
612 cp.fStartColorRandom[0] = 0;
613 cp.fStartColorRandom[1] = 100;
614 cp.fStartColorRandom[2] = 0;
615 cp.fStartColorRandom[3] = 50;
616 cp.bStartLock = false;
617
618 cp.fEndSize = 8;
619 cp.fEndSizeRandom = 13;
620 cp.fEndColor[0] = 0;
621 cp.fEndColor[1] = 60;
622 cp.fEndColor[2] = 0;
623 cp.fEndColor[3] = 40;
624 cp.fEndColorRandom[0] = 0;
625 cp.fEndColorRandom[1] = 100;
626 cp.fEndColorRandom[2] = 0;
627 cp.fEndColorRandom[3] = 50;
628 cp.bEndLock = false;
629
630 cp.iBlendMode = 5;
631
632 pPS.SetParams(cp);
633 pPS.ulParticleSpawn = 0;
634
635 pPS.SetTexture("graph/particles/big_greypouf", 0, 200);
636
637 pPS.fParticleFreq = -1;
638
639 pPS.bParticleFollow = true;
640
641 pPS.SetPos(eSrc);
642 pPS.Update(0);
643 }
644
Update(unsigned long _ulTime)645 void CPoisonProjectile::Update(unsigned long _ulTime)
646 {
647 if (ulCurrentTime <= 2000)
648 {
649 ulCurrentTime += _ulTime;
650 }
651
652 // on passe de 5 à 100 partoches en 1.5secs
653 if (ulCurrentTime < 750)
654 {
655 pPS.iParticleNbMax = 2;
656 pPS.Update(_ulTime);
657 }
658 else
659 {
660 if (!bOk)
661 {
662 bOk = true;
663
664 // go
665 ParticleParams cp;
666 cp.iNbMax = 100;
667 cp.fLife = 500;
668 cp.fLifeRandom = 300;
669 cp.p3Pos.x = fBetaRadSin * 20;
670 cp.p3Pos.y = 0.f;
671 cp.p3Pos.z = fBetaRadCos * 20;
672
673 cp.p3Direction = -eMove;
674
675 cp.fAngle = radians(4);
676 cp.fSpeed = 150;
677 cp.fSpeedRandom = 50;//15;
678 cp.p3Gravity.x = 0;
679 cp.p3Gravity.y = 10;
680 cp.p3Gravity.z = 0;
681 cp.fFlash = 0;
682 cp.fRotation = 80;
683 cp.bRotationRandomDirection = true;
684 cp.bRotationRandomStart = true;
685
686 cp.fStartSize = 2;
687 cp.fStartSizeRandom = 2;
688 cp.fStartColor[0] = 0;
689 cp.fStartColor[1] = 39;
690 cp.fStartColor[2] = 0;
691 cp.fStartColor[3] = 100;
692 cp.fStartColorRandom[0] = 50;
693 cp.fStartColorRandom[1] = 21;
694 cp.fStartColorRandom[2] = 0;
695 cp.fStartColorRandom[3] = 0;
696 cp.bStartLock = false;
697
698 cp.fEndSize = 7;
699 cp.fEndSizeRandom = 5;
700 cp.fEndColor[0] = 0;
701 cp.fEndColor[1] = 25;
702 cp.fEndColor[2] = 0;
703 cp.fEndColor[3] = 100;
704 cp.fEndColorRandom[0] = 50;
705 cp.fEndColorRandom[1] = 20;
706 cp.fEndColorRandom[2] = 0;
707 cp.fEndColorRandom[3] = 0;
708 cp.bEndLock = false;
709
710 cp.iBlendMode = 5;
711 cp.bTexInfo = false;
712 pPSStream.SetParams(cp);
713 pPSStream.ulParticleSpawn = 0;
714
715 pPSStream.SetTexture("graph/particles/big_greypouf", 0, 200);
716
717 pPSStream.fParticleFreq = 80;
718 pPSStream.bParticleFollow = true;
719 }
720
721 pPSStream.Update(_ulTime);
722 pPSStream.SetPos(eCurPos);
723
724 pPS.Update(_ulTime);
725 pPS.SetPos(eCurPos);
726
727 fTrail = ((ulCurrentTime - 750) * (1.0f / (ulDuration - 750.0f))) * 9 * (BEZIERPrecision + 2);
728 }
729 }
730
Render()731 float CPoisonProjectile::Render() {
732
733 if(ulCurrentTime >= ulDuration) {
734 return 0.f;
735 }
736
737 GRenderer->SetCulling(Renderer::CullNone);
738 GRenderer->SetRenderState(Renderer::DepthWrite, false);
739 GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
740 GRenderer->SetRenderState(Renderer::AlphaBlending, true);
741
742 int n = BEZIERPrecision;
743 float delta = 1.0f / n;
744
745 Vec3f lastpos = pathways[0].p;
746
747 int arx_check_init = -1;
748
749 int i = 0;
750 for(i = 0; i < 9; i++) {
751
752 int kpprec = std::max(i - 1, 0);
753 int kpsuiv = i + 1 ;
754 int kpsuivsuiv = (i < (9 - 2)) ? kpsuiv + 1 : kpsuiv;
755
756 for(int toto = 1; toto < n; toto++) {
757
758 if(fTrail < i * n + toto) {
759 break;
760 }
761
762 float t = toto * delta;
763
764 float t2 = t * t ;
765 float t3 = t2 * t ;
766 float f0 = 2.f * t3 - 3.f * t2 + 1.f ;
767 float f1 = -2.f * t3 + 3.f * t2 ;
768 float f2 = t3 - 2.f * t2 + t ;
769 float f3 = t3 - t2 ;
770
771 float val = pathways[kpsuiv].p.x;
772 float p0 = 0.5f * (val - pathways[kpprec].p.x);
773 float p1 = 0.5f * (pathways[kpsuivsuiv].p.x - pathways[i].p.x);
774 lastpos.x = f0 * pathways[i].p.x + f1 * val + f2 * p0 + f3 * p1;
775
776 val = pathways[kpsuiv].p.y;
777 p0 = 0.5f * (val - pathways[kpprec].p.y);
778 p1 = 0.5f * (pathways[kpsuivsuiv].p.y - pathways[i].p.y);
779 lastpos.y = f0 * pathways[i].p.y + f1 * val + f2 * p0 + f3 * p1;
780
781 val = pathways[kpsuiv].p.z;
782 p0 = 0.5f * (val - pathways[kpprec].p.z);
783 p1 = 0.5f * (pathways[kpsuivsuiv].p.z - pathways[i].p.z);
784 lastpos.z = f0 * pathways[i].p.z + f1 * val + f2 * p0 + f3 * p1;
785
786 ++arx_check_init;
787 }
788 }
789
790 // arx_assert(arx_check_init >= 0); TODO why should this hold?
791
792 eCurPos = lastpos;
793
794 if(fTrail >= (i * n)) {
795 LaunchPoisonExplosion(&lastpos);
796 }
797
798 GRenderer->SetCulling(Renderer::CullNone);
799 GRenderer->SetRenderState(Renderer::DepthWrite, false);
800 GRenderer->SetRenderState(Renderer::AlphaBlending, true);
801
802 return 1;
803 }
804
805 //-----------------------------------------------------------------------------
806 //-----------------------------------------------------------------------------
CMultiPoisonProjectile(long nbmissiles)807 CMultiPoisonProjectile::CMultiPoisonProjectile(long nbmissiles)
808 {
809 SetDuration(2000);
810 uiNumber = min(5L, nbmissiles);
811 pTab = NULL;
812 pTab = new CPoisonProjectile*[uiNumber]();
813
814 for(unsigned int i = 0 ; i < uiNumber ; i++) {
815 pTab[i] = new CPoisonProjectile();
816 pTab[i]->spellinstance = this->spellinstance;
817 }
818 }
819
820 //-----------------------------------------------------------------------------
~CMultiPoisonProjectile()821 CMultiPoisonProjectile::~CMultiPoisonProjectile()
822 {
823 for (unsigned int i = 0 ; i < uiNumber ; i++)
824 {
825 if (pTab[i]->lLightId != -1)
826 {
827 DynLight[pTab[i]->lLightId].duration = 2000;
828 DynLight[pTab[i]->lLightId].time_creation = (unsigned long)(arxtime);
829 pTab[i]->lLightId = -1;
830 }
831
832 delete pTab[i];
833 }
834
835 delete [] pTab;
836 }
837
838 //-----------------------------------------------------------------------------
Create(Vec3f _eSrc,float _afBeta=0)839 void CMultiPoisonProjectile::Create(Vec3f _eSrc, float _afBeta = 0) {
840
841 (void)_afBeta;
842
843 float afBeta = 0.f;
844
845 Entity * caster = entities[spells[spellinstance].caster];
846 spells[spellinstance].hand_group = caster->obj->fastaccess.primary_attach;
847 if(spells[spellinstance].hand_group != -1) {
848 long group = spells[spellinstance].hand_group;
849 spells[spellinstance].hand_pos = caster->obj->vertexlist3[group].v;
850 }
851
852 if (spells[spellinstance].caster == 0) // player
853 {
854 afBeta = player.angle.b;
855
856 if (spells[spellinstance].hand_group != -1)
857 {
858 _eSrc.x = spells[spellinstance].hand_pos.x - EEsin(radians(afBeta)) * 90;
859 _eSrc.y = spells[spellinstance].hand_pos.y;
860 _eSrc.z = spells[spellinstance].hand_pos.z + EEcos(radians(afBeta)) * 90;
861 }
862 else
863 {
864 _eSrc.x = player.pos.x - EEsin(radians(afBeta)) * 90;
865 _eSrc.y = player.pos.y;
866 _eSrc.z = player.pos.z + EEcos(radians(afBeta)) * 90;
867 }
868 }
869 else
870 {
871 afBeta = entities[spells[spellinstance].caster]->angle.b;
872
873 if (spells[spellinstance].hand_group != -1)
874 {
875 _eSrc.x = spells[spellinstance].hand_pos.x - EEsin(radians(afBeta)) * 90;
876 _eSrc.y = spells[spellinstance].hand_pos.y;
877 _eSrc.z = spells[spellinstance].hand_pos.z + EEcos(radians(afBeta)) * 90;
878 }
879 else
880 {
881 _eSrc.x = entities[spells[spellinstance].caster]->pos.x - EEsin(radians(afBeta)) * 90;
882 _eSrc.y = entities[spells[spellinstance].caster]->pos.y;
883 _eSrc.z = entities[spells[spellinstance].caster]->pos.z + EEcos(radians(afBeta)) * 90;
884 }
885 }
886
887
888 long lMax = 0;
889
890 for (unsigned int i = 0 ; i < uiNumber ; i++)
891 {
892 pTab[i]->Create(_eSrc, afBeta + frand2() * 10.0f);
893 long lTime = ulDuration + Random::get(0, 5000);
894 pTab[i]->SetDuration(lTime);
895 lMax = max(lMax, lTime);
896
897 CPoisonProjectile * pPP = (CPoisonProjectile *) pTab[i];
898
899 pPP->lLightId = GetFreeDynLight();
900
901 if (pPP->lLightId != -1)
902 {
903 long id = pPP->lLightId;
904 DynLight[id].exist = 1;
905 DynLight[id].intensity = 2.3f;
906 DynLight[id].fallend = 250.f;
907 DynLight[id].fallstart = 150.f;
908 DynLight[id].rgb = Color3f::green;
909 DynLight[id].pos = pPP->eSrc;
910 DynLight[id].time_creation = (unsigned long)(arxtime);
911 DynLight[id].duration = 200;
912 }
913
914 pTab[i]->spellinstance = this->spellinstance;
915
916 }
917
918 SetDuration(lMax + 1000);
919 }
920
921 //-----------------------------------------------------------------------------
Update(unsigned long _ulTime)922 void CMultiPoisonProjectile::Update(unsigned long _ulTime)
923 {
924 for (unsigned int i = 0 ; i < uiNumber ; i++)
925 {
926 pTab[i]->Update(_ulTime);
927 }
928 }
929
930 //-----------------------------------------------------------------------------
Render()931 float CMultiPoisonProjectile::Render()
932 {
933
934
935 for (unsigned int i = 0 ; i < uiNumber ; i++)
936 {
937 float fa = pTab[i]->Render();
938
939 CPoisonProjectile * pPoisonProjectile = (CPoisonProjectile *) pTab[i];
940
941 if (pPoisonProjectile->lLightId != -1)
942 {
943 long id = pPoisonProjectile->lLightId;
944 DynLight[id].exist = 1;
945 DynLight[id].intensity = 2.3f * fa;
946 DynLight[id].fallend = 250.f;
947 DynLight[id].fallstart = 150.f;
948 DynLight[id].rgb = Color3f::green;
949 DynLight[id].pos = pPoisonProjectile->eCurPos;
950 DynLight[id].time_creation = (unsigned long)(arxtime);
951 DynLight[id].duration = 200;
952 }
953
954 long t = ARX_DAMAGES_GetFree();
955 AddPoisonFog(&pPoisonProjectile->eCurPos, spells[spellinstance].caster_level + 7);
956
957 if ((t != -1)
958 && (spells[pTab[i]->spellinstance].timcreation + 1600 < (unsigned long)(arxtime)))
959 {
960 damages[t].pos = pPoisonProjectile->eCurPos;
961 damages[t].radius = 120.f;
962 float v = spells[spellinstance].caster_level;
963 v = 4.f + v * ( 1.0f / 10 ) * 6.f ;
964 damages[t].damages = v * ( 1.0f / 1000 ) * framedelay;
965 damages[t].area = DAMAGE_FULL;
966 damages[t].duration = static_cast<long>(FrameDiff);
967 damages[t].source = spells[spellinstance].caster;
968 damages[t].flags = 0;
969 damages[t].type = DAMAGE_TYPE_MAGICAL | DAMAGE_TYPE_POISON;
970 damages[t].exist = true;
971 }
972 }
973
974 return 1;
975 }
976
CRepelUndead()977 CRepelUndead::CRepelUndead() {
978
979 eSrc = Vec3f::ZERO;
980 eTarget = Vec3f::ZERO;
981
982 ulCurrentTime = ulDuration + 1;
983
984 tex_p2 = TextureContainer::Load("graph/obj3d/textures/(fx)_tsu_blueting");
985
986 if(!ssol) { // Pentacle
987 ssol = LoadTheObj("graph/obj3d/interactive/fix_inter/fx_rune_guard/fx_rune_guard.teo");
988 }
989 ssol_count++;
990
991 if(!slight) { // Twirl
992 slight = LoadTheObj("graph/obj3d/interactive/fix_inter/fx_rune_guard/fx_rune_guard02.teo");
993 }
994 slight_count++; //runes
995
996 if(!srune) {
997 srune = LoadTheObj("graph/obj3d/interactive/fix_inter/fx_rune_guard/fx_rune_guard03.teo");
998 }
999 srune_count++;
1000 }
1001
~CRepelUndead()1002 CRepelUndead::~CRepelUndead() {
1003
1004 ssol_count--;
1005
1006 if (ssol && (ssol_count <= 0))
1007 {
1008 ssol_count = 0;
1009 delete ssol;
1010 ssol = NULL;
1011 }
1012
1013 slight_count--;
1014
1015 if (slight && (slight_count <= 0))
1016 {
1017 slight_count = 0;
1018 delete slight;
1019 slight = NULL;
1020 }
1021
1022 srune_count--;
1023
1024 if (srune && (srune_count <= 0))
1025 {
1026 srune_count = 0;
1027 delete srune;
1028 srune = NULL;
1029 }
1030 }
1031
Create(Vec3f aeSrc,float afBeta)1032 void CRepelUndead::Create(Vec3f aeSrc, float afBeta) {
1033
1034 SetDuration(ulDuration);
1035 eTarget = eSrc = aeSrc;
1036 fBeta = afBeta;
1037 fBetaRad = radians(fBeta);
1038 fBetaRadCos = (float)cos(fBetaRad);
1039 fBetaRadSin = (float)sin(fBetaRad);
1040 fSize = 1;
1041 bDone = true;
1042 }
1043
Update(unsigned long _ulTime)1044 void CRepelUndead::Update(unsigned long _ulTime) {
1045
1046 ulCurrentTime += _ulTime;
1047 if(spellinstance < 0) {
1048 return;
1049 }
1050
1051 eSrc = entities[spells[spellinstance].target]->pos;
1052
1053 if(spells[spellinstance].target == 0) {
1054 fBeta = player.angle.b;
1055 } else {
1056 fBeta = entities[spells[spellinstance].target]->angle.b;
1057 }
1058 }
1059
Render()1060 float CRepelUndead::Render() {
1061
1062 if(ulCurrentTime >= ulDuration) {
1063 return 0.f;
1064 }
1065
1066 GRenderer->SetRenderState(Renderer::DepthWrite, false);
1067 GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
1068 GRenderer->SetRenderState(Renderer::AlphaBlending, true);
1069
1070 Anglef eObjAngle;
1071 Vec3f eObjPos;
1072 Vec3f eObjScale;
1073 Color3f rgbObjColor;
1074
1075 eObjAngle.b = fBeta;
1076 eObjAngle.a = 0;
1077 eObjAngle.g = 0;
1078 eObjPos.x = eSrc.x;
1079 eObjPos.y = eSrc.y - 5.f;
1080 eObjPos.z = eSrc.z;
1081 rgbObjColor.r = 0.6f;
1082 rgbObjColor.g = 0.6f;
1083 rgbObjColor.b = 0.8f;
1084
1085 float vv = 1.f + (EEsin(arxtime.get_updated() * ( 1.0f / 1000 )));
1086 vv *= ( 1.0f / 2 );
1087 vv += 1.1f;
1088 eObjScale.z = vv;
1089 eObjScale.y = vv;
1090 eObjScale.x = vv;
1091
1092 if(ssol) {
1093 DrawEERIEObjEx(ssol, &eObjAngle, &eObjPos, &eObjScale, &rgbObjColor);
1094 }
1095
1096 vv *= 100.f;
1097
1098 for(int n = 0; n < 4; n++) {
1099
1100 PARTICLE_DEF * pd = createParticle();
1101 if(!pd) {
1102 break;
1103 }
1104
1105 float dx = -EEsin(frand2() * 360.f) * vv;
1106 float dz = EEcos(frand2() * 360.f) * vv;
1107 pd->ov = eSrc + Vec3f(dx, 0.f, dz);
1108 pd->move = Vec3f(0.8f * frand2(), -4.f * rnd(), 0.8f * frand2());
1109 pd->scale = Vec3f::repeat(-0.1f);
1110 pd->tolive = Random::get(2600, 3200);
1111 pd->tc = tex_p2;
1112 pd->siz = 0.3f;
1113 pd->rgb = Color3f(.4f, .4f, .6f);
1114 }
1115
1116 if(lLightId == -1) {
1117 lLightId = GetFreeDynLight();
1118 }
1119
1120 if(lLightId != -1) {
1121 long id = lLightId;
1122 DynLight[id].exist = 1;
1123 DynLight[id].intensity = 2.3f;
1124 DynLight[id].fallend = 350.f;
1125 DynLight[id].fallstart = 150.f;
1126 DynLight[id].rgb = Color3f(0.8f, 0.8f, 1.f);
1127 DynLight[id].pos = eSrc + Vec3f(0.f, -50.f, 0.f);
1128 DynLight[id].duration = 200;
1129 DynLight[id].time_creation = (unsigned long)(arxtime);
1130 }
1131
1132 return 1;
1133 }
1134
1135 //-----------------------------------------------------------------------------
1136 // LEVITATION
1137 //-----------------------------------------------------------------------------
1138 EERIE_3DOBJ * stone1 = NULL;
1139 long stone1_count = 0;
1140 EERIE_3DOBJ * stone0 = NULL;
1141 long stone0_count = 0;
1142
CLevitate()1143 CLevitate::CLevitate()
1144 {
1145 int nb = 2;
1146
1147 while (nb--)
1148 {
1149 this->cone[nb].coned3d = NULL;
1150 this->cone[nb].coneind = NULL;
1151 this->cone[nb].conevertex = NULL;
1152 }
1153
1154 if(!stone0) {
1155 stone0 = loadObject("graph/obj3d/interactive/fix_inter/fx_raise_dead/stone01.teo");
1156 }
1157
1158 stone0_count++;
1159
1160 if(!stone1) {
1161 stone1 = loadObject("graph/obj3d/interactive/fix_inter/fx_raise_dead/stone02.teo");
1162 }
1163
1164 stone1_count++;
1165 }
1166 //-----------------------------------------------------------------------------
~CLevitate()1167 CLevitate::~CLevitate()
1168 {
1169 stone0_count--;
1170
1171 if (stone0 && (stone0_count <= 0))
1172 {
1173 stone0_count = 0;
1174 delete stone0;
1175 stone0 = NULL;
1176 }
1177
1178 stone1_count--;
1179
1180 if (stone1 && (stone1_count <= 0))
1181 {
1182 stone1_count = 0;
1183 delete stone1;
1184 stone1 = NULL;
1185 }
1186 }
1187
CreateConeStrip(float rbase,float rhaut,float hauteur,int def,int numcone)1188 void CLevitate::CreateConeStrip(float rbase, float rhaut, float hauteur, int def,
1189 int numcone) {
1190
1191 T_CONE & c = cone[numcone];
1192
1193 free(c.coned3d);
1194 free(c.conevertex);
1195 free(c.coneind);
1196
1197 c.conenbvertex = def * 2 + 2;
1198 c.conenbfaces = def * 2 + 2;
1199 c.coned3d = (TexturedVertex *)malloc(c.conenbvertex * sizeof(TexturedVertex));
1200 c.conevertex = (Vec3f *)malloc(c.conenbvertex * sizeof(Vec3f));
1201 c.coneind = (unsigned short *)malloc(c.conenbvertex * sizeof(unsigned short));
1202
1203 Vec3f * vertex = c.conevertex;
1204 unsigned short * pind = c.coneind;
1205 unsigned short ind = 0;
1206 int nb;
1207 float a = 0.f;
1208 float da = 360.f / (float)def;
1209 nb = this->cone[numcone].conenbvertex >> 1;
1210
1211 while(nb) {
1212 *pind++ = ind++;
1213 *pind++ = ind++;
1214 *vertex++ = Vec3f(rhaut * EEcos(radians(a)), -hauteur, rhaut * EEsin(radians(a)));
1215 *vertex++ = Vec3f(rbase * EEcos(radians(a)), 0.f, rbase * EEsin(radians(a)));
1216 a += da;
1217 nb--;
1218 }
1219 }
1220
Create(int def,float rbase,float rhaut,float hauteur,Vec3f * pos,unsigned long _ulDuration)1221 void CLevitate::Create(int def, float rbase, float rhaut, float hauteur, Vec3f * pos, unsigned long _ulDuration)
1222 {
1223 SetDuration(_ulDuration);
1224
1225 if (def < 3) return;
1226
1227 this->CreateConeStrip(rbase, rhaut, hauteur, def, 0);
1228 this->CreateConeStrip(rbase, rhaut * 1.5f, hauteur * 0.5f, def, 1);
1229
1230 this->key = 0;
1231 this->pos = *pos;
1232 this->rbase = rbase;
1233 this->rhaut = rhaut;
1234 this->hauteur = hauteur;
1235 this->currdurationang = 0;
1236 this->scale = 0.f;
1237 this->ang = 0.f;
1238 this->def = (short)def;
1239 this->tsouffle = TextureContainer::Load("graph/obj3d/textures/(fx)_sebsouffle");
1240
1241 this->timestone = 0;
1242 this->nbstone = 0;
1243
1244
1245 this->stone[0] = stone0;
1246 this->stone[1] = stone1;
1247
1248 int nb = 256;
1249
1250 while (nb--)
1251 {
1252 this->tstone[nb].actif = 0;
1253 }
1254 }
1255
AddStone(Vec3f * pos)1256 void CLevitate::AddStone(Vec3f * pos) {
1257
1258 if(arxtime.is_paused() || nbstone > 255) {
1259 return;
1260 }
1261
1262 int nb = 256;
1263 while(nb--) {
1264 if(!tstone[nb].actif) {
1265 nbstone++;
1266 tstone[nb].actif = 1;
1267 tstone[nb].numstone = rand() & 1;
1268 tstone[nb].pos = *pos;
1269 tstone[nb].yvel = rnd() * -5.f;
1270 tstone[nb].ang = Anglef(rnd() * 360.f, rnd() * 360.f, rnd() * 360.f);
1271 tstone[nb].angvel = Anglef(5.f * rnd(), 6.f * rnd(), 3.f * rnd());
1272 tstone[nb].scale = Vec3f::repeat(0.2f + rnd() * 0.3f);
1273 tstone[nb].time = Random::get(2000, 2500);
1274 tstone[nb].currtime = 0;
1275 break;
1276 }
1277 }
1278 }
1279
DrawStone()1280 void CLevitate::DrawStone()
1281 {
1282 GRenderer->SetBlendFunc(Renderer::BlendInvDstColor, Renderer::BlendOne);
1283 GRenderer->SetRenderState(Renderer::AlphaBlending, true);
1284 int nb = 256;
1285
1286 while (nb--)
1287 {
1288 if (this->tstone[nb].actif)
1289 {
1290 float a = (float)this->tstone[nb].currtime / (float)this->tstone[nb].time;
1291
1292 if (a > 1.f)
1293 {
1294 a = 1.f;
1295 this->tstone[nb].actif = 0;
1296 }
1297
1298 int col = Color4f(Color3f::white, 1.f - a).toBGRA();
1299
1300 if (this->stone[this->tstone[nb].numstone])
1301 DrawEERIEObjExEx(this->stone[this->tstone[nb].numstone], &this->tstone[nb].ang, &this->tstone[nb].pos, &this->tstone[nb].scale, col);
1302
1303 PARTICLE_DEF * pd = createParticle();
1304 if(pd) {
1305 pd->ov = tstone[nb].pos;
1306 pd->move = Vec3f(0.f, 3.f * rnd(), 0.f);
1307 pd->siz = 3.f + 3.f * rnd();
1308 pd->tolive = 1000;
1309 pd->timcreation = -(long(arxtime) + 1000l); // TODO WTF?
1310 pd->special = FIRE_TO_SMOKE | FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION
1311 | DISSIPATING;
1312 pd->fparam = 0.0000001f;
1313 }
1314
1315 //update mvt
1316 if (!arxtime.is_paused())
1317 {
1318 a = (((float)this->currframetime) * 100.f) / (float)this->tstone[nb].time;
1319 tstone[nb].pos.y += tstone[nb].yvel * a;
1320 tstone[nb].ang += tstone[nb].angvel * a;
1321
1322 this->tstone[nb].yvel *= 1.f - (1.f / 100.f);
1323
1324 this->tstone[nb].currtime += this->currframetime;
1325 }
1326 }
1327 }
1328
1329 GRenderer->SetRenderState(Renderer::AlphaBlending, false);
1330 }
1331
1332 /*--------------------------------------------------------------------------*/
Update(unsigned long _ulTime)1333 void CLevitate::Update(unsigned long _ulTime)
1334 {
1335 float a;
1336
1337 //animation cone
1338 if (!arxtime.is_paused()) this->currdurationang += _ulTime;
1339
1340 this->ang = (float)this->currdurationang / 1000.f;
1341
1342 if (this->ang > 1.f)
1343 {
1344 this->currdurationang = 0;
1345 this->ang = 1.f;
1346 }
1347
1348 if (!arxtime.is_paused()) ulCurrentTime += _ulTime;
1349
1350 switch (this->key)
1351 {
1352 case 0:
1353 //monté du cone
1354 a = (float) ulCurrentTime / 1000.f;
1355
1356 if (a > 1.f)
1357 {
1358 a = 0.f;
1359 this->key++;
1360 }
1361
1362 this->scale = a;
1363 break;
1364 case 1:
1365 //animation cone
1366 this->scale = (float)ulCurrentTime / (float)ulDuration;
1367
1368 if (ulCurrentTime >= ulDuration)
1369 {
1370 this->scale = 1.f;
1371 this->key++;
1372 }
1373
1374 break;
1375 }
1376
1377 if (!arxtime.is_paused())
1378 {
1379 this->currframetime = _ulTime;
1380 this->timestone -= _ulTime;
1381 }
1382
1383 if (this->timestone <= 0)
1384 {
1385 this->timestone = Random::get(50, 150);
1386 Vec3f pos;
1387
1388 float r = this->rbase * frand2();
1389 pos.x = this->pos.x + r;
1390 pos.y = this->pos.y;
1391 pos.z = this->pos.z + r;
1392 this->AddStone(&pos);
1393 }
1394 }
1395
1396 /*--------------------------------------------------------------------------*/
Render()1397 float CLevitate::Render()
1398 {
1399 if (this->key > 1) return 0;
1400
1401 GRenderer->SetRenderState(Renderer::AlphaBlending, true);
1402 GRenderer->SetRenderState(Renderer::DepthWrite, false);
1403
1404 //calcul du cone
1405 TexturedVertex d3dvs, *d3dv;
1406 Vec3f * vertex;
1407 int nb, nbc, col;
1408 float ddu = this->ang;
1409 float u = ddu, du = .99999999f / (float)this->def;
1410
1411 switch (this->key)
1412 {
1413 case 0:
1414 nbc = 2;
1415
1416 while (nbc--)
1417 {
1418 vertex = this->cone[nbc].conevertex;
1419 d3dv = this->cone[nbc].coned3d;
1420 nb = (this->cone[nbc].conenbvertex) >> 1;
1421
1422 while (nb)
1423 {
1424 d3dvs.p.x = this->pos.x + (vertex + 1)->x + ((vertex->x - (vertex + 1)->x) * this->scale);
1425 d3dvs.p.y = this->pos.y + (vertex + 1)->y + ((vertex->y - (vertex + 1)->y) * this->scale);
1426 d3dvs.p.z = this->pos.z + (vertex + 1)->z + ((vertex->z - (vertex + 1)->z) * this->scale);
1427
1428 EE_RT2(&d3dvs, d3dv);
1429
1430
1431 float fRandom = rnd() * 80.f;
1432
1433 col = checked_range_cast<int>(fRandom);
1434
1435 if (!arxtime.is_paused()) d3dv->color = Color::grayb(col).toBGR(col);
1436
1437 d3dv->uv.x = u;
1438 d3dv->uv.y = 0.f;
1439 vertex++;
1440 d3dv++;
1441
1442 d3dvs.p.x = this->pos.x + vertex->x;
1443 d3dvs.p.y = this->pos.y;
1444 d3dvs.p.z = this->pos.z + vertex->z;
1445
1446 EE_RT2(&d3dvs, d3dv);
1447
1448
1449 fRandom = rnd() * 80.f;
1450
1451 col = checked_range_cast<int>(fRandom);
1452
1453
1454 if (!arxtime.is_paused()) d3dv->color = Color::black.toBGR(col);
1455
1456 d3dv->uv.x = u;
1457 d3dv->uv.y = 0.9999999f;
1458 vertex++;
1459 d3dv++;
1460
1461 u += du;
1462 nb--;
1463 }
1464
1465 u = ddu;
1466 du = -du;
1467 }
1468
1469 nbc = 3;
1470 while(nbc--) {
1471
1472 PARTICLE_DEF * pd = createParticle();
1473 if(!pd) {
1474 break;
1475 }
1476
1477 float a = radians(360.f * rnd());
1478 pd->ov = pos + Vec3f(rbase * EEcos(a), 0.f, rbase * EEsin(a));
1479 float t = fdist(pd->ov, pos);
1480 pd->move = Vec3f((5.f + 5.f * rnd()) * ((pd->ov.x - pos.x) / t), 3.f * rnd(),
1481 (5.f + 5.f * rnd()) * ((pd->ov.z - pos.z) / t));
1482 pd->siz = 30.f + 30.f * rnd();
1483 pd->tolive = 3000;
1484 pd->timcreation = -(long(arxtime) + 3000l); // TODO WTF
1485 pd->special = FIRE_TO_SMOKE | FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION
1486 | DISSIPATING;
1487 pd->fparam = 0.0000001f;
1488 }
1489 break;
1490
1491 case 1:
1492 nbc = 2;
1493
1494 while (nbc--)
1495 {
1496 vertex = this->cone[nbc].conevertex;
1497 d3dv = this->cone[nbc].coned3d;
1498 nb = (this->cone[nbc].conenbvertex) >> 1;
1499
1500 while (nb)
1501 {
1502 d3dvs.p = this->pos + *vertex;
1503
1504 EE_RT2(&d3dvs, d3dv);
1505 col = Random::get(0, 80);
1506
1507 if (!arxtime.is_paused()) d3dv->color = Color::grayb(col).toBGR(col);
1508
1509 d3dv->uv.x = u;
1510 d3dv->uv.y = 0.f;
1511 vertex++;
1512 d3dv++;
1513
1514 d3dvs.p.x = this->pos.x + vertex->x;
1515 d3dvs.p.y = this->pos.y;
1516 d3dvs.p.z = this->pos.z + vertex->z;
1517
1518 EE_RT2(&d3dvs, d3dv);
1519 col = Random::get(0, 80);
1520
1521 if (!arxtime.is_paused()) d3dv->color = Color::black.toBGR(col);
1522
1523 d3dv->uv.x = u;
1524 d3dv->uv.y = 1;
1525 vertex++;
1526 d3dv++;
1527
1528 u += du;
1529 nb--;
1530 }
1531
1532 u = ddu;
1533 du = -du;
1534 }
1535
1536 nbc = 10;
1537 while(nbc--) {
1538
1539 PARTICLE_DEF * pd = createParticle();
1540 if(!pd) {
1541 break;
1542 }
1543
1544 float a = radians(360.f * rnd());
1545 pd->ov = pos + Vec3f(rbase * EEcos(a), 0.f, rbase * EEsin(a));
1546 float t = fdist(pd->ov, pos);
1547 pd->move = Vec3f((5.f + 5.f * rnd()) * ((pd->ov.x - pos.x) / t), 3.f * rnd(),
1548 (5.f + 5.f * rnd()) * ((pd->ov.z - pos.z) / t));
1549 pd->siz = 30.f + 30.f * rnd();
1550 pd->tolive = 3000;
1551 pd->timcreation = -(long(arxtime) + 3000l); // TODO WTF
1552 pd->special = FIRE_TO_SMOKE | FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION
1553 | DISSIPATING;
1554 pd->fparam = 0.0000001f;
1555 }
1556
1557 break;
1558 }
1559
1560 //tracé du cone back
1561 GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
1562 GRenderer->SetRenderState(Renderer::AlphaBlending, true);
1563 GRenderer->GetTextureStage(0)->SetWrapMode(TextureStage::WrapMirror);
1564
1565 GRenderer->SetTexture(0, tsouffle);
1566
1567 GRenderer->SetCulling(Renderer::CullCW);
1568 int i = cone[1].conenbfaces - 2;
1569 int j = 0;
1570
1571 while (i--)
1572 {
1573 ARX_DrawPrimitive(&cone[1].coned3d[j],
1574 &cone[1].coned3d[j+1],
1575 &cone[1].coned3d[j+2]);
1576 j++;
1577 }
1578
1579 i = cone[0].conenbfaces - 2;
1580 j = 0;
1581
1582 while (i--)
1583 {
1584 ARX_DrawPrimitive(&cone[0].coned3d[j],
1585 &cone[0].coned3d[j+1],
1586 &cone[0].coned3d[j+2]);
1587 j++;
1588 }
1589
1590 //tracé du cone front
1591 GRenderer->SetCulling(Renderer::CullCCW);
1592
1593 i = cone[1].conenbfaces - 2;
1594 j = 0;
1595
1596 while (i--)
1597 {
1598 ARX_DrawPrimitive(&cone[1].coned3d[j],
1599 &cone[1].coned3d[j+1],
1600 &cone[1].coned3d[j+2]);
1601 j++;
1602 }
1603
1604 i = cone[0].conenbfaces - 2;
1605 j = 0;
1606
1607 while (i--)
1608 {
1609 ARX_DrawPrimitive(&cone[0].coned3d[j],
1610 &cone[0].coned3d[j+1],
1611 &cone[0].coned3d[j+2]);
1612 j++;
1613 }
1614
1615 //tracé des pierres
1616 GRenderer->SetBlendFunc(Renderer::BlendSrcAlpha, Renderer::BlendInvSrcAlpha);
1617 this->DrawStone();
1618
1619 GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendZero);
1620 GRenderer->SetRenderState(Renderer::AlphaBlending, false);
1621 GRenderer->SetRenderState(Renderer::DepthWrite, true);
1622
1623 return 0;
1624 }
1625