//---------------------------------------------------------------------
void CHeal::Update(unsigned long aulTime)
{
	ulCurrentTime += aulTime;

	if (ulCurrentTime >= ulDuration)
	{
		return;
	}

	if (spells[spellinstance].caster == 0)
	{
		eSrc.x = player.pos.x;
		eSrc.y = player.pos.y;
		eSrc.z = player.pos.z;
	}
	else
	{
		if (ValidIONum(spells[spellinstance].target))
		{
			eSrc.x = inter.iobj[spells[spellinstance].target]->pos.x;
			eSrc.y = inter.iobj[spells[spellinstance].target]->pos.y;
			eSrc.z = inter.iobj[spells[spellinstance].target]->pos.z;
		}
	}

	if (pPS->lLightId == -1)
		pPS->lLightId = GetFreeDynLight();

	if (pPS->lLightId != -1)
	{
		long id = pPS->lLightId;
		DynLight[id].exist = 1;
		DynLight[id].intensity = 2.3f;
		DynLight[id].fallstart = 200.f;
		DynLight[id].fallend   = 350.f;
		DynLight[id].rgb.r = 0.4f;
		DynLight[id].rgb.g = 0.4f;
		DynLight[id].rgb.b = 1.0f;
		DynLight[id].pos.x = eSrc.x;
		DynLight[id].pos.y = eSrc.y - 50.f;
		DynLight[id].pos.z = eSrc.z;
		DynLight[id].duration = 200;
		DynLight[id].extras = 0;
	}

	unsigned long ulCalc = ulDuration - ulCurrentTime ;
	ARX_CHECK_LONG(ulCalc);
	long ff = 	ARX_CLEAN_WARN_CAST_LONG(ulCalc);

	if (ff < 1500)
	{
		pPS->uMaxParticles = 0;
		pPS->ulParticleSpawn = PARTICLE_CIRCULAR;
		pPS->p3ParticleGravity.x = 0;
		pPS->p3ParticleGravity.y = 0;
		pPS->p3ParticleGravity.z = 0;

		list<CParticle *>::iterator i;

		for (i = pPS->listParticle.begin(); i != pPS->listParticle.end(); ++i)
		{
			CParticle * pP = *i;

			if (pP->isAlive())
			{
				pP->fColorEnd[3] = 0;

				if (pP->ulTime + ff < pP->ulTTL)
				{
					pP->ulTime = pP->ulTTL - ff;
				}
			}
		}
	}

	pPS->SetPos(eSrc);
	pPS->Update(aulTime);
}
//-----------------------------------------------------------------------------
void CParticleSystem::Render(LPDIRECT3DDEVICE7 _lpD3DDevice, int _iSRCBLEND, int _iDESTBLEND)
{
	SETCULL(_lpD3DDevice, D3DCULL_NONE);
	SETZWRITE(_lpD3DDevice, false);

	_lpD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,  iSrcBlend);
	_lpD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, iDstBlend);
	SETALPHABLEND(_lpD3DDevice, true);

	int inumtex = 0;

	list<CParticle *>::iterator i;

	for (i = listParticle.begin(); i != listParticle.end(); ++i)
	{
		CParticle * p = *i;

		if (p->isAlive())
		{
			if (fParticleFlash > 0)
			{
				if (rnd() < fParticleFlash)
					continue;
			}

			if (iNbTex > 0)
			{
				inumtex = p->iTexNum;

				if (iTexTime == 0)
				{

					float fNbTex	= (p->ulTime * p->fOneOnTTL) * (iNbTex);
					ARX_CHECK_INT(fNbTex);

					inumtex = ARX_CLEAN_WARN_CAST_INT(fNbTex);


					if (inumtex >= iNbTex)
					{
						inumtex = iNbTex - 1;
					}
				}
				else
				{
					if (p->iTexTime > iTexTime)
					{
						p->iTexTime -= iTexTime;
						p->iTexNum++;

						if (p->iTexNum > iNbTex - 1)
						{
							if (bTexLoop)
							{
								p->iTexNum = 0;
							}
							else
							{
								p->iTexNum = iNbTex - 1;
							}
						}

						inumtex = p->iTexNum;
					}
				}
			}

			D3DTLVERTEX p3pos;
			p3pos.sx = p->p3Pos.x;
			p3pos.sy = p->p3Pos.y;
			p3pos.sz = p->p3Pos.z;

			if (bParticleFollow)
			{
				p3pos.sx += p3Pos.x;
				p3pos.sy += p3Pos.y;
				p3pos.sz += p3Pos.z;
			}

			float fRot = 0;

			if (fParticleRotation != 0)
			{
				if (p->iRot == 1)
					fRot = (fParticleRotation) * p->ulTime + p->fRotStart;
				else
					fRot = (-fParticleRotation) * p->ulTime + p->fRotStart;

				if ((tex_tab[inumtex] && tex_tab[inumtex]->m_pddsSurface))
					EERIEDrawRotatedSprite(_lpD3DDevice, &p3pos, p->fSize, tex_tab[inumtex], p->ulColor, 2, fRot);
			}
			else
			{
				if ((tex_tab[inumtex] && tex_tab[inumtex]->m_pddsSurface))
					EERIEDrawSprite(_lpD3DDevice, &p3pos, p->fSize, tex_tab[inumtex], p->ulColor, 2);
			}
		}
	}
}
//-----------------------------------------------------------------------------
void LaunchPoisonExplosion(EERIE_3D * aePos)
{
	// système de partoches pour l'explosion
	CParticleSystem * pPS = new CParticleSystem();
	CParticleParams cp;
	cp.iNbMax = 80; 
	cp.fLife = 1500;
	cp.fLifeRandom = 500;
	cp.p3Pos.x = 5;
	cp.p3Pos.y = 5;
	cp.p3Pos.z = 5;
	cp.p3Direction.x = 0;
	cp.p3Direction.y = 4;
	cp.p3Direction.z = 0;
	cp.fAngle = DEG2RAD(360);
	cp.fSpeed = 200;
	cp.fSpeedRandom = 0;
	cp.p3Gravity.x = 0;
	cp.p3Gravity.y = 17;
	cp.p3Gravity.z = 0;
	cp.fFlash = 0;
	cp.fRotation = 80;
	cp.bRotationRandomDirection = true;
	cp.bRotationRandomStart = true;

	cp.fStartSize = 5;
	cp.fStartSizeRandom = 3;
	cp.fStartColor[0] = 0;
	cp.fStartColor[1] = 76;
	cp.fStartColor[2] = 0;
	cp.fStartColor[3] = 0;
	cp.fStartColorRandom[0] = 0;
	cp.fStartColorRandom[1] = 0;
	cp.fStartColorRandom[2] = 0;
	cp.fStartColorRandom[3] = 150; 
	cp.bStartLock = false;

	cp.fEndSize = 30;
	cp.fEndSizeRandom = 5;
	cp.fEndColor[0] = 0;
	cp.fEndColor[1] = 0;
	cp.fEndColor[2] = 0;
	cp.fEndColor[3] = 0;
	cp.fEndColorRandom[0] = 0;
	cp.fEndColorRandom[1] = 25; 
	cp.fEndColorRandom[2] = 0;
	cp.fEndColorRandom[3] = 20; 
	cp.bEndLock = false;

	cp.iBlendMode = 3;
	cp.iFreq = -1;
	cp.bTexInfo = FALSE;
	pPS->SetParams(cp);
	pPS->ulParticleSpawn = 0;
	pPS->SetTexture("graph\\particles\\big_greypouf.bmp", 0, 200);

	pPS->SetPos(*aePos);
	pPS->Update(0);
	pPS->iParticleNbMax = 0;

	list<CParticle *>::iterator i;

	for (i = pPS->listParticle.begin(); i != pPS->listParticle.end(); ++i)
	{
		CParticle * pP = *i;

		if (pP->isAlive())
		{
			if (pP->p3Velocity.y >= 0.5f * 200)
				pP->p3Velocity.y = 0.5f * 200;

			if (pP->p3Velocity.y <= -0.5f * 200)
				pP->p3Velocity.y = -0.5f * 200;
		}
	}

	if (pParticleManager)
	{
		pParticleManager->AddSystem(pPS);
	}
}
//-----------------------------------------------------------------------------
void CParticleSystem::Update(long _lTime)
{
	if (ARXPausedTimer) return;

	ulTime += _lTime;
	int nbtotal = 0;
	int iNb;
	float fTimeSec = _lTime * DIV1000;
	CParticle * pP;

	list<CParticle *>::iterator i;
	iParticleNbAlive = 0;

	i = listParticle.begin();

	while (i != listParticle.end())
	{
		pP = *i;
		++i;
		nbtotal++;

		if (pP->isAlive())
		{
			pP->Update(_lTime);
			pP->p3Velocity.x += p3ParticleGravity.x * fTimeSec;
			pP->p3Velocity.y += p3ParticleGravity.y * fTimeSec;
			pP->p3Velocity.z += p3ParticleGravity.z * fTimeSec;
			iParticleNbAlive ++;
		}
		else
		{
			if (iParticleNbAlive >= iParticleNbMax)
			{
				delete pP;
				listParticle.remove(pP);
			}
			else
			{
				pP->Regen();
				SetParticleParams(pP);
				pP->Validate();
				pP->Update(0);
				ulNbParticleGen++;
				iParticleNbAlive++;
			}
		}
	}

	// cr�ation de particules en fct de la fr�quence
	if (iParticleNbAlive < iParticleNbMax)
	{
		long t = iParticleNbMax - iParticleNbAlive;

		if (fParticleFreq != -1)
		{

			ARX_CHECK_LONG(fTimeSec * fParticleFreq);
			t = min(ARX_CLEAN_WARN_CAST_LONG(fTimeSec * fParticleFreq), t);


			if (t < 1) t = 1;
		}

		for (iNb = 0; iNb < t; iNb++)
		{
			CParticle * pP  = new CParticle();
			SetParticleParams(pP);
			pP->Validate();
			pP->Update(0);
			listParticle.insert(listParticle.end(), pP);
			ulNbParticleGen ++;
			iParticleNbAlive++;
		}
	}
}