static Vec3f GetChestPos(EntityHandle num) {
	
	if(num == 0) {
		return player.pos + Vec3f(0.f, 70.f, 0.f);
	}

	if(ValidIONum(num)) {
		long idx = GetGroupOriginByName(entities[num]->obj, "chest");

		if(idx >= 0) {
			return entities[num]->obj->vertexlist3[idx].v;
		} else {
			return entities[num]->pos + Vec3f(0.f, -120.f, 0.f);
		}
	} else {
		// should not happen
		return Vec3f_ZERO;
	}
}
Example #2
0
static Vec3f GetChestPos(EntityHandle num) {
	
	if(num == EntityHandle_Player) {
		return player.pos + Vec3f(0.f, 70.f, 0.f);
	}
	
	Entity * io = entities.get(num);
	if(!io) {
		// should not happen
		return Vec3f(0.f);
	}
	
	ObjVertHandle idx = GetGroupOriginByName(io->obj, "chest");
	
	if(idx != ObjVertHandle()) {
		return io->obj->vertexWorldPositions[idx.handleData()].v;
	}
	
	return io->pos + Vec3f(0.f, -120.f, 0.f);
}
void LightningStrikeSpell::Update(float timeDelta) {
	
	float fBeta = 0.f;
	float falpha = 0.f;
	
	Entity * caster = entities[m_caster];
	long idx = GetGroupOriginByName(caster->obj, "chest");
	if(idx >= 0) {
		m_caster_pos = caster->obj->vertexlist3[idx].v;
	} else {
		m_caster_pos = caster->pos;
	}
	
	if(m_caster == PlayerEntityHandle) {
		falpha = -player.angle.getYaw();
		fBeta = player.angle.getPitch();
	} else {
		fBeta = caster->angle.getPitch();
		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(timeDelta);
	m_lightning.Render();
	
	ARX_SOUND_RefreshPosition(m_snd_loop, entities[m_caster]->pos);
}
Example #4
0
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->vertexWorldPositions[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)))));
		} 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)))));
		}
	}
	
	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(g_gameTime.lastFrameDuration());
	m_lightning.Render();
	
	ARX_SOUND_RefreshPosition(m_snd_loop, entities[m_caster]->pos);
}
Example #5
0
// Converts a Theo Object to an EERIE object
static EERIE_3DOBJ * TheoToEerie(const char * adr, long size, const res::path & texpath, const res::path & fic) {
	
	LogWarning << "TheoToEerie " << fic;
	
	if(!adr)
		return NULL;
	
	res::path txpath = texpath.empty() ? "graph/obj3d/textures" : texpath;
	
	if(size < 10) {
		return NULL;
	}
	
	size_t pos = 0;
	
	const THEO_HEADER * pth = reinterpret_cast<const THEO_HEADER *>(adr + pos);
	pos += sizeof(THEO_HEADER);
	
	if(pth->version < 3003 || pth->version > 3011) {
		LogError << "TheoToEerie: invalid version in " << fic << ": found " << pth->version
		         << " expected 3004 to 3011";
		return NULL;
	}
	
	EERIE_3DOBJ * eerie = new EERIE_3DOBJ;
	eerie->clear();
	
	eerie->file = fic;
	
	if(pth->type_write == 0) {
		// read the texture
		
		LogError <<  "WARNING object " << fic << " SAVE MAP IN OBJECT = INVALID... Using Dummy Textures...";
		
		eerie->texturecontainer.resize(pth->nb_maps);
		for(long i = 0; i < pth->nb_maps; i++) {
			pos += sizeof(THEO_TEXTURE);
			eerie->texturecontainer[i] = GetAnyTexture();
		}
		
	} else {
		
		if((pth->type_write & SAVE_MAP_BMP) || (pth->type_write & SAVE_MAP_TGA)) {
			
			eerie->texturecontainer.resize(pth->nb_maps);
			for(long i = 0; i < pth->nb_maps; i++) {
				
				res::path name;
				if(pth->version >= 3008) {
					const THEO_SAVE_MAPS_IN_3019 * tsmi3019 = reinterpret_cast<const THEO_SAVE_MAPS_IN_3019 *>(adr + pos);
					pos += sizeof(THEO_SAVE_MAPS_IN_3019);
					name = res::path::load(util::loadString(tsmi3019->texture_name)).remove_ext();
				} else {
					const THEO_SAVE_MAPS_IN * tsmi = reinterpret_cast<const THEO_SAVE_MAPS_IN *>(adr + pos);
					pos += sizeof(THEO_SAVE_MAPS_IN);
					name = res::path::load(util::loadString(tsmi->texture_name)).remove_ext();
				}
				
				if(!name.empty()) {
					eerie->texturecontainer[i] = TextureContainer::Load(txpath / name, TextureContainer::Level);
				}
			}
		}
	}
	
	pos = pth->object_seek;
	loadObjectData(eerie, adr, &pos, pth->version);
	eerie->angle = Anglef::ZERO;
	eerie->pos = Vec3f_ZERO;

	// NORMALS CALCULATIONS

	//Compute Faces Areas
	for(size_t i = 0; i < eerie->facelist.size(); i++) {
		const Vec3f & p0 = eerie->vertexlist[eerie->facelist[i].vid[0]].v;
		const Vec3f & p1 = eerie->vertexlist[eerie->facelist[i].vid[1]].v;
		const Vec3f & p2 = eerie->vertexlist[eerie->facelist[i].vid[2]].v;
		eerie->facelist[i].temp = glm::distance((p0 + p1) * .5f, p2) * glm::distance(p0, p1) * .5f;
	}

	for(size_t i = 0; i < eerie->facelist.size(); i++) {
		CalcObjFaceNormal(
		    &eerie->vertexlist[eerie->facelist[i].vid[0]].v,
		    &eerie->vertexlist[eerie->facelist[i].vid[1]].v,
		    &eerie->vertexlist[eerie->facelist[i].vid[2]].v,
		    &eerie->facelist[i]
		);
		float area = eerie->facelist[i].temp;

		for(long j = 0; j < 3; j++) {
			float mod = area * area;
			Vec3f nrml = eerie->facelist[i].norm * mod;
			float count = mod;

			for(size_t i2 = 0; i2 < eerie->facelist.size(); i2++) {
				if(i != i2) {
					float area2 = eerie->facelist[i].temp;

					for(long j2 = 0; j2 < 3; j2++) {
						if(closerThan(eerie->vertexlist[eerie->facelist[i2].vid[j2]].v, eerie->vertexlist[eerie->facelist[i].vid[j]].v, .1f)) {
							mod = (area2 * area2);
							nrml += eerie->facelist[i2].norm * mod;
							count += mod; 
						}
					}
				}
			}

			count = 1.f / count;
			eerie->vertexlist[eerie->facelist[i].vid[j]].vert.p = nrml * count;
		}
	}

	for(size_t i = 0; i < eerie->facelist.size(); i++) {
		for(long j = 0; j < 3; j++) {
			eerie->vertexlist[eerie->facelist[i].vid[j]].norm = eerie->vertexlist[eerie->facelist[i].vid[j]].vert.p;
		}
	}

	// Apply Normals Spherical correction for NPC head
	long neck_orgn = GetGroupOriginByName(eerie, "neck");
	long head_idx = EERIE_OBJECT_GetGroup(eerie, "head");

	if(head_idx >= 0 && neck_orgn >= 0) {
		VertexGroup & headGroup = eerie->grouplist[head_idx];
		
		Vec3f center = Vec3f_ZERO;
		Vec3f origin = eerie->vertexlist[neck_orgn].v;
		float count = (float)headGroup.indexes.size();

		if(count > 0.f) {
			for(size_t idx = 0 ; idx < headGroup.indexes.size(); idx++) {
				center += eerie->vertexlist[ headGroup.indexes[idx] ].v;
			}
			
			center = (center * (1.f / count) + origin + origin) * (1.0f / 3);
			float max_threshold = glm::distance(origin, center);
			
			for(size_t i = 0; i < headGroup.indexes.size(); i++) {
				EERIE_VERTEX * ev = &eerie->vertexlist[headGroup.indexes[i]];
				float d = glm::distance(ev->v, origin);
				float factor = 1.f;

				if(d < max_threshold) {
					factor = d / max_threshold;
				}

				float ifactor = 1.f - factor;
				Vec3f fakenorm;
				fakenorm = ev->v - center;
				fakenorm = glm::normalize(fakenorm);
				ev->norm = ev->norm * ifactor + fakenorm * factor;
				ev->norm = glm::normalize(ev->norm);
			}
		}
	}

	// NORMALS CALCULATIONS END
	//***********************************************************
	
	eerie->m_skeleton = NULL;
	EERIE_CreateCedricData(eerie);
	return eerie;
}
Example #6
0
//-----------------------------------------------------------------------------
void CFireBall::Update(unsigned long aulTime)
{
	ulCurrentTime += aulTime;

	if(ulCurrentTime > MIN_TIME_FIREBALL) {
		// smoke en retard
		pPSSmoke.SetPos(eCurPos);
		pPSSmoke.Update(aulTime);
		eCurPos += eMove * (aulTime * 0.0045f);
		pPSFire.SetPos(eCurPos);
		pPSFire.fParticleSpeed = 100;
		pPSFire.fParticleSpeedRandom = 200;
		pPSFire.p3ParticleGravity = -eMove * 2.f;
		pPSFire2.p3ParticleGravity = -eMove * 2.f;
		pPSFire2.SetPos(eCurPos);
		pPSFire2.fParticleSpeed = 100;
		pPSFire2.fParticleSpeedRandom = 100;
	}
	else
	{
		float afAlpha = 0.f;
	
		if (spells[spellinstance].caster == 0)
		{
			SetAngle(player.angle.b);
			afAlpha = player.angle.a;
			long idx = GetGroupOriginByName(entities[spells[spellinstance].caster]->obj, "chest");

			if (idx)
			{
				eCurPos.x = entities[spells[spellinstance].caster]->obj->vertexlist3[idx].v.x - fBetaRadSin * 60;
				eCurPos.y = entities[spells[spellinstance].caster]->obj->vertexlist3[idx].v.y;
				eCurPos.z = entities[spells[spellinstance].caster]->obj->vertexlist3[idx].v.z + fBetaRadCos * 60;
			}
			else
			{
				eCurPos.x = player.pos.x - fBetaRadSin * 60;
				eCurPos.y = player.pos.y;
				eCurPos.z = player.pos.z + fBetaRadCos * 60;
			}
		}
		else
		{
			SetAngle(entities[spells[spellinstance].caster]->angle.b);

			eCurPos.x = entities[spells[spellinstance].caster]->pos.x - fBetaRadSin * 60;
			eCurPos.y = entities[spells[spellinstance].caster]->pos.y;
			eCurPos.z = entities[spells[spellinstance].caster]->pos.z + fBetaRadCos * 60;

			if ((ValidIONum(spells[spellinstance].caster))
			        && (entities[spells[spellinstance].caster]->ioflags & IO_NPC))
			{
				eCurPos.x -= EEsin(radians(entities[spells[spellinstance].caster]->angle.b)) * 30.f;
				eCurPos.y -= 80.f;
				eCurPos.z += EEcos(radians(entities[spells[spellinstance].caster]->angle.b)) * 30.f;
			}
			
			Entity * io = entities[spells[spellinstance].caster];

			if (ValidIONum(io->targetinfo))
			{
				Vec3f * p1 = &eCurPos;
				Vec3f p2 = entities[io->targetinfo]->pos;
				p2.y -= 60.f;
				afAlpha = 360.f - (degrees(getAngle(p1->y, p1->z, p2.y, p2.z + dist(Vec2f(p2.x, p2.z), Vec2f(p1->x, p1->z))))); //alpha entre orgn et dest;
			}
		}


		eMove.x = - fBetaRadSin * 100 * cos(radians(MAKEANGLE(afAlpha)));
		eMove.y = sin(radians(MAKEANGLE(afAlpha))) * 100;
		eMove.z = + fBetaRadCos * 100 * cos(radians(MAKEANGLE(afAlpha)));

		Vec3f vMove = eMove.getNormalized();

		// smoke en retard
		pPSSmoke.p3ParticleDirection = -vMove;
		pPSSmoke.SetPos(eCurPos);
		pPSSmoke.RecomputeDirection();
		eCurPos = eCurPos + eMove * (aulTime * 0.0045f);
		pPSFire.p3ParticleDirection = -vMove;
		pPSFire.RecomputeDirection();
		pPSFire.SetPos(eCurPos);
		pPSFire.p3ParticleGravity = -eMove * 2.f;
		pPSFire2.p3ParticleDirection = -vMove;
		pPSFire2.p3ParticleGravity = -eMove * 2.f;
		pPSFire2.RecomputeDirection();
		pPSFire2.SetPos(eCurPos);
	}
	
	pPSFire.Update(aulTime);
	pPSFire2.Update(aulTime);
}