CPoisonProjectile::CPoisonProjectile()
	: eSrc(Vec3f_ZERO)
	, lightIntensityFactor(1.f)
	, fBetaRadCos(0.f)
	, fBetaRadSin(0.f)
	, bOk(false)
	, fTrail(-1.f)
{
	SetDuration(ArxDurationMs(2000));
	m_elapsed = m_duration + ArxDurationMs(1);
}
void FireFieldSpell::Launch() {
	
	spells.endByCaster(m_caster, SPELL_FIRE_FIELD);
	
	ARX_SOUND_PlaySFX(SND_SPELL_FIRE_FIELD_START);
	
	m_duration = (m_launchDuration > ArxDuration(-1)) ? m_launchDuration : ArxDurationMs(100000);
	m_hasDuration = true;
	m_fManaCostPerSecond = 2.8f;
	m_light = LightHandle();
	
	Vec3f target;
	float beta = 0.f;
	bool displace = false;
	if(m_caster == EntityHandle_Player) {
		target = player.basePosition();
		beta = player.angle.getYaw();
		displace = true;
	} else {
		if(ValidIONum(m_caster)) {
			Entity * io = entities[m_caster];
			target = io->pos;
			beta = io->angle.getYaw();
			displace = (io->ioflags & IO_NPC) == IO_NPC;
		} else {
			ARX_DEAD_CODE();
		}
	}
	if(displace) {
		target += angleToVectorXZ(beta) * 250.f;
	}
	
	m_pos = target + Vec3f(0, -10, 0);
	
	DamageParameters damage;
	damage.radius = 150.f;
	damage.damages = 10.f;
	damage.area = DAMAGE_FULL;
	damage.duration = ArxDurationMs(100000000);
	damage.source = m_caster;
	damage.flags = 0;
	damage.type = DAMAGE_TYPE_MAGICAL | DAMAGE_TYPE_FIRE | DAMAGE_TYPE_FIELD;
	damage.pos = target;
	m_damage = DamageCreate(damage);
	
	m_snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_FIRE_FIELD_LOOP, &target, 1.f, ARX_SOUND_PLAY_LOOPED);
	
	pPSStream.SetParams(g_particleParameters[ParticleParam_FireFieldBase]);
	pPSStream.SetPos(m_pos);
	
	pPSStream1.SetParams(g_particleParameters[ParticleParam_FireFieldFlame]);
	pPSStream1.SetPos(m_pos + Vec3f(0, 10, 0));
	pPSStream1.Update(0);
}
void MagicSightSpell::Launch()
{
	m_fManaCostPerSecond = 0.36f;
	m_hasDuration = true;
	m_duration = (m_launchDuration > ArxDurationMs(-1)) ? m_launchDuration : ArxDurationMs(6000000);
	
	ARX_SOUND_PlaySFX(SND_SPELL_VISION_START, &m_caster_pos);
	
	if(m_caster == EntityHandle_Player) {
		player.m_improve = true;
		m_snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_VISION_LOOP, &m_caster_pos, 1.f, ARX_SOUND_PLAY_LOOPED);
	}
}
static void ARX_TEMPORARY_TrySound(Entity * source, Material collisionMaterial, float volume) {
	
	if(source->ioflags & IO_BODY_CHUNK)
		return;
	
	ArxInstant now = arxtime.now();
	
	if(now > source->soundtime) {
		
		source->soundcount++;
		
		if(source->soundcount < 5) {
			Material material;
			if(EEIsUnderWater(source->pos))
				material = MATERIAL_WATER;
			else if(source->material)
				material = source->material;
			else
				material = MATERIAL_STONE;
			
			if(volume > 1.f)
				volume = 1.f;
			
			long soundLength = ARX_SOUND_PlayCollision(material, collisionMaterial, volume, 1.f, source->pos, source);
			
			source->soundtime = now + ArxDurationMs(soundLength >> 4) + ArxDurationMs(50);
		}
void FlyingEyeSpell::Update() {
	
	const ArxInstant now = arxtime.now();
	
	const ArxDuration framediff3 = now - m_lastupdate;
	
	eyeball.floating = std::sin(m_lastupdate - m_timcreation * 0.001f);
	eyeball.floating *= 10.f;
	
	if(m_lastupdate - m_timcreation <= ArxDurationMs(3000)) {
		eyeball.exist = m_lastupdate - m_timcreation * (1.0f / 30);
		eyeball.size = Vec3f(1.f - float(eyeball.exist) * 0.01f);
		eyeball.angle.setYaw(eyeball.angle.getYaw() + toMs(framediff3) * 0.6f);
	} else {
		eyeball.exist = 2;
	}
	
	m_lastupdate = now;
	
	Entity * io = entities.player();
	
	if(io->obj->fastaccess.primary_attach != ActionPoint()) {
		Vec3f pos = actionPointPosition(io->obj, io->obj->fastaccess.primary_attach);
		FlyingEyeSpellUpdateHand(pos, m_light1);
	}
	
	if(io->obj->fastaccess.left_attach != ActionPoint()) {
		Vec3f pos = actionPointPosition(io->obj, io->obj->fastaccess.left_attach);
		FlyingEyeSpellUpdateHand(pos, m_light2);
	}
}
void ConfuseSpell::Launch() {
	
	ARX_SOUND_PlaySFX(SND_SPELL_CONFUSE, &entities[m_target]->pos);
	
	m_hasDuration = true;
	m_fManaCostPerSecond = 1.5f;
	m_duration = (m_launchDuration > ArxDuration(-1)) ? m_launchDuration : ArxDurationMs(5000);
	
	
	tex_p1 = TextureContainer::Load("graph/obj3d/textures/(fx)_tsu_blueting");
	tex_trail = TextureContainer::Load("graph/obj3d/textures/(fx)_bandelette_blue");
	
	const char tex[] = "graph/obj3d/interactive/fix_inter/fx_papivolle/fx_papivolle.tea";
	ANIM_HANDLE * anim_papii = EERIE_ANIMMANAGER_Load(tex);
	
	AnimLayer & au = animlayer[0];
	au.next_anim = NULL;
	au.cur_anim = anim_papii;
	au.ctime = AnimationDuration_ZERO;
	au.flags = EA_LOOP;
	au.nextflags = 0;
	au.lastframe = 0;
	au.currentInterpolation = 0;
	au.currentFrame = 0;
	au.altidx_cur = 0;
	au.altidx_next = 0;
	
	m_targets.push_back(m_target);
}
static void LaunchMagicMissileExplosion(const Vec3f & _ePos, bool mrCheat) {
	
	ParticleParams cp = g_particleParameters[ParticleParam_MagicMissileExplosion];
	
	if(mrCheat) {
		cp = g_particleParameters[ParticleParam_MagicMissileExplosionMar];
	}
	
	ParticleSystem * pPS = new ParticleSystem();
	pPS->SetParams(cp);
	pPS->SetPos(_ePos);
	pPS->Update(0);
	
	EERIE_LIGHT * light = dynLightCreate();
	if(light) {
		light->intensity = 2.3f;
		light->fallstart = 250.f;
		light->fallend   = 420.f;

		if(mrCheat) {
			light->rgb = Color3f(1.f, 0.3f, .8f);
		} else {
			light->rgb = Color3f(0.f, 0.f, .8f);
		}

		light->pos = _ePos;
		light->duration = ArxDurationMs(1500);
	}

	arx_assert(pParticleManager);
	pParticleManager->AddSystem(pPS);

	ARX_SOUND_PlaySFX(SND_SPELL_MM_HIT, &_ePos);
}
Exemple #8
0
void ARX_SPEECH_Add(const std::string & text) {

    if(text.empty())
        return;

    ArxInstant now = arxtime.now();
    if(now == ArxInstant_ZERO) {
        now = ArxInstantMs(1);
    }

    if(speech[MAX_SPEECH - 1].timecreation != ArxInstant_ZERO) {
        ARX_SPEECH_MoveUp();
    }

    for(size_t i = 0; i < MAX_SPEECH; i++) {

        if(speech[i].timecreation != ArxInstant_ZERO)
            continue;

        // Sets creation time
        speech[i].timecreation = now;
        speech[i].duration = ArxDurationMs(2000 + text.length() * 60);
        speech[i].text = text;
        return;
    }

    LogInfo << "Failed to add speech: " << text;
}
void FireFieldSpell::Update() {
	
	pPSStream.Update(g_framedelay);
	pPSStream1.Update(g_framedelay);
	
	EERIE_LIGHT * el = dynLightCreate(m_light);
	if(el) {
		el->pos = m_pos + Vec3f(0.f, -120.f, 0.f);
		el->intensity = 4.6f;
		el->fallstart = Random::getf(150.f, 180.f);
		el->fallend   = Random::getf(290.f, 320.f);
		el->rgb = Color3f(1.f, 0.8f, 0.6f) + Color3f(Random::getf(-0.1f, 0.f), 0.f, 0.f);
		el->duration = ArxDurationMs(600);
		el->extras=0;
	}
	
	if(VisibleSphere(Sphere(m_pos - Vec3f(0.f, 120.f, 0.f), 350.f))) {
		
		pPSStream.Render();
		pPSStream1.Render();
		
		float fDiff = g_framedelay / 8.f;
		int nTime = checked_range_cast<int>(fDiff);
		
		for(long nn=0;nn<=nTime+1;nn++) {
			
			PARTICLE_DEF * pd = createParticle();
			if(!pd) {
				break;
			}
			
			float t = Random::getf() * (glm::pi<float>() * 2.f) - glm::pi<float>();
			float ts = std::sin(t);
			float tc = std::cos(t);
			pd->ov = m_pos + Vec3f(120.f * ts, 15.f * ts, 120.f * tc) * randomVec();
			pd->move = Vec3f(2.f, 1.f, 2.f) + Vec3f(-4.f, -8.f, -4.f) * randomVec3f();
			pd->siz = 7.f;
			pd->tolive = Random::getu(500, 1500);
			pd->tc = fire2;
			pd->m_flags = ROTATING | FIRE_TO_SMOKE;
			pd->m_rotation = Random::getf(-0.1f, 0.1f);
			pd->scale = Vec3f(-8.f);
			
			PARTICLE_DEF * pd2 = createParticle();
			if(!pd2) {
				break;
			}
			
			*pd2 = *pd;
			pd2->delay = Random::getu(60, 210);
		}
		
	}
}
void LightningStrikeSpell::Launch() {
	
	Vec3f target(0.f, 0.f, -500.f);
	m_lightning.Create(Vec3f_ZERO, target);
	m_lightning.SetDuration(ArxDurationMs(500 * m_level));
	m_lightning.m_isMassLightning = false;
	m_duration = m_lightning.m_duration;
	
	ARX_SOUND_PlaySFX(SND_SPELL_LIGHTNING_START, &m_caster_pos);
	
	m_snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_LIGHTNING_LOOP, &m_caster_pos, 1.f, ARX_SOUND_PLAY_LOOPED);
}
Exemple #11
0
void FissureFx::SetDuration(ArxDuration alDurationIntro, ArxDuration alDurationRender, ArxDuration alDurationOuttro)
{
	ulDurationIntro  = arx::clamp(alDurationIntro,  ArxDurationMs(100), ArxDurationMs(100000));
	ulDurationRender = arx::clamp(alDurationRender, ArxDurationMs(100), ArxDurationMs(100000));
	ulDurationOuttro = arx::clamp(alDurationOuttro, ArxDurationMs(100), ArxDurationMs(100000));
	
	m_elapsed = ArxDuration_ZERO;
	m_duration = ulDurationIntro + ulDurationRender + ulDurationOuttro;
}
Exemple #12
0
CRiseDead::CRiseDead()
	: FissureFx()
	, m_eSrc(Vec3f_ZERO)
	, fBetaRadCos(0.f)
	, fBetaRadSin(0.f)
	, tex_light(NULL)
	, end(40 - 1)
	, iSize(100)
	, bIntro(true)
	, sizeF(0)
	, fSizeIntro(0.f)
{
	m_elapsed = m_duration + ArxDurationMs(1);
	
	tex_light = TextureContainer::Load("graph/obj3d/textures/(fx)_tsu4");
}
Exemple #13
0
static bool SelectSpellTargetCursorRender() {
	
	if(   !SPECIAL_DRAGINTER_RENDER
	   && LOOKING_FOR_SPELL_TARGET
	) {
		ArxDuration elapsed = arxtime.now() - LOOKING_FOR_SPELL_TARGET_TIME;
		if(elapsed > ArxDurationMs(7000)) {
			ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE, &player.pos);
			ARX_SPELLS_CancelSpellTarget();
		}
		
		TextureContainer * surf;
		
		if(FlyingOverIO
			&& (((LOOKING_FOR_SPELL_TARGET & 1) && (FlyingOverIO->ioflags & IO_NPC))
			||  ((LOOKING_FOR_SPELL_TARGET & 2) && (FlyingOverIO->ioflags & IO_ITEM)))
		){
			surf = cursorTargetOn;
			
			if(eeMouseUp1()) {
				ARX_SPELLS_LaunchSpellTarget(FlyingOverIO);
			}
		} else {
			surf = cursorTargetOff;
			
			if(GInput->actionPressed(CONTROLS_CUST_MAGICMODE)) {
				ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE, &player.pos);
				ARX_SPELLS_CancelSpellTarget();
			}
		}
		
		Vec2f pos = Vec2f(DANAEMouse);
		
		if(TRUE_PLAYER_MOUSELOOK_ON) {
			pos = MemoMouse;
		}
		
		Vec2f texSize = Vec2f(surf->size());
		pos += -texSize * 0.5f;
		
		EERIEDrawBitmap(Rectf(pos, texSize.x, texSize.y), 0.f, surf, Color::white);
		
		return true;
	}
	return false;
}
Exemple #14
0
CSummonCreature::CSummonCreature()
	: FissureFx()
	, fBetaRadCos(0.f)
	, fBetaRadSin(0.f)
	, end(0)
	, bIntro(true)
	, sizeF(0.f)
	, fSizeIntro(0.f)
{
	
	m_eSrc = Vec3f_ZERO;
	
	m_elapsed = m_duration + ArxDurationMs(1);
	
	iSize = 100;
	fOneOniSize = 1.0f / ((float) iSize);
	
	tex_light = TextureContainer::Load("graph/obj3d/textures/(fx)_tsu4");
}
void LightningStrikeSpell::Update() {
	
	float fBeta = 0.f;
	float falpha = 0.f;
	
	Entity * caster = entities[m_caster];
	ObjVertHandle idx = GetGroupOriginByName(caster->obj, "chest");
	if(idx != ObjVertHandle()) {
		m_caster_pos = caster->obj->vertexlist3[idx.handleData()].v;
	} else {
		m_caster_pos = caster->pos;
	}
	
	if(m_caster == EntityHandle_Player) {
		falpha = -player.angle.getPitch();
		fBeta = player.angle.getYaw();
	} else {
		fBeta = caster->angle.getYaw();
		if(ValidIONum(caster->targetinfo) && caster->targetinfo != m_caster) {
			const Vec3f & p1 = m_caster_pos;
			Vec3f p2 = GetChestPos(caster->targetinfo);
			falpha = MAKEANGLE(glm::degrees(getAngle(p1.y, p1.z, p2.y, p2.z + glm::distance(Vec2f(p2.x, p2.z), Vec2f(p1.x, p1.z))))); //alpha entre orgn et dest;
		} else if(ValidIONum(m_target)) {
			const Vec3f & p1 = m_caster_pos;
			Vec3f p2 = GetChestPos(m_target);
			falpha = MAKEANGLE(glm::degrees(getAngle(p1.y, p1.z, p2.y, p2.z + glm::distance(Vec2f(p2.x, p2.z), Vec2f(p1.x, p1.z))))); //alpha entre orgn et dest;
		}
	}
	
	m_lightning.m_pos = m_caster_pos;
	m_lightning.m_beta = fBeta;
	m_lightning.m_alpha = falpha;
	
	m_lightning.m_caster = m_caster;
	m_lightning.m_level = m_level;
	
	m_lightning.Update(ArxDurationMs(g_framedelay));
	m_lightning.Render();
	
	ARX_SOUND_RefreshPosition(m_snd_loop, entities[m_caster]->pos);
}
void FlyingEyeSpell::Launch()
{
	static TextureContainer * tc4 = TextureContainer::Load("graph/particles/smoke");
	
	ARX_SOUND_PlaySFX(SND_SPELL_EYEBALL_IN);
	
	m_lastupdate = m_timcreation;
	m_duration = ArxDurationMs(1000000);
	m_hasDuration = true;
	m_fManaCostPerSecond = 3.2f;
	eyeball.exist = 1;
	
	eyeball.pos = player.pos;
	eyeball.pos += angleToVectorXZ(player.angle.getYaw()) * 200.f;
	eyeball.pos += Vec3f(0.f, 50.f, 0.f);
	
	eyeball.angle = player.angle;
	
	for(long n = 0; n < 12; n++) {
		
		PARTICLE_DEF * pd = createParticle();
		if(!pd) {
			break;
		}
		
		pd->ov = eyeball.pos + randomVec(-5.f, 5.f);
		pd->move = randomVec(-2.f, 2.f);
		pd->siz = 28.f;
		pd->tolive = Random::getu(2000, 6000);
		pd->scale = Vec3f(12.f);
		pd->tc = tc4;
		pd->m_flags = FADE_IN_AND_OUT | ROTATING | DISSIPATING;
		pd->m_rotation = 0.0000001f;
		pd->rgb = Color3f(0.7f, 0.7f, 1.f);
	}
	
	TRUE_PLAYER_MOUSELOOK_ON = true;
	SLID_START = g_platformTime.frameStart();
	bOldLookToggle = config.input.mouseLookToggle;
	config.input.mouseLookToggle = true;
}
void CPoisonProjectile::Update(ArxDuration timeDelta)
{
	if(m_elapsed <= ArxDurationMs(2000)) {
		m_elapsed += timeDelta;
	}

	// on passe de 5 à 100 partoches en 1.5secs
	if(m_elapsed < 750) {
		pPS.m_parameters.m_nbMax = 2;
		pPS.Update(timeDelta);
	} else {
		if(!bOk) {
			bOk = true;
			// go
			
			ParticleParams pp = g_particleParameters[ParticleParam_Poison3];
			pp.m_pos = Vec3f(fBetaRadSin * 20, 0.f, fBetaRadCos * 20);
			pp.m_direction = -eMove * 0.1f;
			
			pPSStream.SetParams(pp);
		}

		pPSStream.Update(timeDelta);
		pPSStream.SetPos(eCurPos);

		pPS.Update(timeDelta);
		pPS.SetPos(eCurPos);

		fTrail = ((m_elapsed - 750) * (1.0f / (m_duration - 750.0f))) * 9 * (BEZIERPrecision + 2);
	}

	if(m_elapsed >= m_duration)
		lightIntensityFactor = 0.f;
	else
		lightIntensityFactor = 1.f;
}
void IceFieldSpell::Launch()
{
	spells.endByCaster(m_caster, SPELL_ICE_FIELD);
	
	ARX_SOUND_PlaySFX(SND_SPELL_ICE_FIELD);
	
	m_duration = (m_launchDuration > ArxDuration(-1)) ? m_launchDuration : ArxDurationMs(100000);
	m_hasDuration = true;
	m_fManaCostPerSecond = 2.8f;
	m_light = LightHandle();
	
	Vec3f target;
	float beta = 0.f;
	bool displace = false;
	if(m_caster == EntityHandle_Player) {
		target = player.basePosition();
		beta = player.angle.getYaw();
		displace = true;
	} else {
		if(ValidIONum(m_caster)) {
			Entity * io = entities[m_caster];
			target = io->pos;
			beta = io->angle.getYaw();
			displace = (io->ioflags & IO_NPC) == IO_NPC;
		} else {
			ARX_DEAD_CODE();
		}
	}
	if(displace) {
		target += angleToVectorXZ(beta) * 250.f;
	}
	
	m_pos = target;
	
	DamageParameters damage;
	damage.radius = 150.f;
	damage.damages = 10.f;
	damage.area = DAMAGE_FULL;
	damage.duration = ArxDurationMs(100000000);
	damage.source = m_caster;
	damage.flags = 0;
	damage.type = DAMAGE_TYPE_MAGICAL | DAMAGE_TYPE_COLD | DAMAGE_TYPE_FIELD;
	damage.pos = target;
	m_damage = DamageCreate(damage);
	
	tex_p1 = TextureContainer::Load("graph/obj3d/textures/(fx)_tsu_blueting");
	tex_p2 = TextureContainer::Load("graph/obj3d/textures/(fx)_tsu_bluepouf");
	
	for(int i = 0; i < iMax; i++) {
		float t = Random::getf();

		if (t < 0.5f)
			tType[i] = 0;
		else
			tType[i] = 1;
		
		tSize[i] = Vec3f_ZERO;
		tSizeMax[i] = randomVec3f() + Vec3f(0.f, 0.2f, 0.f);
		
		Vec3f minPos;
		if(tType[i] == 0) {
			minPos = Vec3f(1.2f, 1, 1.2f);
		} else {
			minPos = Vec3f(0.4f, 0.3f, 0.4f);
		}
		
		tSizeMax[i] = glm::max(tSizeMax[i], minPos);
		
		if(tType[i] == 0) {
			tPos[i].x = m_pos.x + Random::getf(-80.f, 80.f);
			tPos[i].y = m_pos.y;
			tPos[i].z = m_pos.z + Random::getf(-80.f, 80.f);
		} else {
			tPos[i].x = m_pos.x + Random::getf(-120.f, 120.f);
			tPos[i].y = m_pos.y;
			tPos[i].z = m_pos.z + Random::getf(-120.f, 120.f);
		}
	}
	
	m_snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_ICE_FIELD_LOOP, &target, 1.f, ARX_SOUND_PLAY_LOOPED);
}
//TODO Move somewhere else
void Cedric_ApplyLightingFirstPartRefactor(Entity *io) {

	if(!io)
		return;

	io->special_color = Color3f::white;

	float poisonpercent = 0.f;
	float trappercent = 0.f;
	float secretpercent = 0.f;

	if((io->ioflags & IO_NPC) && io->_npcdata->poisonned > 0.f) {
		poisonpercent = io->_npcdata->poisonned * ( 1.0f / 20 );
		if(poisonpercent > 1.f)
			poisonpercent = 1.f;
	}

	if((io->ioflags & IO_ITEM) && io->poisonous > 0.f && io->poisonous_count) {
		poisonpercent = io->poisonous * (1.0f / 20);
		if(poisonpercent > 1.f)
			poisonpercent = 1.f;
	}

	if((io->ioflags & IO_FIX) && io->_fixdata->trapvalue > -1) {
		trappercent = player.TRAP_DETECT - io->_fixdata->trapvalue;
		if(trappercent > 0.f) {
			trappercent = 0.6f + trappercent * ( 1.0f / 100 );
			trappercent = glm::clamp(trappercent, 0.6f, 1.f);
		}
	}

	if((io->ioflags & IO_FIX) && io->secretvalue > -1) {
		secretpercent = player.TRAP_SECRET - io->secretvalue;
		if(secretpercent > 0.f) {
			secretpercent = 0.6f + secretpercent * ( 1.0f / 100 );
			secretpercent = glm::clamp(secretpercent, 0.6f, 1.f);
		}
	}

	if(poisonpercent > 0.f) {
		io->special_color = Color3f::green;
	}

	if(trappercent > 0.f) {
		io->special_color = Color3f(trappercent, 1.f - trappercent, 1.f - trappercent);
	}

	if(secretpercent > 0.f) {
		io->special_color = Color3f(1.f - secretpercent, 1.f - secretpercent, secretpercent);
	}

	if(io->ioflags & IO_FREEZESCRIPT) {
		io->special_color = Color3f::blue;
	}

	if(io->sfx_flag & SFX_TYPE_YLSIDE_DEATH) {
		if(io->show == SHOW_FLAG_TELEPORTING) {
			io->sfx_time = io->sfx_time + ArxDurationMs(g_framedelay);

			if (io->sfx_time >= arxtime.now())
				io->sfx_time = arxtime.now();
		} else {
			const ArxDuration elapsed = arxtime.now() - io->sfx_time;

			if(elapsed > ArxDuration_ZERO) {
				if(elapsed < ArxDurationMs(3000)) { // 5 seconds to red
					float ratio = toMs(elapsed) * (1.0f / 3000);
					io->special_color = Color3f(1.f, 1.f - ratio, 1.f - ratio);
					io->highlightColor += Color3f(std::max(ratio - 0.5f, 0.f), 0.f, 0.f) * 255;
					AddRandomSmoke(io, 1);
				} else if(elapsed < ArxDurationMs(6000)) { // 5 seconds to White
					float ratio = toMs(elapsed) * (1.0f / 3000);
					io->special_color = Color3f::red;
					io->highlightColor += Color3f(std::max(ratio - 0.5f, 0.f), 0.f, 0.f) * 255;
					AddRandomSmoke(io, 2);
				} else { // SFX finish
					io->sfx_time = ArxInstant_ZERO;

					if(io->ioflags & IO_NPC) {
						MakePlayerAppearsFX(io);
						AddRandomSmoke(io, 50);
						Color3f rgb = io->_npcdata->blood_color.to<float>();
						Sphere sp = Sphere(io->pos, 200.f);
						
						long count = 6;
						while(count--) {
							Sphere splatSphere = Sphere(sp.origin, Random::getf(30.f, 60.f));
							PolyBoomAddSplat(splatSphere, rgb, 1);
							sp.origin.y -= Random::getf(0.f, 150.f);

							ARX_PARTICLES_Spawn_Splat(sp.origin, 200.f, io->_npcdata->blood_color);

							sp.origin = io->pos + randomVec3f() * Vec3f(200.f, 20.f,200.f) - Vec3f(100.f, 10.f, 100.f);
							sp.radius = Random::getf(100.f, 200.f);
						}
						
						EERIE_LIGHT * light = dynLightCreate();
						if(light) {
							light->intensity = Random::getf(0.7f, 2.7f);
							light->fallend = 600.f;
							light->fallstart = 400.f;
							light->rgb = Color3f(1.0f, 0.8f, 0.f);
							light->pos = io->pos + Vec3f(0.f, -80.f, 0.f);
							light->duration = ArxDurationMs(600);
						}

						if(io->sfx_flag & SFX_TYPE_INCINERATE) {
							io->sfx_flag &= ~SFX_TYPE_INCINERATE;
							io->sfx_flag &= ~SFX_TYPE_YLSIDE_DEATH;
							SpellBase * spell = spells.getSpellOnTarget(io->index(), SPELL_INCINERATE);

							if(!spell)
								spell = spells.getSpellOnTarget(io->index(), SPELL_MASS_INCINERATE);

							if(spell) {
								spells.endSpell(spell);
								float damages = 20 * spell->m_level;
								damages = ARX_SPELLS_ApplyFireProtection(io, damages);

								if (ValidIONum(spell->m_caster))
									ARX_DAMAGES_DamageNPC(io, damages, spell->m_caster, true, &entities[spell->m_caster]->pos);
								else
									ARX_DAMAGES_DamageNPC(io, damages, spell->m_caster, true, &io->pos);

								ARX_SOUND_PlaySFX(SND_SPELL_FIRE_HIT, &io->pos);
							}
						} else {
							io->sfx_flag &= ~SFX_TYPE_YLSIDE_DEATH;
							ARX_INTERACTIVE_DestroyIOdelayed(io);
						}
					}
				}
			}
		}
	}
}
static void Cedric_RenderObject(EERIE_3DOBJ * eobj, Skeleton * obj, Entity * io, const Vec3f & pos, float invisibility) {

	if(invisibility == 1.f)
		return;

	Entity *use_io = io;

	if(!io && IN_BOOK_DRAW && eobj == entities.player()->obj)
		use_io = entities.player();

	HaloInfo haloInfo;
	if(use_io) {
		if(use_io == entities.player()) {
			pushSlotHalo(haloInfo, EQUIP_SLOT_HELMET,   eobj->fastaccess.sel_head);
			pushSlotHalo(haloInfo, EQUIP_SLOT_ARMOR,    eobj->fastaccess.sel_chest);
			pushSlotHalo(haloInfo, EQUIP_SLOT_LEGGINGS, eobj->fastaccess.sel_leggings);
		}
	
		if(use_io->halo.flags & HALO_ACTIVE) {
			haloInfo.push(HaloRenderInfo(&use_io->halo));
		}
		
		if(haloInfo.size > 0) {
			PrepareAnimatedObjectHalo(haloInfo, pos, obj, eobj);
		}
	}

	bool glow = false;
	ColorRGBA glowColor;
	if(io && (io->sfx_flag & SFX_TYPE_YLSIDE_DEATH) && io->show != SHOW_FLAG_TELEPORTING) {
		const ArxDuration elapsed = arxtime.now() - io->sfx_time;
		if(elapsed >= ArxDurationMs(3000) && elapsed < ArxDurationMs(6000)) {
			float ratio = toMs(elapsed - ArxDurationMs(3000)) * (1.0f / 3000);
			glowColor = Color::gray(ratio).toRGB();
			glow = true;
		}
	}
	
	for(size_t i = 0; i < eobj->facelist.size(); i++) {
		const EERIE_FACE & face = eobj->facelist[i];

		if((face.facetype & POLY_HIDE) && !IN_BOOK_DRAW)
			continue;

		if(CullFace(eobj, face))
			continue;

		if(face.texid < 0)
			continue;

		TextureContainer *pTex = eobj->texturecontainer[face.texid];
		if(!pTex)
			continue;

		float fTransp = 0.f;

		TexturedVertex *tvList = GetNewVertexList(&pTex->m_modelBatch, face, invisibility, fTransp);

		for(size_t n = 0; n < 3; n++) {
			tvList[n].p     = eobj->vertexlist3[face.vid[n]].vert.p;
			tvList[n].rhw   = eobj->vertexlist3[face.vid[n]].vert.rhw;
			tvList[n].color = eobj->vertexlist3[face.vid[n]].vert.color;
			tvList[n].uv.x  = face.u[n];
			tvList[n].uv.y  = face.v[n];
		}

		if((face.facetype & POLY_TRANS) || invisibility > 0.f) {
			tvList[0].color = tvList[1].color = tvList[2].color = Color::gray(fTransp).toRGB();
		}

		if(haloInfo.size) {
			AddAnimatedObjectHalo(haloInfo, face.vid, invisibility, eobj, io, tvList);
		}
		
		if(glow) {
			TexturedVertex * tv2 = PushVertexInTable(&TexSpecialColor.m_modelBatch, BatchBucket_Opaque);
			std::copy(tvList, tvList + 3, tv2);
			tv2[0].color = tv2[1].color = tv2[2].color = glowColor;
		}
	}
}
Exemple #21
0
// Draws Flame Particles
void TreatBackgroundActions() {
	
	ARX_PROFILE_FUNC();
	
	float fZFar = square(ACTIVECAM->cdepth * fZFogEnd * 1.3f);
	
	for(size_t i = 0; i < g_staticLightsMax; i++) {
		
		EERIE_LIGHT * gl = g_staticLights[i];
		if(!gl) {
			continue;
		}
		
		float dist = arx::distance2(gl->pos,	ACTIVECAM->orgTrans.pos);
		if(dist > fZFar) {
			// Out of treat range
			ARX_SOUND_Stop(gl->sample);
			gl->sample = audio::INVALID_ID;
			continue;
		}
		
		if((gl->extras & EXTRAS_SPAWNFIRE) && gl->m_ignitionStatus) {
			DamageParameters damage;
			damage.radius = gl->ex_radius;
			damage.damages = gl->ex_radius * (1.0f / 7);
			damage.area = DAMAGE_FULL;
			damage.duration = ArxDurationMs(1);
			damage.source = EntityHandle();
			damage.flags = 0;
			damage.type = DAMAGE_TYPE_MAGICAL | DAMAGE_TYPE_FIRE | DAMAGE_TYPE_NO_FIX;
			damage.pos = gl->pos;
			DamageCreate(damage);
		}
		
		if(!(gl->extras & (EXTRAS_SPAWNFIRE | EXTRAS_SPAWNSMOKE)) || !gl->m_ignitionStatus) {
			if(!gl->m_ignitionStatus && gl->sample != audio::INVALID_ID) {
				ARX_SOUND_Stop(gl->sample);
				gl->sample = audio::INVALID_ID;
			}
			continue;
		}
		
		if(gl->sample == audio::INVALID_ID) {
			gl->sample = SND_FIREPLACE;
			ARX_SOUND_PlaySFX(gl->sample, &gl->pos, Random::getf(0.95f, 1.05f), ARX_SOUND_PLAY_LOOPED);
		} else {
			ARX_SOUND_RefreshPosition(gl->sample, gl->pos);
		}
		
		float amount = 2.f;
		if(dist < square(ACTIVECAM->cdepth * (1.f / 6))) {
			amount = 3.f;
		} else if(dist < square(ACTIVECAM->cdepth * (1.f / 3))) {
			amount = 2.5f;
		}
		const float targetFPS = 61.f;
		const float targetDelay = 1000.f / targetFPS;
		long count = gl->m_storedFlameTime.update(amount * g_framedelay * (1.f / targetDelay));
		
		for(long n = 0; n < count; n++) {
			
			if(Random::getf() < gl->ex_frequency) {
				PARTICLE_DEF * pd = createParticle();
				if(pd) {
					float t = Random::getf() * glm::pi<float>();
					Vec3f s = Vec3f(std::sin(t), std::sin(t), std::cos(t)) * randomVec();
					pd->ov = gl->pos + s * gl->ex_radius;
					pd->move = Vec3f(2.f, 2.f, 2.f) - Vec3f(4.f, 22.f, 4.f) * randomVec3f();
					pd->move *= gl->ex_speed;
					pd->siz = 7.f * gl->ex_size;
					pd->tolive = 500 + Random::getu(0, 1000 * gl->ex_speed);
					if((gl->extras & EXTRAS_SPAWNFIRE) && (gl->extras & EXTRAS_SPAWNSMOKE)) {
						pd->m_flags = FIRE_TO_SMOKE;
					}
					pd->tc = (gl->extras & EXTRAS_SPAWNFIRE) ? fire2 : smokeparticle;
					pd->m_flags |= ROTATING;
					pd->m_rotation = 0.1f - Random::getf(0.f, 0.2f) * gl->ex_speed;
					pd->scale = Vec3f(-8.f);
					pd->rgb = (gl->extras & EXTRAS_COLORLEGACY) ? gl->rgb : Color3f::white;
				}
			}
			
			if(!(gl->extras & EXTRAS_SPAWNFIRE) || Random::getf() <= 0.95f) {
				continue;
			}
			
			if(Random::getf() < gl->ex_frequency) {
				PARTICLE_DEF * pd = createParticle();
				if(pd) {
					float t = Random::getf() * (glm::pi<float>() * 2.f) - glm::pi<float>();
					Vec3f s = Vec3f(std::sin(t), std::sin(t), std::cos(t)) * randomVec();
					pd->ov = gl->pos + s * gl->ex_radius;
					Vec3f vect = glm::normalize(pd->ov - gl->pos);
					float d = (gl->extras & EXTRAS_FIREPLACE) ? 6.f : 4.f;
					pd->move = Vec3f(vect.x * d, Random::getf(-18.f, -10.f), vect.z * d) * gl->ex_speed;
					pd->siz = 4.f * gl->ex_size * 0.3f;
					pd->tolive = 1200 + Random::getu(0, 500 * gl->ex_speed);
					pd->tc = fire2;
					pd->m_flags |= ROTATING | GRAVITY;
					pd->m_rotation = 0.1f - Random::getf(0.f, 0.2f) * gl->ex_speed;
					pd->scale = Vec3f(-3.f);
					pd->rgb = (gl->extras & EXTRAS_COLORLEGACY) ? gl->rgb : Color3f::white;
				}
			}
			
		}
	}
}
void ConfuseSpell::End() {
	
	m_targets.clear();
	endLightDelayed(m_light, ArxDurationMs(500));
}
void ConfuseSpell::Update() {
	
	Vec3f pos = entities[m_target]->pos;
	if(m_target != EntityHandle_Player) {
		pos.y += entities[m_target]->physics.cyl.height - 30.f;
	}
	
	ObjVertHandle idx = entities[m_target]->obj->fastaccess.head_group_origin;
	if(idx != ObjVertHandle()) {
		pos = entities[m_target]->obj->vertexlist3[idx.handleData()].v;
		pos.y -= 50.f;
	}
	
	eCurPos = pos;
	
	RenderMaterial mat;
	mat.setDepthTest(false);
	mat.setBlendType(RenderMaterial::Additive);
	mat.setTexture(tex_trail);
	
	Anglef stiteangle = Anglef(0.f, -glm::degrees(arxtime.now_f() * ( 1.0f / 500 )), 0.f);
	
	{
		AnimationDuration delta = AnimationDurationUs(s64(g_framedelay * 1000.f));
		EERIEDrawAnimQuatUpdate(spapi, animlayer, stiteangle, eCurPos, delta, NULL, false);
		EERIEDrawAnimQuatRender(spapi, eCurPos, NULL, 0.f);
	}
	
	for(int i = 0; i < 6; i++) {
		
		PARTICLE_DEF * pd = createParticle();
		if(!pd) {
			break;
		}
		
		Vec2f p = glm::diskRand(15.f);
		pd->ov = eCurPos + Vec3f(p.x, 0.f, p.y);
		
		pd->move = Vec3f(0.f, Random::getf(1.f, 4.f), 0.f);
		pd->siz = 0.25f;
		pd->tolive = Random::getu(2300, 3300);
		pd->tc = tex_p1;
		pd->m_flags = PARTICLE_GOLDRAIN | FADE_IN_AND_OUT | ROTATING | DISSIPATING;
		pd->m_rotation = 0.0000001f;
		
		Color3f baseColor = Color3f(0.4f, 0.2f, 0.4f);
		Color3f randomFactor = Color3f(0.4f, 0.6f, 0.4f);
		Color3f c = baseColor + randomColor3f() * randomFactor;
		while(glm::abs(c.r - c.g) > 0.3f && glm::abs(c.g - c.b) > 0.3f) {
			c = baseColor + randomColor3f() * randomFactor;
		}
		pd->rgb = c * Color3f(0.8f, 0.8f, 0.8f);
	}
	
	EERIE_LIGHT * light = dynLightCreate(m_light);
	if(light) {
		light->intensity = 1.3f;
		light->fallstart = 180.f;
		light->fallend   = 420.f;
		light->rgb = Color3f(0.3f, 0.3f, 0.5f) + Color3f(0.2f, 0.f, 0.2f) * randomColor3f();
		light->pos = eCurPos;
		light->duration = ArxDurationMs(200);
		light->extras = 0;
	}
}
//***********************************************************************************************
// flags & 1 = blood spawn only
//-----------------------------------------------------------------------------------------------
//***********************************************************************************************
bool ARX_EQUIPMENT_Strike_Check(Entity * io_source, Entity * io_weapon, float ratioaim, long flags, EntityHandle targ) {
	
	ARX_PROFILE_FUNC();
	
	arx_assert(io_source);
	arx_assert(io_weapon);
	
	bool ret = false;
	EntityHandle source = io_source->index();
	EntityHandle weapon = io_weapon->index();
	
	EXCEPTIONS_LIST_Pos = 0;

	float drain_life = ARX_EQUIPMENT_GetSpecialValue(io_weapon, IO_SPECIAL_ELEM_DRAIN_LIFE);
	float paralyse = ARX_EQUIPMENT_GetSpecialValue(io_weapon, IO_SPECIAL_ELEM_PARALYZE);

	BOOST_FOREACH(const EERIE_ACTIONLIST & action, io_weapon->obj->actionlist) {
		
		float rad = GetHitValue(action.name);

		if(rad == -1)
			continue;
		
		Sphere sphere;
		sphere.origin = actionPointPosition(io_weapon->obj, action.idx);
		sphere.radius = rad; 

		if(source != EntityHandle_Player)
			sphere.radius += 15.f;

		std::vector<EntityHandle> sphereContent;

		if(CheckEverythingInSphere(sphere, source, targ, sphereContent)) {
			BOOST_FOREACH(const EntityHandle & content, sphereContent) {
				if(ValidIONum(content)
						&& !(entities[content]->ioflags & IO_BODY_CHUNK))
				{
					bool HIT_SPARK = false;
					EXCEPTIONS_LIST[EXCEPTIONS_LIST_Pos] = content;
					EXCEPTIONS_LIST_Pos++;

					if(EXCEPTIONS_LIST_Pos >= MAX_IN_SPHERE)
						EXCEPTIONS_LIST_Pos--;

					Entity * target = entities[content];
			
					Vec3f pos;
					Color color = Color::white;
					long hitpoint = -1;
					float curdist = 999999.f;
					
					Vec3f vector = (sphere.origin - target->pos) * Vec3f(1.f, 0.5f, 1.f);
					vector = glm::normalize(vector);

					for(size_t ii = 0; ii < target->obj->facelist.size(); ii++) {
						if(target->obj->facelist[ii].facetype & POLY_HIDE)
							continue;

						float d = glm::distance(sphere.origin, target->obj->vertexlist3[target->obj->facelist[ii].vid[0]].v);

						if(d < curdist) {
							hitpoint = target->obj->facelist[ii].vid[0];
							curdist = d;
						}
					}

					if(hitpoint >= 0) {
						color = (target->ioflags & IO_NPC) ? target->_npcdata->blood_color : Color::white;
						pos = target->obj->vertexlist3[hitpoint].v;
					}
					else ARX_DEAD_CODE(); 
					
					float dmgs = 0.f;
					if(!(flags & 1)) {
						Vec3f posi;

						if(hitpoint >= 0) {
							posi = target->obj->vertexlist3[hitpoint].v;
							dmgs = ARX_EQUIPMENT_ComputeDamages(io_source, target, ratioaim, &posi);
						} else {
							dmgs = ARX_EQUIPMENT_ComputeDamages(io_source, target, ratioaim);
						}

						if(target->ioflags & IO_NPC) {
							ret = true;
							target->spark_n_blood = 0;
							target->_npcdata->SPLAT_TOT_NB = 0;

							if(drain_life > 0.f) {
								float life_gain = std::min(dmgs, drain_life);
								life_gain = std::min(life_gain, target->_npcdata->lifePool.current);
								life_gain = std::max(life_gain, 0.f);
								ARX_DAMAGES_HealInter(io_source, life_gain);
							}

							if(paralyse > 0.f) {
								ArxDuration ptime = ArxDurationMs(std::min(dmgs * 1000.f, paralyse));
								ARX_SPELLS_Launch(SPELL_PARALYSE,
								                  weapon,
								                  SPELLCAST_FLAG_NOMANA | SPELLCAST_FLAG_NOCHECKCANCAST,
								                  5,
								                  content,
								                  ptime);
							}
						}

						if(io_source == entities.player())
							ARX_DAMAGES_DurabilityCheck(io_weapon, 0.2f);
					}

					if(dmgs > 0.f || ((target->ioflags & IO_NPC) && target->spark_n_blood == SP_BLOODY)) {
						if(target->ioflags & IO_NPC) {
							target->spark_n_blood = SP_BLOODY;

							if(!(flags & 1)) {
								ARX_PARTICLES_Spawn_Splat(pos, dmgs, color);
								
								Vec3f vertPos = target->obj->vertexlist3[hitpoint].v;
								
								float power = (dmgs * ( 1.0f / 40 )) + 0.7f;
								
								Vec3f vect;
								vect.x = vertPos.x - io_source->pos.x;
								vect.y = 0;
								vect.z = vertPos.z - io_source->pos.z;
								vect = glm::normalize(vect);
								
								Sphere sp;
								sp.origin.x = vertPos.x + vect.x * 30.f;
								sp.origin.y = vertPos.y;
								sp.origin.z = vertPos.z + vect.z * 30.f;
								sp.radius = 3.5f * power * 20;

								if(CheckAnythingInSphere(sp, EntityHandle_Player, CAS_NO_NPC_COL)) {
									Color3f rgb = color.to<float>();
									
									Sphere splatSphere;
									splatSphere.origin = sp.origin;
									splatSphere.radius = 30.f;
									PolyBoomAddSplat(splatSphere, rgb, 1);
								}
							}

							ARX_PARTICLES_Spawn_Blood2(pos, dmgs, color, target);
						} else {
							if(target->ioflags & IO_ITEM)
								ParticleSparkSpawn(pos, Random::getu(0, 3), SpawnSparkType_Default);
							else
								ParticleSparkSpawn(pos, Random::getu(0, 30), SpawnSparkType_Default);

							ARX_NPC_SpawnAudibleSound(pos, io_source);

							if(io_source == entities.player())
								HIT_SPARK = true;
						}
					} else if((target->ioflags & IO_NPC) && (dmgs <= 0.f || target->spark_n_blood == SP_SPARKING)) {
						unsigned int nb;

						if(target->spark_n_blood == SP_SPARKING)
							nb = Random::getu(0, 3);
						else
							nb = 30;

						if(target->ioflags & IO_ITEM)
							nb = 1;

						ParticleSparkSpawn(pos, nb, SpawnSparkType_Default);
						ARX_NPC_SpawnAudibleSound(pos, io_source);
						target->spark_n_blood = SP_SPARKING;

						if(!(target->ioflags & IO_NPC))
							HIT_SPARK = true;
					} else if(dmgs <= 0.f && ((target->ioflags & IO_FIX) || (target->ioflags & IO_ITEM))) {
						unsigned int nb;

						if(target->spark_n_blood == SP_SPARKING)
							nb = Random::getu(0, 3);
						else
							nb = 30;

						if(target->ioflags & IO_ITEM)
							nb = 1;

						ParticleSparkSpawn(pos, nb, SpawnSparkType_Default);
						ARX_NPC_SpawnAudibleSound(pos, io_source);
						target->spark_n_blood = SP_SPARKING;

						if (!(target->ioflags & IO_NPC))
							HIT_SPARK = true;
					}

					if(HIT_SPARK) {
						if(!io_source->isHit) {
							ARX_DAMAGES_DurabilityCheck(io_weapon, 1.f);
							io_source->isHit = true;
							
							std::string _weapon_material = "metal";
							const std::string * weapon_material = &_weapon_material;
							
							if(!io_weapon->weaponmaterial.empty()) {
								weapon_material = &io_weapon->weaponmaterial;
							}
							
							if(target->material != MATERIAL_NONE) {
								const char * matStr = ARX_MATERIAL_GetNameById(target->material);
								ARX_SOUND_PlayCollision(*weapon_material, matStr, 1.f, 1.f, sphere.origin, NULL);
							}
						}
					}
				}
			}
		}

		const EERIEPOLY * ep = CheckBackgroundInSphere(sphere);
		if(ep) {
			if(io_source == entities.player()) {
				if(!io_source->isHit) {
					ARX_DAMAGES_DurabilityCheck(io_weapon, 1.f);
					io_source->isHit = true;
					
						std::string _weapon_material = "metal";
						const std::string * weapon_material = &_weapon_material;
						if(!io_weapon->weaponmaterial.empty()) {
							weapon_material = &io_weapon->weaponmaterial;
						}

						std::string bkg_material = "earth";

						if(ep && ep->tex && !ep->tex->m_texName.empty())
							bkg_material = GetMaterialString(ep->tex->m_texName);

						ARX_SOUND_PlayCollision(*weapon_material, bkg_material, 1.f, 1.f, sphere.origin, io_source);
				}
			}

			ParticleSparkSpawn(sphere.origin, Random::getu(0, 10), SpawnSparkType_Default);
			ARX_NPC_SpawnAudibleSound(sphere.origin, io_source);
		}
	}

	return ret;
}
void MagicMissileSpell::Launch() {
	
	m_duration = ArxDurationMs(6000);
	
	m_hand_group = GetActionPointIdx(entities[m_caster]->obj, "primary_attach");
	
	if(m_hand_group != ActionPoint()) {
		Entity * caster = entities[m_caster];
		ActionPoint group = m_hand_group;
		m_hand_pos = actionPointPosition(caster->obj, group);
	}
	
	Vec3f startPos;
	float pitch, yaw;
	if(m_caster == EntityHandle_Player) {
		yaw = player.angle.getYaw();
		pitch = player.angle.getPitch();
		
		Vec3f vector = angleToVector(Anglef(pitch, yaw, 0.f)) * 60.f;
		
		if(m_hand_group != ActionPoint()) {
			startPos = m_hand_pos;
		} else {
			startPos = player.pos;
			startPos += angleToVectorXZ(yaw);
		}
		
		startPos += vector;
		
	} else {
		pitch = 0;
		yaw = entities[m_caster]->angle.getYaw();
		
		Vec3f vector = angleToVector(Anglef(pitch, yaw, 0.f)) * 60.f;
		
		if(m_hand_group != ActionPoint()) {
			startPos = m_hand_pos;
		} else {
			startPos = entities[m_caster]->pos;
		}
		
		startPos += vector;
		
		Entity * io = entities[m_caster];
		
		if(ValidIONum(io->targetinfo)) {
			const Vec3f & p1 = m_caster_pos;
			const Vec3f & p2 = entities[io->targetinfo]->pos;
			pitch = -(glm::degrees(getAngle(p1.y, p1.z, p2.y, p2.z + glm::distance(Vec2f(p2.x, p2.z), Vec2f(p1.x, p1.z))))); //alpha entre orgn et dest;
		} else if (ValidIONum(m_target)) {
			const Vec3f & p1 = m_caster_pos;
			const Vec3f & p2 = entities[m_target]->pos;
			pitch = -(glm::degrees(getAngle(p1.y, p1.z, p2.y, p2.z + glm::distance(Vec2f(p2.x, p2.z), Vec2f(p1.x, p1.z))))); //alpha entre orgn et dest;
		}
	}
	
	m_mrCheat = (m_caster == EntityHandle_Player && cur_mr == 3);
	
	ArxDuration lMax = ArxDuration_ZERO;
	
	long number;
	if(sp_max || cur_rf == 3) {
		number = long(m_level);
	} else {
		number = glm::clamp(long(m_level + 1) / 2, 1l, 5l);
	}
	
	pTab.reserve(number);
	
	for(size_t i = 0; i < size_t(number); i++) {
		CMagicMissile * missile = NULL;
		if(!m_mrCheat) {
			missile = new CMagicMissile();
		} else {
			missile = new MrMagicMissileFx();
		}
		
		pTab.push_back(missile);
		
		Anglef angles(pitch, yaw, 0.f);
		
		if(i > 0) {
			angles.setPitch(angles.getPitch() + Random::getf(-4.0f, 4.0f));
			angles.setYaw(angles.getYaw() + Random::getf(-6.0f, 6.0f));
		}
		
		missile->Create(startPos, angles);
		
		ArxDuration lTime = m_duration + ArxDurationMs(Random::get(-1000, 1000));
		
		lTime		= std::max(ArxDurationMs(1000), lTime);
		lMax		= std::max(lMax, lTime);
		
		missile->SetDuration(lTime);
		
		EERIE_LIGHT * el = dynLightCreate(missile->lLightId);
		if(el) {
			el->intensity	= 0.7f + 2.3f;
			el->fallend		= 190.f;
			el->fallstart	= 80.f;
			
			if(m_mrCheat) {
				el->rgb = Color3f(1.f, 0.3f, 0.8f);
			} else {
				el->rgb = Color3f(0.f, 0.f, 1.f);
			}
			
			el->pos = startPos;
			el->duration = ArxDurationMs(300);
		}
	}
	
	m_duration = lMax + ArxDurationMs(1000);
}
void MagicMissileSpell::Update() {
	
	
	for(size_t i = 0; i < pTab.size(); i++) {
		CMagicMissile * missile = pTab[i];
		
		if(missile->bExplo)
			continue;
			
		Sphere sphere = Sphere(missile->eCurPos, 10.f);
		
		if(CheckAnythingInSphere(sphere, m_caster, CAS_NO_SAME_GROUP)) {
			
			LaunchMagicMissileExplosion(missile->eCurPos, m_mrCheat);
			ARX_NPC_SpawnAudibleSound(missile->eCurPos, entities[m_caster]);
			
			missile->SetTTL(ArxDurationMs(1000));
			missile->bExplo = true;
			missile->bMove  = false;
			
			missile->lLightId = LightHandle();
			
			DamageParameters damage;
			damage.pos = missile->eCurPos;
			damage.radius = 80.f;
			damage.damages = (4 + m_level * ( 1.0f / 5 )) * .8f;
			damage.area	= DAMAGE_FULL;
			damage.duration = ArxDuration(-1);
			damage.source = m_caster;
			damage.flags = DAMAGE_FLAG_DONT_HURT_SOURCE;
			damage.type = DAMAGE_TYPE_MAGICAL;
			DamageCreate(damage);
			
			Color3f rgb(.3f, .3f, .45f);
			ARX_PARTICLES_Add_Smoke(missile->eCurPos, 0, 6, rgb);
		}
	}
	
	for(size_t i = 0 ; i < pTab.size() ; i++) {
		pTab[i]->Update(ArxDurationMs(g_framedelay));
	}
	
	{ // CheckAllDestroyed
		long nbmissiles	= 0;
		
		for(size_t i = 0; i < pTab.size(); i++) {
			CMagicMissile *pMM = pTab[i];
			if(pMM->bMove)
				nbmissiles++;
		}
		
		if(nbmissiles == 0)
			m_duration = ArxDuration_ZERO;
	}
	
	for(size_t i = 0; i < pTab.size(); i++) {
		pTab[i]->Render();
		
		CMagicMissile * pMM = pTab[i];
		
		EERIE_LIGHT * el = lightHandleGet(pMM->lLightId);
		if(el) {
			el->intensity		= 0.7f + 2.3f * pMM->lightIntensityFactor;
			el->pos = pMM->eCurPos;
			el->creationTime	= arxtime.now();
		}
	}
}
void IceFieldSpell::Update() {
	
	EERIE_LIGHT * el = dynLightCreate(m_light);
	if(el) {
		el->pos = m_pos + Vec3f(0.f, -120.f, 0.f);
		el->intensity = 4.6f;
		el->fallstart = Random::getf(150.f, 180.f);
		el->fallend   = Random::getf(290.f, 320.f);
		el->rgb = Color3f(0.76f, 0.76f, 1.0f) + Color3f(0.f, 0.f, Random::getf(-0.1f, 0.f));
		el->duration = ArxDurationMs(600);
		el->extras=0;
	}

	if(!VisibleSphere(Sphere(m_pos - Vec3f(0.f, 120.f, 0.f), 350.f)))
		return;
	
	RenderMaterial mat;
	mat.setDepthTest(true);
	mat.setBlendType(RenderMaterial::Additive);
	
	for(int i = 0; i < iMax; i++) {
		
		tSize[i] += Vec3f(0.1f);
		tSize[i] = glm::min(tSize[i], tSizeMax[i]);
		
		Anglef stiteangle = Anglef::ZERO;
		Vec3f stitepos;
		Vec3f stitescale;
		Color3f stitecolor;

		stiteangle.setYaw(glm::cos(glm::radians(tPos[i].x)) * 360);
		stitepos.x = tPos[i].x;
		stitepos.y = m_pos.y;
		stitepos.z = tPos[i].z;
		
		stitecolor.r = tSizeMax[i].y * 0.7f;
		stitecolor.g = tSizeMax[i].y * 0.7f;
		stitecolor.b = tSizeMax[i].y * 0.9f;

		if(stitecolor.r > 1)
			stitecolor.r = 1;

		if(stitecolor.g > 1)
			stitecolor.g = 1;

		if(stitecolor.b > 1)
			stitecolor.b = 1;

		stitescale.z = tSize[i].x;
		stitescale.y = tSize[i].y;
		stitescale.x = tSize[i].z;

		EERIE_3DOBJ * obj = (tType[i] == 0) ? smotte : stite;
		
		Draw3DObject(obj, stiteangle, stitepos, stitescale, stitecolor, mat);
	}
	
	for(int i = 0; i < iMax * 0.5f; i++) {
		
		float t = Random::getf();
		if(t < 0.01f) {
			
			PARTICLE_DEF * pd = createParticle();
			if(pd) {
				pd->ov = tPos[i] + randomVec(-5.f, 5.f);
				pd->move = randomVec(-2.f, 2.f);
				pd->siz = 20.f;
				pd->tolive = Random::getu(2000, 6000);
				pd->tc = tex_p2;
				pd->m_flags = FADE_IN_AND_OUT | ROTATING | DISSIPATING;
				pd->m_rotation = 0.0000001f;
				pd->rgb = Color3f(0.7f, 0.7f, 1.f);
			}
			
		} else if (t > 0.095f) {
			
			PARTICLE_DEF * pd = createParticle();
			if(pd) {
				pd->ov = tPos[i] + randomVec(-5.f, 5.f) + Vec3f(0.f, 50.f, 0.f);
				pd->move = Vec3f(0.f, Random::getf(-2.f, 2.f), 0.f);
				pd->siz = 0.5f;
				pd->tolive = Random::getu(2000, 6000);
				pd->tc = tex_p1;
				pd->m_flags = FADE_IN_AND_OUT | ROTATING | DISSIPATING;
				pd->m_rotation = 0.0000001f;
				pd->rgb = Color3f(0.7f, 0.7f, 1.f);
			}
			
		}
	}
}
void DouseSpell::Launch()
{
	m_duration = ArxDurationMs(500);
	
	Vec3f target;
	if(m_hand_group != ActionPoint()) {
		target = m_hand_pos;
	} else {
		target = m_caster_pos;
		target.y -= 50.f;
	}
	
	float fPerimeter = 400.f + m_level * 30.f;
	
	CheckForIgnition(Sphere(target, fPerimeter), 0, 1);
	
	for(size_t ii = 0; ii < g_staticLightsMax; ii++) {
		EERIE_LIGHT * light = g_staticLights[ii];
		
		if(!light || !(light->extras & EXTRAS_EXTINGUISHABLE)) {
			continue;
		}
		
		if(!(light->extras & EXTRAS_SEMIDYNAMIC)
		  && !(light->extras & EXTRAS_SPAWNFIRE)
		  && !(light->extras & EXTRAS_SPAWNSMOKE)) {
			continue;
		}
		
		if(!light->m_ignitionStatus) {
			continue;
		}
		
		if(!fartherThan(target, light->pos, fPerimeter)) {
			m_lights.push_back(ii);
		}
	}
	
	if(player.torch && closerThan(target, player.pos, fPerimeter)) {
		ARX_PLAYER_ClickedOnTorch(player.torch);
	}
	
	for(size_t k = 0; k < MAX_SPELLS; k++) {
		SpellBase * spell = spells[SpellHandle(k)];
		
		if(!spell) {
			continue;
		}
		
		switch(spell->m_type) {
			
			case SPELL_FIREBALL: {
				Vec3f pos = spell->getPosition();
				float radius = std::max(m_level * 2.f, 12.f);
				if(closerThan(target, pos, fPerimeter + radius)) {
					spell->m_level -= m_level;
					if(spell->m_level < 1) {
						spells.endSpell(spell);
					}
				}
				break;
			}
			
			case SPELL_FIRE_FIELD: {
				Vec3f pos = spell->getPosition();
				if(closerThan(target, pos, fPerimeter + 200)) {
					spell->m_level -= m_level;
					if(spell->m_level < 1) {
						spells.endSpell(spell);
					}
				}
				break;
			}
			
			default: break;
		}
	}
}
void IgnitSpell::Launch()
{
	m_duration = ArxDurationMs(500);
	
	if(m_hand_group != ActionPoint()) {
		m_srcPos = m_hand_pos;
	} else {
		m_srcPos = m_caster_pos - Vec3f(0.f, 50.f, 0.f);
	}
	
	EERIE_LIGHT * light = dynLightCreate();
	if(light) {
		light->intensity = 1.8f;
		light->fallend   = 450.f;
		light->fallstart = 380.f;
		light->rgb       = Color3f(1.f, 0.75f, 0.5f);
		light->pos       = m_srcPos;
		light->duration  = ArxDurationMs(300);
	}
	
	float fPerimeter = 400.f + m_level * 30.f;
	
	m_lights.clear();
	m_elapsed = ArxDuration_ZERO;
	
	CheckForIgnition(Sphere(m_srcPos, fPerimeter), 1, 1);
	
	for(size_t ii = 0; ii < g_staticLightsMax; ii++) {
		EERIE_LIGHT * light = g_staticLights[ii];
		
		if(!light || !(light->extras & EXTRAS_EXTINGUISHABLE)) {
			continue;
		}
		
		if(m_caster == EntityHandle_Player && (light->extras & EXTRAS_NO_IGNIT)) {
			continue;
		}
		
		if(!(light->extras & EXTRAS_SEMIDYNAMIC)
		  && !(light->extras & EXTRAS_SPAWNFIRE)
		  && !(light->extras & EXTRAS_SPAWNSMOKE)) {
			continue;
		}
		
		if(light->m_ignitionStatus) {
			continue;
		}
		
		if(!fartherThan(m_srcPos, light->pos, fPerimeter)) {
			
			T_LINKLIGHTTOFX entry;
			
			entry.m_targetLight = ii;
			
			EERIE_LIGHT * light = dynLightCreate(entry.m_effectLight);
			if(light) {
				light->intensity = Random::getf(0.7f, 2.7f);
				light->fallend = 400.f;
				light->fallstart = 300.f;
				light->rgb = Color3f(1.f, 1.f, 1.f);
				light->pos = light->pos;
			}
		
			m_lights.push_back(entry);
		}
	}
	
	for(size_t n = 0; n < MAX_SPELLS; n++) {
		SpellBase * spell = spells[SpellHandle(n)];
		
		if(!spell) {
			continue;
		}
		if(spell->m_type == SPELL_FIREBALL) {
			Vec3f pos = static_cast<FireballSpell *>(spell)->getPosition();
			
			float radius = std::max(m_level * 2.f, 12.f);
			if(closerThan(m_srcPos, pos, fPerimeter + radius)) {
				spell->m_level += 1;
			}
		}
	}
}
Exemple #30
0
void ARX_SPEECH_Update() {

    ArxInstant now = arxtime.now();

    if(cinematicBorder.isActive() || BLOCK_PLAYER_CONTROLS)
        ARX_CONVERSATION_CheckAcceleratedSpeech();

    for(size_t i = 0; i < MAX_ASPEECH; i++) {
        if(!aspeech[i].exist)
            continue;

        Entity * io = aspeech[i].io;

        // updates animations
        if(io) {
            if(aspeech[i].flags & ARX_SPEECH_FLAG_OFFVOICE)
                ARX_SOUND_RefreshSpeechPosition(aspeech[i].sample);
            else
                ARX_SOUND_RefreshSpeechPosition(aspeech[i].sample, io);

            if((io != entities.player() || EXTERNALVIEW) && ValidIOAddress(io)) {

                if(!io->anims[aspeech[i].mood])
                    aspeech[i].mood = ANIM_TALK_NEUTRAL;

                ANIM_HANDLE * anim = io->anims[aspeech[i].mood];
                if(anim) {
                    AnimLayer & layer2 = io->animlayer[2];
                    if(layer2.cur_anim != anim || (layer2.flags & EA_ANIMEND)) {
                        changeAnimation(io, 2, anim);
                    }
                }
            }
        }

        // checks finished speech
        if(now >= aspeech[i].time_creation + aspeech[i].duration) {
            EERIE_SCRIPT *es = aspeech[i].es;
            Entity *io = aspeech[i].ioscript;
            long scrpos = aspeech[i].scrpos;
            ARX_SPEECH_Release(i);

            if(es && ValidIOAddress(io))
                ScriptEvent::send(es, SM_EXECUTELINE, "", io, "", scrpos);
        }
    }

    for(size_t i = 0; i < MAX_ASPEECH; i++) {
        ARX_SPEECH *speech = &aspeech[i];

        if(!speech->exist)
            continue;

        if(speech->text.empty())
            continue;

        if(!cinematicBorder.isActive())
            continue;

        if(cinematicBorder.CINEMA_DECAL < 100.f)
            continue;

        Vec2i sSize = hFontInBook->getTextSize(speech->text);

        float fZoneClippHeight	=	static_cast<float>(sSize.y * 3);
        float fStartYY			=	100 * g_sizeRatio.y;
        float fStartY			=	static_cast<float>(((int)fStartYY - (int)fZoneClippHeight) >> 1);
        float fDepY				=	((float)g_size.height()) - fStartYY + fStartY - speech->fDeltaY + sSize.y;
        float fZoneClippY		=	fDepY + speech->fDeltaY;

        float fAdd = fZoneClippY + fZoneClippHeight ;

        Rect::Num y = checked_range_cast<Rect::Num>(fZoneClippY);
        Rect::Num h = checked_range_cast<Rect::Num>(fAdd);

        Rect clippingRect(0, y+1, g_size.width(), h);
        if(config.interface.limitSpeechWidth) {
            s32 w = std::min(g_size.width(), s32(640 * g_sizeRatio.y));
            clippingRect.left = (g_size.width() - w) / 2;
            clippingRect.right = (g_size.width() + w) / 2;
        }

        float height = (float)ARX_UNICODE_DrawTextInRect(
                           hFontInBook,
                           Vec2f(clippingRect.left + 10.f, fDepY + fZoneClippHeight),
                           clippingRect.right - 10.f,
                           speech->text,
                           Color::white,
                           &clippingRect);

        GRenderer->SetBlendFunc(BlendZero, BlendInvSrcColor);
        GRenderer->SetRenderState(Renderer::AlphaBlending, true);
        GRenderer->SetRenderState(Renderer::DepthTest, false);

        EERIEDrawFill2DRectDegrad(Vec2f(0.f, fZoneClippY - 1.f),
                                  Vec2f(static_cast<float>(g_size.width()), fZoneClippY + (sSize.y * 3 / 4)),
                                  0.f, Color::white, Color::black);
        EERIEDrawFill2DRectDegrad(Vec2f(0.f, fZoneClippY + fZoneClippHeight - (sSize.y * 3 / 4)),
                                  Vec2f(static_cast<float>(g_size.width()), fZoneClippY + fZoneClippHeight),
                                  0.f, Color::black, Color::white);

        GRenderer->SetBlendFunc(BlendOne, BlendZero);
        GRenderer->SetRenderState(Renderer::DepthTest, true);
        GRenderer->SetRenderState(Renderer::AlphaBlending, false);

        height += fZoneClippHeight;

        if(speech->fDeltaY <= height) {
            //vitesse du scroll
            float fDTime;

            if(speech->sample) {
                ArxDuration duration = ARX_SOUND_GetDuration(speech->sample);
                if(duration == ArxDuration_ZERO) {
                    duration = ArxDurationMs(4000);
                }

                fDTime = (height * g_framedelay) / duration; //speech->duration;
                float fTimeOneLine = sSize.y * fDTime;

                if(speech->iTimeScroll >= fTimeOneLine) {
                    float fResteLine = sSize.y - speech->fPixelScroll;
                    float fTimePlus = (fResteLine * g_framedelay) / duration;
                    fDTime -= fTimePlus;
                    speech->fPixelScroll = 0.f;
                    speech->iTimeScroll = 0;
                }
                speech->iTimeScroll	+= checked_range_cast<int>(g_framedelay);
            } else {
                fDTime = (height * g_framedelay) / 4000.0f;
            }

            speech->fDeltaY			+= fDTime;
            speech->fPixelScroll	+= fDTime;
        }
    }
}