static void FlyingEyeSpellUpdateHand(const Vec3f & pos, LightHandle & light) {
	
	EERIE_LIGHT * el = dynLightCreate(light);
	if(el) {
		el->intensity = 1.3f;
		el->fallend = 180.f;
		el->fallstart = 50.f;
		el->rgb = Color3f(0.7f, 0.3f, 1.f);
		el->pos = pos;
	}
	
	for(long kk = 0; kk < 2; kk++) {
		
		PARTICLE_DEF * pd = createParticle();
		if(!pd) {
			break;
		}
		
		pd->ov = pos + 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::getu(1500, 3500);
		pd->scale = Vec3f(0.2f);
		pd->tc = TC_smoke;
		pd->m_flags = FADE_IN_AND_OUT | ROTATING | DISSIPATING;
		pd->sourceionum = EntityHandle_Player;
		pd->m_rotation = 0.0000001f;
		pd->rgb = Color3f(.7f, .3f, 1.f) + Color3f(-.1f, -.1f, -.1f) * randomColor3f();
	}
}
static void CheckExp(long i) {
	
	if((Thrown[i].flags & ATO_FIERY) && !(Thrown[i].flags & ATO_UNDERWATER)) {
		const Vec3f & pos = Thrown[i].position;

		ARX_BOOMS_Add(pos);
		LaunchFireballBoom(pos, 10);
		DoSphericDamage(Sphere(pos, 50.f), 4.f * 2, DAMAGE_AREA, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL, PlayerEntityHandle);
		ARX_SOUND_PlaySFX(SND_SPELL_FIRE_HIT, &pos);
		ARX_NPC_SpawnAudibleSound(pos, entities.player());
		LightHandle id = GetFreeDynLight();

		if(lightHandleIsValid(id) && framedelay > 0) {
			EERIE_LIGHT * light = lightHandleGet(id);
			
			light->intensity = 3.9f;
			light->fallstart = 400.f;
			light->fallend   = 440.f;
			light->rgb = Color3f(1.f, .8f, .6f) - randomColor3f() * Color3f(.2f, .2f, .2f);
			light->pos = pos;
			light->ex_flaresize = 40.f;
			light->duration = 1500;
		}
	}
}
CMagicMissile::CMagicMissile()
	: CSpellFx()
	, bExplo(false)
	, bMove(true)
	, eCurPos()
	, lightIntensityFactor()
	, iLength()
	, iBezierPrecision()
	, fTrail()
	, snd_loop()
{
	SetDuration(2000);
	ulCurrentTime = ulDuration + 1;
	
	m_trailColor = Color3f(0.9f, 0.9f, 0.7f) + Color3f(0.1f, 0.1f, 0.3f) * randomColor3f();
	m_projectileColor = Color3f(0.3f, 0.3f, 0.5f);
	tex_mm = TextureContainer::Load("graph/obj3d/textures/(fx)_bandelette_blue");
}
Exemple #4
0
void TreatBackgroundDynlights() {

    ARX_PROFILE_FUNC();

    for(size_t i = 0; i < MAX_LIGHTS; i++) {
        EERIE_LIGHT *light = GLight[i];

        if(light && (light->extras & EXTRAS_SEMIDYNAMIC)) {

            float fMaxdist = player.m_telekinesis ? 850 : 300;

            if(!fartherThan(light->pos, ACTIVECAM->orgTrans.pos, fMaxdist)) {
                ComputeLight2DPos(light);
            } else {
                light->m_screenRect.max.x = -1;
                light->m_screenRect.min.x = 1;
            }

            if(!light->m_ignitionStatus) {
                // just extinguished
                if(lightHandleIsValid(light->m_ignitionLightHandle)) {
                    lightHandleGet(light->m_ignitionLightHandle)->exist = 0;
                    light->m_ignitionLightHandle = LightHandle();

                    for(size_t l = 0; l < entities.size(); l++) {
                        const EntityHandle handle = EntityHandle(l);
                        Entity * e = entities[handle];

                        if(e && (e->ioflags & IO_MARKER)) {
                            Vec3f _pos2 = GetItemWorldPosition(e);
                            if(!fartherThan(light->pos, _pos2, 300.f)) {
                                SendIOScriptEvent(e, SM_CUSTOM, "douse");
                            }
                        }
                    }
                }
            } else {
                // just light up
                if(!lightHandleIsValid(light->m_ignitionLightHandle)) {
                    for(size_t l = 0; l < entities.size(); l++) {
                        const EntityHandle handle = EntityHandle(l);
                        Entity * e = entities[handle];

                        if(e && (e->ioflags & IO_MARKER)) {
                            Vec3f _pos2 = GetItemWorldPosition(e);
                            if(!fartherThan(light->pos, _pos2, 300.f)) {
                                SendIOScriptEvent(e, SM_CUSTOM, "fire");
                            }
                        }
                    }

                    light->m_ignitionLightHandle = GetFreeDynLight();
                }

                if(lightHandleIsValid(light->m_ignitionLightHandle)) {
                    EERIE_LIGHT *dynamicLight = lightHandleGet(light->m_ignitionLightHandle);

                    dynamicLight->pos          = light->pos;
                    dynamicLight->fallstart    = light->fallstart;
                    dynamicLight->fallend      = light->fallend;
                    dynamicLight->m_isIgnitionLight  = true;
                    dynamicLight->intensity    = light->intensity;
                    dynamicLight->ex_flaresize = light->ex_flaresize;
                    dynamicLight->extras       = light->extras;
                    dynamicLight->duration     = std::numeric_limits<long>::max();

                    dynamicLight->rgb = light->rgb - light->rgb * light->ex_flicker * randomColor3f() * 0.5f;

                    dynamicLight->rgb = componentwise_max(dynamicLight->rgb, Color3f::black);
                    RecalcLight(dynamicLight);
                }
            }
        }
    }

    for(size_t i = 0; i < MAX_DYNLIGHTS; i++) {
        EERIE_LIGHT * el = &DynLight[i];

        if(el->exist && el->duration) {
            float tim = (float)float(arxtime) - (float)el->time_creation;
            float duration = (float)el->duration;

            if(tim >= duration) {
                float sub = framedelay * 0.001f;

                el->rgb.r -= sub;
                el->rgb.g -= sub;
                el->rgb.b -= sub;

                if(el->rgb.r < 0)
                    el->rgb.r = 0.f;

                if(el->rgb.g < 0)
                    el->rgb.g = 0.f;

                if(el->rgb.b < 0)
                    el->rgb.b = 0.f;

                if(el->rgb.r + el->rgb.g + el->rgb.b == 0) {
                    el->exist = 0;
                    el->duration = 0;
                }
            }
        }
    }
}
Exemple #5
0
void TreatBackgroundDynlights() {
	
	ARX_PROFILE_FUNC();
	
	for(size_t i = 0; i < g_staticLightsMax; i++) {
		EERIE_LIGHT * light = g_staticLights[i];
		
		if(light && (light->extras & EXTRAS_SEMIDYNAMIC)) {
			
			float fMaxdist = player.m_telekinesis ? 850 : 300;
			
			if(!fartherThan(light->pos, g_camera->m_pos, fMaxdist)) {
				ComputeLight2DPos(light);
			} else {
				light->m_screenRect = Rectf(1, 0, -1, 0); // Intentionally invalid
			}
			
			if(!light->m_ignitionStatus) {
				
				// just extinguished
				EERIE_LIGHT * dynLight = lightHandleGet(light->m_ignitionLightHandle);
				if(dynLight) {
					dynLight->m_exists = false;
					light->m_ignitionLightHandle = LightHandle();
					for(size_t l = 0; l < entities.size(); l++) {
						const EntityHandle handle = EntityHandle(l);
						Entity * e = entities[handle];
						if(e && (e->ioflags & IO_MARKER)) {
							Vec3f _pos2 = GetItemWorldPosition(e);
							if(!fartherThan(light->pos, _pos2, 300.f)) {
								SendIOScriptEvent(NULL, e, SM_CUSTOM, "douse");
							}
						}
					}
				}
				
			} else {
				
				// just light up
				if(!lightHandleGet(light->m_ignitionLightHandle)) {
					for(size_t l = 0; l < entities.size(); l++) {
						const EntityHandle handle = EntityHandle(l);
						Entity * e = entities[handle];
						if(e && (e->ioflags & IO_MARKER)) {
							Vec3f _pos2 = GetItemWorldPosition(e);
							if(!fartherThan(light->pos, _pos2, 300.f)) {
								SendIOScriptEvent(NULL, e, SM_CUSTOM, "fire");
							}
						}
					}
					light->m_ignitionLightHandle = GetFreeDynLight();
				}
				
				EERIE_LIGHT * dynamicLight = lightHandleGet(light->m_ignitionLightHandle);
				if(dynamicLight) {
					dynamicLight->pos          = light->pos;
					dynamicLight->fallstart    = light->fallstart;
					dynamicLight->fallend      = light->fallend;
					dynamicLight->m_isIgnitionLight  = true;
					dynamicLight->intensity    = light->intensity;
					dynamicLight->ex_flaresize = light->ex_flaresize;
					dynamicLight->extras       = light->extras;
					dynamicLight->duration     = GameDurationMs(std::numeric_limits<long>::max());
					
					dynamicLight->rgb = light->rgb - light->rgb * light->ex_flicker * randomColor3f() * 0.5f;
					
					dynamicLight->rgb = componentwise_max(dynamicLight->rgb, Color3f::black);
					RecalcLight(dynamicLight);
				}
			}
		}
	}

	for(size_t i = 0; i < g_dynamicLightsMax; i++) {
		EERIE_LIGHT * el = &g_dynamicLights[i];

		if(el->m_exists && el->duration != 0) {
			const GameDuration elapsed = g_gameTime.now() - el->creationTime;
			const GameDuration duration = el->duration;

			if(elapsed >= duration) {
				float sub = g_gameTime.lastFrameDuration() / GameDurationMs(1000);

				el->rgb.r -= sub;
				el->rgb.g -= sub;
				el->rgb.b -= sub;

				if(el->rgb.r < 0)
					el->rgb.r = 0.f;

				if(el->rgb.g < 0)
					el->rgb.g = 0.f;

				if(el->rgb.b < 0)
					el->rgb.b = 0.f;

				if(el->rgb.r + el->rgb.g + el->rgb.b == 0) {
					el->m_exists = false;
					el->duration = 0;
				}
			}
		}
	}
}
void AddFlare(const Vec2s & pos, float sm, short typ, Entity * io, bool bookDraw) {
	
	int oldest = 0;
	size_t i;
	for(i = 0; i < MAX_FLARES; i++) {
		if(!magicFlares[i].exist) {
			break;
		}
		if(magicFlares[i].tolive < magicFlares[oldest].tolive) {
			oldest = i;
		}
	}
	if(i >= MAX_FLARES) {
		removeFlare(magicFlares[oldest]);
		i = oldest;
	}

	FLARES * fl = &magicFlares[i];
	fl->exist = 1;
	flarenum++;

	if(!bookDraw)
		fl->bDrawBitmap = 0;
	else
		fl->bDrawBitmap = 1;

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

	fl->pos.x = float(pos.x) - rnd() * 4.f;
	fl->pos.y = float(pos.y) - rnd() * 4.f - 50.f;
	fl->tv.rhw = fl->v.rhw = 1.f;

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

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

	switch(PIPOrgb) {
		case 0: {
			fl->rgb = Color3f(.4f, 0.f, .4f) + Color3f(2.f/3, 2.f/3, 2.f/3) * randomColor3f();
			break;
		}
		case 1: {
			fl->rgb = Color3f(.5f, .5f, 0.f) + Color3f(.625f, .625f, .55f) * randomColor3f();
			break;
		}
		case 2: {
			fl->rgb = Color3f(.4f, 0.f, 0.f) + Color3f(2.f/3, .55f, .55f) * randomColor3f();
			break;
		}
	}

	if(typ == -1) {
		float zz = eeMousePressed1() ? 0.29f : ((sm > 0.5f) ? rnd() : 1.f);
		if(zz < 0.2f) {
			fl->type = 2;
			fl->size = rnd() * 42.f + 42.f;
			fl->tolive = (800.f + rnd() * 800.f) * FLARE_MUL;
		} else if(zz < 0.5f) {
			fl->type = 3;
			fl->size = rnd() * 52.f + 16.f;
			fl->tolive = (800.f + rnd() * 800.f) * FLARE_MUL;
		} else {
			fl->type = 1;
			fl->size = (rnd() * 24.f + 32.f) * sm;
			fl->tolive = (1700.f + rnd() * 500.f) * FLARE_MUL;
		}
	} else {
		fl->type = (rnd() > 0.8f) ? 1 : 4;
		fl->size = (rnd() * 38.f + 64.f) * sm;
		fl->tolive = (1700.f + rnd() * 500.f) * FLARE_MUL;
	}

	fl->dynlight = LightHandle::Invalid;

	for(long kk = 0; kk < 3; kk++) {

		if(rnd() < 0.5f) {
			continue;
		}

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

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

		pd->ov = fl->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::get(0, 800);
		pd->tc = fire2;
		if(kk == 1) {
			pd->move.y = 4.f;
			pd->siz = 1.5f;
		} else {
			pd->siz = 1.f + rnd();
		}
		pd->rgb = Color3f(fl->rgb.r * (2.f/3), fl->rgb.g * (2.f/3), fl->rgb.b * (2.f/3));
		pd->fparam = 1.2f;

		if(bookDraw)
			pd->is2D = true;
	}
}
void ConfuseSpell::Update(float timeDelta) {
	
	ARX_UNUSED(timeDelta);
	
	Vec3f pos = entities[m_target]->pos;
	if(m_target != PlayerEntityHandle) {
		pos.y += entities[m_target]->physics.cyl.height - 30.f;
	}
	
	long idx = entities[m_target]->obj->fastaccess.head_group_origin;
	if(idx >= 0) {
		pos = entities[m_target]->obj->vertexlist3[idx].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.get_updated() * ( 1.0f / 500 )), 0.f);
	Draw3DObject(spapi, stiteangle, eCurPos, Vec3f_ONE, Color3f::white, mat);
	
	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::get(2300, 3300);
		pd->tc = tex_p1;
		pd->special = PARTICLE_GOLDRAIN | FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION
					  | DISSIPATING;
		pd->fparam = 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);
	}
	
	if(!lightHandleIsValid(m_light))
		m_light = GetFreeDynLight();

	if(lightHandleIsValid(m_light)) {
		EERIE_LIGHT * light = lightHandleGet(m_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 = 200;
		light->extras = 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) {
		long id;

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

		pouet--;

		if(id != -1) {
			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 = eobj->vertexlist3[id].v;
			}
			
			for(long kk = 0; kk < 2; kk++) {
				
				PARTICLE_DEF * pd = createParticle();
				if(!pd) {
					break;
				}
				
				pd->ov = eobj->vertexlist3[id].v + 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].v;
				pd->fparam = 0.0000001f;
				pd->rgb = Color3f(.7f, .3f, 1.f) + Color3f(-.1f, -.1f, -.1f) * randomColor3f();
			}
		}
	}
}
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;
	}
}
Exemple #10
0
void ARX_THROWN_OBJECT_Manage(unsigned long time_offset)
{
	for(size_t i = 0; i < MAX_THROWN_OBJECTS; i++) {
		ARX_THROWN_OBJECT *thrownObj = &Thrown[i];
		if(!(thrownObj->flags & ATO_EXIST))
			continue;

		{
		// Is Object Visible & Near ?

		EERIE_BKG_INFO * bkgData = getFastBackgroundData(thrownObj->position.x, thrownObj->position.z);

		if(!bkgData || !bkgData->treat) {
			continue;
		}

		// Now render object !
		if(!thrownObj->obj)
			continue;

		TransformInfo t(thrownObj->position, thrownObj->quat);
		DrawEERIEInter_ModelTransform(thrownObj->obj, t);

		if((thrownObj->flags & ATO_FIERY) && (thrownObj->flags & ATO_MOVING)
		   && !(thrownObj->flags & ATO_UNDERWATER)) {

			LightHandle id = GetFreeDynLight();
			if(lightHandleIsValid(id) && framedelay > 0) {
				EERIE_LIGHT * light = lightHandleGet(id);
				
				light->intensity = 1.f;
				light->fallstart = 100.f;
				light->fallend   = 240.f;
				light->rgb = Color3f(1.f, .8f, .6f) - randomColor3f() * Color3f(.2f, .2f, .2f);
				light->pos = thrownObj->position;
				light->ex_flaresize = 40.f;
				light->extras |= EXTRAS_FLARE;
				light->duration = static_cast<long>(framedelay * 0.5f);
			}

			float p = 3.f;

			while(p > 0.f) {
				p -= 0.5f;

				if(thrownObj->obj) {
					long notok = 10;
					std::vector<EERIE_FACE>::iterator it;

					while(notok-- > 0) {
						it = Random::getIterator(thrownObj->obj->facelist);
						arx_assert(it != thrownObj->obj->facelist.end());

						if(it->facetype & POLY_HIDE)
							continue;

						notok = -1;
					}

					if(notok < 0) {
						Vec3f pos = thrownObj->obj->vertexlist3[it->vid[0]].v;

						createFireParticles(pos, 2, 180);
					}
				}
			}
		}

		if(thrownObj->pRuban) {
			thrownObj->pRuban->SetNextPosition(thrownObj->position);
			thrownObj->pRuban->Update(time_offset);
		}

		Vec3f original_pos;

		if(thrownObj->flags & ATO_MOVING) {
			long need_kill = 0;
			float mod = (float)time_offset * thrownObj->velocity;
			original_pos = thrownObj->position;
			thrownObj->position.x += thrownObj->vector.x * mod;
			float gmod = 1.f - thrownObj->velocity;

			gmod = glm::clamp(gmod, 0.f, 1.f);

			thrownObj->position.y += thrownObj->vector.y * mod + (time_offset * gmod);
			thrownObj->position.z += thrownObj->vector.z * mod;

			CheckForIgnition(Sphere(original_pos, 10.f), 0, 2);

			Vec3f wpos = thrownObj->position;
			wpos.y += 20.f;
			EERIEPOLY * ep = EEIsUnderWater(wpos);

			if(thrownObj->flags & ATO_UNDERWATER) {
				if(!ep) {
					thrownObj->flags &= ~ATO_UNDERWATER;
					ARX_SOUND_PlaySFX(SND_PLOUF, &thrownObj->position);
				}
			} else if(ep) {
				thrownObj->flags |= ATO_UNDERWATER;
				ARX_SOUND_PlaySFX(SND_PLOUF, &thrownObj->position);
			}

			// Check for collision MUST be done after DRAWING !!!!
			long nbact = thrownObj->obj->actionlist.size();

			for(long j = 0; j < nbact; j++) {
				float rad = GetHitValue(thrownObj->obj->actionlist[j].name);

				if(rad == -1)
					continue;

				rad *= .5f;

				const Vec3f v0 = thrownObj->obj->vertexlist3[thrownObj->obj->actionlist[j].idx].v;
				Vec3f dest = original_pos + thrownObj->vector * 95.f;
				Vec3f orgn = original_pos - thrownObj->vector * 25.f;
				EERIEPOLY * ep = CheckArrowPolyCollision(orgn, dest);

				if(ep) {
					ARX_PARTICLES_Spawn_Spark(v0, 14, 0);
					CheckExp(i);

					if(ValidIONum(thrownObj->source))
						ARX_NPC_SpawnAudibleSound(v0, entities[thrownObj->source]);

					thrownObj->flags &= ~ATO_MOVING;
					thrownObj->velocity = 0.f;
					
					std::string bkg_material = "earth";

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

					if(ValidIONum(thrownObj->source)) {
						char weapon_material[64] = "dagger";
						
						ARX_SOUND_PlayCollision(weapon_material, bkg_material, 1.f, 1.f, v0, entities[thrownObj->source]);
					}

					thrownObj->position = original_pos;
					j = 200;
				} else if(IsPointInField(v0)) {
					ARX_PARTICLES_Spawn_Spark(v0, 24, 0);
					CheckExp(i);

					if (ValidIONum(thrownObj->source))
						ARX_NPC_SpawnAudibleSound(v0, entities[thrownObj->source]);

					thrownObj->flags &= ~ATO_MOVING;
					thrownObj->velocity = 0.f;
					
					if(ValidIONum(thrownObj->source)) {
						char weapon_material[64] = "dagger";
						char bkg_material[64] = "earth";
						
						ARX_SOUND_PlayCollision(weapon_material, bkg_material, 1.f, 1.f, v0, entities[thrownObj->source]);
					}

					thrownObj->position = original_pos;
					j = 200;
					need_kill = 1;
				} else {
					for(float precision = 0.5f; precision <= 6.f; precision += 0.5f) {
						Sphere sphere;
						sphere.origin = v0 + thrownObj->vector * precision * 4.5f;
						sphere.radius = rad + 3.f;

						std::vector<EntityHandle> sphereContent;

						if(CheckEverythingInSphere(sphere, thrownObj->source, EntityHandle::Invalid, sphereContent)) {
							for(size_t jj = 0; jj < sphereContent.size(); jj++) {

								if(ValidIONum(sphereContent[jj])
										&& sphereContent[jj] != thrownObj->source)
								{

									Entity * target = entities[sphereContent[jj]];

									if(target->ioflags & IO_NPC) {
										Vec3f pos;
										Color color = Color::none;
										long hitpoint = -1;
										float curdist = 999999.f;

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

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

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

										if(hitpoint >= 0) {
											color = target->_npcdata->blood_color;
											pos = target->obj->vertexlist3[hitpoint].v;
										}

										if(thrownObj->source == 0) {
											float damages = ARX_THROWN_ComputeDamages(i, thrownObj->source, sphereContent[jj]);

											if(damages > 0.f) {
												arx_assert(hitpoint >= 0);

												if(target->ioflags & IO_NPC) {
													target->_npcdata->SPLAT_TOT_NB = 0;
													ARX_PARTICLES_Spawn_Blood2(original_pos, damages, color, target);
												}

												ARX_PARTICLES_Spawn_Blood2(pos, damages, color, target);
												ARX_DAMAGES_DamageNPC(target, damages, thrownObj->source, false, &pos);

												if(Random::getf(0.f, 100.f) > target->_npcdata->resist_poison) {
													target->_npcdata->poisonned += thrownObj->poisonous;
												}

												CheckExp(i);
											} else {
												ARX_PARTICLES_Spawn_Spark(v0, 14, 0);
												ARX_NPC_SpawnAudibleSound(v0, entities[thrownObj->source]);
											}
										}
									} else {
										// not NPC
										if(target->ioflags & IO_FIX) {
											if(ValidIONum(thrownObj->source))
												ARX_DAMAGES_DamageFIX(target, 0.1f, thrownObj->source, false);
										}

										ARX_PARTICLES_Spawn_Spark(v0, 14, 0);

										if(ValidIONum(thrownObj->source))
											ARX_NPC_SpawnAudibleSound(v0, entities[thrownObj->source]);

										CheckExp(i);
									}

									// Need to deal damages !
									thrownObj->flags &= ~ATO_MOVING;
									thrownObj->velocity = 0.f;
									need_kill = 1;
									precision = 500.f;
									j = 200;
								}
							}
						}
					}
				}
			}

			if(need_kill)
				ARX_THROWN_OBJECT_Kill(i);
		}
		}
	}
}
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;
		}
		
	}
}
Exemple #12
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;
	}
}