diff --git a/Source/missiles.cpp b/Source/missiles.cpp index 282a7b442..7e08f7e02 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -2991,6 +2991,9 @@ void MI_FireRing(Missile &missile) uint8_t lvl = missile._micaster == TARGET_MONSTERS ? Players[src]._pLevel : currlevel; int dmg = 16 * (GenerateRndSum(10, 2) + lvl + 2) / 2; + if (missile.limitReached) + return; + for (auto displacement : CrawlTable[3]) { Point target = Point { missile.var1, missile.var2 } + displacement; if (!InDungeonBounds(target)) @@ -3002,9 +3005,9 @@ void MI_FireRing(Missile &missile) continue; if (!LineClearMissile(missile.position.tile, target)) continue; - if (TileHasAny(dp, TileProperties::BlockMissile) || missile.limitReached) { + if (TileHasAny(dp, TileProperties::BlockMissile)) { missile.limitReached = true; - continue; + return; } AddMissile(target, target, Direction::South, MIS_FIREWALL, TARGET_BOTH, src, dmg, missile._mispllvl); @@ -3060,10 +3063,8 @@ void MI_LightningWallC(Missile &missile) } } -void MI_FireNova(Missile &missile) +void MI_NovaCommon(Missile &missile, missile_id projectileType) { - int sx1 = 0; - int sy1 = 0; int id = missile._misource; int dam = missile._midam; Point src = missile.position.tile; @@ -3073,20 +3074,29 @@ void MI_FireNova(Missile &missile) dir = Players[id]._pdir; en = TARGET_MONSTERS; } - for (const auto &k : VisionCrawlTable) { - if (sx1 != k[6] || sy1 != k[7]) { - Displacement offsets[] = { { k[6], k[7] }, { -k[6], -k[7] }, { -k[6], +k[7] }, { +k[6], -k[7] } }; - for (Displacement offset : offsets) - AddMissile(src, src + offset, dir, MIS_FIRENOVA, en, id, dam, missile._mispllvl); - sx1 = k[6]; - sy1 = k[7]; - } + + constexpr std::array quarterRadius = { { { 4, 0 }, { 4, 1 }, { 4, 2 }, { 4, 3 }, { 4, 4 }, { 3, 4 }, { 2, 4 }, { 1, 4 }, { 0, 4 } } }; + for (Displacement quarterOffset : quarterRadius) { + // This ends up with two missiles targeting offsets 4,0, 0,4, -4,0, 0,-4. + std::array offsets { quarterOffset, quarterOffset.flipXY(), quarterOffset.flipX(), quarterOffset.flipY() }; + for (Displacement offset : offsets) + AddMissile(src, src + offset, dir, projectileType, en, id, dam, missile._mispllvl); } missile._mirange--; if (missile._mirange == 0) missile._miDelFlag = true; } +void MI_FireNova(Missile &missile) +{ + MI_NovaCommon(missile, MIS_FIRENOVA); +} + +void MI_Nova(Missile &missile) +{ + MI_NovaCommon(missile, MIS_LIGHTBALL); +} + void MI_SpecArrow(Missile &missile) { int id = missile._misource; @@ -3638,34 +3648,6 @@ void MI_Wave(Missile &missile) missile._miDelFlag = true; } -void MI_Nova(Missile &missile) -{ - int sx1 = 0; - int sy1 = 0; - int id = missile._misource; - int dam = missile._midam; - Point src = missile.position.tile; - Direction dir = Direction::South; - mienemy_type en = TARGET_PLAYERS; - if (!missile.IsTrap()) { - dir = Players[id]._pdir; - en = TARGET_MONSTERS; - } - for (const auto &k : VisionCrawlTable) { - if (sx1 != k[6] || sy1 != k[7]) { - AddMissile(src, src + Displacement { k[6], k[7] }, dir, MIS_LIGHTBALL, en, id, dam, missile._mispllvl); - AddMissile(src, src + Displacement { -k[6], -k[7] }, dir, MIS_LIGHTBALL, en, id, dam, missile._mispllvl); - AddMissile(src, src + Displacement { -k[6], k[7] }, dir, MIS_LIGHTBALL, en, id, dam, missile._mispllvl); - AddMissile(src, src + Displacement { k[6], -k[7] }, dir, MIS_LIGHTBALL, en, id, dam, missile._mispllvl); - sx1 = k[6]; - sy1 = k[7]; - } - } - missile._mirange--; - if (missile._mirange == 0) - missile._miDelFlag = true; -} - void MI_Blodboil(Missile &missile) { missile._mirange--;