From 520bf5d9bd73b4292320a28860705cc64ebe2f59 Mon Sep 17 00:00:00 2001 From: Eric Robinson <68359262+kphoenix137@users.noreply.github.com> Date: Mon, 2 Sep 2024 14:12:18 -0400 Subject: [PATCH] Fix visually overlapping sprites for wall spells (#7208) --- Source/misdat.cpp | 5 +- Source/missiles.cpp | 125 +++++++++++++++-------------- Source/missiles.h | 5 +- assets/txtdata/missiles/misdat.tsv | 4 +- 4 files changed, 69 insertions(+), 70 deletions(-) diff --git a/Source/misdat.cpp b/Source/misdat.cpp index edab9e73f94..d006779713e 100644 --- a/Source/misdat.cpp +++ b/Source/misdat.cpp @@ -225,7 +225,7 @@ tl::expected ParseMissileAddFn(std::string_view if (value == "AddHealOther") return AddHealOther; if (value == "AddElemental") return AddElemental; if (value == "AddIdentify") return AddIdentify; - if (value == "AddFireWallControl") return AddFireWallControl; + if (value == "AddWallControl") return AddWallControl; if (value == "AddInfravision") return AddInfravision; if (value == "AddFlameWaveControl") return AddFlameWaveControl; if (value == "AddNova") return AddNova; @@ -265,7 +265,6 @@ tl::expected ParseMissileProcessFn(std::str if (value == "ProcessLightningBow") return ProcessLightningBow; if (value == "ProcessRingOfFire") return ProcessRingOfFire; if (value == "ProcessSearch") return ProcessSearch; - if (value == "ProcessLightningWallControl") return ProcessLightningWallControl; if (value == "ProcessImmolation") return ProcessImmolation; if (value == "ProcessSpectralArrow") return ProcessSpectralArrow; if (value == "ProcessLightningControl") return ProcessLightningControl; @@ -283,7 +282,7 @@ tl::expected ParseMissileProcessFn(std::str if (value == "ProcessStoneCurse") return ProcessStoneCurse; if (value == "ProcessApocalypseBoom") return ProcessApocalypseBoom; if (value == "ProcessRhino") return ProcessRhino; - if (value == "ProcessFireWallControl") return ProcessFireWallControl; + if (value == "ProcessWallControl") return ProcessWallControl; if (value == "ProcessInfravision") return ProcessInfravision; if (value == "ProcessApocalypse") return ProcessApocalypse; if (value == "ProcessFlameWaveControl") return ProcessFlameWaveControl; diff --git a/Source/missiles.cpp b/Source/missiles.cpp index 31d9a17df37..bfc35d18e8e 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -690,7 +690,7 @@ bool GuardianTryFireAt(Missile &missile, Point target) return true; } -bool GrowWall(int id, Point position, Point target, MissileID type, int spellLevel, int damage) +bool GrowWall(int id, Point position, Point target, MissileID type, int spellLevel, int damage, bool skipWall = false) { [[maybe_unused]] int dp = dPiece[position.x][position.y]; assert(dp <= MAXTILES && dp >= 0); @@ -699,7 +699,8 @@ bool GrowWall(int id, Point position, Point target, MissileID type, int spellLev return false; } - AddMissile(position, position, Direction::South, type, TARGET_BOTH, id, damage, spellLevel); + if (!skipWall) + AddMissile(position, position, Direction::South, type, TARGET_BOTH, id, damage, spellLevel); return true; } @@ -2433,7 +2434,7 @@ void AddIdentify(Missile &missile, AddMissileParameter & /*parameter*/) } } -void AddFireWallControl(Missile &missile, AddMissileParameter ¶meter) +void AddWallControl(Missile &missile, AddMissileParameter ¶meter) { std::optional spreadPosition = FindClosestValidPosition( [start = missile.position.start](Point target) { @@ -3176,43 +3177,6 @@ void ProcessSearch(Missile &missile) AutoMapShowItems = false; } -void ProcessLightningWallControl(Missile &missile) -{ - missile._mirange--; - if (missile._mirange == 0) { - missile._miDelFlag = true; - return; - } - - int id = missile._misource; - int lvl = !missile.IsTrap() ? Players[id].getCharacterLevel() : 0; - int dmg = 16 * (GenerateRndSum(10, 2) + lvl + 2); - - { - Point position = { missile.var1, missile.var2 }; - Point target = position + static_cast(missile.var3); - - if (!missile.limitReached && GrowWall(id, position, target, MissileID::LightningWall, missile._mispllvl, dmg)) { - missile.var1 = target.x; - missile.var2 = target.y; - } else { - missile.limitReached = true; - } - } - - { - Point position = { missile.var5, missile.var6 }; - Point target = position + static_cast(missile.var4); - - if (missile.var7 == 0 && GrowWall(id, position, target, MissileID::LightningWall, missile._mispllvl, dmg)) { - missile.var5 = target.x; - missile.var6 = target.y; - } else { - missile.var7 = 1; - } - } -} - void ProcessNovaCommon(Missile &missile, MissileID projectileType) { int id = missile._misource; @@ -3724,7 +3688,46 @@ void ProcessRhino(Missile &missile) PutMissile(missile); } -void ProcessFireWallControl(Missile &missile) +/* + * @brief Moves the control missile towards the right and grows walls. + * @param missile The control missile. + * @param type The missile ID of the wall missile. + * @param dmg The damage of the wall missile. + */ +static void ProcessWallControlLeft(Missile &missile, const MissileID type, const int dmg) +{ + const Point leftPosition = { missile.var1, missile.var2 }; + const Point target = leftPosition + static_cast(missile.var3); + + if (!missile.limitReached && GrowWall(missile._misource, leftPosition, target, type, missile._mispllvl, dmg)) { + missile.var1 = target.x; + missile.var2 = target.y; + } else { + missile.limitReached = true; + } +} + +/* + * @brief Moves the control missile towards the right and grows walls. + * @param missile The control missile. + * @param type The missile ID of the wall missile. + * @param dmg The damage of the wall missile. + * @param skipTile Should the tile be skipped. + */ +static void ProcessWallControlRight(Missile &missile, const MissileID type, const int dmg, const bool skipWall = false) +{ + const Point rightPosition = { missile.var5, missile.var6 }; + const Point target = rightPosition + static_cast(missile.var4); + + if (missile.var7 == 0 && GrowWall(missile._misource, rightPosition, target, type, missile._mispllvl, dmg, skipWall)) { + missile.var5 = target.x; + missile.var6 = target.y; + } else { + missile.var7 = 1; + } +} + +void ProcessWallControl(Missile &missile) { missile._mirange--; if (missile._mirange == 0) { @@ -3732,31 +3735,29 @@ void ProcessFireWallControl(Missile &missile) return; } - int id = missile._misource; - - { - Point position = { missile.var1, missile.var2 }; - Point target = position + static_cast(missile.var3); + MissileID type; + const int sourceIdx = missile._misource; + int lvl = 0; + int dmg = 0; - if (!missile.limitReached && GrowWall(id, position, target, MissileID::FireWall, missile._mispllvl, 0)) { - missile.var1 = target.x; - missile.var2 = target.y; - } else { - missile.limitReached = true; - } + switch (missile._mitype) { + case MissileID::FireWallControl: + type = MissileID::FireWall; + break; + case MissileID::LightningWallControl: + type = MissileID::LightningWall; + lvl = !missile.IsTrap() ? Players[sourceIdx].getCharacterLevel() : 0; + dmg = 16 * (GenerateRndSum(10, 2) + lvl + 2); + break; + default: + app_fatal("ProcessWallControl: Invalid missile type for control missile"); } - { - Point position = { missile.var5, missile.var6 }; - Point target = position + static_cast(missile.var4); + const Point leftPosition = { missile.var1, missile.var2 }; + const Point rightPosition = { missile.var5, missile.var6 }; - if (missile.var7 == 0 && GrowWall(id, position, target, MissileID::FireWall, missile._mispllvl, 0)) { - missile.var5 = target.x; - missile.var6 = target.y; - } else { - missile.var7 = 1; - } - } + ProcessWallControlLeft(missile, type, dmg); + ProcessWallControlRight(missile, type, dmg, leftPosition == rightPosition); } void ProcessInfravision(Missile &missile) diff --git a/Source/missiles.h b/Source/missiles.h index aeba01dbc93..a1927bf9b22 100644 --- a/Source/missiles.h +++ b/Source/missiles.h @@ -363,7 +363,7 @@ void AddIdentify(Missile &missile, AddMissileParameter ¶meter); * var5: X coordinate of the second wave * var6: Y coordinate of the second wave */ -void AddFireWallControl(Missile &missile, AddMissileParameter ¶meter); +void AddWallControl(Missile &missile, AddMissileParameter ¶meter); void AddInfravision(Missile &missile, AddMissileParameter ¶meter); /** @@ -421,7 +421,6 @@ void ProcessBigExplosion(Missile &missile); void ProcessLightningBow(Missile &missile); void ProcessRingOfFire(Missile &missile); void ProcessSearch(Missile &missile); -void ProcessLightningWallControl(Missile &missile); void ProcessImmolation(Missile &missile); void ProcessSpectralArrow(Missile &missile); void ProcessLightningControl(Missile &missile); @@ -439,7 +438,7 @@ void ProcessTeleport(Missile &missile); void ProcessStoneCurse(Missile &missile); void ProcessApocalypseBoom(Missile &missile); void ProcessRhino(Missile &missile); -void ProcessFireWallControl(Missile &missile); +void ProcessWallControl(Missile &missile); void ProcessInfravision(Missile &missile); void ProcessApocalypse(Missile &missile); void ProcessFlameWaveControl(Missile &missile); diff --git a/assets/txtdata/missiles/misdat.tsv b/assets/txtdata/missiles/misdat.tsv index 37ea3e69665..986f99a9372 100644 --- a/assets/txtdata/missiles/misdat.tsv +++ b/assets/txtdata/missiles/misdat.tsv @@ -37,7 +37,7 @@ Etherealize SpellEtherealize Etherealize Physical Spurt Spurt Physical ApocalypseBoom AddApocalypseBoom ProcessApocalypseBoom ApocalypseBoom Physical Healing AddHealing Physical,Invisible -FireWallControl AddFireWallControl ProcessFireWallControl FireWall Fire,Invisible +FireWallControl AddWallControl ProcessWallControl FireWall Fire,Invisible Infravision AddInfravision ProcessInfravision SpellInfravision Physical,Invisible Identify AddIdentify Physical,Invisible FlameWaveControl AddFlameWaveControl ProcessFlameWaveControl SpellFlameWave FireWall Fire @@ -70,7 +70,7 @@ DiabloApocalypse AddDiabloApocalypse Physical,Invisible Mana AddMana Physical,Invisible Magi AddMagi Physical,Invisible LightningWall AddLightningWall ProcessLightningWall SpellLightningWall SpellLightningHit Lightning Lightning -LightningWallControl AddFireWallControl ProcessLightningWallControl Lightning Lightning,Invisible +LightningWallControl AddWallControl ProcessWallControl Lightning Lightning,Invisible Immolation AddNova ProcessImmolation SpellFirebolt SpellFireHit Fireball Fire SpectralArrow AddSpectralArrow ProcessSpectralArrow Arrow Physical,Arrow FireballBow AddImmolation ProcessFireball ShootFireballBow SpellFireHit Fireball Fire Blockable