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; } } } } }
void lightHandleDestroy(LightHandle & handle) { if(lightHandleIsValid(handle)) { lightHandleGet(handle)->exist = 0; } handle = LightHandle(); }
void ConfuseSpell::Update() { 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); arxtime.update(); Anglef stiteangle = Anglef(0.f, -glm::degrees(arxtime.now_f() * ( 1.0f / 500 )), 0.f); { EERIEDrawAnimQuatUpdate(spapi, animlayer, stiteangle, eCurPos, g_framedelay, 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->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 IceFieldSpell::Update() { if(!lightHandleIsValid(m_light)) m_light = GetFreeDynLight(); if(lightHandleIsValid(m_light)) { EERIE_LIGHT * el = lightHandleGet(m_light); el->pos = m_pos + Vec3f(0.f, -120.f, 0.f); el->intensity = 4.6f; el->fallstart = Random::getf(150.f, 180.f); el->fallend = Random::getf(290.f, 320.f); el->rgb = Color3f(0.76f, 0.76f, 1.0f) + Color3f(0.f, 0.f, Random::getf(-0.1f, 0.f)); el->duration = 600; el->extras=0; } if(!VisibleSphere(Sphere(m_pos - Vec3f(0.f, 120.f, 0.f), 350.f))) return; RenderMaterial mat; mat.setDepthTest(true); mat.setBlendType(RenderMaterial::Additive); for(int i = 0; i < iMax; i++) { tSize[i] += Vec3f(0.1f); tSize[i] = glm::min(tSize[i], tSizeMax[i]); Anglef stiteangle = Anglef::ZERO; Vec3f stitepos; Vec3f stitescale; Color3f stitecolor; stiteangle.setPitch(glm::cos(glm::radians(tPos[i].x)) * 360); stitepos.x = tPos[i].x; stitepos.y = m_pos.y; stitepos.z = tPos[i].z; stitecolor.r = tSizeMax[i].y * 0.7f; stitecolor.g = tSizeMax[i].y * 0.7f; stitecolor.b = tSizeMax[i].y * 0.9f; if(stitecolor.r > 1) stitecolor.r = 1; if(stitecolor.g > 1) stitecolor.g = 1; if(stitecolor.b > 1) stitecolor.b = 1; stitescale.z = tSize[i].x; stitescale.y = tSize[i].y; stitescale.x = tSize[i].z; EERIE_3DOBJ * obj = (tType[i] == 0) ? smotte : stite; Draw3DObject(obj, stiteangle, stitepos, stitescale, stitecolor, mat); } for(int i = 0; i < iMax * 0.5f; i++) { float t = Random::getf(); if(t < 0.01f) { PARTICLE_DEF * pd = createParticle(); if(pd) { pd->ov = tPos[i] + randomVec(-5.f, 5.f); pd->move = randomVec(-2.f, 2.f); pd->siz = 20.f; pd->tolive = Random::getu(2000, 6000); pd->tc = tex_p2; pd->special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING; pd->fparam = 0.0000001f; pd->rgb = Color3f(0.7f, 0.7f, 1.f); } } else if (t > 0.095f) { PARTICLE_DEF * pd = createParticle(); if(pd) { pd->ov = tPos[i] + randomVec(-5.f, 5.f) + Vec3f(0.f, 50.f, 0.f); pd->move = Vec3f(0.f, Random::getf(-2.f, 2.f), 0.f); pd->siz = 0.5f; pd->tolive = Random::getu(2000, 6000); pd->tc = tex_p1; pd->special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING; pd->fparam = 0.0000001f; pd->rgb = Color3f(0.7f, 0.7f, 1.f); } } } }
void FlyingEyeSpell::Update() { const unsigned long now = arxtime.now_ul(); const long framediff3 = now - 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=now; 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::getu(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(); } } } }
void CreateFieldSpell::Launch() { unsigned long start = arxtime.now_ul(); if(m_flags & SPELLCAST_FLAG_RESTORE) { start -= std::min(start, 4000ul); } m_timcreation = start; m_duration = (m_launchDuration > -1) ? m_launchDuration : 800000; m_hasDuration = true; m_fManaCostPerSecond = 1.2f; Vec3f target; float beta = 0.f; bool displace = false; if(m_caster == PlayerEntityHandle) { target = entities.player()->pos; beta = player.angle.getPitch(); displace = true; } else { if(ValidIONum(m_caster)) { Entity * io = entities[m_caster]; target = io->pos; beta = io->angle.getPitch(); displace = (io->ioflags & IO_NPC) == IO_NPC; } else { ARX_DEAD_CODE(); } } if(displace) { target += angleToVectorXZ(beta) * 250.f; } ARX_SOUND_PlaySFX(SND_SPELL_CREATE_FIELD, &target); res::path cls = "graph/obj3d/interactive/fix_inter/blue_cube/blue_cube"; Entity * io = AddFix(cls, -1, IO_IMMEDIATELOAD); if(io) { ARX_INTERACTIVE_HideGore(io); RestoreInitialIOStatusOfIO(io); m_entity = io->index(); io->scriptload = 1; io->ioflags |= IO_NOSAVE | IO_FIELD; io->initpos = io->pos = target; SendInitScriptEvent(io); m_field.Create(target); m_field.SetDuration(m_duration); m_field.lLightId = GetFreeDynLight(); if(lightHandleIsValid(m_field.lLightId)) { EERIE_LIGHT * light = lightHandleGet(m_field.lLightId); light->intensity = 0.7f + 2.3f; light->fallend = 500.f; light->fallstart = 400.f; light->rgb = Color3f(0.8f, 0.0f, 1.0f); light->pos = m_field.eSrc - Vec3f(0.f, 150.f, 0.f); } m_duration = m_field.GetDuration(); if(m_flags & SPELLCAST_FLAG_RESTORE) { m_field.Update(4000); } } else { m_duration = 0; } }
void RiseDeadSpell::Update() { if(m_creationFailed) { m_light = LightHandle(); return; } m_duration+=200; m_fissure.Update(g_framedelay); m_fissure.Render(); if(lightHandleIsValid(m_light)) { EERIE_LIGHT * light = lightHandleGet(m_light); light->intensity = 0.7f + 2.3f; light->fallend = 500.f; light->fallstart = 400.f; light->rgb = Color3f(0.8f, 0.2f, 0.2f); light->duration=800; light->creationTime = arxtime.now_ul(); } unsigned long tim = m_fissure.ulCurrentTime; if(tim > 3000 && m_entity == EntityHandle() && !m_creationFailed) { ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, &m_targetPos); Cylinder phys = Cylinder(m_targetPos, 50, -200); float anything = CheckAnythingInCylinder(phys, NULL, CFLAG_JUST_TEST); if(glm::abs(anything) < 30) { const char * cls = "graph/obj3d/interactive/npc/undead_base/undead_base"; Entity * io = AddNPC(cls, -1, IO_IMMEDIATELOAD); if(io) { ARX_INTERACTIVE_HideGore(io); RestoreInitialIOStatusOfIO(io); io->summoner = m_caster; io->ioflags|=IO_NOSAVE; m_entity = io->index(); io->scriptload=1; ARX_INTERACTIVE_Teleport(io, phys.origin); SendInitScriptEvent(io); if(ValidIONum(m_caster)) { EVENT_SENDER = entities[m_caster]; } else { EVENT_SENDER = NULL; } SendIOScriptEvent(io,SM_SUMMONED); Vec3f pos = m_fissure.m_eSrc; pos += randomVec3f() * 100.f; pos += Vec3f(-50.f, 50.f, -50.f); MakeCoolFx(pos); } m_light = LightHandle(); } else { ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE); m_creationFailed = true; m_duration=0; } } else if(!arxtime.is_paused() && tim < 4000) { if(Random::getf() > 0.95f) { MakeCoolFx(m_fissure.m_eSrc); } } }