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/effects/SpellEffects.h"
46 
47 #include "animation/AnimationRender.h"
48 #include "game/Player.h"
49 #include "graphics/Math.h"
50 
51 
CSpellFx()52 CSpellFx::CSpellFx() :
53 	fBeta(0),
54 	fManaCostToLaunch(10),
55 	fManaCostPerSecond(10),
56 	lLightId(-1),
57 	lSrc(-1),
58 	spellinstance(-1)
59 {
60 	SetDuration(1000);
61 	SetAngle(fBeta);
62 };
63 
64 //-----------------------------------------------------------------------------
SetDuration(const unsigned long ulaDuration)65 void CSpellFx::SetDuration(const unsigned long ulaDuration)
66 {
67 	ulDuration = ulaDuration;
68 
69 	if (ulDuration <= 0) ulDuration = 100;
70 
71 	fOneOnDuration = 1.f / (float)(ulDuration);
72 
73 	ulCurrentTime = 0;
74 };
75 
76 //-----------------------------------------------------------------------------
getCurrentTime()77 unsigned long CSpellFx::getCurrentTime() {
78 	return ulCurrentTime;
79 };
80 
81 //-----------------------------------------------------------------------------
GetDuration()82 unsigned long CSpellFx::GetDuration()
83 {
84 	return ulDuration;
85 };
86 
87 //-----------------------------------------------------------------------------
SetAngle(float afAngle)88 void CSpellFx::SetAngle(float afAngle)
89 {
90 	fBeta = afAngle;
91 	fBetaRad = radians(fBeta);
92 	fBetaRadCos = (float) cos(fBetaRad);
93 	fBetaRadSin = (float) sin(fBetaRad);
94 }
95 
Update(float _fParam)96 void CSpellFx::Update(float _fParam) {
97 	Update(checked_range_cast<unsigned long>(_fParam));
98 }
99 
100 //-----------------------------------------------------------------------------
Draw3DLineTex(Vec3f s,Vec3f e,Color color,float fStartSize,float fEndSize)101 void Draw3DLineTex(Vec3f s, Vec3f e, Color color, float fStartSize, float fEndSize) {
102 
103 	float fBeta = MAKEANGLE(player.angle.b);
104 	float xxs = (float)(fStartSize * cos(radians(fBeta)));
105 	float xxe = (float)(fEndSize * cos(radians(fBeta)));
106 	float zzs = fStartSize;
107 	float zze = fEndSize;
108 
109 	TexturedVertex v[4];
110 	TexturedVertex v2[4];
111 
112 	v2[0].color = v2[1].color = v2[2].color = v2[3].color = color.toBGRA();
113 
114 	// version 2 faces
115 	v2[0].uv = Vec2f::ZERO;
116 	v2[1].uv = Vec2f::X_AXIS;
117 	v2[2].uv = Vec2f::ONE;
118 	v2[3].uv = Vec2f::Y_AXIS;
119 
120 	v[0].p.x = s.x;
121 	v[0].p.y = s.y + zzs;
122 	v[0].p.z = s.z;
123 
124 	v[1].p.x = s.x;
125 	v[1].p.y = s.y - zzs;
126 	v[1].p.z = s.z;
127 
128 	v[2].p.x = e.x;
129 	v[2].p.y = e.y - zze;
130 	v[2].p.z = e.z;
131 
132 	v[3].p.x = e.x;
133 	v[3].p.y = e.y + zze;
134 	v[3].p.z = e.z;
135 
136 	EE_RT2(&v[0], &v2[0]);
137 	EE_RT2(&v[1], &v2[1]);
138 	EE_RT2(&v[2], &v2[2]);
139 	EE_RT2(&v[3], &v2[3]);
140 	ARX_DrawPrimitive(&v2[0], &v2[1], &v2[2]);
141 	ARX_DrawPrimitive(&v2[0], &v2[2], &v2[3]);
142 
143 	zzs *= (float) sin(radians(fBeta));
144 	zze *= (float) sin(radians(fBeta));
145 
146 	v[0].p.x = s.x + xxs;
147 	v[0].p.y = s.y;
148 	v[0].p.z = s.z + zzs;
149 
150 	v[1].p.x = s.x - xxs;
151 	v[1].p.y = s.y;
152 	v[1].p.z = s.z - zzs;
153 
154 	v[2].p.x = e.x - xxe;
155 	v[2].p.y = e.y;
156 	v[2].p.z = e.z - zze;
157 
158 	v[3].p.x = e.x + xxe;
159 	v[3].p.y = e.y;
160 	v[3].p.z = e.z + zze;
161 
162 	EE_RT2(&v[0], &v2[0]);
163 	EE_RT2(&v[1], &v2[1]);
164 	EE_RT2(&v[2], &v2[2]);
165 	EE_RT2(&v[3], &v2[3]);
166 	ARX_DrawPrimitive(&v2[0], &v2[1], &v2[2]);
167 	ARX_DrawPrimitive(&v2[0], &v2[2], &v2[3]);
168 }
169 
Draw3DLineTex2(Vec3f s,Vec3f e,float fSize,Color color,Color color2)170 void Draw3DLineTex2(Vec3f s, Vec3f e, float fSize, Color color, Color color2) {
171 
172 	float fBeta = MAKEANGLE(player.angle.b);
173 	float zz = fSize;
174 	float xx = (float)(fSize * cos(radians(fBeta)));
175 
176 	TexturedVertex v[4];
177 	TexturedVertex v2[4];
178 
179 	v2[0].color = v2[1].color = color.toBGRA();
180 	v2[2].color = v2[3].color = color2.toBGRA();
181 
182 	// version 2 faces
183 	v2[0].uv = Vec2f::ZERO;
184 	v2[1].uv = Vec2f::X_AXIS;
185 	v2[2].uv = Vec2f::ONE;
186 	v2[3].uv = Vec2f::Y_AXIS;
187 
188 	v[0].p.x = s.x;
189 	v[0].p.y = s.y + zz;
190 	v[0].p.z = s.z;
191 
192 	v[1].p.x = s.x;
193 	v[1].p.y = s.y - zz;
194 	v[1].p.z = s.z;
195 
196 	v[2].p.x = e.x;
197 	v[2].p.y = e.y - zz;
198 	v[2].p.z = e.z;
199 
200 	v[3].p.x = e.x;
201 	v[3].p.y = e.y + zz;
202 	v[3].p.z = e.z;
203 
204 	EE_RT2(&v[0], &v2[0]);
205 	EE_RT2(&v[1], &v2[1]);
206 	EE_RT2(&v[2], &v2[2]);
207 	EE_RT2(&v[3], &v2[3]);
208 	ARX_DrawPrimitive(&v2[0], &v2[1], &v2[3]);
209 	ARX_DrawPrimitive(&v2[1], &v2[2], &v2[3]);
210 
211 	zz *= (float) sin(radians(fBeta));
212 
213 	v[0].p.x = s.x + xx;
214 	v[0].p.y = s.y;
215 	v[0].p.z = s.z + zz;
216 
217 	v[1].p.x = s.x - xx;
218 	v[1].p.y = s.y;
219 	v[1].p.z = s.z - zz;
220 
221 	v[2].p.x = e.x - xx;
222 	v[2].p.y = e.y;
223 	v[2].p.z = e.z - zz;
224 
225 	v[3].p.x = e.x + xx;
226 	v[3].p.y = e.y;
227 	v[3].p.z = e.z + zz;
228 
229 	EE_RT2(&v[0], &v2[0]);
230 	EE_RT2(&v[1], &v2[1]);
231 	EE_RT2(&v[2], &v2[2]);
232 	EE_RT2(&v[3], &v2[3]);
233 	ARX_DrawPrimitive(&v2[0], &v2[1], &v2[3]);
234 	ARX_DrawPrimitive(&v2[1], &v2[2], &v2[3]);
235 }
236 
Split(TexturedVertex * v,int a,int b,float fX,float fMulX,float fY,float fMulY,float fZ,float fMulZ)237 void Split(TexturedVertex * v, int a, int b, float fX, float fMulX, float fY, float fMulY, float fZ, float fMulZ)
238 {
239 	if (a != b)
240 	{
241 		int i = (int)((a + b) * 0.5f);
242 
243 		if ((i != a) && (i != b))
244 		{
245 			v[i].p.x = (v[a].p.x + v[b].p.x) * 0.5f + fX * frand2();
246 			v[i].p.y = (v[a].p.y + v[b].p.y) * 0.5f + fY * frand2();
247 			v[i].p.z = (v[a].p.z + v[b].p.z) * 0.5f + fZ * frand2();
248 			Split(v, a, i, fX, fMulX, fY, fMulY, fZ, fMulZ);
249 			Split(v, i, b, fX, fMulX, fY, fMulY, fZ, fMulZ);
250 		}
251 	}
252 }
253 
254 //-----------------------------------------------------------------------------
Split(TexturedVertex * v,int a,int b,float yo,float fMul)255 void Split(TexturedVertex * v, int a, int b, float yo, float fMul)
256 {
257 	if (a != b)
258 	{
259 		int i = (int)((a + b) * 0.5f);
260 
261 		if ((i != a) && (i != b))
262 		{
263 			v[i].p = (v[a].p + v[b].p) * 0.5f + randomVec(-yo, yo);
264 			Split(v, a, i, yo * fMul);
265 			Split(v, i, b, yo * fMul);
266 		}
267 	}
268 }
269 
270