Result execute(Context & context) {
		
		std::string inout = context.getWord();
		const PlatformDuration duration = PlatformDurationMs(context.getFloat());
		
		if(inout == "out") {
			
			Color3f color;
			color.r = context.getFloat();
			color.g = context.getFloat();
			color.b = context.getFloat();
			fadeSetColor(color);
			
			fadeRequestStart(FadeType_Out, duration);
			
			DebugScript(" out " << toMs(duration) << ' ' << color.r << ' ' << color.g << ' ' << color.b);
		} else if(inout == "in") {
			
			fadeRequestStart(FadeType_In, duration);
			
			DebugScript(" in " << toMs(duration));
		} else {
			ScriptWarning << "unexpected fade direction: " << inout;
			return Failed;
		}
		
		return Success;
	}
Beispiel #2
0
void CheatDrawText() {
	
	if(sp_max_start == PlatformInstant_ZERO)
		return;
	
	PlatformDuration elapsed = g_platformTime.frameStart() - sp_max_start;

	if(sp_max_start != PlatformInstant_ZERO && elapsed < PlatformDurationMs(20000)) {
		float modi = float(toMs(PlatformDurationMs(20000) - elapsed)) * ( 1.0f / 2000 ) * ( 1.0f / 10 );
		float sizX = 16;
		
		Vec2f p = Vec2f(g_size.center());
		p.x -= sp_max_ch.length() * ( 1.0f / 2 ) * sizX;
		
		for(size_t i = 0; i < sp_max_ch.length(); i++) {
			Vec2f d = p + Vec2f(sizX * i, sp_max_y[i]);
			
			sp_max_y[i] = std::sin(d.x + arxtime.now_f() * ( 1.0f / 100 )) * 30.f * modi;
			std::string tex(1, sp_max_ch[i]);

			UNICODE_ARXDrawTextCenter(hFontInBook, d + Vec2f(-1,-1), tex, Color::none);
			UNICODE_ARXDrawTextCenter(hFontInBook, d + Vec2f( 1, 1), tex, Color::none);
			UNICODE_ARXDrawTextCenter(hFontInBook, d, tex, sp_max_col[i]);
		}
	}
}
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);
	}
}
Beispiel #4
0
void TextManager::Update(PlatformDuration _iDiffFrame) {
	
	std::vector<ManagedText *>::iterator itManage;
	for(itManage = entries.begin(); itManage != entries.end();) {
		
		ManagedText * pArxText = *itManage;
		
		if(pArxText->lTimeOut < 0) {
			delete pArxText;
			itManage = entries.erase(itManage);
			continue;
		}
		
		pArxText->lTimeOut -= _iDiffFrame;
		
		if(pArxText->lTimeScroll < 0
		   && pArxText->fDeltaY < float(pArxText->rRect.bottom - pArxText->rRectClipp.bottom)) {
			pArxText->fDeltaY += pArxText->fSpeedScrollY * toMs(_iDiffFrame);
			
			if(pArxText->fDeltaY >= (pArxText->rRect.bottom - pArxText->rRectClipp.bottom)) {
				pArxText->fDeltaY = static_cast<float>(pArxText->rRect.bottom - pArxText->rRectClipp.bottom);
			}
		} else {
			pArxText->lTimeScroll -= _iDiffFrame;
		}
		
		++itManage;
	}
	
}
void CinematicBorder::update() {
	
	if(m_direction == 1) {
		CINEMA_DECAL += float(toMs(g_platformTime.lastFrameDuration())) * (1.0f/10);

		if(CINEMA_DECAL > 100.f) {
			CINEMA_DECAL = 100.f;
			m_direction = 0;
		}
	} else if(m_direction == -1) {
		CINEMA_DECAL -= float(toMs(g_platformTime.lastFrameDuration())) * (1.0f/10);

		if(CINEMA_DECAL < 0.f) {
			CINEMA_DECAL = 0.f;
			m_direction = 0;
		}
	}
}
Beispiel #6
0
void ScreenArrows::update() {
	
	if(!config.input.borderTurning) {
		return;
	}
	
	fArrowMove += .5f * toMs(g_platformTime.lastFrameDuration());
	if(fArrowMove > 180.f) {
		fArrowMove = 0.f;
	}
	
	float fMove = glm::abs(glm::sin(glm::radians(fArrowMove))) * m_horizontalArrowSize.x * m_scale * .5f;
	
	const Rectf parent = createChild(Rectf(g_size), Anchor_Center, Vec2f(g_size.size()) - Vec2f(fMove), Anchor_Center);
	m_left   = createChild(parent, Anchor_LeftCenter,   m_horizontalArrowSize * m_scale, Anchor_LeftCenter);
	m_right  = createChild(parent, Anchor_RightCenter,  m_horizontalArrowSize * m_scale, Anchor_RightCenter);
	m_top    = createChild(parent, Anchor_TopCenter,    m_verticalArrowSize * m_scale,   Anchor_TopCenter);
	m_bottom = createChild(parent, Anchor_BottomCenter, m_verticalArrowSize * m_scale,   Anchor_BottomCenter);
	
}
Beispiel #7
0
void ARX_INTERFACE_ManageOpenedBook_Finish(const Vec2f & mousePos, Rectf rect, float scale)
{
	
	RenderState baseState = render3D().depthTest(false).fog(false);
	
	Vec3f pos = Vec3f(0.f, 0.f, 2100.f);
	
	EERIE_LIGHT * light = lightHandleGet(torchLightHandle);
	
	EERIE_LIGHT tl = *light;
	
	light->pos = Vec3f(500.f, -1960.f, 1590.f);
	light->m_exists = true;
	light->rgb = Color3f(0.6f, 0.7f, 0.9f);
	light->intensity = 1.8f;
	light->fallstart = 4520.f;
	light->fallend = light->fallstart + 600.f;
	RecalcLight(light);
	
	Camera * oldcam = g_camera;
	
	g_culledDynamicLights[0] = light;
	g_culledDynamicLightsCount = 1;
	
	Vec2i tmpPos(0);
	
	GRenderer->SetAntialiasing(true);
	
	float wave = timeWaveSin(g_platformTime.frameStart(), PlatformDurationMsf(1256.6370614f));
	float ptDelta = toMs(g_platformTime.lastFrameDuration());
	
	Camera bookcam;
	bookcam.angle = Anglef();
	bookcam.m_pos = Vec3f(0.f);
	bookcam.focal = 500.f;
	bookcam.cdepth = 2200.f;
	
	for(size_t i = 0; i < RUNE_COUNT; i++) {
		if(!gui::necklace.runes[i])
			continue;
		
		EERIE_3DOBJ * rune = gui::necklace.runes[i];
		
		Vec2i projectionCenter = Vec2i(rect.topLeft() + (Vec2f(285, 36) + Vec2f(tmpPos) * Vec2f(45, 64)) * scale);
		
		PrepareCamera(&bookcam, Rect(rect), projectionCenter);
		
		if(player.hasRune((Rune)i)) {
			
			Anglef angle;
			if(rune->angle.getYaw() != 0.f) {
				if(rune->angle.getYaw() > 300.f) {
					rune->angle.setYaw(300.f);
				}
				angle.setYaw(wave * rune->angle.getYaw() * (1.0f / 40));
			}
			
			rune->angle.setYaw(rune->angle.getYaw() - ptDelta * 0.2f);
			
			if(rune->angle.getYaw() < 0.f)
				rune->angle.setYaw(0.f);
			
			// Now draw the rune
			TransformInfo t2(pos, glm::quat_cast(toRotationMatrix(angle)));
			DrawEERIEInter(rune, t2, NULL, false, 0.f);
			
			Rectf runeBox = UpdateBbox2d(*rune).toRect();
			
			PopAllTriangleListOpaque(baseState);
			
			tmpPos.x++;
			
			if(tmpPos.x > 4) {
				tmpPos.x = 0;
				tmpPos.y++;
			}
			
			// TODO this is a workaround for vertexClipPositions being relative to viewport
			Vec2f mousePosInViewport = mousePos - rect.topLeft();
			
			// Checks for Mouse floating over a rune...
			if(runeBox.contains(mousePosInViewport)) {
				bool r = false;
				
				for(size_t j = 0; j < rune->facelist.size(); j++) {
					float n = PtIn2DPolyProj(rune->vertexClipPositions, &rune->facelist[j], mousePosInViewport.x, mousePosInViewport.y);
					if(n != 0.f) {
						r = true;
						break;
					}
				}
				
				if(r) {
					
					TransformInfo t(pos, glm::quat_cast(toRotationMatrix(angle)));
					DrawEERIEInter(rune, t, NULL, false, 0.f);
					
					rune->angle.setYaw(rune->angle.getYaw() + ptDelta * 2.f);
					
					PopAllTriangleListOpaque(baseState.blendAdditive());
					
					cursorSetInteraction();
					
					if(eeMouseDown1()) {
						PlayerBookDrawRune((Rune)i);
					}
				}
			}
			
			TransformInfo t1(pos, quat_identity());
			DrawEERIEInter(gui::necklace.lacet, t1, NULL, false, 0.f);
			
			PopAllTriangleListOpaque(baseState);
		}
	}
	
	*light = tl;
	
	PrepareCamera(oldcam, g_size);
	
	GRenderer->SetAntialiasing(false);
	
}
//TODO Move somewhere else
void Cedric_ApplyLightingFirstPartRefactor(Entity *io) {

	if(!io)
		return;

	io->special_color = Color3f::white;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	if(invisibility == 1.f)
		return;

	Entity *use_io = io;

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

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

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

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

		if(CullFace(eobj, face))
			continue;

		if(face.texid < 0)
			continue;

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

		float fTransp = 0.f;

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

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

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

		if(haloInfo.size) {
			AddAnimatedObjectHalo(haloInfo, face.vid, invisibility, eobj, io, tvList);
		}
		
		if(glow) {
			TexturedVertex * tv2 = PushVertexInTable(&TexSpecialColor.m_modelBatch, BatchBucket_Opaque);
			std::copy(tvList, tvList + 3, tv2);
			tv2[0].color = tv2[1].color = tv2[2].color = glowColor;
		}
	}
}
Beispiel #10
0
void ShowFrameDurationPlot() {
	
	Vec2i windowSize = mainApp->getWindow()->getSize();
	size_t maxSamples = size_t(windowSize.x);
	
	if(maxSamples != frameDurationPlotValues.capacity()) {
		frameDurationPlotValues.set_capacity(maxSamples);
	}
	if(maxSamples != frameDurationPlotVertices.size()) {
		frameDurationPlotVertices.resize(maxSamples);
	}
	
	GRenderer->ResetTexture(0);
	
	frameDurationPlotValues.push_front(toMs(g_platformTime.lastFrameDuration()));
	
	float avg = std::accumulate(frameDurationPlotValues.begin(), frameDurationPlotValues.end(), 0.f) / frameDurationPlotValues.size();
	float worst = *std::max_element(frameDurationPlotValues.begin(), frameDurationPlotValues.end());
	
	const float OFFSET_Y = 80.f;
	const float SCALE_Y = 4.0f;

	for(size_t i = 0; i < frameDurationPlotValues.size(); ++i)
	{
		float time = frameDurationPlotValues[i];
		frameDurationPlotVertices[i].color = Color::white.toRGB();
		frameDurationPlotVertices[i].p.x = i;
		frameDurationPlotVertices[i].p.y = OFFSET_Y + (time * SCALE_Y);
		frameDurationPlotVertices[i].p.z = 1.0f;
		frameDurationPlotVertices[i].w = 1.0f;
	}

	EERIEDRAWPRIM(Renderer::LineStrip, &frameDurationPlotVertices[0], frameDurationPlotValues.size());

	Color avgColor = Color::blue * 0.5f + Color::white * 0.5f;
	float avgPos = OFFSET_Y + (avg * SCALE_Y);
	drawLine(Vec2f(0, avgPos), Vec2f(windowSize.x, avgPos), 1.0f, Color::blue);

	Color worstColor = Color::red * 0.5f + Color::white * 0.5f;
	float worstPos = OFFSET_Y + (worst * SCALE_Y);
	drawLine(Vec2f(0, worstPos), Vec2f(windowSize.x, worstPos), 1.0f, Color::red);

	Font * font = hFontDebug;
	float lineOffset = font->getLineHeight() + 2;

	std::string labels[3] = { "Average: ", "Worst: ", "Current: " };
	Color colors[3] = { avgColor, worstColor, Color::white };
	float values[3] = { avg, worst, frameDurationPlotValues[0] };

	std::string texts[3];
	float widths[3];
	static float labelWidth = 0.f;
	static float valueWidth = 0.f;
	for(size_t i = 0; i < 3; i++) {
		// Format value
		std::ostringstream oss;
		oss << std::fixed << std::setprecision(2) << values[i] << " ms ("<< 1.f / (values[i] * 0.001f) << " FPS)";
		texts[i] = oss.str();
		// Calculate widths (could be done more efficiently for monospace fonts...)
		labelWidth = std::max(labelWidth, float(font->getTextSize(labels[i]).width()));
		widths[i] = font->getTextSize(texts[i]).width();
		valueWidth = std::max(valueWidth, widths[i]);
	}

	float x = 10;
	float y = 10;
	float xend = x + labelWidth + 10 + valueWidth;
	for(size_t i = 0; i < 3; i++) {
		font->draw(Vec2i(x, y), labels[i], Color::gray(0.8f));
		font->draw(Vec2i(xend - widths[i], y), texts[i], colors[i]);
		y += lineOffset;
	}

}
Beispiel #11
0
/**
 * Query OS for timestamp.
 * Retrieve the current value of system clock and convert to milliseconds.
 *
 * @param[in] portLibrary The port library.
 *
 * @return 0 on failure, time value in milliseconds on success.
 * @deprecated Use @ref time_hires_clock and @ref time_hires_delta
 *
 * technically, this should return uint64_t since both timeval.tv_sec and
 * timeval.tv_usec are long
 */
