// flag 1 = randomize pos void ARX_PARTICLES_Add_Smoke(const Vec3f & pos, long flags, long amount, const Color3f & rgb) { Vec3f mod = (flags & 1) ? randomVec(-50.f, 50.f) : Vec3f_ZERO; while(amount--) { PARTICLE_DEF * pd = createParticle(); if(!pd) { return; } pd->ov = pos + mod; if(flags & 2) { pd->siz = Random::getf(15.f, 35.f); pd->scale = randomVec(40.f, 55.f); } else { pd->siz = Random::getf(5.f, 13.f); pd->scale = randomVec(10.f, 15.f); } pd->m_flags = ROTATING | FADE_IN_AND_OUT; pd->tolive = Random::getu(1100, 1500); pd->delay = amount * 120 + Random::getu(0, 100); pd->move = Vec3f(Random::getf(-0.25f, 0.25f), Random::getf(-0.7f, 0.3f), Random::getf(-0.25f, 0.25f)); pd->rgb = rgb; pd->tc = smokeparticle; pd->m_rotation = 0.01f; } }
void FlyingEyeSpell::End() { ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE, &entities[m_caster]->pos); static TextureContainer * tc4=TextureContainer::Load("graph/particles/smoke"); ARX_SOUND_PlaySFX(SND_SPELL_EYEBALL_OUT); eyeball.exist = -100; for(long n = 0; n < 12; n++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } pd->ov = eyeball.pos + randomVec(-5.f, 5.f); pd->move = randomVec(-2.f, 2.f); pd->siz = 28.f; pd->tolive = Random::get(2000, 6000); pd->scale = Vec3f(12.f); pd->tc = tc4; pd->special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING; pd->fparam = 0.0000001f; pd->rgb = Color3f(0.7f, 0.7f, 1.f); } config.input.mouseLookToggle = bOldLookToggle; lightHandleDestroy(special[2]); lightHandleDestroy(special[1]); }
static void ARX_DAMAGES_AddVisual(DAMAGE_INFO * di, Vec3f * pos, float dmg, Entity * io) { if(!(di->params.type & DAMAGE_TYPE_FAKEFIRE)) { return; } long num = -1; if(io) { num = Random::get(0, io->obj->vertexlist.size() / 4 - 1) * 4 + 1; } unsigned long tim = (unsigned long)(arxtime); if(di->lastupd + 200 < tim) { di->lastupd = tim; if(di->params.type & DAMAGE_TYPE_MAGICAL) { ARX_SOUND_PlaySFX(SND_SPELL_MAGICAL_HIT, pos, 0.8F + 0.4F * rnd()); } else { ARX_SOUND_PlaySFX(SND_SPELL_FIRE_HIT, pos, 0.8F + 0.4F * rnd()); } } for(long k = 0 ; k < 14 ; k++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } if(io) { arx_assert(num >= 0); pd->ov = io->obj->vertexlist3[num].v + randomVec(-5.f, 5.f); } else { pd->ov = *pos + randomVec(-50.f, 50.f); } pd->siz = glm::clamp(dmg, 5.f, 15.f); pd->scale = Vec3f(-10.f); pd->special = ROTATING | MODULATE_ROTATION | FIRE_TO_SMOKE; pd->tolive = Random::get(500, 900); pd->move = Vec3f(1.f - 2.f * rnd(), 2.f - 16.f * rnd(), 1.f - 2.f * rnd()); if(di->params.type & DAMAGE_TYPE_MAGICAL) { pd->rgb = Color3f(0.3f, 0.3f, 0.8f); } else { pd->rgb = Color3f::gray(0.5f); } pd->tc = TC_fire2; pd->fparam = 0.1f - rnd() * 0.2f; } }
void ARX_FOGS_Render() { if(arxtime.is_paused()) { return; } int iDiv = 4 - config.video.levelOfDetail; float flDiv = static_cast<float>(1 << iDiv); for(long i = 0; i < MAX_FOG; i++) { FOG_DEF *fog = &fogs[i]; if(!fog->exist) continue; long count = std::max(1l, checked_range_cast<long>(framedelay / flDiv)); while(count--) { if(rnd() * 2000.f >= fog->frequency) { continue; } PARTICLE_DEF * pd = createParticle(true); if(!pd) { break; } pd->special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING; if(fog->special & FOG_DIRECTIONAL) { pd->ov = fog->pos; pd->move = fog->move * (fog->speed * 0.1f); } else { pd->ov = fog->pos + randomVec(-100.f, 100.f); pd->move = Vec3f::repeat(fog->speed) - randomVec(0.f, 2.f); pd->move *= Vec3f(fog->speed * 0.2f, 1.f / 15, fog->speed * 0.2f); } pd->scale = Vec3f::repeat(fog->scale); pd->tolive = fog->tolive + Random::get(0, fog->tolive); pd->tc = TC_smoke; pd->siz = (fog->size + rnd() * fog->size * 2.f) * (1.0f / 3); pd->rgb = fog->rgb; pd->fparam = fog->rotatespeed; } fog->lastupdate = (unsigned long)(arxtime); } }
void ARX_PARTICLES_Spawn_Lava_Burn(Vec3f pos, Entity * io) { if(io && io->obj && !io->obj->facelist.empty()) { size_t num = 0; long notok = 10; while(notok-- > 0) { num = Random::getu(0, io->obj->facelist.size() - 1); if(io->obj->facelist[num].facetype & POLY_HIDE) { continue; } if(glm::abs(pos.y-io->obj->vertexlist3[io->obj->facelist[num].vid[0]].v.y) > 50.f) { continue; } notok = -1; } pos = io->obj->vertexlist3[io->obj->facelist[num].vid[0]].v; } PARTICLE_DEF * pd = createParticle(); if(!pd) { return; } pd->ov = pos; pd->move = randomVec3f() * Vec3f(2.f, -12.f, 2.f) - Vec3f(4.f, 15.f, 4.f); pd->tolive = 800; pd->tc = smokeparticle; pd->siz = 15.f; pd->scale = randomVec(15.f, 20.f); pd->m_flags = FIRE_TO_SMOKE; if(Random::getf() > 0.5f) { pd->m_flags |= SUBSTRACT; } }
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(); } }
void PoisonProjectileSpell::AddPoisonFog(const Vec3f & pos, float power) { int iDiv = 4 - config.video.levelOfDetail; float flDiv = static_cast<float>(1 << iDiv); arxtime.update(); long count = std::max(1l, checked_range_cast<long>(framedelay / flDiv)); while(count--) { if(rnd() * 2000.f >= power) { continue; } PARTICLE_DEF * pd = createParticle(); if(!pd) { return; } float speed = 1.f; float fval = speed * 0.2f; pd->special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING; pd->ov = pos + randomVec(-100.f, 100.f); pd->scale = Vec3f(8.f, 8.f, 10.f); pd->move = Vec3f((speed - rnd()) * fval, (speed - speed * rnd()) * (1.f / 15), (speed - rnd()) * fval); pd->tolive = Random::get(4500, 9000); pd->tc = TC_smoke; pd->siz = (80.f + rnd() * 160.f) * (1.f / 3); pd->rgb = Color3f(rnd() * (1.f / 3), 1.f, rnd() * 0.1f); pd->fparam = 0.001f; } }
void AddRandomSmoke(Entity * io, long amount) { if(!io) { return; } for(long i = 0; i < amount; i++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { return; } long vertex = Random::get(0, io->obj->vertexlist.size() - 1); pd->ov = io->obj->vertexlist3[vertex].v + randomVec(-5.f, 5.f); pd->siz = Random::getf(0.f, 8.f); if(pd->siz < 4.f) { pd->siz = 4.f; } pd->scale = Vec3f(10.f); pd->m_flags = ROTATING | FADE_IN_AND_OUT; pd->tolive = Random::getu(900, 1300); pd->move = Vec3f(Random::getf(-0.25f, 0.25f), Random::getf(-0.7f, 0.3f), Random::getf(-0.25f, 0.25f)); pd->rgb = Color3f(0.3f, 0.3f, 0.34f); pd->tc = smokeparticle; pd->m_rotation = 0.001f; } }
void FireFieldSpell::Update(float timeDelta) { pPSStream.Update(timeDelta); pPSStream1.Update(timeDelta); 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 = 150.f+rnd()*30.f; el->fallend = 290.f+rnd()*30.f; el->rgb = Color3f(1.f, 0.8f, 0.6f) - Color3f(rnd()*(1.0f/10), 0.f, 0.f); el->duration = 600; el->extras=0; } if(VisibleSphere(Sphere(m_pos - Vec3f(0.f, 120.f, 0.f), 350.f))) { pPSStream.Render(); pPSStream1.Render(); float fDiff = timeDelta / 8.f; int nTime = checked_range_cast<int>(fDiff); for(long nn=0;nn<=nTime+1;nn++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } float t = rnd() * (PI * 2.f) - PI; float ts = std::sin(t); float tc = std::cos(t); pd->ov = m_pos + Vec3f(120.f * ts, 15.f * ts, 120.f * tc) * randomVec(); pd->move = Vec3f(2.f, 1.f, 2.f) + Vec3f(-4.f, -8.f, -4.f) * Vec3f(rnd(), rnd(), rnd()); pd->siz = 7.f; pd->tolive = Random::get(500, 1500); pd->tc = fire2; pd->special = ROTATING | MODULATE_ROTATION | FIRE_TO_SMOKE; pd->fparam = 0.1f - rnd() * 0.2f; pd->scale = Vec3f(-8.f); PARTICLE_DEF * pd2 = createParticle(); if(!pd2) { break; } *pd2 = *pd; pd2->delay = Random::get(60, 210); } } }
void MassLightningStrikeSpell::Update(float timeDelta) { for(size_t i = 0; i < pTab.size(); i++) { CLightning * lightning = pTab[i]; lightning->m_caster = m_caster; lightning->m_level = m_level; lightning->Update(timeDelta); } for(size_t i = 0; i < pTab.size(); i++) { pTab[i]->Render(); } Vec3f position; position = m_pos + randomVec(-250.f, 250.f); ARX_SOUND_RefreshPosition(m_snd_loop, position); ARX_SOUND_RefreshVolume(m_snd_loop, 1.f); ARX_SOUND_RefreshPitch(m_snd_loop, Random::getf(0.8f, 1.2f)); if(Random::getf() > 0.62f) { position = m_pos + randomVec(-250.f, 250.f); ARX_SOUND_PlaySFX(SND_SPELL_SPARK, &position, Random::getf(0.8f, 1.2f)); } if(Random::getf() > 0.82f) { position = m_pos + randomVec(-250.f, 250.f); ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, &position, Random::getf(0.8f, 1.2f)); } if(0 > (long(m_duration) - 1800) && !m_soundEffectPlayed) { m_soundEffectPlayed = true; ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, NULL, Random::getf(0.8f, 1.2f)); } if(lightHandleIsValid(m_light)) { EERIE_LIGHT * light = lightHandleGet(m_light); light->intensity = Random::getf(1.3f, 2.3f); } }
void FireFieldSpell::Update() { pPSStream.Update(g_framedelay); pPSStream1.Update(g_framedelay); EERIE_LIGHT * el = dynLightCreate(m_light); if(el) { 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(1.f, 0.8f, 0.6f) + Color3f(Random::getf(-0.1f, 0.f), 0.f, 0.f); el->duration = ArxDurationMs(600); el->extras=0; } if(VisibleSphere(Sphere(m_pos - Vec3f(0.f, 120.f, 0.f), 350.f))) { pPSStream.Render(); pPSStream1.Render(); float fDiff = g_framedelay / 8.f; int nTime = checked_range_cast<int>(fDiff); for(long nn=0;nn<=nTime+1;nn++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } float t = Random::getf() * (glm::pi<float>() * 2.f) - glm::pi<float>(); float ts = std::sin(t); float tc = std::cos(t); pd->ov = m_pos + Vec3f(120.f * ts, 15.f * ts, 120.f * tc) * randomVec(); pd->move = Vec3f(2.f, 1.f, 2.f) + Vec3f(-4.f, -8.f, -4.f) * randomVec3f(); pd->siz = 7.f; pd->tolive = Random::getu(500, 1500); pd->tc = fire2; pd->m_flags = ROTATING | FIRE_TO_SMOKE; pd->m_rotation = Random::getf(-0.1f, 0.1f); pd->scale = Vec3f(-8.f); PARTICLE_DEF * pd2 = createParticle(); if(!pd2) { break; } *pd2 = *pd; pd2->delay = Random::getu(60, 210); } } }
void FlyingEyeSpell::Launch() { static TextureContainer * tc4 = TextureContainer::Load("graph/particles/smoke"); ARX_SOUND_PlaySFX(SND_SPELL_EYEBALL_IN); m_lastupdate = m_timcreation; m_duration = 1000000; m_hasDuration = true; m_fManaCostPerSecond = 3.2f; eyeball.exist = 1; eyeball.pos = player.pos; eyeball.pos += angleToVectorXZ(player.angle.getPitch()) * 200.f; eyeball.pos += Vec3f(0.f, 50.f, 0.f); eyeball.angle = player.angle; for(long n = 0; n < 12; n++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } pd->ov = eyeball.pos + randomVec(-5.f, 5.f); pd->move = randomVec(-2.f, 2.f); pd->siz = 28.f; pd->tolive = Random::get(2000, 6000); pd->scale = Vec3f(12.f); pd->tc = tc4; pd->special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING; pd->fparam = 0.0000001f; pd->rgb = Color3f(0.7f, 0.7f, 1.f); } TRUE_PLAYER_MOUSELOOK_ON = true; SLID_START = float(arxtime); bOldLookToggle = config.input.mouseLookToggle; config.input.mouseLookToggle = true; }
void Split(TexturedVertex * v, int a, int b, float yo, float fMul) { if (a != b) { int i = (int)((a + b) * 0.5f); if ((i != a) && (i != b)) { v[i].p = (v[a].p + v[b].p) * 0.5f + randomVec(-yo, yo); Split(v, a, i, yo * fMul); Split(v, i, b, yo * fMul); } } }
void Particle::randomPosAdjust() { if (type.compare("Faded") == 0) { D3DXVECTOR3 playerVec =EntityManager::getInstance()->currentPlayer->getPos() -startPosition ; D3DXVec3Normalize(&playerVec,&playerVec); float rando = (float)rand()/RAND_MAX; D3DXVECTOR3 randomVec(0.0f,-1.0f + rando * 2.0f,0.0f); D3DXVec3Cross(&randomVec,&playerVec,&randomVec); ge3D_position +=randomVec; rando = (float)rand()/RAND_MAX; //ge3D_position.z += (-.5f + dist(eng) * 1.0f)* playerVec.z; } }
void BubbleEmitter::SetBubbleParameter( BubbleActorPtr bubbleActor, unsigned int curUniform, const Vector2& emitPosition, const Vector2& direction, const Vector2& displacement ) { Vector2 dir(direction); int halfRange = displacement.x / 2; // for the y coordinate, always negative, so bubbles always go upwards Vector2 randomVec( rand_r( &mRandomSeed ) % static_cast<int>(displacement.x) - halfRange, -rand_r( &mRandomSeed ) % static_cast<int>(displacement.y) ); dir.Normalize(); randomVec.x -= dir.x*halfRange; randomVec.y *= 1.0f - fabsf(dir.x)*0.33f; if(randomVec.y > 0.0f) { randomVec.y *= 0.33f; } Vector4 startAndEndPos( emitPosition.x, emitPosition.y, emitPosition.x+randomVec.x, emitPosition.y+randomVec.y ); bubbleActor->SetStartAndEndPosition( curUniform, startAndEndPos ); bubbleActor->SetPercentage( curUniform, 0.f); }
void ManageQuakeFX(EERIE_CAMERA * cam) { if(QuakeFx.intensity>0.f) { float tim=(float)arxtime.get_frame_time()-(float)QuakeFx.start; if(tim >= QuakeFx.duration) { QuakeFx.intensity=0.f; return; } float itmod=1.f-(tim/QuakeFx.duration); float periodicity=std::sin((float)arxtime.get_frame_time()*QuakeFx.frequency*( 1.0f / 100 )); if(periodicity > 0.5f && QuakeFx.sound) ARX_SOUND_PlaySFX(SND_QUAKE, NULL, 1.0F - 0.5F * QuakeFx.intensity); float truepower = periodicity * QuakeFx.intensity * itmod * 0.01f; float halfpower = truepower * .5f; cam->orgTrans.pos += randomVec(-halfpower, halfpower); cam->angle.setPitch(cam->angle.getPitch() + Random::getf() * truepower - halfpower); cam->angle.setYaw(cam->angle.getYaw() + Random::getf() * truepower - halfpower); cam->angle.setRoll(cam->angle.getRoll() + Random::getf() * truepower - halfpower); } }
void ARX_PARTICLES_Spawn_Splat(const Vec3f & pos, float dmgs, Color col) { const unsigned long tolive = 1000 + static_cast<unsigned long>(dmgs) * 3; float power = (dmgs * (1.f / 60)) + .9f; for(long kk = 0; kk < 20; kk++) { PARTICLE_DEF * pd = createParticle(true); if(!pd) { return; } pd->m_flags = PARTICLE_SUB2 | SUBSTRACT | GRAVITY; pd->ov = pos; pd->move = randomVec(-11.5f, 11.5f); pd->tolive = tolive; pd->tc = blood_splat; pd->siz = 0.3f + 0.01f * power; pd->scale = Vec3f(0.2f + 0.3f * power); pd->zdec = true; pd->rgb = col.to<float>(); } }
//----------------------------------------------------------------------------- // Updates all currently launched projectiles void ARX_MISSILES_Update() { TextureContainer * tc = TC_fire; unsigned long tim = (unsigned long)(arxtime); for(unsigned long i(0); i < MAX_MISSILES; i++) { if(missiles[i].type == MISSILE_NONE) continue; long framediff = missiles[i].timecreation + missiles[i].tolive - tim; if(framediff < 0) { ARX_MISSILES_Kill(i); continue; } long framediff3 = tim - missiles[i].timecreation; switch(missiles[i].type) { case MISSILE_NONE: break; case MISSILE_FIREBALL: { Vec3f pos; pos = missiles[i].startpos + missiles[i].velocity * Vec3f(framediff3); if(missiles[i].longinfo != -1) { DynLight[missiles[i].longinfo].pos = pos; } Vec3f orgn = missiles[i].lastpos; Vec3f dest = pos; Vec3f tro = Vec3f(70.f); EERIEPOLY *ep = GetMinPoly(dest.x, dest.y, dest.z); EERIEPOLY *epp = GetMaxPoly(dest.x, dest.y, dest.z); if(closerThan(player.pos, pos, 200.f)) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(&pos); Add3DBoom(&pos); DoSphericDamage(&dest, 180.0F, 200.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } if(ep && ep->center.y < dest.y) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(&dest); Add3DBoom(&dest); DoSphericDamage(&dest, 180.0F, 200.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } if(epp && epp->center.y > dest.y) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(&dest); Add3DBoom(&dest); DoSphericDamage(&dest, 180.0F, 200.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } Vec3f hit; EERIEPOLY *tp = NULL; if(EERIELaunchRay3(&orgn, &dest, &hit, tp, 1)) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(&hit); Add3DBoom(&hit); DoSphericDamage(&dest, 180.0F, 200.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } if(!EECheckInPoly(&dest) || EEIsUnderWater(&dest)) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(&dest); Add3DBoom(&dest); DoSphericDamage(&dest, 180.0F, 200.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } long ici = IsCollidingAnyInter(dest.x, dest.y, dest.z, &tro); if(ici != -1 && ici != missiles[i].owner) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(&dest); Add3DBoom(&dest); DoSphericDamage(&dest, 180.0F, 200.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } PARTICLE_DEF * pd = createParticle(); if(pd) { pd->ov = pos; pd->move = missiles[i].velocity; pd->move += Vec3f(3.f - 6.f * rnd(), 4.f - 12.f * rnd(), 3.f - 6.f * rnd()); pd->tolive = Random::get(500, 1000); pd->tc = tc; pd->siz = 12.f * float(missiles[i].tolive - framediff3) * (1.f / 4000); pd->scale = randomVec(15.f, 20.f); pd->special = FIRE_TO_SMOKE; } missiles[i].lastpos = pos; break; } } missiles[i].lastupdate = tim; } }
int main() { std::string nebulaResponse; std::cout << "Start with nebula? [y/N] "; std::getline(std::cin,nebulaResponse); bool makeNebula = (!nebulaResponse.empty() && std::tolower(nebulaResponse[0]) == 'y'); std::cout << std::endl; printControls(); Perlin perlin{(int)PERLIN_WIDTH,(int)PERLIN_HEIGHT}; PlanetSystem system; sf::RenderWindow window(sf::VideoMode(INITIAL_WIDTH,INITIAL_HEIGHT),"Gravity"); Planet planetToAdd(START_MASS,Vec2f::ZERO,Vec2f::ZERO); planetToAdd.drawUnfilled = true; sf::VertexArray velLine; velLine.resize(2); velLine.setPrimitiveType(sf::Lines); velLine[0].color = velLine[1].color = sf::Color::Blue; sf::VertexArray velLineTmp; velLineTmp.resize(2); velLineTmp.setPrimitiveType(sf::Lines); velLineTmp[0].color = velLineTmp[1].color = sf::Color::Blue; sf::View camera(sf::FloatRect(0,0,INITIAL_WIDTH,INITIAL_HEIGHT)); sf::Vector2f prevMouseLoc; bool movingCamera = false; bool running = true; system.setDrawingTrails(true); if(makeNebula) { for(int x=0;x<20;x++) { for(int y=0;y<20;y++) { Vec2f loc = {{(float)(x/20.0*INITIAL_WIDTH), (float)(y/20.0*INITIAL_HEIGHT)}}; Vec2f perlinLoc = {{loc[0]/(float)INITIAL_WIDTH*PERLIN_WIDTH, loc[1]/(float)INITIAL_HEIGHT*PERLIN_HEIGHT}}; double noise = perlin.octaveNoise(perlinLoc[0],perlinLoc[1]); Planet p{(float)(40+noise*60),loc,randomVec(40)}; system.addPlanet(p); } } } window.setFramerateLimit(FPS); while(window.isOpen()) { //std::cout << "tick\n"; sf::Event event; while(window.pollEvent(event)) { switch(event.type) { case sf::Event::Closed: window.close(); break; case sf::Event::Resized: camera.setSize(event.size.width,event.size.height); break; case sf::Event::MouseWheelMoved: { float newRadius = planetToAdd.radius()+event.mouseWheel.delta; planetToAdd.mass = std::min(MAX_MASS,std::exp(newRadius)); } break; case sf::Event::MouseButtonPressed: if(event.mouseButton.button == sf::Mouse::Middle) { system.clear(); } break; case sf::Event::MouseButtonReleased: if(event.mouseButton.button == sf::Mouse::Left) { system.addPlanet(planetToAdd); } case sf::Event::KeyPressed: if(event.key.code == sf::Keyboard::Space) { system.setDrawingTrails(!system.drawingTrails()); } else if(event.key.code == sf::Keyboard::P) { running = !running; } default: break; } } if(sf::Mouse::isButtonPressed(sf::Mouse::Right)) { sf::Vector2f mouseLoc = sf::Vector2f(sf::Mouse::getPosition(window)); if(!movingCamera) { movingCamera = true; } else { camera.move(prevMouseLoc-mouseLoc); } prevMouseLoc = mouseLoc; } else { movingCamera = false; } sf::Vector2f worldOffset = camera.getCenter()-camera.getSize()/2.0f; bool drawVelLine = false; if(!sf::Mouse::isButtonPressed(sf::Mouse::Left)) { sf::Vector2i mouseLoc = sf::Mouse::getPosition(window); planetToAdd.loc[0] = worldOffset.x+mouseLoc.x; planetToAdd.loc[1] = worldOffset.y+mouseLoc.y; velLine[0].position = worldOffset+sf::Vector2f(mouseLoc); } else { drawVelLine = true; velLine[1].position = worldOffset +sf::Vector2f(sf::Mouse::getPosition(window)); planetToAdd.vel[0] = velLine[1].position.x - velLine[0].position.x; planetToAdd.vel[1] = velLine[1].position.y - velLine[0].position.y; planetToAdd.vel *= VEL_SCALAR; } if(running) { system.tick(DT); } window.clear(sf::Color::Black); window.setView(camera); window.draw(system); window.draw(planetToAdd); if(drawVelLine) { window.draw(velLine); } if(!running) { for(auto& planet:system._planets) { makeVelLine(planet,velLineTmp); window.draw(velLineTmp); } } window.display(); } }
//----------------------------------------------------------------------------- // Updates all currently launched projectiles void ARX_MISSILES_Update() { ARX_PROFILE_FUNC(); TextureContainer * tc = TC_fire; unsigned long tim = (unsigned long)(arxtime); for(unsigned long i(0); i < MAX_MISSILES; i++) { if(missiles[i].type == MISSILE_NONE) continue; long framediff = missiles[i].timecreation + missiles[i].tolive - tim; if(framediff < 0) { ARX_MISSILES_Kill(i); continue; } long framediff3 = tim - missiles[i].timecreation; switch(missiles[i].type) { case MISSILE_NONE: break; case MISSILE_FIREBALL: { Vec3f pos; pos = missiles[i].startpos + missiles[i].velocity * Vec3f(framediff3); if(lightHandleIsValid(missiles[i].longinfo)) { EERIE_LIGHT * light = lightHandleGet(missiles[i].longinfo); light->pos = pos; } Vec3f orgn = missiles[i].lastpos; Vec3f dest = pos; Vec3f tro = Vec3f(70.f); EERIEPOLY *ep = GetMinPoly(dest); EERIEPOLY *epp = GetMaxPoly(dest); if(closerThan(player.pos, pos, 200.f)) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(pos); Add3DBoom(pos); DoSphericDamage(Sphere(dest, 200.0F), 180.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } if(ep && ep->center.y < dest.y) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(dest); Add3DBoom(dest); DoSphericDamage(Sphere(dest, 200.0F), 180.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } if(epp && epp->center.y > dest.y) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(dest); Add3DBoom(dest); DoSphericDamage(Sphere(dest, 200.0F), 180.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } Vec3f hit; if(EERIELaunchRay3(orgn, dest, hit, 1)) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(hit); Add3DBoom(hit); DoSphericDamage(Sphere(dest, 200.0F), 180.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } if(!CheckInPoly(dest) || EEIsUnderWater(dest)) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(dest); Add3DBoom(dest); DoSphericDamage(Sphere(dest, 200.0F), 180.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } EntityHandle ici = IsCollidingAnyInter(dest, tro); if(ici != EntityHandle() && ici != missiles[i].owner) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(dest); Add3DBoom(dest); DoSphericDamage(Sphere(dest, 200.0F), 180.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } PARTICLE_DEF * pd = createParticle(); if(pd) { pd->ov = pos; pd->move = missiles[i].velocity; pd->move += Vec3f(3.f, 4.f, 3.f) + Vec3f(-6.f, -12.f, -6.f) * randomVec3f(); pd->tolive = Random::get(500, 1000); pd->tc = tc; pd->siz = 12.f * float(missiles[i].tolive - framediff3) * (1.f / 4000); pd->scale = randomVec(15.f, 20.f); pd->special = FIRE_TO_SMOKE; } missiles[i].lastpos = pos; break; } } missiles[i].lastupdate = tim; } }
//----------------------------------------------------------------------------- void CIceProjectile::Create(Vec3f aeSrc, float afBeta) { SetDuration(ulDuration); SetAngle(afBeta); fSize = 1; float xmin, ymin, zmin; Vec3f s, e, h; s.x = aeSrc.x; s.y = aeSrc.y - 100; s.z = aeSrc.z; float fspelldist = static_cast<float>(iMax * 15); fspelldist = min(fspelldist, 200.0f); fspelldist = max(fspelldist, 450.0f); e.x = aeSrc.x - fBetaRadSin * fspelldist; e.y = aeSrc.y - 100; e.z = aeSrc.z + fBetaRadCos * fspelldist; float fd; if (!Visible(&s, &e, NULL, &h)) { e.x = h.x + fBetaRadSin * 20; e.y = h.y; e.z = h.z - fBetaRadCos * 20; } fd = fdist(s, e); float fCalc = ulDuration * (fd / fspelldist); SetDuration(checked_range_cast<unsigned long>(fCalc)); float fDist = (fd / fspelldist) * iMax ; iNumber = checked_range_cast<int>(fDist); int end = iNumber / 2; tv1a[0].p = s + Vec3f(0.f, 100.f, 0.f); tv1a[end].p = e + Vec3f(0.f, 100.f, 0.f); Split(tv1a, 0, end, 80, 0.5f, 0, 1, 80, 0.5f); for (int i = 0; i < iNumber; i++) { float t = rnd(); if (t < 0.5f) tType[i] = 0; else tType[i] = 1; tSize[i] = Vec3f::ZERO; tSizeMax[i] = randomVec() + Vec3f(0.f, 0.2f, 0.f); if (tType[i] == 0) { xmin = 1.2f; ymin = 1; zmin = 1.2f; } else { xmin = 0.4f; ymin = 0.3f; zmin = 0.4f; } if (tSizeMax[i].x < xmin) tSizeMax[i].x = xmin; if (tSizeMax[i].y < ymin) tSizeMax[i].y = ymin; if (tSizeMax[i].z < zmin) tSizeMax[i].z = zmin; int iNum = static_cast<int>(i / 2); if (tType[i] == 0) { tPos[i].x = tv1a[iNum].p.x + frand2() * 80; tPos[i].y = tv1a[iNum].p.y; tPos[i].z = tv1a[iNum].p.z + frand2() * 80; } else { tPos[i].x = tv1a[iNum].p.x + frand2() * 40; tPos[i].y = tv1a[iNum].p.y; tPos[i].z = tv1a[iNum].p.z + frand2() * 40; } long ttt = ARX_DAMAGES_GetFree(); if(ttt != -1) { damages[ttt].pos = tPos[i]; damages[ttt].radius = 60.f; damages[ttt].damages = 0.1f * spells[spellinstance].caster_level; damages[ttt].area = DAMAGE_FULL; damages[ttt].duration = ulDuration; damages[ttt].source = spells[spellinstance].caster; damages[ttt].flags = DAMAGE_FLAG_DONT_HURT_SOURCE; damages[ttt].type = DAMAGE_TYPE_MAGICAL | DAMAGE_TYPE_COLD; damages[ttt].exist = true; } } fColor = 1; }
void IceFieldSpell::Update(float timeDelta) { ARX_UNUSED(timeDelta); 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 = 150.f+rnd()*30.f; el->fallend = 290.f+rnd()*30.f; el->rgb = Color3f(0.76f, 0.76f, 1.0f) + Color3f(0.f, 0.f, -rnd()*(1.0f/10)); 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 = rnd(); 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::get(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, 2.f - 4.f * rnd(), 0.f); pd->siz = 0.5f; pd->tolive = Random::get(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); } } } }
//--------------------------------------------------------------------- float CIceProjectile::Render() { int i = 0; if (ulCurrentTime >= ulDuration) return 0.f; GRenderer->SetCulling(Renderer::CullCW); GRenderer->SetRenderState(Renderer::DepthWrite, false); GRenderer->SetBlendFunc(Renderer::BlendInvDstColor, Renderer::BlendOne); GRenderer->SetRenderState(Renderer::AlphaBlending, true); iMax = (int)((iNumber * 2) * fOneOnDuration * ulCurrentTime); if (iMax > iNumber) iMax = iNumber; for (i = 0; i < iMax; i++) { if (tSize[i].x < tSizeMax[i].x) tSize[i].x += 0.1f; if (tSize[i].x > tSizeMax[i].x) tSize[i].x = tSizeMax[i].x; if (tSize[i].y < tSizeMax[i].y) tSize[i].y += 0.1f; if (tSize[i].y < 0) tSize[i].y = 0; if (tSize[i].y > tSizeMax[i].y) tSize[i].y = tSizeMax[i].y; if (tSize[i].z < tSizeMax[i].z) tSize[i].z += 0.1f; if (tSize[i].z > tSizeMax[i].z) tSize[i].z = tSizeMax[i].z; Anglef stiteangle; Vec3f stitepos; Vec3f stitescale; Color3f stitecolor; stiteangle.b = (float) cos(radians(tPos[i].x)) * 360; stiteangle.a = 0; stiteangle.g = 0; stitepos = tPos[i]; float tt; tt = tSizeMax[i].y * fColor; stitecolor.g = stitecolor.r = tt * 0.7f; stitecolor.b = tt * 0.9f; if (stitecolor.r > 1) stitecolor.r = 1; if (stitecolor.g > 1) stitecolor.g = 1; if (stitecolor.b > 1) stitecolor.b = 1; stitescale = tSize[i]; if (tType[i] == 0) DrawEERIEObjEx(smotte, &stiteangle, &stitepos, &stitescale, &stitecolor); else DrawEERIEObjEx(stite, &stiteangle, &stitepos, &stitescale, &stitecolor); } for(i = 0; i < min(iNumber, iMax + 1); i++) { float t = rnd(); 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; float t = min(2000.f + rnd() * 2000.f, ulDuration - ulCurrentTime + 500.0f * rnd()); pd->tolive = checked_range_cast<unsigned long>(t); 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, 2.f - 4.f * rnd(), 0.f); pd->siz = 0.5f; float t = min(2000.f + rnd() * 1000.f, ulDuration - ulCurrentTime + 500.0f * rnd()); pd->tolive = checked_range_cast<unsigned long>(t); 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); } } } return 1; }
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) * Vec3f(rnd(), rnd(), rnd()); 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) * Color3f(rnd(), rnd(), rnd()); } } } }
void IceFieldSpell::Update() { EERIE_LIGHT * el = dynLightCreate(m_light); if(el) { 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 = ArxDurationMs(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.setYaw(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->m_flags = FADE_IN_AND_OUT | ROTATING | DISSIPATING; pd->m_rotation = 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->m_flags = FADE_IN_AND_OUT | ROTATING | DISSIPATING; pd->m_rotation = 0.0000001f; pd->rgb = Color3f(0.7f, 0.7f, 1.f); } } } }
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 CLightning::Render() { if(ulCurrentTime >= ulDuration) return; if(m_iTTL <= 0) { fTotoro = 0; fMySize = 2; ReCreate(8); } Vec3f ePos; float fBeta = 0.f; float falpha = 0.f; if(m_isMassLightning) { ePos = Vec3f_ZERO; } else { ePos = m_pos; fBeta = m_beta; falpha = m_alpha; } float f = 1.5f * fMySize; m_cnodetab[0].f = randomVec(-f, f); RenderMaterial mat; mat.setCulling(Renderer::CullNone); mat.setDepthTest(false); mat.setBlendType(RenderMaterial::Additive); float fbeta = fBeta + rnd() * 2 * fMySize; for(size_t i = 0; i < m_nbtotal && i <= fTotoro; i++) { CLightningNode & node = m_cnodetab[i]; Vec3f astart = m_cnodetab[node.parent].pos + m_cnodetab[node.parent].f; float temp = 1.5f * fMySize; Vec3f z_z = m_cnodetab[node.parent].f + randomVec(-temp, temp); float zz = node.size + node.size * 0.3f * rnd(); float xx = node.size * glm::cos(glm::radians(-fbeta)); node.f = z_z; Vec3f a = node.pos + z_z; if(!m_isMassLightning) { Vec3f vv2; Vec3f vv1 = astart; vv1 = VRotateX(vv1, (falpha)); vv2 = VRotateY(vv1, 180 - MAKEANGLE(fBeta)); astart = vv2; vv1 = a; vv1 = VRotateX(vv1, (falpha)); vv2 = VRotateY(vv1, 180 - MAKEANGLE(fBeta)); a = vv2; astart += ePos; a += ePos; } if(i % 4 == 0) { Sphere sphere; sphere.origin = a; sphere.radius = std::min(node.size, 50.f); if(CheckAnythingInSphere(sphere, m_caster, CAS_NO_SAME_GROUP)) { DamageParameters damage; damage.pos = sphere.origin; damage.radius = sphere.radius; damage.damages = m_fDamage * m_level * ( 1.0f / 3 ); damage.area = DAMAGE_FULL; damage.duration = 1; damage.source = m_caster; damage.flags = DAMAGE_FLAG_DONT_HURT_SOURCE | DAMAGE_FLAG_ADD_VISUAL_FX; damage.type = DAMAGE_TYPE_FAKEFIRE | DAMAGE_TYPE_MAGICAL | DAMAGE_TYPE_LIGHTNING; DamageCreate(damage); } } { TexturedQuad q; q.v[0].color = Color(255, 255, 255, 255).toRGBA(); q.v[1].color = Color(0, 0, 90, 255).toRGBA(); q.v[2].color = Color(0, 0, 90, 255).toRGBA(); q.v[3].color = Color(255, 255, 255, 255).toRGBA(); q.v[0].uv = Vec2f(0.5f, 0.f); q.v[1].uv = Vec2f_ZERO; q.v[2].uv = Vec2f_Y_AXIS; q.v[3].uv = Vec2f(0.5f, 1.f); q.v[0].p = astart; q.v[1].p = astart + Vec3f(0.f, zz, 0.f); q.v[2].p = a + Vec3f(0.f, zz, 0.f); q.v[3].p = a; drawQuadRTP(mat, q); } { TexturedQuad q; q.v[0].color = Color(255, 255, 255, 255).toRGBA(); q.v[1].color = Color(0, 0, 90, 255).toRGBA(); q.v[2].color = Color(0, 0, 90, 255).toRGBA(); q.v[3].color = Color(255, 255, 255, 255).toRGBA(); q.v[0].uv = Vec2f(0.5f, 0.f); q.v[1].uv = Vec2f_X_AXIS; q.v[2].uv = Vec2f_ONE; q.v[3].uv = Vec2f(0.5f, 1.f); q.v[0].p = astart; q.v[1].p = astart - Vec3f(0.f, zz, 0.f); q.v[2].p = a - Vec3f(0.f, zz, 0.f); q.v[3].p = a; drawQuadRTP(mat, q); } zz *= glm::sin(glm::radians(fbeta)); { TexturedQuad q; q.v[0].color = Color(255, 255, 255, 255).toRGBA(); q.v[1].color = Color(0, 0, 90, 255).toRGBA(); q.v[2].color = Color(0, 0, 90, 255).toRGBA(); q.v[3].color = Color(255, 255, 255, 255).toRGBA(); q.v[0].uv = Vec2f(0.5f, 0.f); q.v[1].uv = Vec2f_X_AXIS; q.v[2].uv = Vec2f_ONE; q.v[3].uv = Vec2f(0.5f, 1.f); q.v[0].p = astart; q.v[1].p = astart + Vec3f(xx, 0.f, zz); q.v[2].p = a + Vec3f(xx, 0.f, zz); q.v[3].p = a; drawQuadRTP(mat, q); } { TexturedQuad q; q.v[0].color = Color(255, 255, 255, 255).toRGBA(); q.v[1].color = Color(0, 0, 90, 255).toRGBA(); q.v[2].color = Color(0, 0, 90, 255).toRGBA(); q.v[3].color = Color(255, 255, 255, 255).toRGBA(); q.v[0].uv = Vec2f(0.5f, 0.f); q.v[1].uv = Vec2f_ZERO; q.v[2].uv = Vec2f_Y_AXIS; q.v[3].uv = Vec2f(0.5f, 1.f); q.v[0].p = astart; q.v[1].p = astart - Vec3f(xx, 0.f, zz); q.v[2].p = a - Vec3f(xx, 0.f, zz); q.v[3].p = a; drawQuadRTP(mat, q); } } }
// Draws Flame Particles void TreatBackgroundActions() { ARX_PROFILE_FUNC(); float fZFar = square(ACTIVECAM->cdepth * fZFogEnd * 1.3f); for(size_t i = 0; i < g_staticLightsMax; i++) { EERIE_LIGHT * gl = g_staticLights[i]; if(!gl) { continue; } float dist = arx::distance2(gl->pos, ACTIVECAM->orgTrans.pos); if(dist > fZFar) { // Out of treat range ARX_SOUND_Stop(gl->sample); gl->sample = audio::INVALID_ID; continue; } if((gl->extras & EXTRAS_SPAWNFIRE) && gl->m_ignitionStatus) { DamageParameters damage; damage.radius = gl->ex_radius; damage.damages = gl->ex_radius * (1.0f / 7); damage.area = DAMAGE_FULL; damage.duration = ArxDurationMs(1); damage.source = EntityHandle(); damage.flags = 0; damage.type = DAMAGE_TYPE_MAGICAL | DAMAGE_TYPE_FIRE | DAMAGE_TYPE_NO_FIX; damage.pos = gl->pos; DamageCreate(damage); } if(!(gl->extras & (EXTRAS_SPAWNFIRE | EXTRAS_SPAWNSMOKE)) || !gl->m_ignitionStatus) { if(!gl->m_ignitionStatus && gl->sample != audio::INVALID_ID) { ARX_SOUND_Stop(gl->sample); gl->sample = audio::INVALID_ID; } continue; } if(gl->sample == audio::INVALID_ID) { gl->sample = SND_FIREPLACE; ARX_SOUND_PlaySFX(gl->sample, &gl->pos, Random::getf(0.95f, 1.05f), ARX_SOUND_PLAY_LOOPED); } else { ARX_SOUND_RefreshPosition(gl->sample, gl->pos); } float amount = 2.f; if(dist < square(ACTIVECAM->cdepth * (1.f / 6))) { amount = 3.f; } else if(dist < square(ACTIVECAM->cdepth * (1.f / 3))) { amount = 2.5f; } const float targetFPS = 61.f; const float targetDelay = 1000.f / targetFPS; long count = gl->m_storedFlameTime.update(amount * g_framedelay * (1.f / targetDelay)); for(long n = 0; n < count; n++) { if(Random::getf() < gl->ex_frequency) { PARTICLE_DEF * pd = createParticle(); if(pd) { float t = Random::getf() * glm::pi<float>(); Vec3f s = Vec3f(std::sin(t), std::sin(t), std::cos(t)) * randomVec(); pd->ov = gl->pos + s * gl->ex_radius; pd->move = Vec3f(2.f, 2.f, 2.f) - Vec3f(4.f, 22.f, 4.f) * randomVec3f(); pd->move *= gl->ex_speed; pd->siz = 7.f * gl->ex_size; pd->tolive = 500 + Random::getu(0, 1000 * gl->ex_speed); if((gl->extras & EXTRAS_SPAWNFIRE) && (gl->extras & EXTRAS_SPAWNSMOKE)) { pd->m_flags = FIRE_TO_SMOKE; } pd->tc = (gl->extras & EXTRAS_SPAWNFIRE) ? fire2 : smokeparticle; pd->m_flags |= ROTATING; pd->m_rotation = 0.1f - Random::getf(0.f, 0.2f) * gl->ex_speed; pd->scale = Vec3f(-8.f); pd->rgb = (gl->extras & EXTRAS_COLORLEGACY) ? gl->rgb : Color3f::white; } } if(!(gl->extras & EXTRAS_SPAWNFIRE) || Random::getf() <= 0.95f) { continue; } if(Random::getf() < gl->ex_frequency) { PARTICLE_DEF * pd = createParticle(); if(pd) { float t = Random::getf() * (glm::pi<float>() * 2.f) - glm::pi<float>(); Vec3f s = Vec3f(std::sin(t), std::sin(t), std::cos(t)) * randomVec(); pd->ov = gl->pos + s * gl->ex_radius; Vec3f vect = glm::normalize(pd->ov - gl->pos); float d = (gl->extras & EXTRAS_FIREPLACE) ? 6.f : 4.f; pd->move = Vec3f(vect.x * d, Random::getf(-18.f, -10.f), vect.z * d) * gl->ex_speed; pd->siz = 4.f * gl->ex_size * 0.3f; pd->tolive = 1200 + Random::getu(0, 500 * gl->ex_speed); pd->tc = fire2; pd->m_flags |= ROTATING | GRAVITY; pd->m_rotation = 0.1f - Random::getf(0.f, 0.2f) * gl->ex_speed; pd->scale = Vec3f(-3.f); pd->rgb = (gl->extras & EXTRAS_COLORLEGACY) ? gl->rgb : Color3f::white; } } } } }
void ARX_PARTICLES_Update(EERIE_CAMERA * cam) { ARX_PROFILE_FUNC(); if(!ACTIVEBKG) { return; } if(ParticleCount == 0) { return; } const ArxInstant now = arxtime.now(); long pcc = ParticleCount; for(size_t i = 0; i < MAX_PARTICLES && pcc > 0; i++) { PARTICLE_DEF * part = &particle[i]; if(!part->exist) { continue; } long framediff = part->timcreation + part->tolive - now; long framediff2 = now - part->timcreation; if(framediff2 < long(part->delay)) { continue; } if(part->delay > 0) { part->timcreation += part->delay; part->delay=0; if((part->m_flags & DELAY_FOLLOW_SOURCE) && part->sourceionum != EntityHandle() && entities[part->sourceionum]) { part->ov = *part->source; Entity * target = entities[part->sourceionum]; Vec3f vector = (part->ov - target->pos) * Vec3f(1.f, 0.5f, 1.f); vector = glm::normalize(vector); part->move = vector * Vec3f(18.f, 5.f, 18.f) + randomVec(-0.5f, 0.5f); } continue; } if(!part->is2D) { EERIE_BKG_INFO * bkgData = getFastBackgroundData(part->ov.x, part->ov.z); if(!bkgData || !bkgData->treat) { part->exist = false; ParticleCount--; continue; } } if(framediff <= 0) { if((part->m_flags & FIRE_TO_SMOKE) && Random::getf() > 0.7f) { part->ov += part->move; part->tolive = part->tolive * 1.375f; part->m_flags &= ~FIRE_TO_SMOKE; part->tc = smokeparticle; part->scale = glm::abs(part->scale * 2.4f); part->rgb = Color3f::gray(.45f); part->move *= 0.5f; part->siz *= 1.f / 3; part->timcreation = now; framediff = part->tolive; } else { part->exist = false; ParticleCount--; continue; } } float val = (part->tolive - framediff) * 0.01f; Vec3f in = part->ov + part->move * val; Vec3f inn = in; if(part->m_flags & GRAVITY) { in.y = inn.y = inn.y + 1.47f * val * val; } float fd = float(framediff2) / float(part->tolive); float r = 1.f - fd; if(part->m_flags & FADE_IN_AND_OUT) { long t = part->tolive / 2; if(framediff2 <= t) { r = float(framediff2) / float(t); } else { r = 1.f - float(framediff2 - t) / float(t); } } if(!part->is2D) { Sphere sp; sp.origin = in; TexturedVertex out; EE_RTP(inn, out); if(out.rhw < 0 || out.p.z > cam->cdepth * fZFogEnd) { continue; } if(part->m_flags & SPLAT_GROUND) { float siz = part->siz + part->scale.x * fd; sp.radius = siz * 10.f; if(CheckAnythingInSphere(sp, EntityHandle_Player, CAS_NO_NPC_COL)) { if(Random::getf() < 0.9f) { Color3f rgb = part->rgb; PolyBoomAddSplat(sp, rgb, 0); } part->exist = false; ParticleCount--; continue; } } if(part->m_flags & SPLAT_WATER) { float siz = part->siz + part->scale.x * fd; sp.radius = siz * Random::getf(10.f, 30.f); if(CheckAnythingInSphere(sp, EntityHandle_Player, CAS_NO_NPC_COL)) { if(Random::getf() < 0.9f) { Color3f rgb = part->rgb * 0.5f; PolyBoomAddSplat(sp, rgb, 2); } part->exist = false; ParticleCount--; continue; } } if((part->m_flags & DISSIPATING) && out.p.z < 0.05f) { out.p.z *= 20.f; r *= out.p.z; } } if(r <= 0.f) { pcc--; continue; } if(part->m_flags & PARTICLE_GOLDRAIN) { float v = Random::getf(-0.1f, 0.1f); if(part->rgb.r + v <= 1.f && part->rgb.r + v > 0.f && part->rgb.g + v <= 1.f && part->rgb.g + v > 0.f && part->rgb.b + v <= 1.f && part->rgb.b + v > 0.f) { part->rgb = Color3f(part->rgb.r + v, part->rgb.g + v, part->rgb.b + v); } } Color color = (part->rgb * r).to<u8>(); if(player.m_improve) { color.g = 0; } TextureContainer * tc = part->tc; if(tc == explo[0] && (part->m_flags & PARTICLE_ANIMATED)) { long animrange = part->cval2 - part->cval1; long num = long(float(framediff2) / float(part->tolive) * animrange); num = glm::clamp(num, long(part->cval1), long(part->cval2)); tc = explo[num]; } float siz = part->siz + part->scale.x * fd; RenderMaterial mat; mat.setTexture(tc); mat.setDepthTest(!(part->m_flags & PARTICLE_NOZBUFFER)); if(part->m_flags & PARTICLE_SUB2) { mat.setBlendType(RenderMaterial::Subtractive2); color.a = glm::clamp(r * 1.5f, 0.f, 1.f) * 255; } else if(part->m_flags & SUBSTRACT) { mat.setBlendType(RenderMaterial::Subtractive); } else { mat.setBlendType(RenderMaterial::Additive); } if(part->m_flags & ROTATING) { if(!part->is2D) { float rott = MAKEANGLE(float(now + framediff2) * part->m_rotation); float temp = (part->zdec) ? 0.0001f : 2.f; float size = std::max(siz, 0.f); EERIEAddSprite(mat, in, size, color, temp, rott); } } else if(part->is2D) { float siz2 = part->siz + part->scale.y * fd; EERIEAddBitmap(mat, in, siz, siz2, tc, color); } else { float temp = (part->zdec) ? 0.0001f : 2.f; EERIEAddSprite(mat, in, siz, color, temp); } pcc--; } }
void AddFlare(const Vec2s & pos, float sm, short typ, Entity * io, bool bookDraw) { long i; for(i = 0; i < MAX_FLARES; i++) { if(!magicFlares[i].exist) { break; } } if(i >= MAX_FLARES) { return; } 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->x = float(pos.x) - rnd() * 4.f; fl->y = float(pos.y) - rnd() * 4.f - 50.f; fl->tv.rhw = fl->v.rhw = 1.f; fl->tv.specular = fl->v.specular = 1; 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); fl->v.p += ka.orgTrans.pos; EE_RTP(&fl->tv, &fl->v); fl->v.p += ka.orgTrans.pos; float vx = -(fl->x - subj.center.x) * 0.2173913f; float vy = (fl->y - subj.center.y) * 0.1515151515151515f; if(io) { fl->v.p.x = io->pos.x - EEsin(radians(MAKEANGLE(io->angle.getPitch() + vx))) * 100.f; fl->v.p.y = io->pos.y + EEsin(radians(MAKEANGLE(io->angle.getYaw() + vy))) * 100.f - 150.f; fl->v.p.z = io->pos.z + EEcos(radians(MAKEANGLE(io->angle.getPitch() + vx))) * 100.f; } else { fl->v.p.x = float(pos.x - (g_size.width() / 2)) * 150.f / float(g_size.width()); fl->v.p.y = float(pos.y - (g_size.height() / 2)) * 150.f / float(g_size.width()); fl->v.p.z = 75.f; ka = *oldcam; SetActiveCamera(&ka); PrepareCamera(&ka); 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); } else { fl->tv.p = Vec3f(fl->x, fl->y, 0.001f); } switch(PIPOrgb) { case 0: { fl->rgb = Color3f(rnd() * (2.f/3) + .4f, rnd() * (2.f/3), rnd() * (2.f/3) + .4f); break; } case 1: { fl->rgb = Color3f(rnd() * .625f + .5f, rnd() * .625f + .5f, rnd() * .55f); break; } case 2: { fl->rgb = Color3f(rnd() * (2.f/3) + .4f, rnd() * .55f, rnd() * .55f); break; } } if(typ == -1) { float zz = (EERIEMouseButton & 1) ? 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 = -1; fl->move = OPIPOrgb; 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->type = PARTICLE_2D; } }