Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for spellcast command's -x flag for all spells #293

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
13421bd
SpellsLvl01: add support for -x spellcast flag
meszaros-lajos-gyorgy Oct 13, 2023
0d1ad32
SpellsLvl02: extract conditions that check spellcasts' -x flag into v…
meszaros-lajos-gyorgy Oct 13, 2023
1721114
SpellsLvl03: add support for -x spellcast flag
meszaros-lajos-gyorgy Oct 13, 2023
b54b528
Spells: Prevent loop sounds of spells with spellcast -x flag
meszaros-lajos-gyorgy Oct 13, 2023
81a1934
SpellsLvl04: Add support for -x spellcast flag
meszaros-lajos-gyorgy Oct 13, 2023
8de7c0c
SpellsLvl01: Wrap more sound related functions with checks for spellc…
meszaros-lajos-gyorgy Oct 13, 2023
cfa4083
SpellsLvl02: Wrap more sound related functions with checks for spellc…
meszaros-lajos-gyorgy Oct 13, 2023
a63450d
SpellsLvl03: Wrap more sound related functions with checks for spellc…
meszaros-lajos-gyorgy Oct 13, 2023
d12d6d0
SpellsLvl05: Wrap more sound related functions with checks for spellc…
meszaros-lajos-gyorgy Oct 14, 2023
9953856
SpellsLvl06: Wrap sound related functions with checks for spellcast -…
meszaros-lajos-gyorgy Oct 14, 2023
af9cf90
SpellsLvl07: Wrap sound related functions with checks for spellcast -…
meszaros-lajos-gyorgy Oct 14, 2023
bf23d43
SpellsLvl01: Remove extra space after if keyword
meszaros-lajos-gyorgy Oct 14, 2023
11dca3a
SpellsLvl08: Wrap sound related functions with checks for spellcast -…
meszaros-lajos-gyorgy Oct 14, 2023
70fa40d
SpellsLvl09: Wrap sound related functions with checks for spellcast -…
meszaros-lajos-gyorgy Oct 14, 2023
9256ffb
SpellsLvl10: Wrap sound related functions with checks for spellcast -…
meszaros-lajos-gyorgy Oct 14, 2023
07e16a5
Spells: Simplify emitsSound conditions
meszaros-lajos-gyorgy Oct 15, 2023
31551cf
Spell: Extract emitsSound's logic into a method
meszaros-lajos-gyorgy Oct 15, 2023
2736b66
spells: Restore whitespace
meszaros-lajos-gyorgy Oct 15, 2023
cef5377
spells: Restore whitespace
meszaros-lajos-gyorgy Oct 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/game/magic/Spell.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ class alignas(16) Spell {
m_duration = 0;
}

bool emitsSound() {
return (m_flags & SPELLCAST_FLAG_NOSOUND) == 0;
}

[[nodiscard]] std::string_view className() const noexcept;
[[nodiscard]] std::string idString() const noexcept;

Expand Down
63 changes: 42 additions & 21 deletions src/game/magic/spells/SpellsLvl01.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,15 @@ void MagicSightSpell::Launch() {
m_hasDuration = m_launchDuration >= 0;
m_duration = m_hasDuration ? m_launchDuration : 0;

ARX_SOUND_PlaySFX(g_snd.SPELL_VISION_START, &m_caster_pos);
if(emitsSound()) {
ARX_SOUND_PlaySFX(g_snd.SPELL_VISION_START, &m_caster_pos);
}

if(m_caster == EntityHandle_Player) {
player.m_improve = true;
m_snd_loop = ARX_SOUND_PlaySFX_loop(g_snd.SPELL_VISION_LOOP, &m_caster_pos, 1.f);
if(emitsSound()) {
m_snd_loop = ARX_SOUND_PlaySFX_loop(g_snd.SPELL_VISION_LOOP, &m_caster_pos, 1.f);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could all or some of these ARX_SOUND calls get a conditional variant where you pass the bool in? yes of course its more efficient to put the if() around each call instead of doing a method call just to jump back immediately, but i dont think this would affect anything.

just easier than to have 500 if(emitsSound) clauses in each spell file.

alternatively, create a macro

#define conditional_call(condition, func) if(condition){func;}
conditional_call(emitsSound, ARX_SOUND_PlaySFX_loop(g_snd.SPELL_VISION_LOOP, &m_caster_pos, 1.f))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, you'd pass a bool to a function just to tell it if it should do anything or not? That doesn't sound good.
It looks like the flag is set at the start of a spell and not anywhere else, so why not check the bit value once and use a member variable for that? Maybe see if you can use Spell base class to simplify what you want to do.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, ARX_SOUND_PlaySFX_loop() could be wrapped in a member function, say playSoundLoop() that checks for the member variable away from the main code, if reducing clutter is the goal.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that playSoundLoop would do exactly what i proposed first with a function. the conditional macro thing would not add any extra function calls but make it a oneliner that is much easier to read. the files are long enough as they are

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't imagine reading that code a year later without having to inspect that macro and spending time on it. This doesn't feel like self-documenting code.

}
}
}

