示例#1
0
void FireFieldSpell::Launch() {
	
	spells.endByCaster(m_caster, SPELL_FIRE_FIELD);
	
	ARX_SOUND_PlaySFX(SND_SPELL_FIRE_FIELD_START);
	
	m_duration = (m_launchDuration > -1) ? m_launchDuration : 100000;
	m_hasDuration = true;
	m_fManaCostPerSecond = 2.8f;
	m_light = LightHandle();
	
	Vec3f target;
	float beta = 0.f;
	bool displace = false;
	if(m_caster == PlayerEntityHandle) {
		target = player.basePosition();
		beta = player.angle.getPitch();
		displace = true;
	} else {
		if(ValidIONum(m_caster)) {
			Entity * io = entities[m_caster];
			target = io->pos;
			beta = io->angle.getPitch();
			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 = 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);
	
	{
	ParticleParams cp = ParticleParams();
	cp.m_nbMax = 100;
	cp.m_life = 2000;
	cp.m_lifeRandom = 1000;
	cp.m_pos = Vec3f(80, 10, 80);
	cp.m_direction = Vec3f(0.f, 1.f, 0.f);
	cp.m_angle = 0;
	cp.m_speed = 0;
	cp.m_speedRandom = 0;
	cp.m_gravity = Vec3f_ZERO;
	cp.m_flash = 0;
	cp.m_rotation = 0;
	cp.m_rotationRandomDirection = false;
	cp.m_rotationRandomStart = false;

	cp.m_startSegment.m_size = 10;
	cp.m_startSegment.m_sizeRandom = 3;
	cp.m_startSegment.m_color = Color(25, 25, 25, 50).to<float>();
	cp.m_startSegment.m_colorRandom = Color(51, 51, 51, 101).to<float>();

	cp.m_endSegment.m_size = 10;
	cp.m_endSegment.m_sizeRandom = 3;
	cp.m_endSegment.m_color = Color(25, 25, 25, 50).to<float>();
	cp.m_endSegment.m_colorRandom = Color(0, 0, 0, 100).to<float>();
	cp.m_texture.m_texLoop = true;

	cp.m_blendMode = RenderMaterial::AlphaAdditive;
	cp.m_freq = 150.0f;
	cp.m_texture.set("graph/particles/firebase", 4, 100);
	cp.m_spawnFlags = 0;
	
	pPSStream.SetParams(cp);
	}
	pPSStream.SetPos(m_pos);
	pPSStream.Update(0);

	//-------------------------------------------------------------------------

	{
	ParticleParams cp = ParticleParams();
	cp.m_nbMax = 50;
	cp.m_life = 1000;
	cp.m_lifeRandom = 500;
	cp.m_pos = Vec3f(100, 10, 100);
	cp.m_direction = Vec3f(0.f, -1.f, 0.f);
	cp.m_angle = glm::radians(10.f);
	cp.m_speed = 0;
	cp.m_speedRandom = 0;
	cp.m_gravity = Vec3f_ZERO;
	cp.m_flash = 0;
	cp.m_rotation = 0;
	cp.m_rotationRandomDirection = false;
	cp.m_rotationRandomStart = false;

	cp.m_startSegment.m_size = 10;
	cp.m_startSegment.m_sizeRandom = 10;
	cp.m_startSegment.m_color = Color(40, 40, 40, 50).to<float>();
	cp.m_startSegment.m_colorRandom = Color(51, 51, 51, 100).to<float>();

	cp.m_endSegment.m_size = 10;
	cp.m_endSegment.m_sizeRandom = 10;
	cp.m_endSegment.m_color = Color(0, 0, 0, 50).to<float>();
	cp.m_endSegment.m_colorRandom = Color(0, 0, 0, 100).to<float>();
	cp.m_texture.m_texLoop = false;

	cp.m_blendMode = RenderMaterial::Additive;
	cp.m_freq = 150.0f;
	cp.m_texture.set("graph/particles/fire", 0, 500);
	cp.m_spawnFlags = 0;
	
	pPSStream1.SetParams(cp);
	}
	pPSStream1.SetPos(m_pos + Vec3f(0, 10, 0));
	pPSStream1.Update(0);
}
示例#2
0
void IceFieldSpell::Launch()
{
	spells.endByCaster(m_caster, SPELL_ICE_FIELD);
	
	ARX_SOUND_PlaySFX(SND_SPELL_ICE_FIELD);
	
	m_duration = (m_launchDuration > -1) ? m_launchDuration : 100000;
	m_hasDuration = true;
	m_fManaCostPerSecond = 2.8f;
	m_light = LightHandle();
	
	Vec3f target;
	float beta = 0.f;
	bool displace = false;
	if(m_caster == PlayerEntityHandle) {
		target = player.basePosition();
		beta = player.angle.getPitch();
		displace = true;
	} else {
		if(ValidIONum(m_caster)) {
			Entity * io = entities[m_caster];
			target = io->pos;
			beta = io->angle.getPitch();
			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 = 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);
}
void AddFlare(const Vec2f & pos, float sm, short typ, Entity * io, bool bookDraw) {
	
	size_t oldest = 0;
	size_t i;
	for(i = 0; i < g_magicFlaresMax; i++) {
		if(!g_magicFlares[i].exist) {
			break;
		}
		if(g_magicFlares[i].tolive < g_magicFlares[oldest].tolive) {
			oldest = i;
		}
	}
	if(i >= g_magicFlaresMax) {
		removeFlare(g_magicFlares[oldest]);
		i = oldest;
	}

	MagicFlare & flare = g_magicFlares[i];
	flare.exist = 1;
	g_magicFlaresCount++;
	
	flare.bDrawBitmap = bookDraw;
	
	flare.io = io;
	if(io) {
		flare.flags = 1;
		io->flarecount++;
	} else {
		flare.flags = 0;
	}

	flare.pos.x = pos.x - Random::getf(0.f, 4.f);
	flare.pos.y = pos.y - Random::getf(0.f, 4.f);

	if(!bookDraw) {
		if(io) {
			float vx = -(flare.pos.x - g_size.center().x) * 0.2173913f;
			float vy = (flare.pos.y - g_size.center().y) * 0.1515151515151515f;
			flare.p = io->pos;
			flare.p += angleToVectorXZ(io->angle.getYaw() + vx) * 100.f;
			flare.p.y += std::sin(glm::radians(MAKEANGLE(io->angle.getPitch() + vy))) * 100.f - 150.f;
		} else {
			Vec3f screenPos(1.0f  * (pos.x - float(g_size.width()  / 2)) * 156.f / (640.f * g_sizeRatio.y),
			                0.75f * (pos.y - float(g_size.height() / 2)) * 156.f / (480.f * g_sizeRatio.y),
			                75.f);
			flare.p = Vec3f(glm::inverse(g_preparedCamera.m_worldToView) * Vec4f(screenPos, 1.0f));
		}
	} else {
		flare.p = Vec3f(flare.pos.x, flare.pos.y, 0.001f);
	}

	switch(g_magicFlareCurrentColor) {
		case 0: {
			flare.rgb = Color3f(0.4f, 0.f, 0.4f) + Color3f(2.f / 3, 2.f / 3, 2.f / 3) * randomColor3f();
			break;
		}
		case 1: {
			flare.rgb = Color3f(0.5f, 0.5f, 0.f) + Color3f(0.625f, 0.625f, 0.55f) * randomColor3f();
			break;
		}
		case 2: {
			flare.rgb = Color3f(0.4f, 0.f, 0.f) + Color3f(2.f / 3, 0.55f, 0.55f) * randomColor3f();
			break;
		}
		default: arx_unreachable();
	}
	
	static const float FLARE_MUL = 2.f;
	
	if(typ == -1) {
		float zz = eeMousePressed1() ? 0.29f : ((sm > 0.5f) ? Random::getf() : 1.f);
		if(zz < 0.2f) {
			flare.type = 2;
			flare.size = Random::getf(42.f, 84.f);
			flare.tolive = PlatformDurationMsf(Random::getf(800.f, 1600.f) * FLARE_MUL);
		} else if(zz < 0.5f) {
			flare.type = 3;
			flare.size = Random::getf(16.f, 68.f);
			flare.tolive = PlatformDurationMsf(Random::getf(800.f, 1600.f) * FLARE_MUL);
		} else {
			flare.type = 1;
			flare.size = Random::getf(32.f, 56.f) * sm;
			flare.tolive = PlatformDurationMsf(Random::getf(1700.f, 2200.f) * FLARE_MUL);
		}
	} else {
		flare.type = (Random::getf() > 0.8f) ? 1 : 4;
		flare.size = Random::getf(64.f, 102.f) * sm;
		flare.tolive = PlatformDurationMsf(Random::getf(1700.f, 2200.f) * FLARE_MUL);
	}

	flare.dynlight = LightHandle();

	for(unsigned int kk = 0; kk < 3; kk++) {

		if(Random::getf() < 0.5f) {
			continue;
		}

		PARTICLE_DEF * pd = createParticle();
		if(!pd) {
			break;
		}

		if(!bookDraw) {
			pd->m_flags = FADE_IN_AND_OUT | ROTATING | DISSIPATING;
			if(!io) {
				pd->m_flags |= PARTICLE_NOZBUFFER;
			}
		} else {
			pd->m_flags = FADE_IN_AND_OUT;
		}

		pd->ov = flare.p + arx::randomVec(-5.f, 5.f);
		pd->move = Vec3f(0.f, 5.f, 0.f);
		pd->scale = Vec3f(-2.f);
		pd->tolive = 1300 + kk * 100 + Random::getu(0, 800);
		pd->tc = fire2;
		if(kk == 1) {
			pd->move.y = 4.f;
			pd->siz = 1.5f;
		} else {
			pd->siz = Random::getf(1.f, 2.f);
		}
		pd->rgb = flare.rgb * (2.f / 3);
		pd->m_rotation = 1.2f;
		if(bookDraw) {
			pd->is2D = true;
		}
		
	}
}
示例#4
0
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 CreateFieldSpell::Launch()
{
	unsigned long start = (unsigned long)(arxtime);
	if(m_flags & SPELLCAST_FLAG_RESTORE) {
		start -= std::min(start, 4000ul);
	}
	m_timcreation = start;
	
	m_duration = (m_launchDuration > -1) ? m_launchDuration : 800000;
	m_hasDuration = true;
	m_fManaCostPerSecond = 1.2f;
	
	Vec3f target;
	float beta = 0.f;
	bool displace = false;
	if(m_caster == PlayerEntityHandle) {
		target = entities.player()->pos;
		beta = player.angle.getPitch();
		displace = true;
	} else {
		if(ValidIONum(m_caster)) {
			Entity * io = entities[m_caster];
			target = io->pos;
			beta = io->angle.getPitch();
			displace = (io->ioflags & IO_NPC) == IO_NPC;
		} else {
			ARX_DEAD_CODE();
		}
	}
	if(displace) {
		target += angleToVectorXZ(beta) * 250.f;
	}
	
	ARX_SOUND_PlaySFX(SND_SPELL_CREATE_FIELD, &target);
	
	res::path cls = "graph/obj3d/interactive/fix_inter/blue_cube/blue_cube";
	Entity * io = AddFix(cls, -1, IO_IMMEDIATELOAD);
	if(io) {
		
		ARX_INTERACTIVE_HideGore(io);
		RestoreInitialIOStatusOfIO(io);
		m_entity = io->index();
		io->scriptload = 1;
		io->ioflags |= IO_NOSAVE | IO_FIELD;
		io->initpos = io->pos = target;
		SendInitScriptEvent(io);
		
		m_field.Create(target);
		m_field.SetDuration(m_duration);
		m_field.lLightId = GetFreeDynLight();
		
		if(lightHandleIsValid(m_field.lLightId)) {
			EERIE_LIGHT * light = lightHandleGet(m_field.lLightId);
			
			light->intensity = 0.7f + 2.3f;
			light->fallend = 500.f;
			light->fallstart = 400.f;
			light->rgb = Color3f(0.8f, 0.0f, 1.0f);
			light->pos = m_field.eSrc - Vec3f(0.f, 150.f, 0.f);
		}
		
		m_duration = m_field.GetDuration();
		
		if(m_flags & SPELLCAST_FLAG_RESTORE) {
			m_field.Update(4000);
		}
		
	} else {
		m_duration = 0;
	}
}
示例#6
0
void IceFieldSpell::Launch() {
	
	spells.endByCaster(m_caster, SPELL_ICE_FIELD);
	
	ARX_SOUND_PlaySFX(g_snd.SPELL_ICE_FIELD);
	
	m_duration = (m_launchDuration >= 0) ? m_launchDuration : GameDurationMs(100000);
	m_hasDuration = true;
	m_fManaCostPerSecond = 2.8f;
	m_light = LightHandle();
	
	Vec3f target;
	float beta;
	bool displace;
	if(m_caster == EntityHandle_Player) {
		target = player.basePosition();
		beta = player.angle.getYaw();
		displace = true;
	} else {
		Entity * io = entities.get(m_caster);
		arx_assert(io);
		target = io->pos;
		beta = io->angle.getYaw();
		displace = (io->ioflags & IO_NPC) == IO_NPC;
	}
	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 = GameDurationMs(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(0.f);
		tSizeMax[i] = arx::randomVec3f() + Vec3f(0.f, 0.2f, 0.f);
		
		Vec3f minPos = (tType[i] == 0) ? Vec3f(1.2f, 1.f, 1.2f) : 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_loop(g_snd.SPELL_ICE_FIELD_LOOP, &target, 1.f);
}
示例#7
0
void PoisonProjectileSpell::Launch() {
	
	ARX_SOUND_PlaySFX(g_snd.SPELL_POISON_PROJECTILE_LAUNCH,
	                  &m_caster_pos);
	
	Vec3f srcPos(0.f);
	float afBeta = 0.f;
	
	Entity * caster = entities[m_caster];
	m_hand_group = caster->obj->fastaccess.primary_attach;

	if(m_hand_group != ActionPoint()) {
		ActionPoint group = m_hand_group;
		m_hand_pos = actionPointPosition(caster->obj, group);
	}
	
	if(m_caster == EntityHandle_Player) {

		afBeta = player.angle.getYaw();

		if(m_hand_group != ActionPoint()) {
			srcPos = m_hand_pos;
		} else {
			srcPos = player.pos;
		}
	} else {
		afBeta = entities[m_caster]->angle.getYaw();

		if(m_hand_group != ActionPoint()) {
			srcPos = m_hand_pos;
		} else {
			srcPos = entities[m_caster]->pos;
		}
	}
	
	srcPos += angleToVectorXZ(afBeta) * 90.f;
	
	size_t uiNumber = glm::clamp(static_cast<unsigned int>(m_level), 1u, 5u);
	
	for(size_t i = 0; i < uiNumber; i++) {
		CPoisonProjectile * projectile = new CPoisonProjectile();
		
		m_projectiles.push_back(projectile);
	}
	
	m_duration = GameDurationMs(8000);
	m_hasDuration = true;
	
	GameDuration lMax = 0;
	
	for(size_t i = 0; i < m_projectiles.size(); i++) {
		CPoisonProjectile * projectile = m_projectiles[i];
		
		projectile->Create(srcPos, afBeta + Random::getf(-10.f, 10.f));
		GameDuration lTime = m_duration + GameDurationMs(Random::getu(0, 5000));
		projectile->SetDuration(lTime);
		lMax = std::max(lMax, lTime);
		
		EERIE_LIGHT * light = dynLightCreate(projectile->lLightId);
		if(light) {
			light->intensity = 2.3f;
			light->fallend = 250.f;
			light->fallstart = 150.f;
			light->rgb = Color3f::green;
			light->pos = projectile->eSrc;
			light->creationTime = g_gameTime.now();
			light->duration = GameDurationMs(200);
		}
	}
	
	m_duration = lMax + GameDurationMs(1000);
}
bool Manage3DCursor(Entity * io, bool simulate) {
	
	arx_assert(io);
	
	if(BLOCK_PLAYER_CONTROLS)
		return false;

	float ag = player.angle.getYaw();

	if(ag > 180)
		ag = ag - 360;

	float drop_miny = float(g_size.center().y) - float(g_size.center().y) * ag * (1.f/70);

	if(DANAEMouse.y < drop_miny)
		return false;
	
	Anglef temp = Anglef::ZERO;

	if(io->ioflags & IO_INVERTED) {
		temp.setYaw(180.f);
		temp.setPitch(-MAKEANGLE(270.f - io->angle.getPitch() - (player.angle.getPitch() - STARTED_ANGLE)));
	} else {
		temp.setPitch(MAKEANGLE(270.f - io->angle.getPitch() - (player.angle.getPitch() - STARTED_ANGLE)));
	}
	
	EERIE_3D_BBOX bbox;
	for(size_t i = 0; i < io->obj->vertexlist.size(); i++) {
		bbox.add(io->obj->vertexlist[i].v);
	}
	
	Vec3f mvectx = angleToVectorXZ(player.angle.getPitch() - 90.f);
	
	Vec2f mod = Vec2f(Vec2i(DANAEMouse) - g_size.center()) / Vec2f(g_size.center()) * Vec2f(160.f, 220.f);
	mvectx *= mod.x;
	Vec3f mvecty(0, mod.y, 0);

	Vec3f orgn = player.pos;
	orgn += angleToVector(player.angle) * 50.f;
	orgn += mvectx;
	orgn.y += mvecty.y;

	Vec3f dest = player.pos;
	dest += angleToVector(player.angle) * 10000.f;
	dest += mvectx;
	dest.y += mvecty.y * 5.f;
	
	Vec3f pos = orgn;

	Vec3f movev = glm::normalize(dest - orgn);

	float lastanything = 0.f;
	float height = -(bbox.max.y - bbox.min.y);

	if(height > -30.f)
		height = -30.f;
	
	Vec3f objcenter = bbox.min + (bbox.max - bbox.min) * Vec3f(0.5f);
	
	Vec3f collidpos = Vec3f_ZERO;
	bool collidpos_ok = false;
	
	{
	float maxdist = 0.f;
	
	for(size_t i = 0; i < io->obj->vertexlist.size(); i++) {
		const EERIE_VERTEX & vert = io->obj->vertexlist[i];
		
		float dist = glm::distance(Vec2f(objcenter.x, objcenter.z), Vec2f(vert.v.x, vert.v.z)) - 4.f;
		maxdist = std::max(maxdist, dist);
	}

	if(io->obj->pbox) {
		Vec2f tmpVert(io->obj->pbox->vert[0].initpos.x, io->obj->pbox->vert[0].initpos.z);
		
		for(int i = 1; i < io->obj->pbox->nb_physvert; i++) {
			const PHYSVERT & physVert = io->obj->pbox->vert[i];
			
			float dist = glm::distance(tmpVert, Vec2f(physVert.initpos.x, physVert.initpos.z)) + 14.f;
			maxdist = std::max(maxdist, dist);
		}
	}
	
	Cylinder cyl2 = Cylinder(Vec3f_ZERO, glm::clamp(maxdist, 20.f, 150.f), std::min(-30.f, height));
	
	const float inc = 10.f;
	long iterating = 40;
	
	while(iterating > 0) {
		cyl2.origin = pos + movev * inc + Vec3f(0.f, bbox.max.y, 0.f);

		float anything = CheckAnythingInCylinder(cyl2, io, CFLAG_JUST_TEST | CFLAG_COLLIDE_NOCOL | CFLAG_NO_NPC_COLLIDE);

		if(anything < 0.f) {
			if(iterating == 40) {
				CANNOT_PUT_IT_HERE = EntityMoveCursor_Invalid;
				// TODO is this correct ?
				return true;
			}

			iterating = 0;

			collidpos = cyl2.origin;

			if(lastanything < 0.f) {
				pos.y += lastanything;
				collidpos.y += lastanything;
			}
		} else {
			pos = cyl2.origin;
			lastanything = anything;
		}

		iterating--;
	}
	collidpos_ok = iterating == -1;
	
	}
	
	objcenter = VRotateY(objcenter, temp.getPitch());
	
	collidpos.x -= objcenter.x;
	collidpos.z -= objcenter.z;

	pos.x -= objcenter.x;
	pos.z -= objcenter.z;

	if(!collidpos_ok) {
		CANNOT_PUT_IT_HERE = EntityMoveCursor_Invalid;
		return false;
	}

	if(collidpos_ok && closerThan(player.pos, pos, 300.f)) {
		if(simulate) {
			ARX_INTERACTIVE_Teleport(io, pos, true);

			io->gameFlags &= ~GFLAG_NOCOMPUTATION;
			
			glm::quat rotation = glm::toQuat(toRotationMatrix(temp));
			
			if(SPECIAL_DRAGINTER_RENDER) {
			if(glm::abs(lastanything) > glm::abs(height)) {
				TransformInfo t(collidpos, rotation, io->scale);

				static const float invisibility = 0.5f;

				DrawEERIEInter(io->obj, t, io, false, invisibility);
			} else {
				TransformInfo t(pos, rotation, io->scale);

				float invisibility = Cedric_GetInvisibility(io);

				DrawEERIEInter(io->obj, t, io, false, invisibility);
			}
			}
		} else {
			if(glm::abs(lastanything) > std::min(glm::abs(height), 12.0f)) {
				Entity * io = DRAGINTER;
				ARX_PLAYER_Remove_Invisibility();
				io->obj->pbox->active = 1;
				io->obj->pbox->stopcount = 0;
				io->pos = collidpos;
				io->velocity = Vec3f_ZERO;

				io->stopped = 1;

				movev.x *= 0.0001f;
				movev.y = 0.1f;
				movev.z *= 0.0001f;
				Vec3f viewvector = movev;

				Anglef angle = temp;
				io->soundtime = 0;
				io->soundcount = 0;
				EERIE_PHYSICS_BOX_Launch(io->obj, io->pos, angle, viewvector);
				ARX_SOUND_PlaySFX(SND_WHOOSH, &pos);
				io->show = SHOW_FLAG_IN_SCENE;
				Set_DragInter(NULL);
			} else {
				ARX_PLAYER_Remove_Invisibility();
				ARX_SOUND_PlayInterface(SND_INVSTD);
				ARX_INTERACTIVE_Teleport(io, pos, true);

				io->angle.setYaw(temp.getYaw());
				io->angle.setPitch(270.f - temp.getPitch());
				io->angle.setRoll(temp.getRoll());

				io->stopped = 0;
				io->show = SHOW_FLAG_IN_SCENE;
				io->obj->pbox->active = 0;
				Set_DragInter(NULL);
			}
		}

		GRenderer->SetCulling(CullNone);
		return true;
	} else {
		CANNOT_PUT_IT_HERE = EntityMoveCursor_Throw;
	}

	return false;
}
示例#9
0
void AddFlare(const Vec2f & pos, float sm, short typ, Entity * io, bool bookDraw) {
	
	size_t oldest = 0;
	size_t i;
	for(i = 0; i < g_magicFlaresMax; i++) {
		if(!g_magicFlares[i].exist) {
			break;
		}
		if(g_magicFlares[i].tolive < g_magicFlares[oldest].tolive) {
			oldest = i;
		}
	}
	if(i >= g_magicFlaresMax) {
		removeFlare(g_magicFlares[oldest]);
		i = oldest;
	}

	MagicFlare & flare = g_magicFlares[i];
	flare.exist = 1;
	g_magicFlaresCount++;

	if(!bookDraw)
		flare.bDrawBitmap = 0;
	else
		flare.bDrawBitmap = 1;

	flare.io = io;
	if(io) {
		flare.flags = 1;
		io->flarecount++;
	} else {
		flare.flags = 0;
	}

	flare.pos.x = pos.x - Random::getf(0.f, 4.f);
	flare.pos.y = pos.y - Random::getf(0.f, 4.f) - 50.f;
	flare.tv.rhw = flare.v.rhw = 1.f;

	if(!bookDraw) {
		EERIE_CAMERA ka = *g_magicFlareCamera;
		ka.angle = Anglef(360.f, 360.f, 360.f) - ka.angle;
		EERIE_CAMERA * oldcam = ACTIVECAM;
		SetActiveCamera(&ka);
		PrepareCamera(&ka, g_size);
		flare.v.p += ka.orgTrans.pos;
		EE_RTP(flare.tv.p, flare.v);
		flare.v.p += ka.orgTrans.pos;

		float vx = -(flare.pos.x - subj.center.x) * 0.2173913f;
		float vy = (flare.pos.y - subj.center.y) * 0.1515151515151515f;
		if(io) {
			flare.v.p = io->pos;
			flare.v.p += angleToVectorXZ(io->angle.getYaw() + vx) * 100.f;
			flare.v.p.y += std::sin(glm::radians(MAKEANGLE(io->angle.getPitch() + vy))) * 100.f - 150.f;
		} else {
			flare.v.p.x = 1.0f  * float(pos.x - (g_size.width()  / 2)) * 156.f / (640.f * g_sizeRatio.y);
			flare.v.p.y = 0.75f * float(pos.y - (g_size.height() / 2)) * 156.f / (480.f * g_sizeRatio.y);
			flare.v.p.z = 75.f;
			ka = *oldcam;
			SetActiveCamera(&ka);
			PrepareCamera(&ka, g_size);
			float temp = (flare.v.p.y * -ka.orgTrans.xsin) + (flare.v.p.z * ka.orgTrans.xcos);
			flare.v.p.y = (flare.v.p.y * ka.orgTrans.xcos) - (-flare.v.p.z * ka.orgTrans.xsin);
			flare.v.p.z = (temp * ka.orgTrans.ycos) - (-flare.v.p.x * ka.orgTrans.ysin);
			flare.v.p.x = (temp * -ka.orgTrans.ysin) + (flare.v.p.x * ka.orgTrans.ycos);
			flare.v.p += oldcam->orgTrans.pos;
		}
		flare.tv.p = flare.v.p;
		SetActiveCamera(oldcam);
		PrepareCamera(oldcam, g_size);
	} else {
		flare.tv.p = Vec3f(flare.pos.x, flare.pos.y, 0.001f);
	}

	switch(g_magicFlareCurrentColor) {
		case 0: {
			flare.rgb = Color3f(.4f, 0.f, .4f) + Color3f(2.f/3, 2.f/3, 2.f/3) * randomColor3f();
			break;
		}
		case 1: {
			flare.rgb = Color3f(.5f, .5f, 0.f) + Color3f(.625f, .625f, .55f) * randomColor3f();
			break;
		}
		case 2: {
			flare.rgb = Color3f(.4f, 0.f, 0.f) + Color3f(2.f/3, .55f, .55f) * randomColor3f();
			break;
		}
	}
	
	static const float FLARE_MUL = 2.f;
	
	if(typ == -1) {
		float zz = eeMousePressed1() ? 0.29f : ((sm > 0.5f) ? Random::getf() : 1.f);
		if(zz < 0.2f) {
			flare.type = 2;
			flare.size = Random::getf(42.f, 84.f);
			flare.tolive = Random::getf(800.f, 1600.f) * FLARE_MUL;
		} else if(zz < 0.5f) {
			flare.type = 3;
			flare.size = Random::getf(16.f, 68.f);
			flare.tolive = Random::getf(800.f, 1600.f) * FLARE_MUL;
		} else {
			flare.type = 1;
			flare.size = Random::getf(32.f, 56.f) * sm;
			flare.tolive = Random::getf(1700.f, 2200.f) * FLARE_MUL;
		}
	} else {
		flare.type = (Random::getf() > 0.8f) ? 1 : 4;
		flare.size = Random::getf(64.f, 102.f) * sm;
		flare.tolive = Random::getf(1700.f, 2200.f) * FLARE_MUL;
	}

	flare.dynlight = LightHandle();

	for(unsigned int kk = 0; kk < 3; kk++) {

		if(Random::getf() < 0.5f) {
			continue;
		}

		PARTICLE_DEF * pd = createParticle();
		if(!pd) {
			break;
		}

		if(!bookDraw) {
			pd->m_flags = FADE_IN_AND_OUT | ROTATING | DISSIPATING;
			if(!io) {
				pd->m_flags |= PARTICLE_NOZBUFFER;
			}
		} else {
			pd->m_flags = FADE_IN_AND_OUT;
		}

		pd->ov = flare.v.p + randomVec(-5.f, 5.f);
		pd->move = Vec3f(0.f, 5.f, 0.f);
		pd->scale = Vec3f(-2.f);
		pd->tolive = 1300 + kk * 100 + Random::getu(0, 800);
		pd->tc = fire2;
		if(kk == 1) {
			pd->move.y = 4.f;
			pd->siz = 1.5f;
		} else {
			pd->siz = Random::getf(1.f, 2.f);
		}
		pd->rgb = Color3f(flare.rgb.r * (2.f/3), flare.rgb.g * (2.f/3), flare.rgb.b * (2.f/3));
		pd->m_rotation = 1.2f;

		if(bookDraw)
			pd->is2D = true;
	}
}