void MassParalyseSpell::Launch() { ARX_SOUND_PlaySFX(SND_SPELL_MASS_PARALYSE); m_duration = (m_launchDuration >= 0) ? m_launchDuration : GameDurationMs(10000); m_hasDuration = true; for(size_t ii = 0; ii < entities.size(); ii++) { const EntityHandle handle = EntityHandle(ii); Entity * tio = entities[handle]; if( handle == m_caster || !tio || !(tio->ioflags & IO_NPC) || tio->show != SHOW_FLAG_IN_SCENE || (tio->ioflags & IO_FREEZESCRIPT) || fartherThan(tio->pos, entities[m_caster]->pos, 500.f) ) { continue; } tio->ioflags |= IO_FREEZESCRIPT; ARX_NPC_Kill_Spell_Launch(tio); m_targets.push_back(tio->index()); } }
void BlessSpell::Launch() { if(m_caster == EntityHandle_Player) { m_target = EntityHandle_Player; } spells.endByCaster(m_target, SPELL_BLESS); ARX_SOUND_PlaySFX(SND_SPELL_BLESS); // TODO m_launchDuration is not used // m_duration = (m_launchDuration > -1) ? m_launchDuration : 2000000; m_duration = GameDurationMs(20000); m_hasDuration = true; m_fManaCostPerSecond = 0.3333f * m_level; m_pos = entities[m_caster]->pos; m_yaw = 0.f; m_scale = 0.f; fRot = 0.f; tex_p1 = TextureContainer::Load("graph/obj3d/textures/(fx)_tsu_blueting"); tex_sol = TextureContainer::Load("graph/particles/(fx)_pentagram_bless"); m_targets.push_back(m_target); }
void ColdProtectionSpell::Launch() { spells.endByTarget(m_target, SPELL_COLD_PROTECTION); spells.endByCaster(m_caster, SPELL_ARMOR); spells.endByCaster(m_caster, SPELL_LOWER_ARMOR); spells.endByCaster(m_caster, SPELL_FIRE_PROTECTION); if(m_caster == EntityHandle_Player) { m_target = EntityHandle_Player; } ARX_SOUND_PlaySFX(SND_SPELL_COLD_PROTECTION_START, &entities[m_target]->pos); if(m_caster == EntityHandle_Player) { m_duration = 0; m_hasDuration = false; } else { m_duration = (m_launchDuration >= 0) ? m_launchDuration : GameDurationMs(20000); m_hasDuration = true; } m_fManaCostPerSecond = 1.f; Entity * io = entities.get(m_target); if(io) { io->halo.flags = HALO_ACTIVE; io->halo.color = Color3f(0.2f, 0.2f, 0.45f); io->halo.radius = 45.f; } m_snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_COLD_PROTECTION_LOOP, &entities[m_target]->pos, 1.f, ARX_SOUND_PLAY_LOOPED); m_targets.push_back(m_target); }
void SummonCreatureSpell::End() { lightHandleDestroy(m_light); // need to killio Entity * io = entities.get(m_summonedEntity); if(io) { ARX_SOUND_PlaySFX(SND_SPELL_ELECTRIC, &io->pos); if(io->scriptload && (io->ioflags & IO_NOSAVE)) { AddRandomSmoke(io, 100); Vec3f posi = io->pos; posi.y -= 100.f; MakeCoolFx(posi); 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.0f); light->pos = posi; light->duration = GameDurationMs(600); } io->destroyOne(); } } m_summonedEntity = EntityHandle(); }
void CurePoisonSpell::Update() { m_pos = entities[m_target]->pos; if(m_target == EntityHandle_Player) m_pos.y += 200; GameDuration ff = m_duration - m_elapsed; if(ff < GameDurationMs(1500)) { m_particles.m_parameters.m_spawnFlags = PARTICLE_CIRCULAR; m_particles.m_parameters.m_gravity = Vec3f(0.f); std::list<Particle *>::iterator i; for(i = m_particles.listParticle.begin(); i != m_particles.listParticle.end(); ++i) { Particle * pP = *i; if(pP->isAlive()) { pP->fColorEnd.a = 0; if(pP->m_age + ff < pP->m_timeToLive) { pP->m_age = pP->m_timeToLive - ff; } } } } m_particles.SetPos(m_pos); m_particles.Update(g_gameTime.lastFrameDuration()); EERIE_LIGHT * light = dynLightCreate(m_light); if(light) { light->intensity = 2.3f; light->fallstart = 200.f; light->fallend = 350.f; light->rgb = Color3f(0.4f, 1.f, 0.4f); light->pos = m_pos + Vec3f(0.f, -50.f, 0.f); light->duration = GameDurationMs(200); light->creationTime = g_gameTime.now(); light->extras = 0; } m_particles.Render(); }
void NegateMagicSpell::Update() { LaunchAntiMagicField(); if(m_target == EntityHandle_Player) { m_pos = player.basePosition(); } else { Entity * target = entities.get(m_target); if(target) { m_pos = target->pos; } } Vec3f stitepos = m_pos - Vec3f(0.f, 10.f, 0.f); RenderMaterial mat; mat.setLayer(RenderMaterial::Decal); mat.setDepthTest(true); mat.setTexture(tex_sol); mat.setBlendType(RenderMaterial::Additive); for(int i = 0; i < 360; i++) { float t = Random::getf(); if(t < 0.04f) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } pd->ov = stitepos + arx::randomOffsetXZ(150.f); pd->move = Vec3f(0.f, Random::getf(-3.f, 0.f), 0.f); pd->siz = 0.3f; pd->tolive = Random::getu(2000, 4000); pd->tc = tex_p2; pd->m_flags = FADE_IN_AND_OUT | ROTATING | DISSIPATING | SUBSTRACT; pd->m_rotation = 0.0000001f; } } float rot = timeWaveSaw(g_gameTime.now(), GameDurationMs(18000)) * 360.f; Anglef stiteangle(0.f, -rot, 0.f); float scalediff = timeWaveSin(g_gameTime.now(), GameDurationMsf(1570.79632f)); { Color3f stitecolor = Color3f::gray(.4f); Vec3f stitescale = Vec3f(3.f + 0.5f * scalediff); Draw3DObject(ssol, stiteangle, stitepos, stitescale, stitecolor, mat); } { Color3f stitecolor = Color3f(.5f, 0.f, .5f); Vec3f stitescale = Vec3f(3.1f + 0.2f * scalediff); Draw3DObject(ssol, stiteangle, stitepos, stitescale, stitecolor, mat); } }
void PoisonProjectileSpell::Update() { for(size_t i = 0; i < m_projectiles.size(); i++) { CPoisonProjectile * projectile = m_projectiles[i]; projectile->Update(g_gameTime.lastFrameDuration()); } for(size_t i = 0; i < m_projectiles.size(); i++) { CPoisonProjectile * projectile = m_projectiles[i]; projectile->Render(); EERIE_LIGHT * light = lightHandleGet(projectile->lLightId); if(light) { light->intensity = 2.3f * projectile->lightIntensityFactor; light->fallend = 250.f; light->fallstart = 150.f; light->rgb = Color3f::green; light->pos = projectile->eCurPos; light->creationTime = g_gameTime.now(); light->duration = GameDurationMs(200); } AddPoisonFog(projectile->eCurPos, m_level + 7); if(m_elapsed > GameDurationMs(1600)) { DamageParameters damage; damage.pos = projectile->eCurPos; damage.radius = 120.f; damage.damages = (4.f + m_level * 0.6f) * 0.001f * g_framedelay; damage.area = DAMAGE_FULL; damage.duration = g_gameTime.lastFrameDuration(); damage.source = m_caster; damage.flags = 0; damage.type = DAMAGE_TYPE_MAGICAL | DAMAGE_TYPE_POISON; DamageCreate(damage); } } }
void PoisonProjectileSpell::End() { for(size_t i = 0; i < m_projectiles.size(); i++) { CPoisonProjectile * projectile = m_projectiles[i]; endLightDelayed(projectile->lLightId, GameDurationMs(2000)); delete projectile; } m_projectiles.clear(); }
void LevitateSpell::Update() { Vec3f target; if(m_target == EntityHandle_Player) { target = player.pos + Vec3f(0.f, 150.f, 0.f); player.levitate = true; } else { target = entities[m_caster]->pos; } m_pos = target; float coneScale = 0.f; int dustParticles = 0; if(m_elapsed < GameDurationMs(1000)) { coneScale = m_elapsed / GameDurationMs(1000); dustParticles = 3; } else { coneScale = 1.f; dustParticles = 10; } cone1.Update(g_gameTime.lastFrameDuration(), m_pos, coneScale); cone2.Update(g_gameTime.lastFrameDuration(), m_pos, coneScale); m_stones.Update(g_gameTime.lastFrameDuration(), m_pos); for(int i = 0; i < dustParticles; i++) { createDustParticle(); } cone1.Render(); cone2.Render(); m_stones.DrawStone(); ARX_SOUND_RefreshPosition(m_snd_loop, entities[m_target]->pos); }
void RotatingCone::Update(GameDuration timeDelta, Vec3f pos, float coneScale) { m_currdurationang += timeDelta; m_pos = pos; m_coneScale = coneScale; m_ang = m_currdurationang / GameDurationMs(1000); if(m_ang > 1.f) { m_currdurationang = 0; m_ang = 1.f; } }
void CPoisonProjectile::Update(GameDuration timeDelta) { if(m_elapsed <= GameDurationMs(2000)) { m_elapsed += timeDelta; } // on passe de 5 à 100 partoches en 1.5secs if(m_elapsed < GameDurationMs(750)) { pPS.m_parameters.m_nbMax = 2; pPS.Update(timeDelta); } else { if(!bOk) { bOk = true; // go ParticleParams pp = g_particleParameters[ParticleParam_Poison3]; pp.m_pos = Vec3f(fBetaRadSin * 20, 0.f, fBetaRadCos * 20); pp.m_direction = -eMove * 0.1f; pPSStream.SetParams(pp); } pPSStream.Update(timeDelta); pPSStream.SetPos(eCurPos); pPS.Update(timeDelta); pPS.SetPos(eCurPos); fTrail = ((m_elapsed - GameDurationMs(750)) / (m_duration - GameDurationMs(750))) * 9 * (BEZIERPrecision + 2); } if(m_elapsed >= m_duration) lightIntensityFactor = 0.f; else lightIntensityFactor = 1.f; }
void IncinerateSpell::Launch() { Entity * tio = entities[m_target]; ARX_SOUND_PlaySFX(SND_SPELL_INCINERATE, &tio->pos); m_snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_INCINERATE_LOOP, &tio->pos, 1.f, ARX_SOUND_PLAY_LOOPED); m_duration = GameDurationMs(20000); m_hasDuration = true; tio->sfx_flag |= SFX_TYPE_YLSIDE_DEATH | SFX_TYPE_INCINERATE; tio->sfx_time = g_gameTime.now(); m_targets.push_back(m_target); }
void MemorizedRunesHud::draw() { if(!(CurrSpellSymbol || player.SpellToMemorize.bSpell)) { return; } Vec2f pos = m_rect.topLeft(); for(int i = 0; i < 6; i++) { bool bHalo = false; if(SpellSymbol[i] != RUNE_NONE) { if(SpellSymbol[i] == player.SpellToMemorize.iSpellSymbols[i]) { bHalo = true; } else { player.SpellToMemorize.iSpellSymbols[i] = SpellSymbol[i]; for(int j = i + 1; j < 6; j++) { player.SpellToMemorize.iSpellSymbols[j] = RUNE_NONE; } } } if(player.SpellToMemorize.iSpellSymbols[i] != RUNE_NONE) { Vec2f size = Vec2f(32.f, 32.f) * m_scale; Rectf rect = Rectf(pos, size.x, size.y); TextureContainer * tc = gui::necklace.pTexTab[player.SpellToMemorize.iSpellSymbols[i]]; if(bHalo) { ARX_INTERFACE_HALO_Render(Color3f(0.2f, 0.4f, 0.8f), HALO_ACTIVE, tc->getHalo(), pos, Vec2f(m_scale)); } EERIEDrawBitmap(rect, 0, tc, Color::white); if(!player.hasRune(player.SpellToMemorize.iSpellSymbols[i])) { UseRenderState state(render2D().blend(BlendInvDstColor, BlendOne).alphaCutout()); EERIEDrawBitmap(rect, 0, cursorMovable, Color3f::gray(.8f).to<u8>()); } pos.x += 32 * m_scale; } } if(g_gameTime.now() - player.SpellToMemorize.lTimeCreation > GameDurationMs(30000)) { player.SpellToMemorize.bSpell = false; } }
void PrecastSpellsGui::update() { m_icons.clear(); if(!isVisible()) return; float intensity = 1.f - PULSATE * 0.5f; intensity = glm::clamp(intensity, 0.f, 1.f); for(size_t i = 0; i < Precast.size(); i++) { PRECAST_STRUCT & precastSlot = Precast[i]; float val = intensity; if(precastSlot.launch_time > 0 && g_gameTime.now() >= precastSlot.launch_time) { float tt = (g_gameTime.now() - precastSlot.launch_time) / GameDurationMs(1000); if(tt > 1.f) tt = 1.f; val *= (1.f - tt); } Color color = Color3f(0, val * 0.5f, val).to<u8>(); Rectf childRect = createChild(m_rect, Anchor_BottomLeft, m_iconSize * m_scale, Anchor_BottomLeft); childRect.move(i * m_iconSize.x * m_scale, 0); SpellType typ = precastSlot.typ; TextureContainer * tc = spellicons[typ].tc; arx_assert(tc); PrecastSpellIconSlot icon; icon.update(childRect, tc, color, PrecastHandle(i)); if(!(player.Interface & INTER_COMBATMODE)) icon.updateInput(); m_icons.push_back(icon); } }
void CurseSpell::Update() { fRot += g_gameTime.lastFrameDuration() / GameDurationMs(4); Vec3f target = Vec3f_ZERO; Entity * targetIo = entities.get(m_target); if(targetIo) { target = targetIo->pos; if(m_target == EntityHandle_Player) target.y -= 200.f; else target.y += targetIo->physics.cyl.height - 30.f; } m_pos = target; RenderMaterial mat; mat.setCulling(CullCW); mat.setDepthTest(true); mat.setBlendType(RenderMaterial::Opaque); Draw3DObject(svoodoo, Anglef(0, fRot, 0), m_pos, Vec3f_ONE, Color3f::white, mat); for(int i = 0; i < 4; i++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } pd->ov = m_pos; pd->move = arx::linearRand(Vec3f(-2.f, -20.f, -2.f), Vec3f(2.f, -10.f, 2.f)); pd->siz = 0.015f; pd->tolive = Random::getu(1000, 1600); pd->tc = tex_p1; pd->m_flags = ROTATING | DISSIPATING | SUBSTRACT | GRAVITY; pd->m_rotation = 0.0000001f; } }
void RuneOfGuardingSpell::Launch() { spells.endByCaster(m_caster, SPELL_RUNE_OF_GUARDING); ARX_SOUND_PlaySFX(g_snd.SPELL_RUNE_OF_GUARDING); m_hasDuration = m_launchDuration >= 0; m_duration = m_hasDuration ? m_launchDuration : 0; m_pos = entities[m_caster]->pos; tex_p2 = TextureContainer::Load("graph/obj3d/textures/(fx)_tsu_blueting"); EERIE_LIGHT * light = dynLightCreate(m_light); if(light) { light->intensity = 0.7f + 2.3f; light->fallend = 500.f; light->fallstart = 400.f; light->rgb = Color3f(1.0f, 0.2f, 0.2f); light->pos = m_pos - Vec3f(0.f, 50.f, 0.f); light->creationTime = g_gameTime.now(); light->duration = GameDurationMs(200); } }
void ConfuseSpell::End() { m_targets.clear(); endLightDelayed(m_light, GameDurationMs(500)); }
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 = GameDurationMs(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(0.f, glm::cos(glm::radians(tPos[i].x)) * 360, 0.f); Vec3f stitepos(tPos[i].x, m_pos.y, tPos[i].z); Vec3f stitescale(tSize[i].z, tSize[i].y, tSize[i].x); Color3f stitecolor = Color3f(0.7f, 0.7f, 0.9f) * tSizeMax[i].y; if(stitecolor.r > 1) { stitecolor.r = 1; } if(stitecolor.g > 1) { stitecolor.g = 1; } if(stitecolor.b > 1) { stitecolor.b = 1; } 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] + arx::randomVec(-5.f, 5.f); pd->move = arx::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] + arx::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 IceFieldSpell::Launch() { spells.endByCaster(m_caster, SPELL_ICE_FIELD); ARX_SOUND_PlaySFX(g_snd.SPELL_ICE_FIELD); m_duration = (m_launchDuration >= 0) ? m_launchDuration : GameDurationMs(100000); m_hasDuration = true; m_fManaCostPerSecond = 2.8f; m_light = LightHandle(); Vec3f target; float beta; bool displace; if(m_caster == EntityHandle_Player) { target = player.basePosition(); beta = player.angle.getYaw(); displace = true; } else { Entity * io = entities.get(m_caster); arx_assert(io); target = io->pos; beta = io->angle.getYaw(); displace = (io->ioflags & IO_NPC) == IO_NPC; } if(displace) { target += angleToVectorXZ(beta) * 250.f; } m_pos = target; DamageParameters damage; damage.radius = 150.f; damage.damages = 10.f; damage.area = DAMAGE_FULL; damage.duration = GameDurationMs(100000000); damage.source = m_caster; damage.flags = 0; damage.type = DAMAGE_TYPE_MAGICAL | DAMAGE_TYPE_COLD | DAMAGE_TYPE_FIELD; damage.pos = target; m_damage = DamageCreate(damage); tex_p1 = TextureContainer::Load("graph/obj3d/textures/(fx)_tsu_blueting"); tex_p2 = TextureContainer::Load("graph/obj3d/textures/(fx)_tsu_bluepouf"); for(int i = 0; i < iMax; i++) { float t = Random::getf(); if(t < 0.5f) { tType[i] = 0; } else { tType[i] = 1; } tSize[i] = Vec3f(0.f); tSizeMax[i] = arx::randomVec3f() + Vec3f(0.f, 0.2f, 0.f); Vec3f minPos = (tType[i] == 0) ? Vec3f(1.2f, 1.f, 1.2f) : Vec3f(0.4f, 0.3f, 0.4f); tSizeMax[i] = glm::max(tSizeMax[i], minPos); if(tType[i] == 0) { tPos[i].x = m_pos.x + Random::getf(-80.f, 80.f); tPos[i].y = m_pos.y; tPos[i].z = m_pos.z + Random::getf(-80.f, 80.f); } else { tPos[i].x = m_pos.x + Random::getf(-120.f, 120.f); tPos[i].y = m_pos.y; tPos[i].z = m_pos.z + Random::getf(-120.f, 120.f); } } m_snd_loop = ARX_SOUND_PlaySFX_loop(g_snd.SPELL_ICE_FIELD_LOOP, &target, 1.f); }
QuickSaveIconGui::QuickSaveIconGui() : m_duration(GameDurationMs(1000)) , m_remainingTime(0) {}
void BlessSpell::Update() { fRot += g_gameTime.lastFrameDuration() / GameDurationMs(4); Entity * target = entities.get(m_target); if(target) { m_pos = target->pos; if(m_target == EntityHandle_Player) m_yaw = player.angle.getYaw(); else m_yaw = target->angle.getYaw(); } m_scale = (m_level + 10) * 6.f; Vec3f pos = m_pos + Vec3f(0, -5, 0); RenderMaterial mat; mat.setCulling(CullNone); mat.setBlendType(RenderMaterial::Additive); mat.setDepthTest(true); mat.setLayer(RenderMaterial::Decal); mat.setTexture(tex_sol); float fBetaRadCos = glm::cos(glm::radians(MAKEANGLE(m_yaw))) * m_scale; float fBetaRadSin = glm::sin(glm::radians(MAKEANGLE(m_yaw))) * m_scale; ColorRGBA color = Color::white.toRGB(); { TexturedQuad q; q.v[0].color = color; q.v[1].color = color; q.v[2].color = color; q.v[3].color = color; q.v[0].uv = Vec2f_ZERO; q.v[1].uv = Vec2f_X_AXIS; q.v[2].uv = Vec2f_ONE; q.v[3].uv = Vec2f_Y_AXIS; q.v[0].p.x = pos.x + fBetaRadCos - fBetaRadSin; q.v[0].p.y = pos.y; q.v[0].p.z = pos.z + fBetaRadSin + fBetaRadCos; q.v[1].p.x = pos.x - fBetaRadCos - fBetaRadSin; q.v[1].p.y = pos.y; q.v[1].p.z = pos.z - fBetaRadSin + fBetaRadCos; q.v[2].p.x = pos.x - fBetaRadCos + fBetaRadSin; q.v[2].p.y = pos.y; q.v[2].p.z = pos.z - fBetaRadSin - fBetaRadCos; q.v[3].p.x = pos.x + fBetaRadCos + fBetaRadSin; q.v[3].p.y = pos.y; q.v[3].p.z = pos.z + fBetaRadSin - fBetaRadCos; drawQuadRTP(mat, q); } for(int i = 0; i < 12; i++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } pd->ov = m_pos - Vec3f(0.f, 20.f, 0.f); pd->move = arx::linearRand(Vec3f(-3.f, 0.f, -3.f), Vec3f(3.f, 0.5f, 3.f)); pd->siz = 0.005f; pd->tolive = Random::getu(1000, 2000); pd->tc = tex_p1; pd->m_flags = FADE_IN_AND_OUT | ROTATING | DISSIPATING; pd->m_rotation = 0.0000001f; pd->rgb = Color3f(0.7f, 0.6f, 0.2f); } }
void RuneOfGuardingSpell::End() { endLightDelayed(m_light, GameDurationMs(500)); }
void DispellFieldSpell::Launch() { m_duration = GameDurationMs(10); m_hasDuration = true; long valid = 0, dispelled = 0; for(size_t n = 0; n < MAX_SPELLS; n++) { SpellBase * spell = spells[SpellHandle(n)]; if(!spell) { continue; } bool cancel = false; Vec3f pos; switch(spell->m_type) { case SPELL_CREATE_FIELD: { if(m_caster != EntityHandle_Player || spell->m_caster == EntityHandle_Player) { pos = static_cast<CreateFieldSpell *>(spell)->getPosition(); cancel = true; } break; } case SPELL_FIRE_FIELD: { pos = static_cast<FireFieldSpell *>(spell)->getPosition(); cancel = true; break; } case SPELL_ICE_FIELD: { pos = static_cast<IceFieldSpell *>(spell)->getPosition(); cancel = true; break; } default: break; } Entity * caster = entities[m_caster]; if(cancel && closerThan(pos, caster->pos, 400.f)) { valid++; if(spell->m_level <= m_level) { spells.endSpell(spell); dispelled++; } } } if(valid > dispelled) { // Some fileds could not be dispelled ARX_SPEECH_AddSpeech(entities.player(), "player_not_skilled_enough", ANIM_TALK_NEUTRAL, ARX_SPEECH_FLAG_NOTEXT); } if(dispelled > 0) { ARX_SOUND_PlaySFX(SND_SPELL_DISPELL_FIELD); } else { ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE, &m_caster_pos); } }
void SummonCreatureSpell::Update() { if(g_gameTime.isPaused()) { return; } if(m_elapsed <= GameDurationMs(4000)) { if(Random::getf() > 0.7f) { Vec3f pos = m_fissure.m_eSrc; MakeCoolFx(pos); } m_fissure.Update(g_gameTime.lastFrameDuration()); m_fissure.Render(); m_requestSummon = true; m_summonedEntity = EntityHandle(); } else if(m_requestSummon) { lightHandleDestroy(m_light); m_requestSummon = false; 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) { long tokeep; res::path cls; if(m_megaCheat) { if(Random::getf() > 0.5f) { tokeep = -1; cls = "graph/obj3d/interactive/npc/wrat_base/wrat_base"; } else { tokeep = 0; cls = "graph/obj3d/interactive/npc/y_mx/y_mx"; } } else if(Random::getf() > 0.997f || (sp_max && Random::getf() > 0.8f) || (cur_mr >= 3 && Random::getf() > 0.3f)) { tokeep = 0; cls = "graph/obj3d/interactive/npc/y_mx/y_mx"; } else if(Random::getf() > 0.997f || (cur_rf >= 3 && Random::getf() > 0.8f) || (cur_mr >= 3 && Random::getf() > 0.3f)) { tokeep = -1; cls = "graph/obj3d/interactive/npc/wrat_base/wrat_base"; } else if(m_level >= 9) { tokeep = 1; cls = "graph/obj3d/interactive/npc/demon/demon"; } else if(Random::getf() > 0.98f) { tokeep = -1; cls = "graph/obj3d/interactive/npc/wrat_base/wrat_base"; } else { tokeep = 0; cls = "graph/obj3d/interactive/npc/chicken_base/chicken_base"; } Entity * io = AddNPC(cls, -1, IO_IMMEDIATELOAD); if(!io) { cls = "graph/obj3d/interactive/npc/chicken_base/chicken_base"; tokeep = 0; io = AddNPC(cls, -1, IO_IMMEDIATELOAD); } if(io) { RestoreInitialIOStatusOfIO(io); io->summoner = m_caster; io->scriptload = 1; if(tokeep == 1) { io->ioflags |= IO_NOSAVE; } io->pos = phys.origin; SendInitScriptEvent(io); if(tokeep < 0) { io->scale = 1.65f; io->physics.cyl.radius = 25; io->physics.cyl.height = -43; io->speed_modif = 1.f; } SendIOScriptEvent(entities.get(m_caster), io, SM_SUMMONED); for(long j = 0; j < 3; j++) { Vec3f pos = m_fissure.m_eSrc; pos += arx::randomVec3f() * 100.f; pos += Vec3f(-50.f, 50.f, -50.f); MakeCoolFx(pos); } if(tokeep == 1) { m_summonedEntity = io->index(); } else { m_summonedEntity = EntityHandle(); } } } } else if(m_summonedEntity == EntityHandle()) { requestEnd(); } }
void RepelUndeadSpell::Update() { Vec3f pos = entities[m_target]->pos; float rot; if(m_target == EntityHandle_Player) { rot = player.angle.getYaw(); } else { rot = entities[m_target]->angle.getYaw(); } m_pos = pos; m_yaw = rot; RenderMaterial mat; mat.setDepthTest(true); mat.setBlendType(RenderMaterial::Additive); Anglef eObjAngle; eObjAngle.setYaw(m_yaw); eObjAngle.setPitch(0); eObjAngle.setRoll(0); float wave = timeWaveSin(g_gameTime.now(), GameDurationMsf(6283.185307f)); float vv = (1.f + wave) * 0.5f + 1.1f; Draw3DObject(ssol, eObjAngle, m_pos + Vec3f(0.f, -5.f, 0.f), Vec3f(vv), Color3f(0.6f, 0.6f, 0.8f), mat); vv *= 100.f; for(int n = 0; n < 4; n++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } // XXX was this supposed to be sphericalRand ? Vec2f d = arx::diskRand(vv); pd->ov = m_pos + Vec3f(d.x, 0.f, d.y); pd->move = arx::linearRand(Vec3f(-0.8f, -4.f, -0.8f), Vec3f(0.8f, 0.f, 0.8f)); pd->scale = Vec3f(-0.1f); pd->tolive = Random::getu(2600, 3200); pd->tc = tex_p2; pd->siz = 0.3f; pd->rgb = Color3f(.4f, .4f, .6f); } EERIE_LIGHT * light = dynLightCreate(m_light); if(light) { light->intensity = 2.3f; light->fallend = 350.f; light->fallstart = 150.f; light->rgb = Color3f(0.8f, 0.8f, 1.f); light->pos = m_pos + Vec3f(0.f, -50.f, 0.f); light->duration = GameDurationMs(200); light->creationTime = g_gameTime.now(); } if (m_target == EntityHandle_Player) ARX_SOUND_RefreshPosition(m_snd_loop, entities[m_target]->pos); }
void ConfuseSpell::Update() { Entity * target = entities.get(m_target); if(!target) { return; } Vec3f pos = target->pos; if(m_target != EntityHandle_Player) { pos.y += target->physics.cyl.height - 30.f; } ObjVertHandle idx = target->obj->fastaccess.head_group_origin; if(idx != ObjVertHandle()) { pos = target->obj->vertexWorldPositions[idx.handleData()].v; pos.y -= 50.f; } eCurPos = pos; RenderMaterial mat; mat.setDepthTest(false); mat.setBlendType(RenderMaterial::Additive); mat.setTexture(tex_trail); float rot = timeWaveSaw(g_gameTime.now(), GameDurationMs(3142)) * 360.f; Anglef stiteangle = Anglef(0.f, -rot, 0.f); { AnimationDuration delta = toAnimationDuration(g_gameTime.lastFrameDuration()); EERIEDrawAnimQuatUpdate(spapi, animlayer, stiteangle, eCurPos, delta, NULL, false); EERIEDrawAnimQuatRender(spapi, eCurPos, NULL, 0.f); } for(int i = 0; i < 6; i++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } Vec2f p = arx::diskRand(15.f); pd->ov = eCurPos + Vec3f(p.x, 0.f, p.y); pd->move = Vec3f(0.f, Random::getf(1.f, 4.f), 0.f); pd->siz = 0.25f; pd->tolive = Random::getu(2300, 3300); pd->tc = tex_p1; pd->m_flags = PARTICLE_GOLDRAIN | FADE_IN_AND_OUT | ROTATING | DISSIPATING; pd->m_rotation = 0.0000001f; Color3f baseColor = Color3f(0.4f, 0.2f, 0.4f); Color3f randomFactor = Color3f(0.4f, 0.6f, 0.4f); Color3f c = baseColor + randomColor3f() * randomFactor; while(glm::abs(c.r - c.g) > 0.3f && glm::abs(c.g - c.b) > 0.3f) { c = baseColor + randomColor3f() * randomFactor; } pd->rgb = c * Color3f(0.8f, 0.8f, 0.8f); } EERIE_LIGHT * light = dynLightCreate(m_light); if(light) { light->intensity = 1.3f; light->fallstart = 180.f; light->fallend = 420.f; light->rgb = Color3f(0.3f, 0.3f, 0.5f) + Color3f(0.2f, 0.f, 0.2f) * randomColor3f(); light->pos = eCurPos; light->duration = GameDurationMs(200); light->extras = 0; } }
void RuneOfGuardingSpell::Update() { EERIE_LIGHT * light = lightHandleGet(m_light); if(light) { float fa = Random::getf(0.85f, 1.0f); light->intensity = 0.7f + 2.3f * fa; light->fallend = 350.f; light->fallstart = 150.f; light->rgb = Color3f(1.0f, 0.2f, 0.2f); light->creationTime = g_gameTime.now(); light->duration = GameDurationMs(200); } Vec3f pos = m_pos + Vec3f(0.f, -20.f, 0.f); RenderMaterial mat; mat.setDepthTest(true); mat.setBlendType(RenderMaterial::Additive); Anglef stiteangle; Color3f stitecolor; float stiteangleb = m_elapsed / GameDurationMs(100); stiteangle.setPitch(0); stiteangle.setRoll(0); stiteangle.setYaw(stiteangleb * 0.1f); stitecolor = Color3f(0.4f, 0.4f, 0.6f); float scale = std::sin(m_elapsed / GameDurationMsf(66.6666666f)); Vec3f stitescale = Vec3f(1.f, -0.1f, 1.f); Draw3DObject(slight, stiteangle, pos, stitescale, stitecolor, mat); stiteangle.setYaw(stiteangleb); stitecolor = Color3f(0.6f, 0.f, 0.f); stitescale = Vec3f(2.f) * (1.f + 0.01f * scale); Draw3DObject(ssol, stiteangle, pos, stitescale, stitecolor, mat); stitecolor = Color3f(0.6f, 0.3f, 0.45f); stitescale = Vec3f(1.8f) * (1.f + 0.02f * scale); Draw3DObject(srune, stiteangle, pos, stitescale, stitecolor, mat); for(int n = 0; n < 4; n++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } pd->ov = pos + arx::randomOffsetXZ(40.f); pd->move = arx::linearRand(Vec3f(-0.8f, -4.f, -0.8f), Vec3f(0.8f, 0.f, 0.8f)); pd->scale = Vec3f(-0.1f); pd->tolive = Random::getu(2600, 3200); pd->tc = tex_p2; pd->siz = 0.3f; pd->rgb = Color3f(.4f, .4f, .6f); } Sphere sphere = Sphere(m_pos, std::max(m_level * 15.f, 50.f)); if(CheckAnythingInSphere(sphere, m_caster, CAS_NO_SAME_GROUP | CAS_NO_BACKGROUND_COL | CAS_NO_ITEM_COL | CAS_NO_FIX_COL | CAS_NO_DEAD_COL)) { spawnFireHitParticle(m_pos, 0); PolyBoomAddScorch(m_pos); LaunchFireballBoom(m_pos, m_level); DoSphericDamage(Sphere(m_pos, 30.f * m_level), 4.f * m_level, DAMAGE_AREA, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL, m_caster); ARX_SOUND_PlaySFX(g_snd.SPELL_RUNE_OF_GUARDING_END, &m_pos); requestEnd(); } }
void CCreateField::Render() { if(!VisibleSphere(Sphere(eSrc - Vec3f(0.f, 120.f, 0.f), 400.f))) return; //------------------------------------------------------------------------- // rendu if(youp) { fglow += 0.5f; if(fglow >= 50) { youp = false; } } else { fglow -= 0.5f; if(fglow <= 0) { youp = true; } } float ysize = std::min(1.0f, m_elapsed / GameDurationMs(1000)); if(ysize >= 1.0f) { size = std::min(1.0f, (m_elapsed - GameDurationMs(1000)) / GameDurationMs(1000)); size = std::max(size, 0.1f); } // ondulation ft += 0.01f; if(ft > 360.0f) { ft = 0.0f; } falpha = glm::sin(glm::radians(fglow)) + Random::getf(0.f, 0.2f); falpha = glm::clamp(falpha, 0.f, 1.f); float smul = 100 * size; // bottom points Vec3f b[4] = { eSrc + Vec3f(-smul, 0.f, -smul), eSrc + Vec3f(smul, 0.f, -smul), eSrc + Vec3f(smul, 0.f, smul), eSrc + Vec3f(-smul, 0.f, smul) }; // top points Vec3f t[4] = { b[0] + Vec3f(0.f, -250 * ysize, 0.f), b[1] + Vec3f(0.f, -250 * ysize, 0.f), b[2] + Vec3f(0.f, -250 * ysize, 0.f), b[3] + Vec3f(0.f, -250 * ysize, 0.f) }; fwrap -= 5.0f; // TODO ignores the frame delay while(fwrap < 0) { fwrap += 360; } RenderMaterial mat; mat.setTexture(tex_jelly); mat.setDepthTest(true); mat.setBlendType(RenderMaterial::Additive); RenderSubDivFace(b, b, 0, 1, 2, 3, mat); RenderSubDivFace(t, t, 0, 3, 2, 1, mat); RenderSubDivFace(b, t, 1, 0, 0, 1, mat); RenderSubDivFace(b, t, 3, 2, 2, 3, mat); RenderSubDivFace(b, t, 0, 3, 3, 0, mat); RenderSubDivFace(b, t, 2, 1, 1, 2, mat); EERIE_LIGHT * light = lightHandleGet(lLightId); if(light) { light->intensity = 0.7f + 2.3f * falpha; light->fallend = 500.f; light->fallstart = 400.f; light->rgb = Color3f(0.8f, 0.0f, 1.0f); light->pos = eSrc + Vec3f(0.f, -150.f, 0.f); light->duration = GameDurationMs(800); } }
void TreatBackgroundDynlights() { ARX_PROFILE_FUNC(); for(size_t i = 0; i < g_staticLightsMax; i++) { EERIE_LIGHT * light = g_staticLights[i]; if(light && (light->extras & EXTRAS_SEMIDYNAMIC)) { float fMaxdist = player.m_telekinesis ? 850 : 300; if(!fartherThan(light->pos, g_camera->m_pos, fMaxdist)) { ComputeLight2DPos(light); } else { light->m_screenRect = Rectf(1, 0, -1, 0); // Intentionally invalid } if(!light->m_ignitionStatus) { // just extinguished EERIE_LIGHT * dynLight = lightHandleGet(light->m_ignitionLightHandle); if(dynLight) { dynLight->m_exists = false; light->m_ignitionLightHandle = LightHandle(); for(size_t l = 0; l < entities.size(); l++) { const EntityHandle handle = EntityHandle(l); Entity * e = entities[handle]; if(e && (e->ioflags & IO_MARKER)) { Vec3f _pos2 = GetItemWorldPosition(e); if(!fartherThan(light->pos, _pos2, 300.f)) { SendIOScriptEvent(NULL, e, SM_CUSTOM, "douse"); } } } } } else { // just light up if(!lightHandleGet(light->m_ignitionLightHandle)) { for(size_t l = 0; l < entities.size(); l++) { const EntityHandle handle = EntityHandle(l); Entity * e = entities[handle]; if(e && (e->ioflags & IO_MARKER)) { Vec3f _pos2 = GetItemWorldPosition(e); if(!fartherThan(light->pos, _pos2, 300.f)) { SendIOScriptEvent(NULL, e, SM_CUSTOM, "fire"); } } } light->m_ignitionLightHandle = GetFreeDynLight(); } EERIE_LIGHT * dynamicLight = lightHandleGet(light->m_ignitionLightHandle); if(dynamicLight) { dynamicLight->pos = light->pos; dynamicLight->fallstart = light->fallstart; dynamicLight->fallend = light->fallend; dynamicLight->m_isIgnitionLight = true; dynamicLight->intensity = light->intensity; dynamicLight->ex_flaresize = light->ex_flaresize; dynamicLight->extras = light->extras; dynamicLight->duration = GameDurationMs(std::numeric_limits<long>::max()); dynamicLight->rgb = light->rgb - light->rgb * light->ex_flicker * randomColor3f() * 0.5f; dynamicLight->rgb = componentwise_max(dynamicLight->rgb, Color3f::black); RecalcLight(dynamicLight); } } } } for(size_t i = 0; i < g_dynamicLightsMax; i++) { EERIE_LIGHT * el = &g_dynamicLights[i]; if(el->m_exists && el->duration != 0) { const GameDuration elapsed = g_gameTime.now() - el->creationTime; const GameDuration duration = el->duration; if(elapsed >= duration) { float sub = g_gameTime.lastFrameDuration() / GameDurationMs(1000); el->rgb.r -= sub; el->rgb.g -= sub; el->rgb.b -= sub; if(el->rgb.r < 0) el->rgb.r = 0.f; if(el->rgb.g < 0) el->rgb.g = 0.f; if(el->rgb.b < 0) el->rgb.b = 0.f; if(el->rgb.r + el->rgb.g + el->rgb.b == 0) { el->m_exists = false; el->duration = 0; } } } } }
void PoisonProjectileSpell::Launch() { ARX_SOUND_PlaySFX(g_snd.SPELL_POISON_PROJECTILE_LAUNCH, &m_caster_pos); Vec3f srcPos(0.f); float afBeta = 0.f; Entity * caster = entities[m_caster]; m_hand_group = caster->obj->fastaccess.primary_attach; if(m_hand_group != ActionPoint()) { ActionPoint group = m_hand_group; m_hand_pos = actionPointPosition(caster->obj, group); } if(m_caster == EntityHandle_Player) { afBeta = player.angle.getYaw(); if(m_hand_group != ActionPoint()) { srcPos = m_hand_pos; } else { srcPos = player.pos; } } else { afBeta = entities[m_caster]->angle.getYaw(); if(m_hand_group != ActionPoint()) { srcPos = m_hand_pos; } else { srcPos = entities[m_caster]->pos; } } srcPos += angleToVectorXZ(afBeta) * 90.f; size_t uiNumber = glm::clamp(static_cast<unsigned int>(m_level), 1u, 5u); for(size_t i = 0; i < uiNumber; i++) { CPoisonProjectile * projectile = new CPoisonProjectile(); m_projectiles.push_back(projectile); } m_duration = GameDurationMs(8000); m_hasDuration = true; GameDuration lMax = 0; for(size_t i = 0; i < m_projectiles.size(); i++) { CPoisonProjectile * projectile = m_projectiles[i]; projectile->Create(srcPos, afBeta + Random::getf(-10.f, 10.f)); GameDuration lTime = m_duration + GameDurationMs(Random::getu(0, 5000)); projectile->SetDuration(lTime); lMax = std::max(lMax, lTime); EERIE_LIGHT * light = dynLightCreate(projectile->lLightId); if(light) { light->intensity = 2.3f; light->fallend = 250.f; light->fallstart = 150.f; light->rgb = Color3f::green; light->pos = projectile->eSrc; light->creationTime = g_gameTime.now(); light->duration = GameDurationMs(200); } } m_duration = lMax + GameDurationMs(1000); }