|
|
|
|
@ -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<Point> 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<Direction>(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<Direction>(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<Direction>(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<Direction>(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<Direction>(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<Direction>(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) |
|
|
|
|
|