Expand All @@ -70,24 +74,26 @@ void MagicSightSpell::End() {
player.m_improve = false;
}

ARX_SOUND_Stop(m_snd_loop);
m_snd_loop = audio::SourcedSample();

Entity * caster = entities.get(m_caster);
if(caster) {
ARX_SOUND_PlaySFX(g_snd.SPELL_VISION_START, &caster->pos);
if(emitsSound()) {
ARX_SOUND_Stop(m_snd_loop);
m_snd_loop = audio::SourcedSample();

Entity * caster = entities.get(m_caster);
if(caster) {
ARX_SOUND_PlaySFX(g_snd.SPELL_VISION_START, &caster->pos);
}
}
}

void MagicSightSpell::Update() {

if(m_caster == EntityHandle_Player) {
if(emitsSound() && m_caster == EntityHandle_Player) {
Vec3f pos = ARX_PLAYER_FrontPos();
ARX_SOUND_RefreshPosition(m_snd_loop, pos);
}
}

static void LaunchMagicMissileExplosion(const Vec3f & _ePos, bool mrCheat) {
static void LaunchMagicMissileExplosion(const Vec3f & _ePos, bool mrCheat, bool emitsSound) {

std::unique_ptr<ParticleSystem> particles = std::make_unique<ParticleSystem>();
if(mrCheat) {
Expand All @@ -112,7 +118,9 @@ static void LaunchMagicMissileExplosion(const Vec3f & _ePos, bool mrCheat) {
light->duration = 1500ms;
}

ARX_SOUND_PlaySFX(g_snd.SPELL_MM_HIT, &_ePos);
if(emitsSound) {
ARX_SOUND_PlaySFX(g_snd.SPELL_MM_HIT, &_ePos);
}

}

Expand Down Expand Up @@ -223,9 +231,11 @@ void MagicMissileSpell::Launch() {
missile.SetDuration(lTime);
}

ARX_SOUND_PlaySFX(g_snd.SPELL_MM_CREATE, &startPos);
ARX_SOUND_PlaySFX(g_snd.SPELL_MM_LAUNCH, &startPos);
snd_loop = ARX_SOUND_PlaySFX_loop(g_snd.SPELL_MM_LOOP, &startPos, 1.f);
if(emitsSound()) {
ARX_SOUND_PlaySFX(g_snd.SPELL_MM_CREATE, &startPos);
ARX_SOUND_PlaySFX(g_snd.SPELL_MM_LAUNCH, &startPos);
snd_loop = ARX_SOUND_PlaySFX_loop(g_snd.SPELL_MM_LOOP, &startPos, 1.f);
}

m_duration = lMax + 1s;
}
Expand All @@ -238,8 +248,10 @@ void MagicMissileSpell::End() {

m_missiles.clear();

ARX_SOUND_Stop(snd_loop);
snd_loop = audio::SourcedSample();
if(emitsSound()) {
ARX_SOUND_Stop(snd_loop);
snd_loop = audio::SourcedSample();
}
}

void MagicMissileSpell::Update() {
Expand All @@ -255,7 +267,7 @@ void MagicMissileSpell::Update() {
Entity * caster = entities.get(m_caster);
if(CheckAnythingInSphere(sphere, caster, CAS_NO_SAME_GROUP)) {

LaunchMagicMissileExplosion(missile.eCurPos, m_mrCheat);
LaunchMagicMissileExplosion(missile.eCurPos, m_mrCheat, emitsSound());
if(caster) {
spawnAudibleSound(missile.eCurPos, *caster);
}
Expand Down Expand Up @@ -287,7 +299,10 @@ void MagicMissileSpell::Update() {
}

averageMissilePos /= float(m_missiles.size());
ARX_SOUND_RefreshPosition(snd_loop, averageMissilePos);

if(emitsSound()) {
ARX_SOUND_RefreshPosition(snd_loop, averageMissilePos);
}

arx_assert(m_lights.size() == m_missiles.size());

Expand Down Expand Up @@ -399,7 +414,9 @@ void IgnitSpell::End() {
for(T_LINKLIGHTTOFX & entry : m_lights) {
EERIE_LIGHT * light = &g_staticLights[entry.m_targetLight];
light->m_ignitionStatus = true;
ARX_SOUND_PlaySFX(g_snd.SPELL_IGNITE, &light->pos);
if(emitsSound()) {
ARX_SOUND_PlaySFX(g_snd.SPELL_IGNITE, &light->pos);
}
lightHandleDestroy(entry.m_effectLight);
}

Expand Down Expand Up @@ -502,7 +519,9 @@ void DouseSpell::End() {
for(size_t index : m_lights) {
EERIE_LIGHT * light = &g_staticLights[index];
light->m_ignitionStatus = false;
ARX_SOUND_PlaySFX(g_snd.SPELL_DOUSE, &light->pos);
if(emitsSound()) {
ARX_SOUND_PlaySFX(g_snd.SPELL_DOUSE, &light->pos);
}
}

}
Expand All @@ -513,7 +532,9 @@ void DouseSpell::Update() {

void ActivatePortalSpell::Launch() {

ARX_SOUND_PlayInterface(g_snd.SPELL_ACTIVATE_PORTAL);
if(emitsSound()) {
ARX_SOUND_PlayInterface(g_snd.SPELL_ACTIVATE_PORTAL);
}

m_duration = 20ms;
m_hasDuration = true;
Expand Down
57 changes: 36 additions & 21 deletions src/game/magic/spells/SpellsLvl02.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ bool HealSpell::CanLaunch() {

void HealSpell::Launch() {

if(!(m_flags & SPELLCAST_FLAG_NOSOUND)) {
if(emitsSound()) {
ARX_SOUND_PlaySFX(g_snd.SPELL_HEALING, &m_caster_pos);
}

Expand Down Expand Up @@ -148,7 +148,7 @@ void DetectTrapSpell::Launch() {

if(m_caster == EntityHandle_Player) {
m_target = m_caster;
if(!(m_flags & SPELLCAST_FLAG_NOSOUND)) {
if(emitsSound()) {
ARX_SOUND_PlayInterface(g_snd.SPELL_DETECT_TRAP);
m_snd_loop = ARX_SOUND_PlaySFX_loop(g_snd.SPELL_DETECT_TRAP_LOOP, &m_caster_pos, 1.f);
}
Expand All @@ -163,15 +163,17 @@ void DetectTrapSpell::Launch() {

void DetectTrapSpell::End() {

ARX_SOUND_Stop(m_snd_loop);
m_snd_loop = audio::SourcedSample();
if(emitsSound()) {
ARX_SOUND_Stop(m_snd_loop);
m_snd_loop = audio::SourcedSample();
}

m_targets.clear();
}

void DetectTrapSpell::Update() {

if(m_caster == EntityHandle_Player) {
if(emitsSound() && m_caster == EntityHandle_Player) {
Vec3f pos = ARX_PLAYER_FrontPos();
ARX_SOUND_RefreshPosition(m_snd_loop, pos);
}
Expand All @@ -189,12 +191,11 @@ void ArmorSpell::Launch()
m_target = m_caster;
}

if(!(m_flags & SPELLCAST_FLAG_NOSOUND)) {
if(emitsSound()) {
ARX_SOUND_PlaySFX(g_snd.SPELL_ARMOR_START, &entities[m_target]->pos);
m_snd_loop = ARX_SOUND_PlaySFX_loop(g_snd.SPELL_ARMOR_LOOP, &entities[m_target]->pos, 1.f);
}

m_snd_loop = ARX_SOUND_PlaySFX_loop(g_snd.SPELL_ARMOR_LOOP, &entities[m_target]->pos, 1.f);

if(m_caster == EntityHandle_Player) {
m_duration = 0;
m_hasDuration = false;
Expand All @@ -217,12 +218,16 @@ void ArmorSpell::Launch()

void ArmorSpell::End() {

ARX_SOUND_Stop(m_snd_loop);
m_snd_loop = audio::SourcedSample();
if(emitsSound()) {
ARX_SOUND_Stop(m_snd_loop);
m_snd_loop = audio::SourcedSample();
}

Entity * target = entities.get(m_target);
if(target) {
ARX_SOUND_PlaySFX(g_snd.SPELL_ARMOR_END, &target->pos);
if(emitsSound()) {
ARX_SOUND_PlaySFX(g_snd.SPELL_ARMOR_END, &target->pos);
}
ARX_HALO_SetToNative(target);
}

Expand All @@ -238,7 +243,9 @@ void ArmorSpell::Update() {
io->halo.radius = 45.f;
}

ARX_SOUND_RefreshPosition(m_snd_loop, entities[m_target]->pos);
if(emitsSound()) {
ARX_SOUND_RefreshPosition(m_snd_loop, entities[m_target]->pos);
}
}

Vec3f ArmorSpell::getPosition() const {
Expand All @@ -258,7 +265,7 @@ void LowerArmorSpell::Launch() {
spells.endByCaster(m_caster, SPELL_FIRE_PROTECTION);
spells.endByCaster(m_caster, SPELL_COLD_PROTECTION);

if(!(m_flags & SPELLCAST_FLAG_NOSOUND)) {
if(emitsSound()) {
ARX_SOUND_PlaySFX(g_snd.SPELL_LOWER_ARMOR, &entities[m_target]->pos);
}

Expand Down Expand Up @@ -290,7 +297,9 @@ void LowerArmorSpell::Launch() {

void LowerArmorSpell::End() {

ARX_SOUND_PlaySFX(g_snd.SPELL_LOWER_ARMOR_END);
if(emitsSound()) {
ARX_SOUND_PlaySFX(g_snd.SPELL_LOWER_ARMOR_END);
}

if(m_haloCreated) {
Entity * io = entities.get(m_target);
Expand All @@ -316,7 +325,9 @@ void LowerArmorSpell::Update() {
}
}

ARX_SOUND_RefreshPosition(m_snd_loop, entities[m_target]->pos);
if(emitsSound()) {
ARX_SOUND_RefreshPosition(m_snd_loop, entities[m_target]->pos);
}
}

Vec3f LowerArmorSpell::getPosition() const {
Expand All @@ -325,12 +336,11 @@ Vec3f LowerArmorSpell::getPosition() const {

void HarmSpell::Launch() {

if(!(m_flags & SPELLCAST_FLAG_NOSOUND)) {
if(emitsSound()) {
ARX_SOUND_PlaySFX(g_snd.SPELL_HARM, &m_caster_pos);
m_snd_loop = ARX_SOUND_PlaySFX_loop(g_snd.SPELL_MAGICAL_SHIELD_LOOP, &m_caster_pos, 1.f);
}

m_snd_loop = ARX_SOUND_PlaySFX_loop(g_snd.SPELL_MAGICAL_SHIELD_LOOP, &m_caster_pos, 1.f);

spells.endByCaster(m_caster, SPELL_LIFE_DRAIN);
spells.endByCaster(m_caster, SPELL_MANA_DRAIN);

Expand Down Expand Up @@ -366,8 +376,10 @@ void HarmSpell::End() {

m_cabal.end();

ARX_SOUND_Stop(m_snd_loop);
m_snd_loop = audio::SourcedSample();
if(emitsSound()) {
ARX_SOUND_Stop(m_snd_loop);
m_snd_loop = audio::SourcedSample();
}
}

void HarmSpell::Update() {
Expand All @@ -388,5 +400,8 @@ void HarmSpell::Update() {
casterPos = entities[m_caster]->pos;
}
Vec3f cabalPos = m_cabal.update(casterPos);
ARX_SOUND_RefreshPosition(m_snd_loop, cabalPos);

if(emitsSound()) {
ARX_SOUND_RefreshPosition(m_snd_loop, cabalPos);
}
}
Loading