static int time_msec_clock() {
    timeval tp;
    struct timezone tzp;
    gettimeofday(&tp, &tzp);
    return toMs(tp);
}
Beispiel #12
0
static jobject OSNetworkSystem_getSocketOption(JNIEnv* env, jobject, jobject fileDescriptor, jint option) {
    NetFd fd(env, fileDescriptor);
    if (fd.isClosed()) {
        return NULL;
    }

    int family = getSocketAddressFamily(fd.get());
    if (family != AF_INET && family != AF_INET6) {
        jniThrowSocketException(env, EAFNOSUPPORT);
        return NULL;
    }

    switch (option) {
    case JAVASOCKOPT_TCP_NODELAY:
        return getSocketOption_Boolean(env, fd, IPPROTO_TCP, TCP_NODELAY);
    case JAVASOCKOPT_SO_SNDBUF:
        return getSocketOption_Integer(env, fd, SOL_SOCKET, SO_SNDBUF);
    case JAVASOCKOPT_SO_RCVBUF:
        return getSocketOption_Integer(env, fd, SOL_SOCKET, SO_RCVBUF);
    case JAVASOCKOPT_SO_BROADCAST:
        return getSocketOption_Boolean(env, fd, SOL_SOCKET, SO_BROADCAST);
    case JAVASOCKOPT_SO_REUSEADDR:
        return getSocketOption_Boolean(env, fd, SOL_SOCKET, SO_REUSEADDR);
    case JAVASOCKOPT_SO_KEEPALIVE:
        return getSocketOption_Boolean(env, fd, SOL_SOCKET, SO_KEEPALIVE);
    case JAVASOCKOPT_SO_OOBINLINE:
        return getSocketOption_Boolean(env, fd, SOL_SOCKET, SO_OOBINLINE);
    case JAVASOCKOPT_IP_TOS:
        if (family == AF_INET) {
            return getSocketOption_Integer(env, fd, IPPROTO_IP, IP_TOS);
        } else {
            return getSocketOption_Integer(env, fd, IPPROTO_IPV6, IPV6_TCLASS);
        }
    case JAVASOCKOPT_SO_LINGER:
        {
            linger lingr;
            bool ok = getSocketOption(env, fd, SOL_SOCKET, SO_LINGER, &lingr);
            if (!ok) {
                return NULL; // We already threw.
            } else if (!lingr.l_onoff) {
                return booleanValueOf(env, false);
            } else {
                return integerValueOf(env, lingr.l_linger);
            }
        }
    case JAVASOCKOPT_SO_TIMEOUT:
        {
            timeval timeout;
            bool ok = getSocketOption(env, fd, SOL_SOCKET, SO_RCVTIMEO, &timeout);
            return ok ? integerValueOf(env, toMs(timeout)) : NULL;
        }
#ifdef ENABLE_MULTICAST
    case JAVASOCKOPT_IP_MULTICAST_IF:
        {
            // Although setsockopt(2) can take an ip_mreqn for IP_MULTICAST_IF, getsockopt(2)
            // always returns an in_addr.
            sockaddr_storage ss;
            memset(&ss, 0, sizeof(ss));
            ss.ss_family = AF_INET; // This call is IPv4-only.
            sockaddr_in* sa = reinterpret_cast<sockaddr_in*>(&ss);
            if (!getSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_IF, &sa->sin_addr)) {
                return NULL;
            }
            return socketAddressToInetAddress(env, &ss);
        }
    case JAVASOCKOPT_IP_MULTICAST_IF2:
        if (family == AF_INET) {
            // The caller's asking for an interface index, but that's not how IPv4 works.
            // Our Java should never get here, because we'll try IP_MULTICAST_IF first and
            // that will satisfy us.
            jniThrowSocketException(env, EAFNOSUPPORT);
        } else {
            return getSocketOption_Integer(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_IF);
        }
    case JAVASOCKOPT_IP_MULTICAST_LOOP:
        if (family == AF_INET) {
            // Although IPv6 was cleaned up to use int, IPv4 multicast loopback uses a byte.
            u_char loopback;
            bool ok = getSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loopback);
            return ok ? booleanValueOf(env, loopback) : NULL;
        } else {
            return getSocketOption_Boolean(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP);
        }
    case JAVASOCKOPT_MULTICAST_TTL:
        if (family == AF_INET) {
            // Although IPv6 was cleaned up to use int, and IPv4 non-multicast TTL uses int,
            // IPv4 multicast TTL uses a byte.
            u_char ttl;
            bool ok = getSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl);
            return ok ? integerValueOf(env, ttl) : NULL;
        } else {
            return getSocketOption_Integer(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS);
        }
