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/Spells02.h"
46 
47 #include <climits>
48 
49 #include "core/Core.h"
50 #include "core/GameTime.h"
51 
52 #include "game/EntityManager.h"
53 #include "game/Player.h"
54 #include "game/Spells.h"
55 
56 #include "graphics/particle/Particle.h"
57 #include "graphics/particle/ParticleParams.h"
58 #include "graphics/particle/ParticleSystem.h"
59 
60 #include "scene/Light.h"
61 #include "scene/Interactive.h"
62 
CHeal()63 CHeal::CHeal()
64 {
65 	SetDuration(1000);
66 	ulCurrentTime = ulDuration + 1;
67 
68 	pPS = new ParticleSystem();
69 }
70 
~CHeal()71 CHeal::~CHeal() {
72 	delete pPS, pPS = NULL;
73 }
74 
Create()75 void CHeal::Create() {
76 
77 	SetAngle(MAKEANGLE(player.angle.b));
78 
79 	if(spells[spellinstance].caster == 0) {
80 		eSrc = player.pos;
81 	} else {
82 		eSrc = entities[spells[spellinstance].caster]->pos;
83 	}
84 
85 	pPS->lLightId = GetFreeDynLight();
86 
87 	if (pPS->lLightId != -1)
88 	{
89 		long id = pPS->lLightId;
90 		DynLight[id].exist = 1;
91 		DynLight[id].intensity = 2.3f;
92 		DynLight[id].fallstart = 200.f;
93 		DynLight[id].fallend   = 350.f;
94 		DynLight[id].rgb.r = 0.4f;
95 		DynLight[id].rgb.g = 0.4f;
96 		DynLight[id].rgb.b = 1.0f;
97 		DynLight[id].pos.x = eSrc.x;
98 		DynLight[id].pos.y = eSrc.y - 50.f;
99 		DynLight[id].pos.z = eSrc.z;
100 		DynLight[id].duration = 200;
101 		DynLight[id].extras = 0;
102 	}
103 
104 	pPS->SetPos(eSrc);
105 	ParticleParams cp;
106 	memset(&cp, 0, sizeof(cp));
107 	cp.iNbMax = 350;
108 	cp.fLife = 800;
109 	cp.fLifeRandom = 2000;
110 	cp.p3Pos.x = 100;
111 	cp.p3Pos.y = 200;
112 	cp.p3Pos.z = 100;
113 	cp.p3Direction.x = 0;
114 	cp.p3Direction.y = -10;
115 	cp.p3Direction.z = 0;
116 	cp.fAngle = radians(5);
117 	cp.fSpeed = 120;
118 	cp.fSpeedRandom = 84;
119 	cp.p3Gravity.x = 0;
120 	cp.p3Gravity.y = -10;
121 	cp.p3Gravity.z = 0;
122 	cp.fFlash = 0;
123 	cp.fRotation = 80;
124 
125 	cp.fStartSize = 8;
126 	cp.fStartSizeRandom = 8;
127 	cp.fStartColor[0] = 205;
128 	cp.fStartColor[1] = 205;
129 	cp.fStartColor[2] = 255;
130 	cp.fStartColor[3] = 245;
131 	cp.fStartColorRandom[0] = 50;
132 	cp.fStartColorRandom[1] = 50;
133 	cp.fStartColorRandom[2] = 0;
134 	cp.fStartColorRandom[3] = 10;
135 
136 	cp.fEndSize = 6;
137 	cp.fEndSizeRandom = 4;
138 	cp.fEndColor[0] = 20;
139 	cp.fEndColor[1] = 20;
140 	cp.fEndColor[2] = 30;
141 	cp.fEndColor[3] = 0;
142 	cp.fEndColorRandom[0] = 0;
143 	cp.fEndColorRandom[1] = 0;
144 	cp.fEndColorRandom[2] = 40;
145 	cp.fEndColorRandom[3] = 0;
146 
147 	cp.iBlendMode = 0;
148 
149 	pPS->SetParams(cp);
150 	pPS->ulParticleSpawn = PARTICLE_CIRCULAR | PARTICLE_BORDER;
151 	pPS->SetTexture("graph/particles/heal_0005", 0, 100);
152 
153 	fSize = 1;
154 }
155 
156 //---------------------------------------------------------------------
Update(unsigned long aulTime)157 void CHeal::Update(unsigned long aulTime)
158 {
159 	ulCurrentTime += aulTime;
160 
161 	if (ulCurrentTime >= ulDuration)
162 	{
163 		return;
164 	}
165 
166 	if(spells[spellinstance].caster == 0) {
167 		eSrc = player.pos;
168 	} else if(ValidIONum(spells[spellinstance].target)) {
169 		eSrc = entities[spells[spellinstance].target]->pos;
170 	}
171 
172 	if (pPS->lLightId == -1)
173 		pPS->lLightId = GetFreeDynLight();
174 
175 	if (pPS->lLightId != -1)
176 	{
177 		long id = pPS->lLightId;
178 		DynLight[id].exist = 1;
179 		DynLight[id].intensity = 2.3f;
180 		DynLight[id].fallstart = 200.f;
181 		DynLight[id].fallend   = 350.f;
182 		DynLight[id].rgb.r = 0.4f;
183 		DynLight[id].rgb.g = 0.4f;
184 		DynLight[id].rgb.b = 1.0f;
185 		DynLight[id].pos.x = eSrc.x;
186 		DynLight[id].pos.y = eSrc.y - 50.f;
187 		DynLight[id].pos.z = eSrc.z;
188 		DynLight[id].duration = 200;
189 		DynLight[id].extras = 0;
190 	}
191 
192 	unsigned long ulCalc = ulDuration - ulCurrentTime ;
193 	arx_assert(ulCalc <= LONG_MAX);
194 	long ff = static_cast<long>(ulCalc);
195 
196 	if (ff < 1500)
197 	{
198 		pPS->uMaxParticles = 0;
199 		pPS->ulParticleSpawn = PARTICLE_CIRCULAR;
200 		pPS->p3ParticleGravity = Vec3f::ZERO;
201 
202 		std::list<Particle *>::iterator i;
203 
204 		for (i = pPS->listParticle.begin(); i != pPS->listParticle.end(); ++i)
205 		{
206 			Particle * pP = *i;
207 
208 			if (pP->isAlive())
209 			{
210 				pP->fColorEnd[3] = 0;
211 
212 				if (pP->ulTime + ff < pP->ulTTL)
213 				{
214 					pP->ulTime = pP->ulTTL - ff;
215 				}
216 			}
217 		}
218 	}
219 
220 	pPS->SetPos(eSrc);
221 	pPS->Update(aulTime);
222 }
223 
224 //---------------------------------------------------------------------
Render()225 float CHeal::Render()
226 {
227 	if (ulCurrentTime >= ulDuration)
228 	{
229 		return 0.f;
230 	}
231 
232 	pPS->Render();
233 
234 	return 1;
235 }
236 
237 //-----------------------------------------------------------------------------
238 // ARMOR
239 //-----------------------------------------------------------------------------
CArmor()240 CArmor::CArmor()
241 {
242 }
243 
244 //-----------------------------------------------------------------------------
~CArmor()245 CArmor::~CArmor()
246 {
247 }
248 
249 //-----------------------------------------------------------------------------
Create(long _ulDuration)250 void CArmor::Create(long _ulDuration) {
251 
252 	SetDuration(_ulDuration);
253 
254 	if (spellinstance != -1)
255 	{
256 
257 		Entity * io = entities[spells[spellinstance].caster];
258 
259 		if ((io) && (!io->halo.flags & HALO_ACTIVE))
260 		{
261 			io->halo.flags |= HALO_ACTIVE;
262 			io->halo.color.r = 0.5f;
263 			io->halo.color.g = 0.5f;
264 			io->halo.color.b = 0.25f;
265 			io->halo.radius = 45.f;
266 			io->halo.dynlight = -1;
267 			spells[spellinstance].longinfo = 1;
268 		}
269 		else spells[spellinstance].longinfo = 0;
270 	}
271 }
272 
273 //-----------------------------------------------------------------------------
Update(unsigned long _ulTime)274 void CArmor::Update(unsigned long _ulTime)
275 {
276 	if (!arxtime.is_paused()) ulCurrentTime += _ulTime;
277 }
278 
279 //-----------------------------------------------------------------------------
Render()280 float CArmor::Render() {
281 
282 	return 0;
283 }
284 
285 
286 //-----------------------------------------------------------------------------
287 // LOWER ARMOR
288 //-----------------------------------------------------------------------------
CLowerArmor()289 CLowerArmor::CLowerArmor()
290 {
291 }
292 
293 //-----------------------------------------------------------------------------
~CLowerArmor()294 CLowerArmor::~CLowerArmor()
295 {
296 }
297 
298 //-----------------------------------------------------------------------------
Create(long _ulDuration)299 void CLowerArmor::Create(long _ulDuration) {
300 
301 	SetDuration(_ulDuration);
302 
303 	if (spellinstance != -1)
304 	{
305 		Entity * io = entities[spells[spellinstance].target];
306 
307 		if ((io) && (!io->halo.flags & HALO_ACTIVE))
308 		{
309 			io->halo.flags |= HALO_ACTIVE;
310 			io->halo.color.r = 1.f;
311 			io->halo.color.g = 0.05f;
312 			io->halo.color.b = 0.0f;
313 			io->halo.radius = 45.f;
314 			io->halo.dynlight = -1;
315 			spells[spellinstance].longinfo = 1;
316 		}
317 		else spells[spellinstance].longinfo = 0;
318 	}
319 }
320 
321 //-----------------------------------------------------------------------------
Update(unsigned long _ulTime)322 void CLowerArmor::Update(unsigned long _ulTime)
323 {
324 	if (!arxtime.is_paused()) ulCurrentTime += _ulTime;
325 }
326 
327 //-----------------------------------------------------------------------------
Render()328 float CLowerArmor::Render() {
329 
330 	return 0;
331 }
332