CPoisonProjectile::CPoisonProjectile() : eSrc(Vec3f_ZERO) , lightIntensityFactor(1.f) , fBetaRadCos(0.f) , fBetaRadSin(0.f) , bOk(false) , fTrail(-1.f) { SetDuration(ArxDurationMs(2000)); m_elapsed = m_duration + ArxDurationMs(1); }
void FireFieldSpell::Launch() { spells.endByCaster(m_caster, SPELL_FIRE_FIELD); ARX_SOUND_PlaySFX(SND_SPELL_FIRE_FIELD_START); m_duration = (m_launchDuration > ArxDuration(-1)) ? m_launchDuration : ArxDurationMs(100000); m_hasDuration = true; m_fManaCostPerSecond = 2.8f; m_light = LightHandle(); Vec3f target; float beta = 0.f; bool displace = false; if(m_caster == EntityHandle_Player) { target = player.basePosition(); beta = player.angle.getYaw(); displace = true; } else { if(ValidIONum(m_caster)) { Entity * io = entities[m_caster]; target = io->pos; beta = io->angle.getYaw(); displace = (io->ioflags & IO_NPC) == IO_NPC; } else { ARX_DEAD_CODE(); } } if(displace) { target += angleToVectorXZ(beta) * 250.f; } m_pos = target + Vec3f(0, -10, 0); DamageParameters damage; damage.radius = 150.f; damage.damages = 10.f; damage.area = DAMAGE_FULL; damage.duration = ArxDurationMs(100000000); damage.source = m_caster; damage.flags = 0; damage.type = DAMAGE_TYPE_MAGICAL | DAMAGE_TYPE_FIRE | DAMAGE_TYPE_FIELD; damage.pos = target; m_damage = DamageCreate(damage); m_snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_FIRE_FIELD_LOOP, &target, 1.f, ARX_SOUND_PLAY_LOOPED); pPSStream.SetParams(g_particleParameters[ParticleParam_FireFieldBase]); pPSStream.SetPos(m_pos); pPSStream1.SetParams(g_particleParameters[ParticleParam_FireFieldFlame]); pPSStream1.SetPos(m_pos + Vec3f(0, 10, 0)); pPSStream1.Update(0); }
void MagicSightSpell::Launch() { m_fManaCostPerSecond = 0.36f; m_hasDuration = true; m_duration = (m_launchDuration > ArxDurationMs(-1)) ? m_launchDuration : ArxDurationMs(6000000); ARX_SOUND_PlaySFX(SND_SPELL_VISION_START, &m_caster_pos); if(m_caster == EntityHandle_Player) { player.m_improve = true; m_snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_VISION_LOOP, &m_caster_pos, 1.f, ARX_SOUND_PLAY_LOOPED); } }
static void ARX_TEMPORARY_TrySound(Entity * source, Material collisionMaterial, float volume) { if(source->ioflags & IO_BODY_CHUNK) return; ArxInstant now = arxtime.now(); if(now > source->soundtime) { source->soundcount++; if(source->soundcount < 5) { Material material; if(EEIsUnderWater(source->pos)) material = MATERIAL_WATER; else if(source->material) material = source->material; else material = MATERIAL_STONE; if(volume > 1.f) volume = 1.f; long soundLength = ARX_SOUND_PlayCollision(material, collisionMaterial, volume, 1.f, source->pos, source); source->soundtime = now + ArxDurationMs(soundLength >> 4) + ArxDurationMs(50); }
void FlyingEyeSpell::Update() { const ArxInstant now = arxtime.now(); const ArxDuration framediff3 = now - m_lastupdate; eyeball.floating = std::sin(m_lastupdate - m_timcreation * 0.001f); eyeball.floating *= 10.f; if(m_lastupdate - m_timcreation <= ArxDurationMs(3000)) { eyeball.exist = m_lastupdate - m_timcreation * (1.0f / 30); eyeball.size = Vec3f(1.f - float(eyeball.exist) * 0.01f); eyeball.angle.setYaw(eyeball.angle.getYaw() + toMs(framediff3) * 0.6f); } else { eyeball.exist = 2; } m_lastupdate = now; Entity * io = entities.player(); if(io->obj->fastaccess.primary_attach != ActionPoint()) { Vec3f pos = actionPointPosition(io->obj, io->obj->fastaccess.primary_attach); FlyingEyeSpellUpdateHand(pos, m_light1); } if(io->obj->fastaccess.left_attach != ActionPoint()) { Vec3f pos = actionPointPosition(io->obj, io->obj->fastaccess.left_attach); FlyingEyeSpellUpdateHand(pos, m_light2); } }
void ConfuseSpell::Launch() { ARX_SOUND_PlaySFX(SND_SPELL_CONFUSE, &entities[m_target]->pos); m_hasDuration = true; m_fManaCostPerSecond = 1.5f; m_duration = (m_launchDuration > ArxDuration(-1)) ? m_launchDuration : ArxDurationMs(5000); tex_p1 = TextureContainer::Load("graph/obj3d/textures/(fx)_tsu_blueting"); tex_trail = TextureContainer::Load("graph/obj3d/textures/(fx)_bandelette_blue"); const char tex[] = "graph/obj3d/interactive/fix_inter/fx_papivolle/fx_papivolle.tea"; ANIM_HANDLE * anim_papii = EERIE_ANIMMANAGER_Load(tex); AnimLayer & au = animlayer[0]; au.next_anim = NULL; au.cur_anim = anim_papii; au.ctime = AnimationDuration_ZERO; au.flags = EA_LOOP; au.nextflags = 0; au.lastframe = 0; au.currentInterpolation = 0; au.currentFrame = 0; au.altidx_cur = 0; au.altidx_next = 0; m_targets.push_back(m_target); }
static void LaunchMagicMissileExplosion(const Vec3f & _ePos, bool mrCheat) { ParticleParams cp = g_particleParameters[ParticleParam_MagicMissileExplosion]; if(mrCheat) { cp = g_particleParameters[ParticleParam_MagicMissileExplosionMar]; } ParticleSystem * pPS = new ParticleSystem(); pPS->SetParams(cp); pPS->SetPos(_ePos); pPS->Update(0); EERIE_LIGHT * light = dynLightCreate(); if(light) { light->intensity = 2.3f; light->fallstart = 250.f; light->fallend = 420.f; if(mrCheat) { light->rgb = Color3f(1.f, 0.3f, .8f); } else { light->rgb = Color3f(0.f, 0.f, .8f); } light->pos = _ePos; light->duration = ArxDurationMs(1500); } arx_assert(pParticleManager); pParticleManager->AddSystem(pPS); ARX_SOUND_PlaySFX(SND_SPELL_MM_HIT, &_ePos); }
void ARX_SPEECH_Add(const std::string & text) { if(text.empty()) return; ArxInstant now = arxtime.now(); if(now == ArxInstant_ZERO) { now = ArxInstantMs(1); } if(speech[MAX_SPEECH - 1].timecreation != ArxInstant_ZERO) { ARX_SPEECH_MoveUp(); } for(size_t i = 0; i < MAX_SPEECH; i++) { if(speech[i].timecreation != ArxInstant_ZERO) continue; // Sets creation time speech[i].timecreation = now; speech[i].duration = ArxDurationMs(2000 + text.length() * 60); speech[i].text = text; return; } LogInfo << "Failed to add speech: " << text; }
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 LightningStrikeSpell::Launch() { Vec3f target(0.f, 0.f, -500.f); m_lightning.Create(Vec3f_ZERO, target); m_lightning.SetDuration(ArxDurationMs(500 * m_level)); m_lightning.m_isMassLightning = false; m_duration = m_lightning.m_duration; ARX_SOUND_PlaySFX(SND_SPELL_LIGHTNING_START, &m_caster_pos); m_snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_LIGHTNING_LOOP, &m_caster_pos, 1.f, ARX_SOUND_PLAY_LOOPED); }
void FissureFx::SetDuration(ArxDuration alDurationIntro, ArxDuration alDurationRender, ArxDuration alDurationOuttro) { ulDurationIntro = arx::clamp(alDurationIntro, ArxDurationMs(100), ArxDurationMs(100000)); ulDurationRender = arx::clamp(alDurationRender, ArxDurationMs(100), ArxDurationMs(100000)); ulDurationOuttro = arx::clamp(alDurationOuttro, ArxDurationMs(100), ArxDurationMs(100000)); m_elapsed = ArxDuration_ZERO; m_duration = ulDurationIntro + ulDurationRender + ulDurationOuttro; }
CRiseDead::CRiseDead() : FissureFx() , m_eSrc(Vec3f_ZERO) , fBetaRadCos(0.f) , fBetaRadSin(0.f) , tex_light(NULL) , end(40 - 1) , iSize(100) , bIntro(true) , sizeF(0) , fSizeIntro(0.f) { m_elapsed = m_duration + ArxDurationMs(1); tex_light = TextureContainer::Load("graph/obj3d/textures/(fx)_tsu4"); }
static bool SelectSpellTargetCursorRender() { if( !SPECIAL_DRAGINTER_RENDER && LOOKING_FOR_SPELL_TARGET ) { ArxDuration elapsed = arxtime.now() - LOOKING_FOR_SPELL_TARGET_TIME; if(elapsed > ArxDurationMs(7000)) { ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE, &player.pos); ARX_SPELLS_CancelSpellTarget(); } TextureContainer * surf; if(FlyingOverIO && (((LOOKING_FOR_SPELL_TARGET & 1) && (FlyingOverIO->ioflags & IO_NPC)) || ((LOOKING_FOR_SPELL_TARGET & 2) && (FlyingOverIO->ioflags & IO_ITEM))) ){ surf = cursorTargetOn; if(eeMouseUp1()) { ARX_SPELLS_LaunchSpellTarget(FlyingOverIO); } } else { surf = cursorTargetOff; if(GInput->actionPressed(CONTROLS_CUST_MAGICMODE)) { ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE, &player.pos); ARX_SPELLS_CancelSpellTarget(); } } Vec2f pos = Vec2f(DANAEMouse); if(TRUE_PLAYER_MOUSELOOK_ON) { pos = MemoMouse; } Vec2f texSize = Vec2f(surf->size()); pos += -texSize * 0.5f; EERIEDrawBitmap(Rectf(pos, texSize.x, texSize.y), 0.f, surf, Color::white); return true; } return false; }
CSummonCreature::CSummonCreature() : FissureFx() , fBetaRadCos(0.f) , fBetaRadSin(0.f) , end(0) , bIntro(true) , sizeF(0.f) , fSizeIntro(0.f) { m_eSrc = Vec3f_ZERO; m_elapsed = m_duration + ArxDurationMs(1); iSize = 100; fOneOniSize = 1.0f / ((float) iSize); tex_light = TextureContainer::Load("graph/obj3d/textures/(fx)_tsu4"); }
void LightningStrikeSpell::Update() { float fBeta = 0.f; float falpha = 0.f; Entity * caster = entities[m_caster]; ObjVertHandle idx = GetGroupOriginByName(caster->obj, "chest"); if(idx != ObjVertHandle()) { m_caster_pos = caster->obj->vertexlist3[idx.handleData()].v; } else { m_caster_pos = caster->pos; } if(m_caster == EntityHandle_Player) { falpha = -player.angle.getPitch(); fBeta = player.angle.getYaw(); } else { fBeta = caster->angle.getYaw(); if(ValidIONum(caster->targetinfo) && caster->targetinfo != m_caster) { const Vec3f & p1 = m_caster_pos; Vec3f p2 = GetChestPos(caster->targetinfo); falpha = MAKEANGLE(glm::degrees(getAngle(p1.y, p1.z, p2.y, p2.z + glm::distance(Vec2f(p2.x, p2.z), Vec2f(p1.x, p1.z))))); //alpha entre orgn et dest; } else if(ValidIONum(m_target)) { const Vec3f & p1 = m_caster_pos; Vec3f p2 = GetChestPos(m_target); falpha = MAKEANGLE(glm::degrees(getAngle(p1.y, p1.z, p2.y, p2.z + glm::distance(Vec2f(p2.x, p2.z), Vec2f(p1.x, p1.z))))); //alpha entre orgn et dest; } } m_lightning.m_pos = m_caster_pos; m_lightning.m_beta = fBeta; m_lightning.m_alpha = falpha; m_lightning.m_caster = m_caster; m_lightning.m_level = m_level; m_lightning.Update(ArxDurationMs(g_framedelay)); m_lightning.Render(); ARX_SOUND_RefreshPosition(m_snd_loop, entities[m_caster]->pos); }
void FlyingEyeSpell::Launch() { static TextureContainer * tc4 = TextureContainer::Load("graph/particles/smoke"); ARX_SOUND_PlaySFX(SND_SPELL_EYEBALL_IN); m_lastupdate = m_timcreation; m_duration = ArxDurationMs(1000000); m_hasDuration = true; m_fManaCostPerSecond = 3.2f; eyeball.exist = 1; eyeball.pos = player.pos; eyeball.pos += angleToVectorXZ(player.angle.getYaw()) * 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::getu(2000, 6000); pd->scale = Vec3f(12.f); pd->tc = tc4; pd->m_flags = FADE_IN_AND_OUT | ROTATING | DISSIPATING; pd->m_rotation = 0.0000001f; pd->rgb = Color3f(0.7f, 0.7f, 1.f); } TRUE_PLAYER_MOUSELOOK_ON = true; SLID_START = g_platformTime.frameStart(); bOldLookToggle = config.input.mouseLookToggle; config.input.mouseLookToggle = true; }
void CPoisonProjectile::Update(ArxDuration timeDelta) { if(m_elapsed <= ArxDurationMs(2000)) { m_elapsed += timeDelta; } // on passe de 5 à 100 partoches en 1.5secs if(m_elapsed < 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 - 750) * (1.0f / (m_duration - 750.0f))) * 9 * (BEZIERPrecision + 2); } if(m_elapsed >= m_duration) lightIntensityFactor = 0.f; else lightIntensityFactor = 1.f; }
void IceFieldSpell::Launch() { spells.endByCaster(m_caster, SPELL_ICE_FIELD); ARX_SOUND_PlaySFX(SND_SPELL_ICE_FIELD); m_duration = (m_launchDuration > ArxDuration(-1)) ? m_launchDuration : ArxDurationMs(100000); m_hasDuration = true; m_fManaCostPerSecond = 2.8f; m_light = LightHandle(); Vec3f target; float beta = 0.f; bool displace = false; if(m_caster == EntityHandle_Player) { target = player.basePosition(); beta = player.angle.getYaw(); displace = true; } else { if(ValidIONum(m_caster)) { Entity * io = entities[m_caster]; target = io->pos; beta = io->angle.getYaw(); displace = (io->ioflags & IO_NPC) == IO_NPC; } else { ARX_DEAD_CODE(); } } 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 = ArxDurationMs(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_ZERO; tSizeMax[i] = randomVec3f() + Vec3f(0.f, 0.2f, 0.f); Vec3f minPos; if(tType[i] == 0) { minPos = Vec3f(1.2f, 1, 1.2f); } else { minPos = 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(SND_SPELL_ICE_FIELD_LOOP, &target, 1.f, ARX_SOUND_PLAY_LOOPED); }
//TODO Move somewhere else void Cedric_ApplyLightingFirstPartRefactor(Entity *io) { if(!io) return; io->special_color = Color3f::white; float poisonpercent = 0.f; float trappercent = 0.f; float secretpercent = 0.f; if((io->ioflags & IO_NPC) && io->_npcdata->poisonned > 0.f) { poisonpercent = io->_npcdata->poisonned * ( 1.0f / 20 ); if(poisonpercent > 1.f) poisonpercent = 1.f; } if((io->ioflags & IO_ITEM) && io->poisonous > 0.f && io->poisonous_count) { poisonpercent = io->poisonous * (1.0f / 20); if(poisonpercent > 1.f) poisonpercent = 1.f; } if((io->ioflags & IO_FIX) && io->_fixdata->trapvalue > -1) { trappercent = player.TRAP_DETECT - io->_fixdata->trapvalue; if(trappercent > 0.f) { trappercent = 0.6f + trappercent * ( 1.0f / 100 ); trappercent = glm::clamp(trappercent, 0.6f, 1.f); } } if((io->ioflags & IO_FIX) && io->secretvalue > -1) { secretpercent = player.TRAP_SECRET - io->secretvalue; if(secretpercent > 0.f) { secretpercent = 0.6f + secretpercent * ( 1.0f / 100 ); secretpercent = glm::clamp(secretpercent, 0.6f, 1.f); } } if(poisonpercent > 0.f) { io->special_color = Color3f::green; } if(trappercent > 0.f) { io->special_color = Color3f(trappercent, 1.f - trappercent, 1.f - trappercent); } if(secretpercent > 0.f) { io->special_color = Color3f(1.f - secretpercent, 1.f - secretpercent, secretpercent); } if(io->ioflags & IO_FREEZESCRIPT) { io->special_color = Color3f::blue; } if(io->sfx_flag & SFX_TYPE_YLSIDE_DEATH) { if(io->show == SHOW_FLAG_TELEPORTING) { io->sfx_time = io->sfx_time + ArxDurationMs(g_framedelay); if (io->sfx_time >= arxtime.now()) io->sfx_time = arxtime.now(); } else { const ArxDuration elapsed = arxtime.now() - io->sfx_time; if(elapsed > ArxDuration_ZERO) { if(elapsed < ArxDurationMs(3000)) { // 5 seconds to red float ratio = toMs(elapsed) * (1.0f / 3000); io->special_color = Color3f(1.f, 1.f - ratio, 1.f - ratio); io->highlightColor += Color3f(std::max(ratio - 0.5f, 0.f), 0.f, 0.f) * 255; AddRandomSmoke(io, 1); } else if(elapsed < ArxDurationMs(6000)) { // 5 seconds to White float ratio = toMs(elapsed) * (1.0f / 3000); io->special_color = Color3f::red; io->highlightColor += Color3f(std::max(ratio - 0.5f, 0.f), 0.f, 0.f) * 255; AddRandomSmoke(io, 2); } else { // SFX finish io->sfx_time = ArxInstant_ZERO; if(io->ioflags & IO_NPC) { MakePlayerAppearsFX(io); AddRandomSmoke(io, 50); Color3f rgb = io->_npcdata->blood_color.to<float>(); Sphere sp = Sphere(io->pos, 200.f); long count = 6; while(count--) { Sphere splatSphere = Sphere(sp.origin, Random::getf(30.f, 60.f)); PolyBoomAddSplat(splatSphere, rgb, 1); sp.origin.y -= Random::getf(0.f, 150.f); ARX_PARTICLES_Spawn_Splat(sp.origin, 200.f, io->_npcdata->blood_color); sp.origin = io->pos + randomVec3f() * Vec3f(200.f, 20.f,200.f) - Vec3f(100.f, 10.f, 100.f); sp.radius = Random::getf(100.f, 200.f); } EERIE_LIGHT * light = dynLightCreate(); if(light) { light->intensity = Random::getf(0.7f, 2.7f); light->fallend = 600.f; light->fallstart = 400.f; light->rgb = Color3f(1.0f, 0.8f, 0.f); light->pos = io->pos + Vec3f(0.f, -80.f, 0.f); light->duration = ArxDurationMs(600); } if(io->sfx_flag & SFX_TYPE_INCINERATE) { io->sfx_flag &= ~SFX_TYPE_INCINERATE; io->sfx_flag &= ~SFX_TYPE_YLSIDE_DEATH; SpellBase * spell = spells.getSpellOnTarget(io->index(), SPELL_INCINERATE); if(!spell) spell = spells.getSpellOnTarget(io->index(), SPELL_MASS_INCINERATE); if(spell) { spells.endSpell(spell); float damages = 20 * spell->m_level; damages = ARX_SPELLS_ApplyFireProtection(io, damages); if (ValidIONum(spell->m_caster)) ARX_DAMAGES_DamageNPC(io, damages, spell->m_caster, true, &entities[spell->m_caster]->pos); else ARX_DAMAGES_DamageNPC(io, damages, spell->m_caster, true, &io->pos); ARX_SOUND_PlaySFX(SND_SPELL_FIRE_HIT, &io->pos); } } else { io->sfx_flag &= ~SFX_TYPE_YLSIDE_DEATH; ARX_INTERACTIVE_DestroyIOdelayed(io); } } } } } } }
static void Cedric_RenderObject(EERIE_3DOBJ * eobj, Skeleton * obj, Entity * io, const Vec3f & pos, float invisibility) { if(invisibility == 1.f) return; Entity *use_io = io; if(!io && IN_BOOK_DRAW && eobj == entities.player()->obj) use_io = entities.player(); HaloInfo haloInfo; if(use_io) { if(use_io == entities.player()) { pushSlotHalo(haloInfo, EQUIP_SLOT_HELMET, eobj->fastaccess.sel_head); pushSlotHalo(haloInfo, EQUIP_SLOT_ARMOR, eobj->fastaccess.sel_chest); pushSlotHalo(haloInfo, EQUIP_SLOT_LEGGINGS, eobj->fastaccess.sel_leggings); } if(use_io->halo.flags & HALO_ACTIVE) { haloInfo.push(HaloRenderInfo(&use_io->halo)); } if(haloInfo.size > 0) { PrepareAnimatedObjectHalo(haloInfo, pos, obj, eobj); } } bool glow = false; ColorRGBA glowColor; if(io && (io->sfx_flag & SFX_TYPE_YLSIDE_DEATH) && io->show != SHOW_FLAG_TELEPORTING) { const ArxDuration elapsed = arxtime.now() - io->sfx_time; if(elapsed >= ArxDurationMs(3000) && elapsed < ArxDurationMs(6000)) { float ratio = toMs(elapsed - ArxDurationMs(3000)) * (1.0f / 3000); glowColor = Color::gray(ratio).toRGB(); glow = true; } } for(size_t i = 0; i < eobj->facelist.size(); i++) { const EERIE_FACE & face = eobj->facelist[i]; if((face.facetype & POLY_HIDE) && !IN_BOOK_DRAW) continue; if(CullFace(eobj, face)) continue; if(face.texid < 0) continue; TextureContainer *pTex = eobj->texturecontainer[face.texid]; if(!pTex) continue; float fTransp = 0.f; TexturedVertex *tvList = GetNewVertexList(&pTex->m_modelBatch, face, invisibility, fTransp); for(size_t n = 0; n < 3; n++) { tvList[n].p = eobj->vertexlist3[face.vid[n]].vert.p; tvList[n].rhw = eobj->vertexlist3[face.vid[n]].vert.rhw; tvList[n].color = eobj->vertexlist3[face.vid[n]].vert.color; tvList[n].uv.x = face.u[n]; tvList[n].uv.y = face.v[n]; } if((face.facetype & POLY_TRANS) || invisibility > 0.f) { tvList[0].color = tvList[1].color = tvList[2].color = Color::gray(fTransp).toRGB(); } if(haloInfo.size) { AddAnimatedObjectHalo(haloInfo, face.vid, invisibility, eobj, io, tvList); } if(glow) { TexturedVertex * tv2 = PushVertexInTable(&TexSpecialColor.m_modelBatch, BatchBucket_Opaque); std::copy(tvList, tvList + 3, tv2); tv2[0].color = tv2[1].color = tv2[2].color = glowColor; } } }
// 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 ConfuseSpell::End() { m_targets.clear(); endLightDelayed(m_light, ArxDurationMs(500)); }
void ConfuseSpell::Update() { Vec3f pos = entities[m_target]->pos; if(m_target != EntityHandle_Player) { pos.y += entities[m_target]->physics.cyl.height - 30.f; } ObjVertHandle idx = entities[m_target]->obj->fastaccess.head_group_origin; if(idx != ObjVertHandle()) { pos = entities[m_target]->obj->vertexlist3[idx.handleData()].v; pos.y -= 50.f; } eCurPos = pos; RenderMaterial mat; mat.setDepthTest(false); mat.setBlendType(RenderMaterial::Additive); mat.setTexture(tex_trail); Anglef stiteangle = Anglef(0.f, -glm::degrees(arxtime.now_f() * ( 1.0f / 500 )), 0.f); { AnimationDuration delta = AnimationDurationUs(s64(g_framedelay * 1000.f)); EERIEDrawAnimQuatUpdate(spapi, animlayer, stiteangle, eCurPos, delta, NULL, false); EERIEDrawAnimQuatRender(spapi, eCurPos, NULL, 0.f); } for(int i = 0; i < 6; i++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } Vec2f p = glm::diskRand(15.f); pd->ov = eCurPos + Vec3f(p.x, 0.f, p.y); pd->move = Vec3f(0.f, Random::getf(1.f, 4.f), 0.f); pd->siz = 0.25f; pd->tolive = Random::getu(2300, 3300); pd->tc = tex_p1; pd->m_flags = PARTICLE_GOLDRAIN | FADE_IN_AND_OUT | ROTATING | DISSIPATING; pd->m_rotation = 0.0000001f; Color3f baseColor = Color3f(0.4f, 0.2f, 0.4f); Color3f randomFactor = Color3f(0.4f, 0.6f, 0.4f); Color3f c = baseColor + randomColor3f() * randomFactor; while(glm::abs(c.r - c.g) > 0.3f && glm::abs(c.g - c.b) > 0.3f) { c = baseColor + randomColor3f() * randomFactor; } pd->rgb = c * Color3f(0.8f, 0.8f, 0.8f); } EERIE_LIGHT * light = dynLightCreate(m_light); if(light) { light->intensity = 1.3f; light->fallstart = 180.f; light->fallend = 420.f; light->rgb = Color3f(0.3f, 0.3f, 0.5f) + Color3f(0.2f, 0.f, 0.2f) * randomColor3f(); light->pos = eCurPos; light->duration = ArxDurationMs(200); light->extras = 0; } }
//*********************************************************************************************** // flags & 1 = blood spawn only //----------------------------------------------------------------------------------------------- //*********************************************************************************************** bool ARX_EQUIPMENT_Strike_Check(Entity * io_source, Entity * io_weapon, float ratioaim, long flags, EntityHandle targ) { ARX_PROFILE_FUNC(); arx_assert(io_source); arx_assert(io_weapon); bool ret = false; EntityHandle source = io_source->index(); EntityHandle weapon = io_weapon->index(); EXCEPTIONS_LIST_Pos = 0; float drain_life = ARX_EQUIPMENT_GetSpecialValue(io_weapon, IO_SPECIAL_ELEM_DRAIN_LIFE); float paralyse = ARX_EQUIPMENT_GetSpecialValue(io_weapon, IO_SPECIAL_ELEM_PARALYZE); BOOST_FOREACH(const EERIE_ACTIONLIST & action, io_weapon->obj->actionlist) { float rad = GetHitValue(action.name); if(rad == -1) continue; Sphere sphere; sphere.origin = actionPointPosition(io_weapon->obj, action.idx); sphere.radius = rad; if(source != EntityHandle_Player) sphere.radius += 15.f; std::vector<EntityHandle> sphereContent; if(CheckEverythingInSphere(sphere, source, targ, sphereContent)) { BOOST_FOREACH(const EntityHandle & content, sphereContent) { if(ValidIONum(content) && !(entities[content]->ioflags & IO_BODY_CHUNK)) { bool HIT_SPARK = false; EXCEPTIONS_LIST[EXCEPTIONS_LIST_Pos] = content; EXCEPTIONS_LIST_Pos++; if(EXCEPTIONS_LIST_Pos >= MAX_IN_SPHERE) EXCEPTIONS_LIST_Pos--; Entity * target = entities[content]; Vec3f pos; Color color = Color::white; long hitpoint = -1; float curdist = 999999.f; Vec3f vector = (sphere.origin - target->pos) * Vec3f(1.f, 0.5f, 1.f); vector = glm::normalize(vector); for(size_t ii = 0; ii < target->obj->facelist.size(); ii++) { if(target->obj->facelist[ii].facetype & POLY_HIDE) continue; float d = glm::distance(sphere.origin, target->obj->vertexlist3[target->obj->facelist[ii].vid[0]].v); if(d < curdist) { hitpoint = target->obj->facelist[ii].vid[0]; curdist = d; } } if(hitpoint >= 0) { color = (target->ioflags & IO_NPC) ? target->_npcdata->blood_color : Color::white; pos = target->obj->vertexlist3[hitpoint].v; } else ARX_DEAD_CODE(); float dmgs = 0.f; if(!(flags & 1)) { Vec3f posi; if(hitpoint >= 0) { posi = target->obj->vertexlist3[hitpoint].v; dmgs = ARX_EQUIPMENT_ComputeDamages(io_source, target, ratioaim, &posi); } else { dmgs = ARX_EQUIPMENT_ComputeDamages(io_source, target, ratioaim); } if(target->ioflags & IO_NPC) { ret = true; target->spark_n_blood = 0; target->_npcdata->SPLAT_TOT_NB = 0; if(drain_life > 0.f) { float life_gain = std::min(dmgs, drain_life); life_gain = std::min(life_gain, target->_npcdata->lifePool.current); life_gain = std::max(life_gain, 0.f); ARX_DAMAGES_HealInter(io_source, life_gain); } if(paralyse > 0.f) { ArxDuration ptime = ArxDurationMs(std::min(dmgs * 1000.f, paralyse)); ARX_SPELLS_Launch(SPELL_PARALYSE, weapon, SPELLCAST_FLAG_NOMANA | SPELLCAST_FLAG_NOCHECKCANCAST, 5, content, ptime); } } if(io_source == entities.player()) ARX_DAMAGES_DurabilityCheck(io_weapon, 0.2f); } if(dmgs > 0.f || ((target->ioflags & IO_NPC) && target->spark_n_blood == SP_BLOODY)) { if(target->ioflags & IO_NPC) { target->spark_n_blood = SP_BLOODY; if(!(flags & 1)) { ARX_PARTICLES_Spawn_Splat(pos, dmgs, color); Vec3f vertPos = target->obj->vertexlist3[hitpoint].v; float power = (dmgs * ( 1.0f / 40 )) + 0.7f; Vec3f vect; vect.x = vertPos.x - io_source->pos.x; vect.y = 0; vect.z = vertPos.z - io_source->pos.z; vect = glm::normalize(vect); Sphere sp; sp.origin.x = vertPos.x + vect.x * 30.f; sp.origin.y = vertPos.y; sp.origin.z = vertPos.z + vect.z * 30.f; sp.radius = 3.5f * power * 20; if(CheckAnythingInSphere(sp, EntityHandle_Player, CAS_NO_NPC_COL)) { Color3f rgb = color.to<float>(); Sphere splatSphere; splatSphere.origin = sp.origin; splatSphere.radius = 30.f; PolyBoomAddSplat(splatSphere, rgb, 1); } } ARX_PARTICLES_Spawn_Blood2(pos, dmgs, color, target); } else { if(target->ioflags & IO_ITEM) ParticleSparkSpawn(pos, Random::getu(0, 3), SpawnSparkType_Default); else ParticleSparkSpawn(pos, Random::getu(0, 30), SpawnSparkType_Default); ARX_NPC_SpawnAudibleSound(pos, io_source); if(io_source == entities.player()) HIT_SPARK = true; } } else if((target->ioflags & IO_NPC) && (dmgs <= 0.f || target->spark_n_blood == SP_SPARKING)) { unsigned int nb; if(target->spark_n_blood == SP_SPARKING) nb = Random::getu(0, 3); else nb = 30; if(target->ioflags & IO_ITEM) nb = 1; ParticleSparkSpawn(pos, nb, SpawnSparkType_Default); ARX_NPC_SpawnAudibleSound(pos, io_source); target->spark_n_blood = SP_SPARKING; if(!(target->ioflags & IO_NPC)) HIT_SPARK = true; } else if(dmgs <= 0.f && ((target->ioflags & IO_FIX) || (target->ioflags & IO_ITEM))) { unsigned int nb; if(target->spark_n_blood == SP_SPARKING) nb = Random::getu(0, 3); else nb = 30; if(target->ioflags & IO_ITEM) nb = 1; ParticleSparkSpawn(pos, nb, SpawnSparkType_Default); ARX_NPC_SpawnAudibleSound(pos, io_source); target->spark_n_blood = SP_SPARKING; if (!(target->ioflags & IO_NPC)) HIT_SPARK = true; } if(HIT_SPARK) { if(!io_source->isHit) { ARX_DAMAGES_DurabilityCheck(io_weapon, 1.f); io_source->isHit = true; std::string _weapon_material = "metal"; const std::string * weapon_material = &_weapon_material; if(!io_weapon->weaponmaterial.empty()) { weapon_material = &io_weapon->weaponmaterial; } if(target->material != MATERIAL_NONE) { const char * matStr = ARX_MATERIAL_GetNameById(target->material); ARX_SOUND_PlayCollision(*weapon_material, matStr, 1.f, 1.f, sphere.origin, NULL); } } } } } } const EERIEPOLY * ep = CheckBackgroundInSphere(sphere); if(ep) { if(io_source == entities.player()) { if(!io_source->isHit) { ARX_DAMAGES_DurabilityCheck(io_weapon, 1.f); io_source->isHit = true; std::string _weapon_material = "metal"; const std::string * weapon_material = &_weapon_material; if(!io_weapon->weaponmaterial.empty()) { weapon_material = &io_weapon->weaponmaterial; } std::string bkg_material = "earth"; if(ep && ep->tex && !ep->tex->m_texName.empty()) bkg_material = GetMaterialString(ep->tex->m_texName); ARX_SOUND_PlayCollision(*weapon_material, bkg_material, 1.f, 1.f, sphere.origin, io_source); } } ParticleSparkSpawn(sphere.origin, Random::getu(0, 10), SpawnSparkType_Default); ARX_NPC_SpawnAudibleSound(sphere.origin, io_source); } } return ret; }
void MagicMissileSpell::Launch() { m_duration = ArxDurationMs(6000); m_hand_group = GetActionPointIdx(entities[m_caster]->obj, "primary_attach"); if(m_hand_group != ActionPoint()) { Entity * caster = entities[m_caster]; ActionPoint group = m_hand_group; m_hand_pos = actionPointPosition(caster->obj, group); } Vec3f startPos; float pitch, yaw; if(m_caster == EntityHandle_Player) { yaw = player.angle.getYaw(); pitch = player.angle.getPitch(); Vec3f vector = angleToVector(Anglef(pitch, yaw, 0.f)) * 60.f; if(m_hand_group != ActionPoint()) { startPos = m_hand_pos; } else { startPos = player.pos; startPos += angleToVectorXZ(yaw); } startPos += vector; } else { pitch = 0; yaw = entities[m_caster]->angle.getYaw(); Vec3f vector = angleToVector(Anglef(pitch, yaw, 0.f)) * 60.f; if(m_hand_group != ActionPoint()) { startPos = m_hand_pos; } else { startPos = entities[m_caster]->pos; } startPos += vector; Entity * io = entities[m_caster]; if(ValidIONum(io->targetinfo)) { const Vec3f & p1 = m_caster_pos; const Vec3f & p2 = entities[io->targetinfo]->pos; pitch = -(glm::degrees(getAngle(p1.y, p1.z, p2.y, p2.z + glm::distance(Vec2f(p2.x, p2.z), Vec2f(p1.x, p1.z))))); //alpha entre orgn et dest; } else if (ValidIONum(m_target)) { const Vec3f & p1 = m_caster_pos; const Vec3f & p2 = entities[m_target]->pos; pitch = -(glm::degrees(getAngle(p1.y, p1.z, p2.y, p2.z + glm::distance(Vec2f(p2.x, p2.z), Vec2f(p1.x, p1.z))))); //alpha entre orgn et dest; } } m_mrCheat = (m_caster == EntityHandle_Player && cur_mr == 3); ArxDuration lMax = ArxDuration_ZERO; long number; if(sp_max || cur_rf == 3) { number = long(m_level); } else { number = glm::clamp(long(m_level + 1) / 2, 1l, 5l); } pTab.reserve(number); for(size_t i = 0; i < size_t(number); i++) { CMagicMissile * missile = NULL; if(!m_mrCheat) { missile = new CMagicMissile(); } else { missile = new MrMagicMissileFx(); } pTab.push_back(missile); Anglef angles(pitch, yaw, 0.f); if(i > 0) { angles.setPitch(angles.getPitch() + Random::getf(-4.0f, 4.0f)); angles.setYaw(angles.getYaw() + Random::getf(-6.0f, 6.0f)); } missile->Create(startPos, angles); ArxDuration lTime = m_duration + ArxDurationMs(Random::get(-1000, 1000)); lTime = std::max(ArxDurationMs(1000), lTime); lMax = std::max(lMax, lTime); missile->SetDuration(lTime); EERIE_LIGHT * el = dynLightCreate(missile->lLightId); if(el) { el->intensity = 0.7f + 2.3f; el->fallend = 190.f; el->fallstart = 80.f; if(m_mrCheat) { el->rgb = Color3f(1.f, 0.3f, 0.8f); } else { el->rgb = Color3f(0.f, 0.f, 1.f); } el->pos = startPos; el->duration = ArxDurationMs(300); } } m_duration = lMax + ArxDurationMs(1000); }
void MagicMissileSpell::Update() { for(size_t i = 0; i < pTab.size(); i++) { CMagicMissile * missile = pTab[i]; if(missile->bExplo) continue; Sphere sphere = Sphere(missile->eCurPos, 10.f); if(CheckAnythingInSphere(sphere, m_caster, CAS_NO_SAME_GROUP)) { LaunchMagicMissileExplosion(missile->eCurPos, m_mrCheat); ARX_NPC_SpawnAudibleSound(missile->eCurPos, entities[m_caster]); missile->SetTTL(ArxDurationMs(1000)); missile->bExplo = true; missile->bMove = false; missile->lLightId = LightHandle(); DamageParameters damage; damage.pos = missile->eCurPos; damage.radius = 80.f; damage.damages = (4 + m_level * ( 1.0f / 5 )) * .8f; damage.area = DAMAGE_FULL; damage.duration = ArxDuration(-1); damage.source = m_caster; damage.flags = DAMAGE_FLAG_DONT_HURT_SOURCE; damage.type = DAMAGE_TYPE_MAGICAL; DamageCreate(damage); Color3f rgb(.3f, .3f, .45f); ARX_PARTICLES_Add_Smoke(missile->eCurPos, 0, 6, rgb); } } for(size_t i = 0 ; i < pTab.size() ; i++) { pTab[i]->Update(ArxDurationMs(g_framedelay)); } { // CheckAllDestroyed long nbmissiles = 0; for(size_t i = 0; i < pTab.size(); i++) { CMagicMissile *pMM = pTab[i]; if(pMM->bMove) nbmissiles++; } if(nbmissiles == 0) m_duration = ArxDuration_ZERO; } for(size_t i = 0; i < pTab.size(); i++) { pTab[i]->Render(); CMagicMissile * pMM = pTab[i]; EERIE_LIGHT * el = lightHandleGet(pMM->lLightId); if(el) { el->intensity = 0.7f + 2.3f * pMM->lightIntensityFactor; el->pos = pMM->eCurPos; el->creationTime = arxtime.now(); } } }
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 DouseSpell::Launch() { m_duration = ArxDurationMs(500); Vec3f target; if(m_hand_group != ActionPoint()) { target = m_hand_pos; } else { target = m_caster_pos; target.y -= 50.f; } float fPerimeter = 400.f + m_level * 30.f; CheckForIgnition(Sphere(target, fPerimeter), 0, 1); for(size_t ii = 0; ii < g_staticLightsMax; ii++) { EERIE_LIGHT * light = g_staticLights[ii]; if(!light || !(light->extras & EXTRAS_EXTINGUISHABLE)) { continue; } if(!(light->extras & EXTRAS_SEMIDYNAMIC) && !(light->extras & EXTRAS_SPAWNFIRE) && !(light->extras & EXTRAS_SPAWNSMOKE)) { continue; } if(!light->m_ignitionStatus) { continue; } if(!fartherThan(target, light->pos, fPerimeter)) { m_lights.push_back(ii); } } if(player.torch && closerThan(target, player.pos, fPerimeter)) { ARX_PLAYER_ClickedOnTorch(player.torch); } for(size_t k = 0; k < MAX_SPELLS; k++) { SpellBase * spell = spells[SpellHandle(k)]; if(!spell) { continue; } switch(spell->m_type) { case SPELL_FIREBALL: { Vec3f pos = spell->getPosition(); float radius = std::max(m_level * 2.f, 12.f); if(closerThan(target, pos, fPerimeter + radius)) { spell->m_level -= m_level; if(spell->m_level < 1) { spells.endSpell(spell); } } break; } case SPELL_FIRE_FIELD: { Vec3f pos = spell->getPosition(); if(closerThan(target, pos, fPerimeter + 200)) { spell->m_level -= m_level; if(spell->m_level < 1) { spells.endSpell(spell); } } break; } default: break; } } }
void IgnitSpell::Launch() { m_duration = ArxDurationMs(500); if(m_hand_group != ActionPoint()) { m_srcPos = m_hand_pos; } else { m_srcPos = m_caster_pos - Vec3f(0.f, 50.f, 0.f); } EERIE_LIGHT * light = dynLightCreate(); if(light) { light->intensity = 1.8f; light->fallend = 450.f; light->fallstart = 380.f; light->rgb = Color3f(1.f, 0.75f, 0.5f); light->pos = m_srcPos; light->duration = ArxDurationMs(300); } float fPerimeter = 400.f + m_level * 30.f; m_lights.clear(); m_elapsed = ArxDuration_ZERO; CheckForIgnition(Sphere(m_srcPos, fPerimeter), 1, 1); for(size_t ii = 0; ii < g_staticLightsMax; ii++) { EERIE_LIGHT * light = g_staticLights[ii]; if(!light || !(light->extras & EXTRAS_EXTINGUISHABLE)) { continue; } if(m_caster == EntityHandle_Player && (light->extras & EXTRAS_NO_IGNIT)) { continue; } if(!(light->extras & EXTRAS_SEMIDYNAMIC) && !(light->extras & EXTRAS_SPAWNFIRE) && !(light->extras & EXTRAS_SPAWNSMOKE)) { continue; } if(light->m_ignitionStatus) { continue; } if(!fartherThan(m_srcPos, light->pos, fPerimeter)) { T_LINKLIGHTTOFX entry; entry.m_targetLight = ii; EERIE_LIGHT * light = dynLightCreate(entry.m_effectLight); if(light) { light->intensity = Random::getf(0.7f, 2.7f); light->fallend = 400.f; light->fallstart = 300.f; light->rgb = Color3f(1.f, 1.f, 1.f); light->pos = light->pos; } m_lights.push_back(entry); } } for(size_t n = 0; n < MAX_SPELLS; n++) { SpellBase * spell = spells[SpellHandle(n)]; if(!spell) { continue; } if(spell->m_type == SPELL_FIREBALL) { Vec3f pos = static_cast<FireballSpell *>(spell)->getPosition(); float radius = std::max(m_level * 2.f, 12.f); if(closerThan(m_srcPos, pos, fPerimeter + radius)) { spell->m_level += 1; } } } }
void ARX_SPEECH_Update() { ArxInstant now = arxtime.now(); if(cinematicBorder.isActive() || BLOCK_PLAYER_CONTROLS) ARX_CONVERSATION_CheckAcceleratedSpeech(); for(size_t i = 0; i < MAX_ASPEECH; i++) { if(!aspeech[i].exist) continue; Entity * io = aspeech[i].io; // updates animations if(io) { if(aspeech[i].flags & ARX_SPEECH_FLAG_OFFVOICE) ARX_SOUND_RefreshSpeechPosition(aspeech[i].sample); else ARX_SOUND_RefreshSpeechPosition(aspeech[i].sample, io); if((io != entities.player() || EXTERNALVIEW) && ValidIOAddress(io)) { if(!io->anims[aspeech[i].mood]) aspeech[i].mood = ANIM_TALK_NEUTRAL; ANIM_HANDLE * anim = io->anims[aspeech[i].mood]; if(anim) { AnimLayer & layer2 = io->animlayer[2]; if(layer2.cur_anim != anim || (layer2.flags & EA_ANIMEND)) { changeAnimation(io, 2, anim); } } } } // checks finished speech if(now >= aspeech[i].time_creation + aspeech[i].duration) { EERIE_SCRIPT *es = aspeech[i].es; Entity *io = aspeech[i].ioscript; long scrpos = aspeech[i].scrpos; ARX_SPEECH_Release(i); if(es && ValidIOAddress(io)) ScriptEvent::send(es, SM_EXECUTELINE, "", io, "", scrpos); } } for(size_t i = 0; i < MAX_ASPEECH; i++) { ARX_SPEECH *speech = &aspeech[i]; if(!speech->exist) continue; if(speech->text.empty()) continue; if(!cinematicBorder.isActive()) continue; if(cinematicBorder.CINEMA_DECAL < 100.f) continue; Vec2i sSize = hFontInBook->getTextSize(speech->text); float fZoneClippHeight = static_cast<float>(sSize.y * 3); float fStartYY = 100 * g_sizeRatio.y; float fStartY = static_cast<float>(((int)fStartYY - (int)fZoneClippHeight) >> 1); float fDepY = ((float)g_size.height()) - fStartYY + fStartY - speech->fDeltaY + sSize.y; float fZoneClippY = fDepY + speech->fDeltaY; float fAdd = fZoneClippY + fZoneClippHeight ; Rect::Num y = checked_range_cast<Rect::Num>(fZoneClippY); Rect::Num h = checked_range_cast<Rect::Num>(fAdd); Rect clippingRect(0, y+1, g_size.width(), h); if(config.interface.limitSpeechWidth) { s32 w = std::min(g_size.width(), s32(640 * g_sizeRatio.y)); clippingRect.left = (g_size.width() - w) / 2; clippingRect.right = (g_size.width() + w) / 2; } float height = (float)ARX_UNICODE_DrawTextInRect( hFontInBook, Vec2f(clippingRect.left + 10.f, fDepY + fZoneClippHeight), clippingRect.right - 10.f, speech->text, Color::white, &clippingRect); GRenderer->SetBlendFunc(BlendZero, BlendInvSrcColor); GRenderer->SetRenderState(Renderer::AlphaBlending, true); GRenderer->SetRenderState(Renderer::DepthTest, false); EERIEDrawFill2DRectDegrad(Vec2f(0.f, fZoneClippY - 1.f), Vec2f(static_cast<float>(g_size.width()), fZoneClippY + (sSize.y * 3 / 4)), 0.f, Color::white, Color::black); EERIEDrawFill2DRectDegrad(Vec2f(0.f, fZoneClippY + fZoneClippHeight - (sSize.y * 3 / 4)), Vec2f(static_cast<float>(g_size.width()), fZoneClippY + fZoneClippHeight), 0.f, Color::black, Color::white); GRenderer->SetBlendFunc(BlendOne, BlendZero); GRenderer->SetRenderState(Renderer::DepthTest, true); GRenderer->SetRenderState(Renderer::AlphaBlending, false); height += fZoneClippHeight; if(speech->fDeltaY <= height) { //vitesse du scroll float fDTime; if(speech->sample) { ArxDuration duration = ARX_SOUND_GetDuration(speech->sample); if(duration == ArxDuration_ZERO) { duration = ArxDurationMs(4000); } fDTime = (height * g_framedelay) / duration; //speech->duration; float fTimeOneLine = sSize.y * fDTime; if(speech->iTimeScroll >= fTimeOneLine) { float fResteLine = sSize.y - speech->fPixelScroll; float fTimePlus = (fResteLine * g_framedelay) / duration; fDTime -= fTimePlus; speech->fPixelScroll = 0.f; speech->iTimeScroll = 0; } speech->iTimeScroll += checked_range_cast<int>(g_framedelay); } else { fDTime = (height * g_framedelay) / 4000.0f; } speech->fDeltaY += fDTime; speech->fPixelScroll += fDTime; } } }