#else
    case JAVASOCKOPT_MULTICAST_TTL:
    case JAVASOCKOPT_IP_MULTICAST_IF:
    case JAVASOCKOPT_IP_MULTICAST_IF2:
    case JAVASOCKOPT_IP_MULTICAST_LOOP:
        jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
        return NULL;
#endif // def ENABLE_MULTICAST
    default:
        jniThrowSocketException(env, ENOPROTOOPT);
        return NULL;
    }
}
Beispiel #13
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;
}
Beispiel #14
0
void updateLightFlares() {
	
	RaycastDebugClear();
	
	ARX_PROFILE_FUNC();
	
	Entity * pTableIO[256];
	size_t nNbInTableIO = 0;
	
	float temp_increase = toMs(g_platformTime.lastFrameDuration()) * 0.004f;
	
	const Vec3f camPos = g_camera->m_pos;
	
	bool bComputeIO = false;

	Vec4f zFar = g_preparedCamera.m_viewToScreen * Vec4f(0.f, 0.f, g_camera->cdepth * fZFogEnd, 1.f);
	float fZFar = zFar.z / zFar.w;

	for(size_t i = 0; i < g_culledDynamicLightsCount; i++) {
		EERIE_LIGHT * el = g_culledDynamicLights[i];
		
		if(!ACTIVEBKG->isInActiveTile(el->pos)) {
			el->m_isVisible = false;
			continue;
		}
		
		if(el->extras & EXTRAS_FLARE) {
			Vec3f lv = el->pos;
			
			Vec4f p = worldToClipSpace(lv);
			Vec3f pos2d = Vec3f(p) / p.w;
			
			el->m_flareFader -= temp_increase;

			if(p.w > 0.f && pos2d.x > 0.f && pos2d.x < g_size.width()
			   && pos2d.y > (cinematicBorder.CINEMA_DECAL * g_sizeRatio.y)
				 && pos2d.y < (g_size.height() - (cinematicBorder.CINEMA_DECAL * g_sizeRatio.y))) {
				
				Vec3f vector = lv - camPos;
				lv -= vector * (50.f / glm::length(vector));
				
				Vec3f ee3dlv = lv;
				Vec2s ees2dlv(checked_range_cast<short>(pos2d.x), checked_range_cast<short>(pos2d.y));
				if(!bComputeIO) {
					GetFirstInterAtPos(ees2dlv, 2, &ee3dlv, pTableIO, &nNbInTableIO);
					bComputeIO = true;
				}
				
				if(   pos2d.z > fZFar
				   || RaycastLightFlare(camPos, el->pos)
				   || GetFirstInterAtPos(ees2dlv, 3, &ee3dlv, pTableIO, &nNbInTableIO)
				) {
					el->m_flareFader -= temp_increase * 2.f;
				} else {
					el->m_flareFader += temp_increase * 2.f;
				}
			}

			el->m_flareFader = glm::clamp(el->m_flareFader, 0.f, .8f);
		}
	}
}
Beispiel #15
0
void ARX_MAGICAL_FLARES_Update() {

	if(!g_magicFlaresCount)
		return;

	shinum++;
	if(shinum >= 10) {
		shinum = 1;
	}
	
	float diff = toMs(g_platformTime.lastFrameDuration());
	
	bool key = !GInput->actionPressed(CONTROLS_CUST_MAGICMODE);

	RenderMaterial mat;
	mat.setBlendType(RenderMaterial::Additive);
	
	EERIE_LIGHT * light = lightHandleGet(torchLightHandle);
	
	for(long j = 1; j < 5; j++) {

		TextureContainer * surf;
		switch(j) {
			case 2:  surf = g_magicFlareTextures.lumignon; break;
			case 3:  surf = g_magicFlareTextures.lumignon2; break;
			case 4:  surf = g_magicFlareTextures.plasm; break;
			default: surf = g_magicFlareTextures.shine[shinum]; break;
		}

		mat.setTexture(surf);

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

			MagicFlare & flare = g_magicFlares[i];

			if(!flare.exist || flare.type != j) {
				continue;
			}

			flare.tolive -= diff * 2.f;
			if(flare.flags & 1) {
				flare.tolive -= diff * 4.f;
			} else if (key) {
				flare.tolive -= diff * 6.f;
			}

			float z = (flare.tolive * 0.00025f);
			float size;
			if(flare.type == 1) {
				size = flare.size * 2 * z;
			} else if(flare.type == 4) {
				size = flare.size * 2.f * z + 10.f;
			} else {
				size = flare.size;
			}

			if(flare.tolive <= 0.f || flare.pos.y < -64.f || size < 3.f) {
				removeFlare(flare);
				continue;
			}

			if(flare.type == 1 && z < 0.6f)  {
				z = 0.6f;
			}

			Color3f c = flare.rgb * z;
			flare.tv.color = c.toRGB();
			flare.v.p = flare.tv.p;

			light->rgb = componentwise_max(light->rgb, c);
			
			EERIE_LIGHT * el = lightHandleGet(flare.dynlight);
			if(el) {
				el->pos = flare.v.p;
				el->rgb = c;
			}

			mat.setDepthTest(flare.io != NULL);
			
			if(flare.bDrawBitmap) {
				size *= 2.f * minSizeRatio();
				EERIEAddBitmap(mat, flare.v.p, size, size, surf, Color::fromRGBA(flare.tv.color));
			} else {
				EERIEAddSprite(mat, flare.v.p, size * 0.025f + 1.f,
				               Color::fromRGBA(flare.tv.color), 2.f);
			}

		}
	}

	light->rgb = componentwise_min(light->rgb, Color3f::white);
}