Ejemplo n.º 1
0
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);
	}
}
Ejemplo n.º 2
0
static ActionPoint GetActionPoint(const EERIE_3DOBJ * obj, const char * name) {
	
	if(!obj)
		return ActionPoint();
	
	BOOST_FOREACH(const EERIE_ACTIONLIST & act, obj->actionlist) {
		if(act.name == name) {
			return act.idx;
		}
	}

	return ActionPoint();
}
Ejemplo n.º 3
0
ActionPoint GetActionPointIdx(const EERIE_3DOBJ * eobj, const std::string & text) {
	
	if(!eobj)
		return ActionPoint();
	
	BOOST_FOREACH(const EERIE_ACTIONLIST & action, eobj->actionlist) {
		if(action.name == text) {
			return action.idx;
		}
	}
	
	return ActionPoint();
}
Ejemplo n.º 4
0
void SpellBase::updateCasterHand() {
	
	// Create hand position if a hand is defined
	if(m_caster == EntityHandle_Player) {
		m_hand_group = entities[m_caster]->obj->fastaccess.primary_attach;
	} else {
		m_hand_group = entities[m_caster]->obj->fastaccess.left_attach;
	}
	
	if(m_hand_group != ActionPoint()) {
		m_hand_pos = actionPointPosition(entities[m_caster]->obj, m_hand_group);
	}
}
Ejemplo n.º 5
0
static void ObjectAddAction(EERIE_3DOBJ * obj, const std::string & name, long act,
                            long sfx, const EERIE_VERTEX * vert) {
	
	size_t newvert = ObjectAddVertex(obj, vert);
	
	for(std::vector<EERIE_ACTIONLIST>::iterator i = obj->actionlist.begin();
	    i != obj->actionlist.end(); ++i) {
		if(i->name == name) {
			return;
		}
	}
	
	obj->actionlist.push_back(EERIE_ACTIONLIST());
	
	EERIE_ACTIONLIST & action = obj->actionlist.back();
	
	action.name = name;
	action.act = act;
	action.sfx = sfx;
	action.idx = ActionPoint(newvert);
}
Ejemplo n.º 6
0
static EERIE_3DOBJ * CreateIntermediaryMesh(const EERIE_3DOBJ * obj1, const EERIE_3DOBJ * obj2, long tw) {
	
	ObjSelection tw1 = ObjSelection();
	ObjSelection tw2 = ObjSelection();
	ObjSelection iw1 = ObjSelection();
	ObjSelection jw1 = ObjSelection();
	ObjSelection sel_head1 = ObjSelection();
	ObjSelection sel_head2 = ObjSelection();
	ObjSelection sel_torso1 = ObjSelection();
	ObjSelection sel_torso2 = ObjSelection();
	ObjSelection sel_legs1 = ObjSelection();
	ObjSelection sel_legs2 = ObjSelection();

	// First we retreive selection groups indexes
	for(size_t i = 0; i < obj1->selections.size(); i++) { // TODO iterator
		ObjSelection sel = ObjSelection(i);
		
		if(obj1->selections[i].name == "head") {
			sel_head1 = sel;
		} else if(obj1->selections[i].name == "chest") {
			sel_torso1 = sel;
		} else if(obj1->selections[i].name == "leggings") {
			sel_legs1 = sel;
		}
	}

	for(size_t i = 0; i < obj2->selections.size(); i++) { // TODO iterator
		ObjSelection sel = ObjSelection(i);
		
		if(obj2->selections[i].name == "head") {
			sel_head2 = sel;
		} else if(obj2->selections[i].name == "chest") {
			sel_torso2 = sel;
		} else if(obj2->selections[i].name == "leggings") {
			sel_legs2 = sel;
		}
	}

	if(sel_head1 == ObjSelection()) return NULL;

	if(sel_head2 == ObjSelection()) return NULL;

	if(sel_torso1 == ObjSelection()) return NULL;

	if(sel_torso2 == ObjSelection()) return NULL;

	if(sel_legs1 == ObjSelection()) return NULL;

	if(sel_legs2 == ObjSelection()) return NULL;

	if(tw == TWEAK_HEAD) {
		tw1 = sel_head1;
		tw2 = sel_head2;
		iw1 = sel_torso1;
		jw1 = sel_legs1;
	}

	if(tw == TWEAK_TORSO) {
		tw1 = sel_torso1;
		tw2 = sel_torso2;
		iw1 = sel_head1;
		jw1 = sel_legs1;
	}

	if(tw == TWEAK_LEGS) {
		tw1 = sel_legs1;
		tw2 = sel_legs2;
		iw1 = sel_torso1;
		jw1 = sel_head1;
	}

	if(tw1 == ObjSelection() || tw2 == ObjSelection())
		return NULL;

	// Now Retreives Tweak Action Points
	{
		ActionPoint idx_head1 = GetActionPoint(obj1, "head2chest");
		if(idx_head1 == ActionPoint())
			return NULL;

		ActionPoint idx_head2 = GetActionPoint(obj2, "head2chest");
		if(idx_head2 == ActionPoint())
			return NULL;

		ActionPoint idx_torso1 = GetActionPoint(obj1, "chest2leggings");
		if(idx_torso1 == ActionPoint())
			return NULL;

		ActionPoint idx_torso2 = GetActionPoint(obj2, "chest2leggings");
		if(idx_torso2 == ActionPoint())
			return NULL;
	}

	// copy vertices
	std::vector<EERIE_VERTEX> obj1vertexlist2 = obj1->vertexlist;
	std::vector<EERIE_VERTEX> obj2vertexlist2 = obj2->vertexlist;

	// Work will contain the Tweaked object
	EERIE_3DOBJ * work = new EERIE_3DOBJ;
	work->pos = obj1->pos;
	work->angle = obj1->angle;
	
	// We reset all data to create a fresh object
	work->cub = obj1->cub;
	work->quat = obj1->quat;
	
	// Linked objects are linked to this object.
	if(obj1->linked.size() > obj2->linked.size()) {
		work->linked = obj1->linked;
	} else {
		work->linked = obj2->linked;
	}
	
	// Is the origin of object in obj1 or obj2 ? Retreives it for work object
	if(IsInSelection(obj1, obj1->origin, tw1)) {
		work->point0 = obj2->point0;
		work->origin = ObjectAddVertex(work, &obj2vertexlist2[obj2->origin]);
	} else {
		work->point0 = obj1->point0;
		work->origin = ObjectAddVertex(work, &obj1vertexlist2[obj1->origin]);
	}

	// Recreate Action Points included in work object.for Obj1
	for(size_t i = 0; i < obj1->actionlist.size(); i++) {
		const EERIE_ACTIONLIST & action = obj1->actionlist[i];

		if(   IsInSelection(obj1, action.idx.handleData(), iw1)
		   || IsInSelection(obj1, action.idx.handleData(), jw1)
		   || action.name == "head2chest"
		   || action.name == "chest2leggings"
		) {
			ObjectAddAction(work, action.name, action.act, action.sfx, &obj1vertexlist2[action.idx.handleData()]);
		}
	}

	// Do the same for Obj2
	for(size_t i = 0; i < obj2->actionlist.size(); i++) {
		const EERIE_ACTIONLIST & action = obj2->actionlist[i];

		if(   IsInSelection(obj2, action.idx.handleData(), tw2)
		   || action.name == "head2chest"
		   || action.name == "chest2leggings"
		) {
			ObjectAddAction(work, action.name, action.act, action.sfx, &obj2vertexlist2[action.idx.handleData()]);
		}
	}

	// Recreate Vertex using Obj1 Vertexes
	for(size_t i = 0; i < obj1->vertexlist.size(); i++) {
		if(IsInSelection(obj1, i, iw1) || IsInSelection(obj1, i, jw1)) {
			ObjectAddVertex(work, &obj1vertexlist2[i]);
		}
	}

	// The same for Obj2
	for(size_t i = 0; i < obj2->vertexlist.size(); i++) {
		if(IsInSelection(obj2, i, tw2)) {
			ObjectAddVertex(work, &obj2vertexlist2[i]);
		}
	}


	// Look in Faces for forgotten Vertexes... AND
	// Re-Create TextureContainers Infos
	// We look for texturecontainers included in the future tweaked object
	TextureContainer * tc = NULL;

	for(size_t i = 0; i < obj1->facelist.size(); i++) {
		const EERIE_FACE & face = obj1->facelist[i];

		if(   (IsInSelection(obj1, face.vid[0], iw1) || IsInSelection(obj1, face.vid[0], jw1))
		   && (IsInSelection(obj1, face.vid[1], iw1) || IsInSelection(obj1, face.vid[1], jw1))
		   && (IsInSelection(obj1, face.vid[2], iw1) || IsInSelection(obj1, face.vid[2], jw1))
		) {
			if(face.texid != -1) {
				if(tc != obj1->texturecontainer[face.texid]) {
					tc = obj1->texturecontainer[face.texid];
					ObjectAddMap(work, tc);
				}
			}

			ObjectAddFace(work, &face, obj1);
		}
	}

	for(size_t i = 0; i < obj2->facelist.size(); i++) {
		const EERIE_FACE & face = obj2->facelist[i];

		if(   IsInSelection(obj2, face.vid[0], tw2)
		   || IsInSelection(obj2, face.vid[1], tw2)
		   || IsInSelection(obj2, face.vid[2], tw2)
		) {

			if(face.texid != -1) {
				if(tc != obj2->texturecontainer[face.texid]) {
					tc = obj2->texturecontainer[face.texid];
					ObjectAddMap(work, tc);
				}
			}

			ObjectAddFace(work, &face, obj2);
		}
	}

	// Recreate Groups
	work->grouplist.resize(std::max(obj1->grouplist.size(), obj2->grouplist.size()));

	for(size_t k = 0; k < obj1->grouplist.size(); k++) {
		const VertexGroup & grp = obj1->grouplist[k];
		
		work->grouplist[k].name = grp.name;
		long v = GetEquivalentVertex(work, &obj1vertexlist2[grp.origin]);

		if(v >= 0) {
			work->grouplist[k].siz = grp.siz;

			if(IsInSelection(obj1, grp.origin, iw1)
			        || IsInSelection(obj1, grp.origin, jw1))
				work->grouplist[k].origin = v;
		}
	}

	for(size_t k = 0; k < obj2->grouplist.size(); k++) {
		if(k >= obj1->grouplist.size()) {
			work->grouplist[k].name = obj2->grouplist[k].name;
		}

		long v = GetEquivalentVertex(work, &obj2vertexlist2[obj2->grouplist[k].origin]);

		if(v >= 0) {
			work->grouplist[k].siz = obj2->grouplist[k].siz;

			if(IsInSelection(obj2, obj2->grouplist[k].origin, tw2))
				work->grouplist[k].origin = v;
		}
	}

	// Recreate Selection Groups (only the 3 selections needed to reiterate MeshTweaking !)
	work->selections.resize(3);
	work->selections[0].name = "head";
	work->selections[1].name = "chest";
	work->selections[2].name = "leggings";

	// Re-Creating sel_head
	if(tw == TWEAK_HEAD) {
		const EERIE_SELECTIONS & sel = obj2->selections[sel_head2.handleData()];
		
		for(size_t l = 0; l < sel.selected.size(); l++) {
			EERIE_VERTEX temp;
			temp.v = obj2vertexlist2[sel.selected[l]].v;
			long t = GetEquivalentVertex(work, &temp);

			if(t != -1) {
				ObjectAddSelection(work, 0, t);
			}
		}
	} else {
		const EERIE_SELECTIONS & sel = obj1->selections[sel_head1.handleData()];
		
		for(size_t l = 0; l < sel.selected.size(); l++) {
			EERIE_VERTEX temp;
			temp.v = obj1vertexlist2[sel.selected[l]].v;
			long t = GetEquivalentVertex(work, &temp);

			if(t != -1) {
				ObjectAddSelection(work, 0, t);
			}
		}
	}

	// Re-Create sel_torso
	if(tw == TWEAK_TORSO) {
		const EERIE_SELECTIONS & sel = obj2->selections[sel_torso2.handleData()];
		
		for(size_t l = 0; l < sel.selected.size(); l++) {
			EERIE_VERTEX temp;
			temp.v = obj2vertexlist2[sel.selected[l]].v;
			long t = GetEquivalentVertex(work, &temp);

			if(t != -1) {
				ObjectAddSelection(work, 1, t);
			}
		}
	} else {
		const EERIE_SELECTIONS & sel = obj1->selections[sel_torso1.handleData()];
		
		for(size_t l = 0; l < sel.selected.size(); l++) {
			EERIE_VERTEX temp;
			temp.v = obj1vertexlist2[sel.selected[l]].v;
			long t = GetEquivalentVertex(work, &temp);

			if(t != -1) {
				ObjectAddSelection(work, 1, t);
			}
		}
	}

	// Re-Create sel_legs
	if(tw == TWEAK_LEGS) {
		const EERIE_SELECTIONS & sel = obj2->selections[sel_legs2.handleData()];
		
		for(size_t l = 0; l < sel.selected.size(); l++) {
			EERIE_VERTEX temp;
			temp.v = obj2vertexlist2[sel.selected[l]].v;
			long t = GetEquivalentVertex(work, &temp);

			if(t != -1) {
				ObjectAddSelection(work, 2, t);
			}
		}
	} else {
		const EERIE_SELECTIONS & sel = obj1->selections[sel_legs1.handleData()];
		
		for(size_t l = 0; l < sel.selected.size(); l++) {
			EERIE_VERTEX temp;
			temp.v = obj1vertexlist2[sel.selected[l]].v;
			long t = GetEquivalentVertex(work, &temp);

			if(t != -1) {
				ObjectAddSelection(work, 2, t);
			}
		}
	}

	//Now recreates other selections...
	for(size_t i = 0; i < obj1->selections.size(); i++) {
		
		if(EERIE_OBJECT_GetSelection(work, obj1->selections[i].name) == ObjSelection()) {
			size_t num = work->selections.size();
			work->selections.resize(num + 1);
			work->selections[num].name = obj1->selections[i].name;

			for(size_t l = 0; l < obj1->selections[i].selected.size(); l++) {
				EERIE_VERTEX temp;
				temp.v = obj1vertexlist2[obj1->selections[i].selected[l]].v;
				long t = GetEquivalentVertex(work, &temp);

				if (t != -1)
				{
					ObjectAddSelection(work, num, t);
				}
			}

			ObjSelection ii = EERIE_OBJECT_GetSelection(obj2, obj1->selections[i].name);

			if(ii != ObjSelection()) {
				const EERIE_SELECTIONS & sel = obj2->selections[ii.handleData()];
				
				for(size_t l = 0; l < sel.selected.size(); l++) {
					EERIE_VERTEX temp;
					temp.v = obj2vertexlist2[sel.selected[l]].v;
					long t = GetEquivalentVertex(work, &temp);

					if(t != -1) {
						ObjectAddSelection(work, num, t);
					}
				}
			}
		}
	}

	for(size_t i = 0; i < obj2->selections.size(); i++) {
		if(EERIE_OBJECT_GetSelection(work, obj2->selections[i].name) == ObjSelection()) {
			size_t num = work->selections.size();
			work->selections.resize(num + 1);
			work->selections[num].name = obj2->selections[i].name;

			for(size_t l = 0; l < obj2->selections[i].selected.size(); l++) {
				EERIE_VERTEX temp;
				temp.v = obj2vertexlist2[obj2->selections[i].selected[l]].v;
				long t = GetEquivalentVertex(work, &temp);

				if(t != -1) {
					ObjectAddSelection(work, num, t);
				}
			}
		}
	}

	// Recreate Animation-groups vertex
	for(size_t i = 0; i < obj1->grouplist.size(); i++) {
		for(size_t j = 0; j < obj1->grouplist[i].indexes.size(); j++) {
			AddVertexToGroup(work, i, &obj1vertexlist2[obj1->grouplist[i].indexes[j]]);
		}
	}

	for(size_t i = 0; i < obj2->grouplist.size(); i++) {
		for(size_t j = 0; j < obj2->grouplist[i].indexes.size(); j++) {
			AddVertexToGroup(work, i, &obj2vertexlist2[obj2->grouplist[i].indexes[j]]);
		}
	}
	
	work->vertexWorldPositions.resize(work->vertexlist.size());
	work->vertexClipPositions.resize(work->vertexlist.size());
	work->vertexColors.resize(work->vertexlist.size());
	
	return work;
}
Ejemplo n.º 7
0
void FlyingEyeSpell::Update(float timeDelta)
{
	ARX_UNUSED(timeDelta);
	
	const unsigned long tim = (unsigned long)(arxtime);
	
	const long framediff3 = tim - m_lastupdate;
	
	eyeball.floating = std::sin(m_lastupdate-m_timcreation * 0.001f);
	eyeball.floating *= 10.f;
	
	if(m_lastupdate-m_timcreation <= 3000) {
		eyeball.exist = m_lastupdate - m_timcreation * (1.0f / 30);
		eyeball.size = Vec3f(1.f - float(eyeball.exist) * 0.01f);
		eyeball.angle.setPitch(eyeball.angle.getPitch() + framediff3 * 0.6f);
	} else {
		eyeball.exist = 2;
	}
	
	m_lastupdate=tim;
	
	Entity * io = entities.player();
	EERIE_3DOBJ * eobj = io->obj;
	long pouet = 2;

	while(pouet) {
		ActionPoint id;

		if(pouet == 2)
			id = io->obj->fastaccess.primary_attach;
		else
			id = GetActionPointIdx(io->obj, "left_attach");

		pouet--;

		if(id != ActionPoint()) {
			if(!lightHandleIsValid(special[pouet])) {
				special[pouet] = GetFreeDynLight();
			}
			if(lightHandleIsValid(special[pouet])) {
				EERIE_LIGHT * el = lightHandleGet(special[pouet]);
				el->intensity = 1.3f;
				el->fallend = 180.f;
				el->fallstart = 50.f;
				el->rgb = Color3f(0.7f, 0.3f, 1.f);
				el->pos = actionPointPosition(eobj, id);
			}
			
			for(long kk = 0; kk < 2; kk++) {
				
				PARTICLE_DEF * pd = createParticle();
				if(!pd) {
					break;
				}
				
				pd->ov = actionPointPosition(eobj, id) + randomVec(-1.f, 1.f);
				pd->move = Vec3f(0.1f, 0.f, 0.1f) + Vec3f(-0.2f, -2.2f, -0.2f) * randomVec3f();
				pd->siz = 5.f;
				pd->tolive = Random::get(1500, 3500);
				pd->scale = Vec3f(0.2f);
				pd->tc = TC_smoke;
				pd->special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING;
				pd->sourceionum = PlayerEntityHandle;
				pd->source = &eobj->vertexlist3[id.handleData()].v; // FIXME passing of pointer to vertex position
				pd->fparam = 0.0000001f;
				pd->rgb = Color3f(.7f, .3f, 1.f) + Color3f(-.1f, -.1f, -.1f) * randomColor3f();
			}
		}
	}
}
Ejemplo n.º 8
0
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;
		}
	}
}
Ejemplo n.º 9
0
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;
			}
		}
	}
}
Ejemplo n.º 10
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);
}
Ejemplo n.º 11
0
static void loadObjectData(EERIE_3DOBJ * eerie, const char * adr, size_t * poss, long version) {
	
	LogWarning << "loadObjectData";
	
	size_t pos = *poss;
	
	const THEO_OFFSETS * to = reinterpret_cast<const THEO_OFFSETS *>(adr + pos);
	pos += sizeof(THEO_OFFSETS);
	
	const THEO_NB * tn = reinterpret_cast<const THEO_NB *>(adr + pos);
	
	LogDebug("Nb Vertex " << tn->nb_vertex << " Nb Action Points " << tn->nb_action_point
	         << " Nb Lines " << tn->nb_lines);
	LogDebug("Nb Faces " << tn->nb_faces << " Nb Groups " << tn->nb_groups);
	
	eerie->vertexlist.resize(tn->nb_vertex);
	eerie->vertexlist3.resize(tn->nb_vertex);
	
	eerie->facelist.resize(tn->nb_faces);
	eerie->grouplist.resize(tn->nb_groups);
	eerie->actionlist.resize(tn->nb_action_point);
	
	eerie->ndata = NULL;
	eerie->pdata = NULL;
	eerie->cdata = NULL;
	eerie->sdata = NULL;
	
	// read vertices
	
	pos = to->vertex_seek;
	
	if(tn->nb_vertex > 65535) {
		LogError << ("Warning Vertex Number Too High...");
	}
	
	for(long i = 0; i < tn->nb_vertex; i++) {
		const THEO_VERTEX * ptv = reinterpret_cast<const THEO_VERTEX *>(adr + pos);
		pos += sizeof(THEO_VERTEX);
		eerie->vertexlist[i].v = ptv->pos.toVec3();
		eerie->cub.xmin = std::min(eerie->cub.xmin, ptv->pos.x);
		eerie->cub.xmax = std::max(eerie->cub.xmax, ptv->pos.x);
		eerie->cub.ymin = std::min(eerie->cub.ymin, ptv->pos.y);
		eerie->cub.ymax = std::max(eerie->cub.ymax, ptv->pos.y);
		eerie->cub.zmin = std::min(eerie->cub.zmin, ptv->pos.z);
		eerie->cub.zmax = std::max(eerie->cub.zmax, ptv->pos.z);
	}

	// Lecture des FACES THEO
	pos = to->faces_seek;

	for(size_t i = 0; i < size_t(tn->nb_faces); i++) {
		
		THEO_FACES_3006 tf3006;
		const THEO_FACES_3006 * ptf3006;
		if(version >= 3006) {
			ptf3006 = reinterpret_cast<const THEO_FACES_3006 *>(adr + pos);
			pos += sizeof(THEO_FACES_3006);
		} else {
			memset(&tf3006, 0, sizeof(THEO_FACES_3006));
			const THEO_FACES * ptf = reinterpret_cast<const THEO_FACES *>(adr + pos);
			pos += sizeof(THEO_FACES);
			tf3006.color = ptf->color;
			tf3006.index1 = ptf->index1;
			tf3006.index2 = ptf->index2;
			tf3006.index3 = ptf->index3;
			tf3006.ismap = ptf->ismap;
			tf3006.liste_uv = ptf->liste_uv;
			tf3006.element_uv = ptf->element_uv;
			tf3006.num_map = ptf->num_map;
			tf3006.tile_x = ptf->tile_x;
			tf3006.tile_y = ptf->tile_y;
			tf3006.user_tile_x = ptf->user_tile_x;
			tf3006.user_tile_y = ptf->user_tile_y;
			tf3006.flag = ptf->flag;
			tf3006.collision_type = ptf->collision_type;
			tf3006.rgb = ptf->rgb;
			tf3006.rgb1 = ptf->rgb1;
			tf3006.rgb2 = ptf->rgb2;
			tf3006.rgb3 = ptf->rgb3;
			tf3006.double_side = ptf->double_side;
			tf3006.transparency = ptf->transparency;
			tf3006.trans = ptf->trans;
			ptf3006 = &tf3006;
		}
		
		eerie->facelist[i].vid[0] = (unsigned short)ptf3006->index1;
		eerie->facelist[i].vid[1] = (unsigned short)ptf3006->index2;
		eerie->facelist[i].vid[2] = (unsigned short)ptf3006->index3;
		
		s32 num_map = ((size_t)ptf3006->num_map >= eerie->texturecontainer.size()) ? -1 : ptf3006->num_map;
		
		if(ptf3006->ismap) {
			eerie->facelist[i].texid = (short)num_map;
			eerie->facelist[i].facetype = POLY_NO_SHADOW;
			
			if(num_map >= 0 && eerie->texturecontainer[num_map] && (eerie->texturecontainer[num_map]->userflags & POLY_NOCOL)) {
				eerie->facelist[i].facetype |= POLY_NOCOL;
			}
		} else {
			eerie->facelist[i].texid = -1;
		}
		
		switch(ptf3006->flag) {
			case 0:
				eerie->facelist[i].facetype |= POLY_GLOW;
				break;
			case 1:
				eerie->facelist[i].facetype |= POLY_NO_SHADOW;
				break;
			case 4:
				eerie->facelist[i].facetype |= POLY_METAL;
				break;
			case 10:
				eerie->facelist[i].facetype |= POLY_NOPATH;
				break;
			case 11:
				eerie->facelist[i].facetype |= POLY_CLIMB;
				break;
			case 12:
				eerie->facelist[i].facetype |= POLY_NOCOL;
				break;
			case 13:
				eerie->facelist[i].facetype |= POLY_NODRAW;
				break;
			case 14:
				eerie->facelist[i].facetype |= POLY_PRECISE_PATH;
				break;
			case 16:
				eerie->facelist[i].facetype |= POLY_NO_CLIMB;
				break;
		}
		
		eerie->facelist[i].ou[0] = (short)ptf3006->liste_uv.u1;
		eerie->facelist[i].ov[0] = (short)ptf3006->liste_uv.v1;
		eerie->facelist[i].ou[1] = (short)ptf3006->liste_uv.u2;
		eerie->facelist[i].ov[1] = (short)ptf3006->liste_uv.v2;
		eerie->facelist[i].ou[2] = (short)ptf3006->liste_uv.u3;
		eerie->facelist[i].ov[2] = (short)ptf3006->liste_uv.v3;
		
		if(ptf3006->double_side) {
			eerie->facelist[i].facetype |= POLY_DOUBLESIDED;
		}
		
		if(ptf3006->transparency > 0) {
			if(ptf3006->transparency == 2) {
				// NORMAL TRANS 0.00001 to 0.999999
				if(ptf3006->trans < 1.f) {
					eerie->facelist[i].facetype |= POLY_TRANS;
					eerie->facelist[i].transval = ptf3006->trans;
				}
			}
			else if (ptf3006->transparency == 1) {
				if(ptf3006->trans < 0.f) {
					// SUBTRACTIVE -0.000001 to -0.999999
					eerie->facelist[i].facetype |= POLY_TRANS;
					eerie->facelist[i].transval = ptf3006->trans;
				} else {
					// ADDITIVE 1.000001 to 1.9999999
					eerie->facelist[i].facetype |= POLY_TRANS;
					eerie->facelist[i].transval = ptf3006->trans + 1.f;
				}
			} else {
				// MULTIPLICATIVE 2.000001 to 2.9999999
				eerie->facelist[i].facetype |= POLY_TRANS;
				eerie->facelist[i].transval = ptf3006->trans + 2.f;
			}
		}
		
		if(eerie->facelist[i].texid != -1 && !eerie->texturecontainer.empty() && eerie->texturecontainer[eerie->facelist[i].texid] != NULL) {
			
			if(eerie->texturecontainer[eerie->facelist[i].texid]->userflags & POLY_TRANS) {
				if(!(eerie->facelist[i].facetype & POLY_TRANS)) {
					eerie->facelist[i].facetype |= POLY_TRANS;
					eerie->facelist[i].transval = ptf3006->trans;
				}
			}
			
			if(eerie->texturecontainer[eerie->facelist[i].texid]->userflags & POLY_WATER) {
				eerie->facelist[i].facetype |= POLY_WATER;
			}
			
			if(eerie->texturecontainer[eerie->facelist[i].texid]->userflags & POLY_LAVA) {
				eerie->facelist[i].facetype |= POLY_LAVA;
			}
			
			if(eerie->texturecontainer[eerie->facelist[i].texid]->userflags & POLY_FALL) {
				eerie->facelist[i].facetype |= POLY_FALL;
			}

			if(eerie->texturecontainer[eerie->facelist[i].texid]->userflags & POLY_CLIMB) {
				eerie->facelist[i].facetype |= POLY_CLIMB;
			}
		}
		
	}
	
	// Groups Data
	pos = to->groups_seek;
	
	for(long i = 0; i < tn->nb_groups; i++) {
		
		THEO_GROUPS_3011 tg3011;
		const THEO_GROUPS_3011 * ptg3011;
		if(version >= 3011) {
			ptg3011 = reinterpret_cast<const THEO_GROUPS_3011 *>(adr + pos);
			pos += sizeof(THEO_GROUPS_3011);
		} else {
			const THEO_GROUPS * ltg = reinterpret_cast<const THEO_GROUPS *>(adr + pos);
			pos += sizeof(THEO_GROUPS);
			memset(&tg3011, 0, sizeof(THEO_GROUPS_3011));
			tg3011.origin = ltg->origin;
			tg3011.nb_index = ltg->nb_index;
			ptg3011 = &tg3011;
		}
		
		eerie->grouplist[i].origin = ptg3011->origin;
		eerie->grouplist[i].indexes.resize(ptg3011->nb_index);
		
		std::copy((const long*)(adr + pos), (const long*)(adr + pos) + ptg3011->nb_index, eerie->grouplist[i].indexes.begin());
		pos += ptg3011->nb_index * sizeof(long);
		
		eerie->grouplist[i].name = boost::to_lower_copy(util::loadString(adr + pos, 256));
		pos += 256;
		eerie->grouplist[i].siz = 0.f;
		
		for(long o = 0; o < ptg3011->nb_index; o++) {
			eerie->grouplist[i].siz = std::max(eerie->grouplist[i].siz,
			                              fdist(eerie->vertexlist[eerie->grouplist[i].origin].v,
			                                           eerie->vertexlist[eerie->grouplist[i].indexes[o]].v));
		}
		
		eerie->grouplist[i].siz = ffsqrt(eerie->grouplist[i].siz) * (1.f/16);
		
	}

	// SELECTIONS
	s32 THEO_nb_selected = *reinterpret_cast<const s32 *>(adr + pos);
	pos += sizeof(s32);
	
	eerie->selections.resize(THEO_nb_selected);
	for(long i = 0; i < THEO_nb_selected; i++) {
		
		const THEO_SELECTED * pts = reinterpret_cast<const THEO_SELECTED *>(adr + pos);
		pos += sizeof(THEO_SELECTED);
		
		eerie->selections[i].name = boost::to_lower_copy(util::loadString(pts->name));
		eerie->selections[i].selected.resize(pts->nb_index);
		
		if(pts->nb_index > 0) {
			std::copy((const long*)(adr + pos), (const long*)(adr + pos) + pts->nb_index, eerie->selections[i].selected.begin());
			pos += sizeof(long) * pts->nb_index;
		}
	}
	
	// Theo Action Points Read
	pos = to->action_point_seek;

	for(long i = 0; i < tn->nb_action_point; i++) {
		
		const THEO_ACTION_POINT * ptap = reinterpret_cast<const THEO_ACTION_POINT *>(adr + pos);
		pos += sizeof(THEO_ACTION_POINT);
		
		eerie->actionlist[i].act = ptap->action;
		eerie->actionlist[i].sfx = ptap->num_sfx;
		eerie->actionlist[i].idx = ActionPoint(ptap->vert_index);
		eerie->actionlist[i].name = boost::to_lower_copy(util::loadString(ptap->name));
	}
	
	eerie->angle = Anglef::ZERO;
	eerie->pos = Vec3f_ZERO;
	
	// Now Interpret Extra Data chunk
	pos = to->extras_seek + 4;
	
	if(version >= 3005) {
		
		const THEO_EXTRA_DATA_3005 * pted3005 = reinterpret_cast<const THEO_EXTRA_DATA_3005 *>(adr + pos);
		pos += sizeof(THEO_EXTRA_DATA_3005);
		
		eerie->pos = pted3005->pos.toVec3();
		
		eerie->angle.setYaw((float)(pted3005->angle.alpha & 0xfff) * THEO_ROTCONVERT);
		eerie->angle.setPitch((float)(pted3005->angle.beta & 0xfff) * THEO_ROTCONVERT);
		eerie->angle.setRoll((float)(pted3005->angle.gamma & 0xfff) * THEO_ROTCONVERT);
		
		eerie->point0 = eerie->vertexlist[pted3005->origin_index].v;
		eerie->origin = pted3005->origin_index;
		
		eerie->quat = pted3005->quat;
	
	} else {
		
		const THEO_EXTRA_DATA * pted = reinterpret_cast<const THEO_EXTRA_DATA *>(adr + pos);
		pos += sizeof(THEO_EXTRA_DATA);
		
		eerie->pos = pted->pos.toVec3();
		
		eerie->angle.setYaw((float)(pted->angle.alpha & 0xfff) * THEO_ROTCONVERT);
		eerie->angle.setPitch((float)(pted->angle.beta & 0xfff) * THEO_ROTCONVERT);
		eerie->angle.setRoll((float)(pted->angle.gamma & 0xfff) * THEO_ROTCONVERT);
		
		eerie->point0 = eerie->vertexlist[pted->origin_index].v;
		eerie->origin = pted->origin_index;
	}
	
	*poss = pos;
	
	eerie->vertexlist3 = eerie->vertexlist;
	ReCreateUVs(eerie);
	EERIE_Object_Precompute_Fast_Access(eerie);
}
Ejemplo n.º 12
0
void ManageCombatModeAnimations() {
	
	arx_assert(entities.player());
	
	if(player.m_aimTime > 0) {
		player.m_aimTime += g_platformTime.lastFrameDuration();
	}
	
	Entity * const io = entities.player();
	
	AnimLayer & layer1 = io->animlayer[1];
	
	ANIM_HANDLE ** alist = io->anims;
	WeaponType weapontype = ARX_EQUIPMENT_GetPlayerWeaponType();
	
	if(weapontype == WEAPON_BARE && LAST_WEAPON_TYPE != weapontype) {
		if(layer1.cur_anim != alist[ANIM_BARE_WAIT]) {
			changeAnimation(io, 1, alist[ANIM_BARE_WAIT]);
			player.m_aimTime = 0;
		}
	}
	
	switch(weapontype) {
		case WEAPON_BARE: { // BARE HANDS PLAYER MANAGEMENT
			if(layer1.cur_anim == alist[ANIM_BARE_WAIT]) {
				player.m_aimTime = 0;
				if(eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_BARE_STRIKE_LEFT_START + player.m_strikeDirection * 3]);
					io->isHit = false;
				}
			}
			
			// Now go for strike cycle...
			for(long j = 0; j < 4; j++) {
				if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT_START + j * 3] && (layer1.flags & EA_ANIMEND)) {
					changeAnimation(io, 1, alist[ANIM_BARE_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP);
					player.m_aimTime = PlatformDuration::ofRaw(1);
				} else if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT_CYCLE + j * 3] && !eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_BARE_STRIKE_LEFT + j * 3]);
					strikeSpeak(io);
					SendIOScriptEvent(NULL, io, SM_STRIKE, "bare");
					player.m_weaponBlocked = AnimationDuration::ofRaw(-1); // TODO inband signaling AnimationDuration
					player.m_strikeDirection = 0;
					player.m_aimTime = 0;
				} else if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT + j * 3]) {
					if(layer1.flags & EA_ANIMEND) {
						changeAnimation(io, 1, alist[ANIM_BARE_WAIT], EA_LOOP);
						player.m_strikeDirection = 0;
						player.m_aimTime = PlatformDuration::ofRaw(1);
						player.m_weaponBlocked = AnimationDuration::ofRaw(-1);
					} else if( layer1.ctime > layer1.currentAltAnim()->anim_time * 0.2f
					        && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.8f
					        && player.m_weaponBlocked == AnimationDuration::ofRaw(-1)) {
						
						ActionPoint id = ActionPoint();
						if(layer1.cur_anim == alist[ANIM_BARE_STRIKE_LEFT]) {
							id = io->obj->fastaccess.left_attach;
						} else { // Strike Right
							id = io->obj->fastaccess.primary_attach;
						}
						
						if(id != ActionPoint()) {
							Sphere sphere;
							sphere.origin = actionPointPosition(io->obj, id);
							sphere.radius = 25.f;
							
							EntityHandle num;
							
							if(CheckAnythingInSphere(sphere, EntityHandle_Player, 0, &num)) {
								float dmgs = (player.m_miscFull.damages + 1) * player.m_strikeAimRatio;
								
								if(ARX_DAMAGES_TryToDoDamage(actionPointPosition(io->obj, id), dmgs, 40, EntityHandle_Player)) {
									player.m_weaponBlocked = layer1.ctime;
								}
								
								ParticleSparkSpawnContinous(sphere.origin, unsigned(dmgs), SpawnSparkType_Success);
								
								if(ValidIONum(num)) {
									static PlatformInstant lastHit = 0;
									PlatformInstant now = g_platformTime.frameStart();
									if(now - lastHit > toPlatformDuration(layer1.ctime)) {
										ARX_SOUND_PlayCollision(entities[num]->material, MATERIAL_FLESH, 1.f, 1.f, sphere.origin, NULL);
										lastHit = now;
									}
								}
							}
						}
					}
				}
			}
			break;
		}
		case WEAPON_DAGGER: { // DAGGER PLAYER MANAGEMENT
			// Waiting and receiving Strike Impulse
			if(layer1.cur_anim == alist[ANIM_DAGGER_WAIT]) {
				player.m_aimTime = 0;
				if(eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_DAGGER_STRIKE_LEFT_START + player.m_strikeDirection * 3]);
					io->isHit = false;
				}
			}
			
			// Now go for strike cycle...
			for(long j = 0; j < 4; j++) {
				if(layer1.cur_anim == alist[ANIM_DAGGER_STRIKE_LEFT_START + j * 3] && (layer1.flags & EA_ANIMEND)) {
					changeAnimation(io, 1, alist[ANIM_DAGGER_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP);
					player.m_aimTime = PlatformDuration::ofRaw(1);
				} else if(layer1.cur_anim == alist[ANIM_DAGGER_STRIKE_LEFT_CYCLE + j * 3] && !eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_DAGGER_STRIKE_LEFT + j * 3]);
					strikeSpeak(io);
					SendIOScriptEvent(NULL, io, SM_STRIKE, "dagger");
					player.m_strikeDirection = 0;
					player.m_aimTime = 0;
				} else if(layer1.cur_anim == alist[ANIM_DAGGER_STRIKE_LEFT + j * 3]) {
					if(   layer1.ctime > layer1.currentAltAnim()->anim_time * 0.3f
					   && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.7f
					) {
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						
						if(player.m_weaponBlocked == AnimationDuration::ofRaw(-1)
							&& ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 0))
						{
							player.m_weaponBlocked = layer1.ctime;
						}
					}
					
					if(layer1.flags & EA_ANIMEND) {
						changeAnimation(io, 1, alist[ANIM_DAGGER_WAIT], EA_LOOP);
						layer1.flags &= ~(EA_PAUSED | EA_REVERSE);
						player.m_strikeDirection = 0;
						player.m_aimTime = PlatformDuration::ofRaw(1);
						player.m_weaponBlocked = AnimationDuration::ofRaw(-1);
					}
					
					if(   player.m_weaponBlocked != AnimationDuration::ofRaw(-1)
					   && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.9f
					) {
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 1);
					}
				}
			}
			break;
		}
		case WEAPON_1H: { // 1HANDED PLAYER MANAGEMENT
			// Waiting and Received Strike Impulse
			if(layer1.cur_anim == alist[ANIM_1H_WAIT]) {
				player.m_aimTime = 0;
				if(eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_1H_STRIKE_LEFT_START + player.m_strikeDirection * 3]);
					io->isHit = false;
				}
			}
			
			// Now go for strike cycle...
			for(long j = 0; j < 4; j++) {
				if(layer1.cur_anim == alist[ANIM_1H_STRIKE_LEFT_START + j * 3] && (layer1.flags & EA_ANIMEND)) {
					changeAnimation(io, 1, alist[ANIM_1H_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP);
					player.m_aimTime = PlatformDuration::ofRaw(1);
				} else if(layer1.cur_anim == alist[ANIM_1H_STRIKE_LEFT_CYCLE + j * 3] && !eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_1H_STRIKE_LEFT + j * 3]);
					strikeSpeak(io);
					SendIOScriptEvent(NULL, io, SM_STRIKE, "1h");
					player.m_strikeDirection = 0;
					player.m_aimTime = 0;
				} else if(layer1.cur_anim == alist[ANIM_1H_STRIKE_LEFT + j * 3]) {
					if(   layer1.ctime > layer1.currentAltAnim()->anim_time * 0.3f
					   && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.7f
					) {
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						
						if(player.m_weaponBlocked == AnimationDuration::ofRaw(-1)
							&& ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 0))
						{
							player.m_weaponBlocked = layer1.ctime;
						}
					}
					
					if(layer1.flags & EA_ANIMEND) {
						changeAnimation(io, 1, alist[ANIM_1H_WAIT], EA_LOOP);
						layer1.flags &= ~(EA_PAUSED | EA_REVERSE);
						player.m_strikeDirection = 0;
						player.m_aimTime = 0;
						player.m_weaponBlocked = AnimationDuration::ofRaw(-1);
					}
					
					if(   player.m_weaponBlocked != AnimationDuration::ofRaw(-1)
					   && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.9f
					) {
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 1);
					}
				}
			}
			break;
		}
		case WEAPON_2H: { // 2HANDED PLAYER MANAGEMENT
			// Waiting and Receiving Strike Impulse
			if(layer1.cur_anim == alist[ANIM_2H_WAIT]) {
				player.m_aimTime = 0;
				if(eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_2H_STRIKE_LEFT_START + player.m_strikeDirection * 3]);
					io->isHit = false;
				}
			}
			
			// Now go for strike cycle...
			for(long j = 0; j < 4; j++) {
				if(layer1.cur_anim == alist[ANIM_2H_STRIKE_LEFT_START + j * 3] && (layer1.flags & EA_ANIMEND)) {
					changeAnimation(io, 1, alist[ANIM_2H_STRIKE_LEFT_CYCLE + j * 3], EA_LOOP);
					player.m_aimTime = PlatformDuration::ofRaw(1);
				} else if(layer1.cur_anim == alist[ANIM_2H_STRIKE_LEFT_CYCLE + j * 3] && !eeMousePressed1()) {
					changeAnimation(io, 1, alist[ANIM_2H_STRIKE_LEFT + j * 3]);
					strikeSpeak(io);
					SendIOScriptEvent(NULL, io, SM_STRIKE, "2h");
					player.m_strikeDirection = 0;
					player.m_aimTime = 0;
				} else if(layer1.cur_anim == alist[ANIM_2H_STRIKE_LEFT + j * 3]) {
					if(   layer1.ctime > layer1.currentAltAnim()->anim_time * 0.3f
					   && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.7f
					) {
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						
						if(player.m_weaponBlocked == AnimationDuration::ofRaw(-1)
							&& ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 0))
						{
							player.m_weaponBlocked = layer1.ctime;
						}
					}
					
					if(layer1.flags & EA_ANIMEND) {
						changeAnimation(io, 1, alist[ANIM_2H_WAIT], EA_LOOP);
						layer1.flags &= ~(EA_PAUSED | EA_REVERSE);
						player.m_strikeDirection = 0;
						player.m_aimTime = 0;
						player.m_weaponBlocked = AnimationDuration::ofRaw(-1);
					}
					
					if(   player.m_weaponBlocked != AnimationDuration::ofRaw(-1)
					   && layer1.ctime < layer1.currentAltAnim()->anim_time * 0.9f
					) {
						Entity * weapon = entities[player.equiped[EQUIP_SLOT_WEAPON]];
						ARX_EQUIPMENT_Strike_Check(io, weapon, player.m_strikeAimRatio, 1);
					}
				}
			}
			break;
		}
		case WEAPON_BOW: { // MISSILE PLAYER MANAGEMENT
			if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_CYCLE]) {
				player.m_bowAimRatio += bowZoomFromDuration(toMs(g_platformTime.lastFrameDuration()));
				
				if(player.m_bowAimRatio > 1.f)
					player.m_bowAimRatio = 1.f;
			}
			
			// Waiting and Receiving Strike Impulse
			if(layer1.cur_anim == alist[ANIM_MISSILE_WAIT]) {
				player.m_aimTime = PlatformDuration::ofRaw(1);
				
				if(eeMousePressed1() && Player_Arrow_Count() > 0) {
					changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE_PART_1]);
					io->isHit = false;
				}
			}
			
			if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_PART_1] && (layer1.flags & EA_ANIMEND)) {
				player.m_aimTime = 0;
				changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE_PART_2]);
				EERIE_LINKEDOBJ_LinkObjectToObject(io->obj, arrowobj, "left_attach", "attach", NULL);
			}
			
			// Now go for strike cycle...
			if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_PART_2] && (layer1.flags & EA_ANIMEND)) {
				changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE_CYCLE], EA_LOOP);
				player.m_aimTime = PlatformDuration::ofRaw(1);
			} else if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_CYCLE] && !eeMousePressed1()) {
				EERIE_LINKEDOBJ_UnLinkObjectFromObject(io->obj, arrowobj);
				changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE]);
				SendIOScriptEvent(NULL, io, SM_STRIKE, "bow");
				StrikeAimtime();
				player.m_strikeAimRatio = player.m_bowAimRatio;
				Entity * quiver = Player_Arrow_Count_Decrease();
				float poisonous = 0.f;
				
				if(quiver) {
					poisonous = quiver->poisonous;
					if(quiver->poisonous_count > 0) {
						quiver->poisonous_count--;
						
						if(quiver->poisonous_count <= 0)
							quiver->poisonous = 0;
					}
					
					ARX_DAMAGES_DurabilityLoss(quiver, 1.f);
					
					// TODO is this needed ?, quivers seem to self destruct via script, but maybe not all
					if(ValidIOAddress(quiver) && quiver->durability <= 0.f) {
						ARX_INTERACTIVE_DestroyIOdelayed(quiver);
					}
				}
				
				float aimratio = player.m_strikeAimRatio;
				
				if(sp_max && poisonous < 3.f)
					poisonous = 3.f;
				
				Vec3f orgPos = player.pos + Vec3f(0.f, 40.f, 0.f);
				
				if(io->obj->fastaccess.left_attach != ActionPoint()) {
					orgPos = actionPointPosition(io->obj, io->obj->fastaccess.left_attach);
				}
				
				Anglef orgAngle = player.angle;
				
				PlayerLaunchArrow_Test(aimratio, poisonous, orgPos, orgAngle);
				
				if(sp_max) {
					Anglef angle;
					Vec3f pos = player.pos + Vec3f(0.f, 40.f, 0.f);
					
					angle.setPitch(player.angle.getPitch());
					angle.setYaw(player.angle.getYaw() + 8);
					angle.setRoll(player.angle.getRoll());
					PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle);
					angle.setPitch(player.angle.getPitch());
					angle.setYaw(player.angle.getYaw() - 8);
					PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle);
					angle.setPitch(player.angle.getPitch());
					angle.setYaw(player.angle.getYaw() + 4.f);
					PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle);
					angle.setPitch(player.angle.getPitch());
					angle.setYaw(player.angle.getYaw() - 4.f);
					PlayerLaunchArrow_Test(aimratio, poisonous, pos, angle);
				}
				
				player.m_aimTime = 0;
			} else if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE]) {
				player.m_bowAimRatio -= bowZoomFromDuration(toMs(g_platformTime.lastFrameDuration()));
				
				if(player.m_bowAimRatio < 0)
					player.m_bowAimRatio = 0;
				
				if(layer1.flags & EA_ANIMEND) {
					player.m_bowAimRatio = 0;
					changeAnimation(io, 1, alist[ANIM_MISSILE_WAIT], EA_LOOP);
					player.m_aimTime = 0;
					player.m_weaponBlocked = AnimationDuration::ofRaw(-1);
					EERIE_LINKEDOBJ_UnLinkObjectFromObject(io->obj, arrowobj);
				}
			}
			break;
		}
	}
	
	LAST_WEAPON_TYPE = weapontype;
}
Ejemplo n.º 13
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);
}