Browse Source

Avoid unnecessary iterations in missile routines (#4843)

* early return from MI_FireRing
* Dedupe Nova missile routines
pull/4831/head
Andrew James 4 years ago committed by GitHub
parent
commit
36bf343de6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 64
      Source/missiles.cpp

64
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<Displacement, 9> 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<Displacement, 4> 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--;

Loading…
Cancel
Save